changeset 683:8c50a7b19425

ecl_vm: more work
author Gauvain "GovanifY" Roussel-Tarbouriech <gauvain@govanify.com>
date Fri, 16 Aug 2019 23:45:28 +0200
parents d6cc9086058c
children c8bb28961d31
files src/th06/ecl.rs src/th06/ecl_vm.rs src/th06/enemy.rs
diffstat 3 files changed, 95 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/th06/ecl.rs
+++ b/src/th06/ecl.rs
@@ -248,10 +248,11 @@ declare_sub_instructions!{
     84 => fn UNK_ins84(param: i32),
     85 => fn NewLaser(laser_type: i16, sprite_idx_offset: i16, angle: f32, speed: f32, start_offset: f32, end_offset: f32, max_length: f32, width: f32, start_duration: i32, duration: i32, end_duration: i32, grazing_delay: i32, grazing_extra_duration: i32, UNK1: i32),
     86 => fn NewLaserTowardsPlayer(laser_type: i16, sprite_idx_offset: i16, angle: f32, speed: f32, start_offset: f32, end_offset: f32, max_length: f32, width: f32, start_duration: i32, duration: i32, end_duration: i32, grazing_delay: i32, grazing_extra_duration: i32, UNK1: i32),
-    87 => fn SetUpcomingLaserId(id: i32),
-    88 => fn AlterLaserAngle(id: i32, delta: f32),
-    90 => fn RepositionLaser(id: i32, ox: f32, oy: f32, oz: f32),
-    92 => fn CanceLaser(id: i32),
+    87 => fn SetUpcomingLaserId(id: u32),
+    88 => fn AlterLaserAngle(id: u32, delta: f32),
+    90 => fn RepositionLaser(id: u32, ox: f32, oy: f32, oz: f32),
+    91 => fn LaserSetCompare(u32: id),
+    92 => fn CancelLaser(id: u32),
     93 => fn SetSpellcard(face: i16, number: i16, name: String),
     94 => fn Endspellcard(),
     95 => fn SpawnEnemy(sub: i32, x: f32, y: f32, z: f32, life: i16, bonus_dropped: i16, die_score: i32),
--- a/src/th06/ecl_vm.rs
+++ b/src/th06/ecl_vm.rs
@@ -593,6 +593,83 @@ impl EclRunner {
                 game.change_bullets_into_star_items();
             }
             */
+            // 84
+            // WARNING: dead code. If the parameter is < 0 it unsets a bullet_flag, otherwise it
+            // sets it, never using the parameter ever
+            /*
+            SubInstruction::UNK_ins84() => {
+                let mut enemy = self.enemy.borrow_mut();
+                enemy.bullet_flag_something
+            }
+            */
+
+            // 85-86 ire newlaser functions
+
+            // 87
+            SubInstruction::SetUpcomingLaserId(laser_id) => {
+                let mut enemy = self.enemy.borrow_mut();
+                enemy.current_laser_id = laser_id;
+            }
+
+            // 88
+            
+            SubInstruction::AlterLaserAngle(laser_id, delta) => {
+                let mut enemy = self.enemy.borrow_mut();
+                if enemy.laser_by_id.contains_key(&laser_id) {
+                    let mut laser = enemy.laser_by_id.get(laser_id);
+                    laser.angle += self.get_f32(delta);
+                }
+            }
+            
+            // 89
+            /*
+            SubInstruction::AlterLaserAnglePlayer(laser_id, delta) => {
+                let mut enemy = self.enemy.borrow_mut();
+                if enemy.laser_by_id.contains_key(&laser_id) {
+                    let mut laser = enemy.laser_by_id.get(laser_id);
+                    let player = enemy.select_player();
+                    laser.angle = enemy.get_angle(player) + angle;
+                }
+            }
+            */
+
+            // 90
+            SubInstruction::RepositionLaser(laser_id, ox, oy, oz) => {
+                let mut enemy = self.enemy.borrow_mut();
+                if enemy.laser_by_id.contains_key(&laser_id) {
+                    let mut laser = enemy.laser_by_id.get(laser_id);
+                    laser.set_base_pos(enemy.pos.x + ox, enemy.pos.y + oy, enemy.z + oz)
+                }
+            }
+            // 91
+            // wat
+            SubInstruction::LaserSetCompare(laser_id) => {
+                let mut enemy = self.enemy.borrow_mut();
+                // in game it checks if either the laser exists OR if one of its member is set to 0
+                // which, uhhhh, we are not going to reimplement for obvious reasons
+                // the correct implementation would be: if this laser does not exist have a
+                // 1/100000 chance to continue, otherwise crash
+                if enemy.laser_by_id.contains_key(&laser_id) {
+                    // let's assume we gud 
+                    self.comparison_reg = 1;
+                } 
+                else{
+                    self.comparison_reg = 0;
+                }
+            }
+
+            // 92
+            /*
+            SubInstruction::RepositionLaser(laser_id, ox, oy, oz) => {
+                let mut enemy = self.enemy.borrow_mut();
+                if enemy.laser_by_id.contains_key(&laser_id) {
+                    let mut laser = enemy.laser_by_id.get(laser_id);
+                    laser.cancel();
+                }
+            }
+            */
+
+
 
 
 
@@ -663,12 +740,24 @@ impl EclRunner {
                 enemy.death_flags = death_flags;
             }
 
+            // 109
+            SubInstruction::MemoryWriteInt(value, index) => {
+                unimplemented!("not again that damn foe corrupted my ret\\x41\\x41\\x41\\x41");
+            }
+
+
             // 117
             SubInstruction::SetTouchable(touchable) => {
                 let mut enemy = self.enemy.borrow_mut();
                 enemy.touchable = touchable != 0;
             }
 
+            // 121
+            // Here lies the Di Sword of sadness
+            SubInstruction::CallSpecialFunction(function, arg) => {
+                unimplemented!("spellcards are a bitch and a half");
+            }
+
             _ => unimplemented!("{:?}", instruction)
         }
     }
--- a/src/th06/enemy.rs
+++ b/src/th06/enemy.rs
@@ -207,7 +207,7 @@ pub struct Enemy {
     timeout_callback: Option<Callback>,
 
     // Laser.
-    laser_by_id: HashMap<u32, Laser>,
+    pub(crate) laser_by_id: HashMap<u32, Laser>,
 
     // Options.
     // TODO: actually a 8 element array.