comparison src/th06/enemy.rs @ 657:ff7b6355cdf1

Port the Enemy struct from Python, for now without its methods.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 09 Aug 2019 01:36:47 +0200
parents
children 3a9d82a02c88
comparison
equal deleted inserted replaced
656:988e5130fb00 657:ff7b6355cdf1
1 //! Module providing an Enemy struct, to be changed by EclRunner.
2
3 use crate::th06::anm0::Anm0;
4 use crate::th06::anm0_vm::{Sprite, AnmRunner};
5 use crate::th06::interpolator::{Interpolator1, Interpolator2};
6 use crate::util::prng::Prng;
7 use std::cell::RefCell;
8 use std::collections::HashMap;
9 use std::rc::{Rc, Weak};
10
11 #[derive(Debug, Clone, Copy)]
12 struct Position {
13 x: f32,
14 y: f32,
15 }
16
17 #[derive(Debug, Clone, Copy)]
18 struct Offset {
19 dx: f32,
20 dy: f32,
21 }
22
23 impl Position {
24 pub fn new(x: f32, y: f32) -> Position {
25 Position { x, y }
26 }
27 }
28
29 impl Offset {
30 pub fn new(dx: f32, dy: f32) -> Offset {
31 Offset { dx, dy }
32 }
33 }
34
35 impl std::ops::Add<Offset> for Position {
36 type Output = Position;
37 fn add(self, offset: Offset) -> Position {
38 Position {
39 x: self.x + offset.dx,
40 y: self.y + offset.dy,
41 }
42 }
43 }
44
45 #[derive(Debug, Clone)]
46 struct Callback;
47
48 #[derive(Debug, Clone)]
49 struct Laser;
50
51 #[derive(Debug, Clone)]
52 struct Process;
53
54 struct Game {
55 enemies: Vec<Enemy>,
56 prng: Rc<RefCell<Prng>>,
57 }
58
59 /// Common to all elements in game.
60 struct Element {
61 pos: Position,
62 removed: bool,
63 sprite: Weak<RefCell<Sprite>>,
64 anmrunner: AnmRunner,
65 }
66
67 /// The enemy struct, containing everything pertaining to an enemy.
68 pub struct Enemy {
69 // Common to all elements in game.
70 pos: Position,
71 removed: bool,
72 sprite: Rc<RefCell<Sprite>>,
73 anmrunner: Rc<RefCell<AnmRunner>>,
74
75 // Specific to enemy.
76 // Floats.
77 z: f32,
78 angle: f32,
79 speed: f32,
80 rotation_speed: f32,
81 acceleration: f32,
82
83 // Ints.
84 type_: u32,
85 bonus_dropped: u32,
86 die_score: u32,
87 frame: u32,
88 life: u32,
89 death_flags: u32,
90 current_laser_id: u32,
91 low_life_trigger: u32,
92 timeout: u32,
93 remaining_lives: u32,
94 bullet_launch_interval: u32,
95 bullet_launch_timer: u32,
96 death_anim: u32,
97 direction: u32,
98 update_mode: u32,
99
100 // Bools.
101 visible: bool,
102 was_visible: bool,
103 touchable: bool,
104 collidable: bool,
105 damageable: bool,
106 boss: bool,
107 automatic_orientation: bool,
108 delay_attack: bool,
109
110 // Tuples.
111 difficulty_coeffs: (f32, f32, u32, u32, u32, u32),
112 extended_bullet_attributes: Option<(u32, u32, u32, u32, f32, f32, f32, f32)>,
113 bullet_attributes: Option<(i16, i16, u32, u32, u32, f32, f32, f32, f32, u32)>,
114 bullet_launch_offset: Offset,
115 movement_dependant_sprites: Option<(f32, f32, f32, f32)>,
116 screen_box: Option<(f32, f32, f32, f32)>,
117
118 // Callbacks.
119 death_callback: Option<Callback>,
120 boss_callback: Option<Callback>,
121 low_life_callback: Option<Callback>,
122 timeout_callback: Option<Callback>,
123
124 // Laser.
125 laser_by_id: HashMap<u32, Laser>,
126
127 // Options.
128 options: Vec<Element>,
129
130 // Interpolators.
131 interpolator: Option<Interpolator2<f32>>,
132 speed_interpolator: Option<Interpolator1<f32>>,
133
134 // Misc stuff, do we need them?
135 anm0: Weak<RefCell<Anm0>>,
136 process: Rc<RefCell<Process>>,
137 game: Weak<RefCell<Game>>,
138 prng: Weak<RefCell<Prng>>,
139 hitbox_half_size: (f32, f32),
140 }
141
142 impl Enemy {
143 /// Sets the animation to the one indexed by index in the current anm0.
144 pub fn set_anim(&mut self, index: u8) {
145 self.sprite = Rc::new(RefCell::new(Sprite::new()));
146 let anm0 = self.anm0.upgrade().unwrap();
147 let anmrunner = AnmRunner::new(&*anm0.borrow(), index, self.sprite.clone(), self.prng.clone(), 0);
148 self.anmrunner = Rc::new(RefCell::new(anmrunner));
149 }
150 }