Mercurial > touhou
comparison src/th06/enemy.rs @ 686:aefe5b5f481e
ecl_vm: implement the SetBulletAttributes opcodes.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 17 Aug 2019 04:28:24 +0200 |
parents | c8bb28961d31 |
children | ac092b70c39a |
comparison
equal
deleted
inserted
replaced
685:11d7e4d6947a | 686:aefe5b5f481e |
---|---|
8 use std::cell::RefCell; | 8 use std::cell::RefCell; |
9 use std::collections::HashMap; | 9 use std::collections::HashMap; |
10 use std::rc::{Rc, Weak}; | 10 use std::rc::{Rc, Weak}; |
11 | 11 |
12 /// The 2D position of an object in the game. | 12 /// The 2D position of an object in the game. |
13 #[derive(Debug, Clone, Copy, Default)] | 13 #[derive(Debug, Clone, Copy, Default, PartialEq)] |
14 pub struct Position { | 14 pub struct Position { |
15 pub(crate) x: f32, | 15 pub(crate) x: f32, |
16 pub(crate) y: f32, | 16 pub(crate) y: f32, |
17 } | 17 } |
18 | 18 |
19 /// An offset which can be added to a Position. | 19 /// An offset which can be added to a Position. |
20 #[derive(Debug, Clone, Copy, Default)] | 20 #[derive(Debug, Clone, Copy, Default, PartialEq)] |
21 pub struct Offset { | 21 pub struct Offset { |
22 dx: f32, | 22 dx: f32, |
23 dy: f32, | 23 dy: f32, |
24 } | 24 } |
25 | 25 |
118 | 118 |
119 #[derive(PartialEq)] | 119 #[derive(PartialEq)] |
120 pub(crate) struct DifficultyCoeffs { | 120 pub(crate) struct DifficultyCoeffs { |
121 pub(crate) speed_a: f32, | 121 pub(crate) speed_a: f32, |
122 pub(crate) speed_b: f32, | 122 pub(crate) speed_b: f32, |
123 pub(crate) nb_a: u16, | 123 pub(crate) nb_a: i16, |
124 pub(crate) nb_b: u16, | 124 pub(crate) nb_b: i16, |
125 pub(crate) shots_a: u16, | 125 pub(crate) shots_a: i16, |
126 pub(crate) shots_b: u16, | 126 pub(crate) shots_b: i16, |
127 } | 127 } |
128 | 128 |
129 impl Default for DifficultyCoeffs { | 129 impl Default for DifficultyCoeffs { |
130 fn default() -> DifficultyCoeffs { | 130 fn default() -> DifficultyCoeffs { |
131 DifficultyCoeffs { | 131 DifficultyCoeffs { |
134 nb_a: 0, | 134 nb_a: 0, |
135 nb_b: 0, | 135 nb_b: 0, |
136 shots_a: 0, | 136 shots_a: 0, |
137 shots_b: 0, | 137 shots_b: 0, |
138 } | 138 } |
139 } | |
140 } | |
141 | |
142 #[derive(Debug, Clone, Default, PartialEq)] | |
143 pub(crate) struct BulletAttributes { | |
144 pub(crate) anim: i16, | |
145 pub(crate) sprite_index_offset: i16, | |
146 pub(crate) pos: Position, // Doesn’t have a z field. | |
147 pub(crate) launch_angle: f32, | |
148 pub(crate) angle: f32, | |
149 pub(crate) speed: f32, | |
150 pub(crate) speed2: f32, | |
151 pub(crate) extended_attributes: (i32, i32, i32, i32, f32, f32, f32, f32), | |
152 // unknown: x32, | |
153 pub(crate) bullets_per_shot: i16, | |
154 pub(crate) number_of_shots: i16, | |
155 pub(crate) bullet_type: i16, | |
156 // zero: x32, | |
157 pub(crate) flags: u32, | |
158 pub(crate) ins84_param: i32, | |
159 } | |
160 | |
161 impl BulletAttributes { | |
162 /// Fire! | |
163 pub fn fire(&mut self) { | |
164 println!("PAN!"); | |
139 } | 165 } |
140 } | 166 } |
141 | 167 |
142 #[derive(PartialEq)] | 168 #[derive(PartialEq)] |
143 pub(crate) enum Direction { | 169 pub(crate) enum Direction { |
196 pub(crate) automatic_orientation: bool, | 222 pub(crate) automatic_orientation: bool, |
197 pub(crate) delay_attack: bool, | 223 pub(crate) delay_attack: bool, |
198 | 224 |
199 // Tuples. | 225 // Tuples. |
200 pub(crate) difficulty_coeffs: DifficultyCoeffs, | 226 pub(crate) difficulty_coeffs: DifficultyCoeffs, |
201 pub(crate) extended_bullet_attributes: Option<(u32, u32, u32, u32, f32, f32, f32, f32)>, | 227 pub(crate) bullet_attributes: BulletAttributes, |
202 pub(crate) bullet_attributes: Option<(i16, i16, u32, u32, u32, f32, f32, f32, f32, u32)>, | 228 pub(crate) bullet_offset: Offset, |
203 pub(crate) bullet_launch_offset: Offset, | |
204 pub(crate) movement_dependant_sprites: Option<(u8, u8, u8, u8)>, | 229 pub(crate) movement_dependant_sprites: Option<(u8, u8, u8, u8)>, |
205 pub(crate) screen_box: Option<(f32, f32, f32, f32)>, | 230 pub(crate) screen_box: Option<(f32, f32, f32, f32)>, |
206 | 231 |
207 // Callbacks. | 232 // Callbacks. |
208 death_callback: Option<Callback>, | 233 death_callback: Option<Callback>, |
272 /// Sets the hitbox around the enemy. | 297 /// Sets the hitbox around the enemy. |
273 pub fn set_hitbox(&mut self, width: f32, height: f32) { | 298 pub fn set_hitbox(&mut self, width: f32, height: f32) { |
274 self.hitbox_half_size = [width / 2., height / 2.]; | 299 self.hitbox_half_size = [width / 2., height / 2.]; |
275 } | 300 } |
276 | 301 |
302 /// Defines the attributes for the next bullet fired, and fire it if delay_attack isn’t set! | |
303 pub fn set_bullet_attributes(&mut self, opcode: u16, anim: i16, sprite_index_offset: i16, | |
304 bullets_per_shot: i16, number_of_shots: i16, speed: f32, | |
305 speed2: f32, launch_angle: f32, angle: f32, flags: u32) { | |
306 // Get the coeffs for the current difficulty. | |
307 let difficulty = self.get_difficulty() as i16; | |
308 let coeff_nb = self.difficulty_coeffs.nb_a + (self.difficulty_coeffs.nb_b - self.difficulty_coeffs.nb_a) * difficulty / 32; | |
309 let coeff_shots = self.difficulty_coeffs.shots_a + (self.difficulty_coeffs.shots_b - self.difficulty_coeffs.shots_a) * difficulty / 32; | |
310 let coeff_speed = self.difficulty_coeffs.speed_a + (self.difficulty_coeffs.speed_b - self.difficulty_coeffs.speed_a) * difficulty as f32 / 32.; | |
311 | |
312 let opcode = 67; | |
313 let mut bullet = &mut self.bullet_attributes; | |
314 | |
315 bullet.anim = anim; | |
316 bullet.bullet_type = opcode - 67; | |
317 bullet.sprite_index_offset = sprite_index_offset; | |
318 | |
319 bullet.bullets_per_shot = bullets_per_shot + coeff_nb; | |
320 if bullet.bullets_per_shot < 1 { | |
321 bullet.bullets_per_shot = 1; | |
322 } | |
323 | |
324 bullet.number_of_shots = number_of_shots + coeff_shots; | |
325 if bullet.number_of_shots < 1 { | |
326 bullet.number_of_shots = 1; | |
327 } | |
328 | |
329 bullet.pos = self.pos + self.bullet_offset; | |
330 | |
331 bullet.speed = speed + coeff_speed; | |
332 if bullet.speed < 0.3 { | |
333 bullet.speed = 0.3; | |
334 } | |
335 | |
336 bullet.speed2 = speed2 + coeff_speed / 2.; | |
337 if bullet.speed2 < 0.3 { | |
338 bullet.speed2 = 0.3; | |
339 } | |
340 | |
341 bullet.launch_angle = launch_angle.atan2(0.); | |
342 bullet.angle = angle; | |
343 bullet.flags = flags; | |
344 | |
345 if !self.delay_attack { | |
346 bullet.fire(); | |
347 } | |
348 } | |
349 | |
277 /// Run all interpolators and such, and update internal variables once per | 350 /// Run all interpolators and such, and update internal variables once per |
278 /// frame. | 351 /// frame. |
279 pub fn update(&mut self) { | 352 pub fn update(&mut self) { |
280 let Position { mut x, mut y } = self.pos; | 353 let Position { mut x, mut y } = self.pos; |
281 | 354 |