diff --git a/src/engine_constants.rs b/src/engine_constants.rs index 8370afa..8426d46 100644 --- a/src/engine_constants.rs +++ b/src/engine_constants.rs @@ -146,6 +146,7 @@ pub struct NPCConsts { pub n006_green_beetle: [Rect; 10], pub n007_basil: [Rect; 6], pub n008_blue_beetle: [Rect; 4], + pub n015_closed_chest: [Rect; 3], pub n016_save_point: [Rect; 8], pub n017_health_refill: [Rect; 2], pub n018_door: [Rect; 2], @@ -486,6 +487,11 @@ impl EngineConstants { Rect { left: 80, top: 96, right: 96, bottom: 112 }, // right Rect { left: 96, top: 96, right: 112, bottom: 112 }, ], + n015_closed_chest: [ + Rect { left: 240, top: 0, right: 256, bottom: 16 }, + Rect { left: 256, top: 0, right: 272, bottom: 16 }, + Rect { left: 272, top: 0, right: 288, bottom: 16 }, + ], n016_save_point: [ Rect { left: 96, top: 16, right: 112, bottom: 32 }, Rect { left: 112, top: 16, right: 128, bottom: 32 }, diff --git a/src/npc/first_cave.rs b/src/npc/first_cave.rs index ab97af3..0d04162 100644 --- a/src/npc/first_cave.rs +++ b/src/npc/first_cave.rs @@ -15,13 +15,53 @@ impl NPC { self.action_num = 1; } - self.anim_rect = state.constants.npc.n059_eye_door[self.anim_num as usize]; + if self.x - (64 * 0x200) < player.x + && self.x + (64 * 0x200) > player.x + && self.y - (64 * 0x200) < player.y + && self.y + (64 * 0x200) > player.y { + self.action_num = 2; + self.anim_counter = 0; + } + } + 2 => { + self.anim_counter += 1; + if self.anim_counter > 2 { + self.anim_counter = 0; + self.anim_num += 1; + + if self.anim_num == 2 { + self.action_num = 3; + } + } + } + 3 => { + if !(self.x - (64 * 0x200) < player.x + && self.x + (64 * 0x200) > player.x + && self.y - (64 * 0x200) < player.y + && self.y + (64 * 0x200) > player.y) { + self.action_num = 4; + self.anim_counter = 0; + } + } + 4 => { + self.anim_counter += 1; + if self.anim_counter > 2 { + self.anim_counter = 0; + self.anim_num -= 1; + + if self.anim_num == 0 { + self.action_num = 1; + } + } } - 2 => {} - 3 => {} _ => {} } + if self.shock > 0 { + self.anim_rect = state.constants.npc.n059_eye_door[3]; + } else { + self.anim_rect = state.constants.npc.n059_eye_door[self.anim_num as usize]; + } Ok(()) } diff --git a/src/npc/misc.rs b/src/npc/misc.rs index ebebc30..a781da1 100644 --- a/src/npc/misc.rs +++ b/src/npc/misc.rs @@ -6,7 +6,62 @@ use crate::player::Player; use crate::SharedGameState; impl NPC { - pub(crate) fn tick_n000_null(&mut self, state: &mut SharedGameState) -> GameResult { + pub(crate) fn tick_n000_null(&mut self) -> GameResult { + if self.action_num != 0xffff { + self.action_num = 0xffff; + self.anim_rect.left = 0; + self.anim_rect.top = 0; + self.anim_rect.right = 0; + self.anim_rect.bottom = 0; + } + Ok(()) + } + + pub(crate) fn tick_n015_chest_closed(&mut self, state: &mut SharedGameState) -> GameResult { + match self.action_num { + 0 | 1 => { + if self.action_num == 0 { + self.action_num = 1; + self.npc_flags.set_interactable(true); + + if self.direction == Direction::Right { + self.vel_y = -0x200; + + // todo smoke + } + + self.anim_rect = state.constants.npc.n015_closed_chest[0]; + } + + self.anim_num = 0; + if state.game_rng.range(0..30) == 0 { + self.action_num = 2; + } + } + 2 => { + self.anim_counter += 1; + if self.anim_counter > 1 { + self.anim_counter = 0; + self.anim_num += 1; + + if self.anim_num > 2 { + self.anim_num = 0; + self.action_num = 1; + } + + self.anim_rect = state.constants.npc.n015_closed_chest[self.anim_num as usize]; + } + } + _ => {} + } + + self.vel_y += 0x40; + if self.vel_y > 0x5ff { + self.vel_y = 0x5ff; + } + + self.y += self.vel_y; + Ok(()) } @@ -28,6 +83,13 @@ impl NPC { self.anim_num = self.anim_counter / 3; self.anim_rect = state.constants.npc.n016_save_point[self.anim_num as usize]; + self.vel_y += 0x40; + if self.vel_y > 0x5ff { + self.vel_y = 0x5ff; + } + + self.y += self.vel_y; + Ok(()) } @@ -87,6 +149,13 @@ impl NPC { _ => {} } + self.vel_y += 0x40; + if self.vel_y > 0x5ff { + self.vel_y = 0x5ff; + } + + self.y += self.vel_y; + Ok(()) } @@ -102,6 +171,7 @@ impl NPC { 1 => { // todo smoke self.action_num = 0; + self.anim_rect = state.constants.npc.n018_door[0] } _ => {} } @@ -140,7 +210,6 @@ impl NPC { Ok(()) } - pub(crate) fn tick_n022_teleporter(&mut self, state: &mut SharedGameState) -> GameResult { match self.action_num { 0 if self.anim_counter == 0 => { diff --git a/src/npc/mod.rs b/src/npc/mod.rs index e9d7dbf..d253cbe 100644 --- a/src/npc/mod.rs +++ b/src/npc/mod.rs @@ -84,11 +84,12 @@ impl GameEntity<&mut Player> for NPC { fn tick(&mut self, state: &mut SharedGameState, player: &mut Player) -> GameResult { // maybe use macros? match self.npc_type { - 0 => { self.tick_n000_null(state) } + 0 => { self.tick_n000_null() } 1 => { self.tick_n001_experience(state) } 2 => { self.tick_n002_behemoth(state) } 5 => { self.tick_n005_green_critter(state, player) } 7 => { self.tick_n007_basil(state, player) } + 15 => { self.tick_n015_chest_closed(state) } 16 => { self.tick_n016_save_point(state) } 17 => { self.tick_n017_health_refill(state) } 18 => { self.tick_n018_door(state) }