diff --git a/src/common.rs b/src/common.rs index 1b73352..0ff5309 100644 --- a/src/common.rs +++ b/src/common.rs @@ -76,6 +76,7 @@ bitfield! { pub alive, set_alive: 7; // 0x80 // engine specific flags + pub drs_dont_remove, set_drs_dont_remove: 13; pub drs_boss, set_drs_boss: 14; pub drs_destroyed, set_drs_destroyed: 15; } diff --git a/src/npc/grasstown.rs b/src/npc/grasstown.rs index ff82fe4..9e8e50d 100644 --- a/src/npc/grasstown.rs +++ b/src/npc/grasstown.rs @@ -3,7 +3,7 @@ use num_traits::clamp; use crate::common::Direction; use crate::ggez::GameResult; -use crate::npc::NPC; +use crate::npc::{NPC, NPCMap}; use crate::player::Player; use crate::shared_game_state::SharedGameState; @@ -347,6 +347,58 @@ impl NPC { Ok(()) } + pub(crate) fn tick_n035_mannan(&mut self, state: &mut SharedGameState) -> GameResult { + if self.action_num <= 2 && self.life <= 89 { + self.action_num = 3; + self.action_counter = 0; + self.anim_num = 2; + self.damage = 0; + self.npc_flags.set_shootable(false); + + state.sound_manager.play_sfx(71); + self.cond.set_drs_dont_remove(true); + self.cond.set_drs_destroyed(true); + } + + if self.action_num == 2 { + self.action_counter += 1; + if self.action_counter > 20 { + self.action_counter = 0; + self.action_num = 1; + self.anim_num = 0; + } + } else if self.action_num > 2 { + if self.action_num == 3 { + self.action_counter += 1; + if self.action_counter == 50 || self.action_counter == 60 { + self.anim_num = 3; + } + if self.action_counter == 53 || self.action_counter == 63 { + self.anim_num = 2; + } + if self.action_counter > 100 { + self.action_num = 4; + } + } + } else if self.action_num >= 0 && self.shock >= 0 { + self.action_num = 2; + self.action_counter = 0; + self.anim_num = 1; + + let mut npc = NPCMap::create_npc(103, &state.npc_table); + npc.cond.set_alive(true); + npc.x = self.x + self.direction.vector_x() * 32 * 0x200; + npc.y = self.y + 32 * 0x200; + npc.direction = self.direction; + state.new_npcs.push(npc); + } + + let dir_offset = if self.direction == Direction::Left { 0 } else { 4 }; + self.anim_rect = state.constants.npc.n035_mannan[self.anim_num as usize + dir_offset]; + + Ok(()) + } + pub(crate) fn tick_n094_kulala(&mut self, state: &SharedGameState, player: &Player) -> GameResult { match self.action_num { 0 => { @@ -538,10 +590,10 @@ impl NPC { self.y += self.vel_y; } - - let dir_offset = if self.direction == Direction::Left { 0 } else { 4 }; - self.anim_rect = state.constants.npc.n095_jelly[self.anim_num as usize + dir_offset]; - + if self.anim_counter == 1 { + let dir_offset = if self.direction == Direction::Left { 0 } else { 4 }; + self.anim_rect = state.constants.npc.n095_jelly[self.anim_num as usize + dir_offset]; + } Ok(()) } diff --git a/src/npc/misc.rs b/src/npc/misc.rs index 39f7028..1606829 100644 --- a/src/npc/misc.rs +++ b/src/npc/misc.rs @@ -475,8 +475,14 @@ impl NPC { self.anim_num = self.anim_counter / 4; self.anim_rect = state.constants.npc.n038_fireplace[self.anim_num as usize]; } - 10 => {} - 11 => {} + 10 | 11 => { + if self.action_num == 10 { + self.action_num = 11; + } + + self.anim_rect.left = 0; + self.anim_rect.right = 0; + } _ => {} } diff --git a/src/npc/mod.rs b/src/npc/mod.rs index 45761a0..7eb70cd 100644 --- a/src/npc/mod.rs +++ b/src/npc/mod.rs @@ -198,6 +198,7 @@ impl GameEntity<(&mut Player, &HashMap>, &mut Stage)> for NPC 30 => self.tick_n030_gunsmith(state), 32 => self.tick_n032_life_capsule(state), 34 => self.tick_n034_bed(state), + 35 => self.tick_n035_mannan(state), 37 => self.tick_n037_sign(state), 38 => self.tick_n038_fireplace(state), 39 => self.tick_n039_save_sign(state), @@ -650,7 +651,11 @@ impl NPCMap { // todo vanish / show damage - npc.cond.set_alive(false); + if npc.cond.drs_dont_remove() { + npc.cond.set_drs_dont_remove(false); + } else { + npc.cond.set_alive(false); + } } }