Mercurial > touhou
view 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 |
line wrap: on
line source
//! Module providing an Enemy struct, to be changed by EclRunner. use crate::th06::anm0::Anm0; use crate::th06::anm0_vm::{Sprite, AnmRunner}; use crate::th06::interpolator::{Interpolator1, Interpolator2}; use crate::util::prng::Prng; use std::cell::RefCell; use std::collections::HashMap; use std::rc::{Rc, Weak}; #[derive(Debug, Clone, Copy)] struct Position { x: f32, y: f32, } #[derive(Debug, Clone, Copy)] struct Offset { dx: f32, dy: f32, } impl Position { pub fn new(x: f32, y: f32) -> Position { Position { x, y } } } impl Offset { pub fn new(dx: f32, dy: f32) -> Offset { Offset { dx, dy } } } impl std::ops::Add<Offset> for Position { type Output = Position; fn add(self, offset: Offset) -> Position { Position { x: self.x + offset.dx, y: self.y + offset.dy, } } } #[derive(Debug, Clone)] struct Callback; #[derive(Debug, Clone)] struct Laser; #[derive(Debug, Clone)] struct Process; struct Game { enemies: Vec<Enemy>, prng: Rc<RefCell<Prng>>, } /// Common to all elements in game. struct Element { pos: Position, removed: bool, sprite: Weak<RefCell<Sprite>>, anmrunner: AnmRunner, } /// The enemy struct, containing everything pertaining to an enemy. pub struct Enemy { // Common to all elements in game. pos: Position, removed: bool, sprite: Rc<RefCell<Sprite>>, anmrunner: Rc<RefCell<AnmRunner>>, // Specific to enemy. // Floats. z: f32, angle: f32, speed: f32, rotation_speed: f32, acceleration: f32, // Ints. type_: u32, bonus_dropped: u32, die_score: u32, frame: u32, life: u32, death_flags: u32, current_laser_id: u32, low_life_trigger: u32, timeout: u32, remaining_lives: u32, bullet_launch_interval: u32, bullet_launch_timer: u32, death_anim: u32, direction: u32, update_mode: u32, // Bools. visible: bool, was_visible: bool, touchable: bool, collidable: bool, damageable: bool, boss: bool, automatic_orientation: bool, delay_attack: bool, // Tuples. difficulty_coeffs: (f32, f32, u32, u32, u32, u32), extended_bullet_attributes: Option<(u32, u32, u32, u32, f32, f32, f32, f32)>, bullet_attributes: Option<(i16, i16, u32, u32, u32, f32, f32, f32, f32, u32)>, bullet_launch_offset: Offset, movement_dependant_sprites: Option<(f32, f32, f32, f32)>, screen_box: Option<(f32, f32, f32, f32)>, // Callbacks. death_callback: Option<Callback>, boss_callback: Option<Callback>, low_life_callback: Option<Callback>, timeout_callback: Option<Callback>, // Laser. laser_by_id: HashMap<u32, Laser>, // Options. options: Vec<Element>, // Interpolators. interpolator: Option<Interpolator2<f32>>, speed_interpolator: Option<Interpolator1<f32>>, // Misc stuff, do we need them? anm0: Weak<RefCell<Anm0>>, process: Rc<RefCell<Process>>, game: Weak<RefCell<Game>>, prng: Weak<RefCell<Prng>>, hitbox_half_size: (f32, f32), } impl Enemy { /// Sets the animation to the one indexed by index in the current anm0. pub fn set_anim(&mut self, index: u8) { self.sprite = Rc::new(RefCell::new(Sprite::new())); let anm0 = self.anm0.upgrade().unwrap(); let anmrunner = AnmRunner::new(&*anm0.borrow(), index, self.sprite.clone(), self.prng.clone(), 0); self.anmrunner = Rc::new(RefCell::new(anmrunner)); } }