changeset 718:c187e0a6b751

ecl_vm: Implement 121 functions 0 and 1.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 24 Sep 2019 17:49:23 +0200
parents d5d5496e4e53
children 28e6332b088d
files src/th06/ecl_vm.rs src/th06/enemy.rs
diffstat 2 files changed, 69 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/th06/ecl_vm.rs
+++ b/src/th06/ecl_vm.rs
@@ -956,7 +956,40 @@ impl EclRunner {
             // 121
             // Here lies the Di Sword of sadness
             SubInstruction::CallSpecialFunction(function, arg) => {
-                unimplemented!("spellcards are a bitch and a half");
+                match function {
+                    0 => {
+                        let mut enemy = self.enemy.borrow_mut();
+                        let game = enemy.game.upgrade().unwrap();
+                        let mut game = game.borrow_mut();
+                        //game.drop_particle(12, enemy.pos, 1, 0xffffffff);
+                        //game.iter_bullets(|mut bullet| {
+                        for bullet in game.bullets.iter() {
+                            //game.new_effect(bullet.sprite, TODO);
+                            let mut bullet = bullet.borrow_mut();
+                            if arg == 0 {
+                                bullet.speed = 0.;
+                                bullet.dpos = [0., 0., 0.];
+                            } else if arg == 1 {
+                                bullet.flags |= 0x10;
+                                bullet.frame = 220;
+                                let rand_angle = game.prng.borrow_mut().get_f64() * 2. * std::f64::consts::PI - std::f64::consts::PI;
+                                bullet.attributes[0] = (rand_angle.cos() * 0.01) as f32;
+                                bullet.attributes[1] = (rand_angle.sin() * 0.01) as f32;
+                            }
+                        }
+                    }
+                    1 => {
+                        let range_x = arg as f64;
+                        let range_y = (arg as f32 * 0.75) as f64;
+                        let rand_x = self.get_prng().borrow_mut().get_f64();
+                        let rand_y = self.get_prng().borrow_mut().get_f64();
+                        let mut enemy = self.enemy.borrow_mut();
+                        let pos = [rand_x * range_x + enemy.pos.x as f64 - range_x / 2.,
+                                   rand_y * range_y + enemy.pos.x as f64 - range_y / 2.];
+                        enemy.bullet_attributes.fire();
+                    }
+                    _ => unimplemented!("spellcards are a bitch and a half")
+                }
             }
 
             _ => unimplemented!("{:?}", instruction)
--- a/src/th06/enemy.rs
+++ b/src/th06/enemy.rs
@@ -74,12 +74,34 @@ pub struct Player {
     pos: Position,
 }
 
+/// Struct representing an enemy bullet.
+pub struct Bullet {
+    /// Current position of the bullet.
+    pub pos: Position,
+
+    /// Current speed of the bullet.
+    pub speed: f32,
+
+    /// Current XXX of the bullet.
+    pub dpos: [f32; 3],
+
+    /// Current XXX of the bullet.
+    pub flags: u32,
+
+    /// Current frame of the bullet.
+    pub frame: i32,
+
+    /// Current attributes of the bullet.
+    pub attributes: [f32; 2],
+}
+
 /// God struct of our game.
 pub struct Game {
     enemies: Vec<Rc<RefCell<Enemy>>>,
     anmrunners: Vec<Rc<RefCell<AnmRunner>>>,
+    pub(crate) bullets: Vec<Rc<RefCell<Bullet>>>,
     player: Rc<RefCell<Player>>,
-    prng: Rc<RefCell<Prng>>,
+    pub(crate) prng: Rc<RefCell<Prng>>,
     rank: Rank,
     difficulty: i32,
 }
@@ -90,6 +112,7 @@ impl Game {
         Game {
             enemies: Vec::new(),
             anmrunners: Vec::new(),
+            bullets: Vec::new(),
             player: Rc::new(RefCell::new(Player { pos: Position { x: 192., y: 384. } })),
             prng,
             rank,
@@ -124,6 +147,17 @@ impl Game {
         sprites
     }
 
+    // TODO: Fix this function so we can stop making Game::bullets pub.
+    /*
+    /// Apply a function on all bullets.
+    pub fn iter_bullets(&mut self, mut f: impl FnMut(Bullet)) {
+        self.bullets.iter().map(|bullet| {
+            let mut bullet = bullet.borrow_mut();
+            f(*bullet)
+        });
+    }
+    */
+
     pub(crate) fn get_player(&self) -> Rc<RefCell<Player>> {
         self.player.clone()
     }