# HG changeset patch # User Gauvain "GovanifY" Roussel-Tarbouriech # Date 1565991928 -7200 # Node ID 8c50a7b19425a3c935014472abaa9e584ade2aa0 # Parent d6cc9086058c5eeb6acfb38967464300909cf959 ecl_vm: more work diff --git a/src/th06/ecl.rs b/src/th06/ecl.rs --- 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), diff --git a/src/th06/ecl_vm.rs b/src/th06/ecl_vm.rs --- 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) } } diff --git a/src/th06/enemy.rs b/src/th06/enemy.rs --- a/src/th06/enemy.rs +++ b/src/th06/enemy.rs @@ -207,7 +207,7 @@ pub struct Enemy { timeout_callback: Option, // Laser. - laser_by_id: HashMap, + pub(crate) laser_by_id: HashMap, // Options. // TODO: actually a 8 element array.