use crate::common::Direction; use crate::framework::error::GameResult; use crate::game::npc::list::NPCList; use crate::game::npc::NPC; use crate::game::player::Player; use crate::game::shared_game_state::SharedGameState; use crate::util::rng::RNG; impl NPC { pub(crate) fn tick_n254_helicopter(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult { match self.action_num { 0 => { self.action_num = 1; // blades let mut npc = NPC::create(255, &state.npc_table); npc.cond.set_alive(true); npc.x = self.x + 0x2400; npc.y = self.y - 0x7200; npc.parent_id = self.id; let _ = npc_list.spawn(0x100, npc.clone()); npc.x = self.x - 0x4000; npc.y = self.y - 0x6800; npc.direction = Direction::Right; let _ = npc_list.spawn(0x100, npc); } 20 => { self.action_num = 21; self.action_counter = 0; self.action_counter2 = 60; } 30 => { self.action_num = 21; // momorin let mut npc = NPC::create(223, &state.npc_table); npc.cond.set_alive(true); npc.x = self.x - 0x1600; npc.y = self.y - 0x1c00; let _ = npc_list.spawn(0x100, npc); } 40 => { self.action_num = 21; // momorin let mut npc = NPC::create(223, &state.npc_table); npc.cond.set_alive(true); npc.x = self.x - 0x1200; npc.y = self.y - 0x1c00; let _ = npc_list.spawn(0x100, npc); // santa let mut npc = NPC::create(40, &state.npc_table); npc.cond.set_alive(true); npc.x = self.x - 0x2c00; npc.y = self.y - 0x1c00; let _ = npc_list.spawn(0x100, npc); // chaco let mut npc = NPC::create(93, &state.npc_table); npc.cond.set_alive(true); npc.x = self.x - 0x4600; npc.y = self.y - 0x1c00; let _ = npc_list.spawn(0x100, npc); } _ => (), } let dir_offset = if self.direction == Direction::Left { 0 } else { 1 }; self.anim_rect = state.constants.npc.n254_helicopter[dir_offset]; Ok(()) } pub(crate) fn tick_n255_helicopter_blades( &mut self, state: &mut SharedGameState, npc_list: &NPCList, ) -> GameResult { match self.action_num { 0 | 1 => { if self.action_num == 0 { self.action_num = 1; if self.direction == Direction::Left { self.display_bounds.left = 0x7000; self.display_bounds.right = 0x7000; } else { self.display_bounds.left = 0x5000; self.display_bounds.right = 0x5000; } } if let Some(parent) = self.get_parent_ref_mut(npc_list) { if parent.action_num >= 20 { self.action_num = 10; } } } 10 | 11 => { self.action_num = 11; self.anim_num += 1; if self.anim_num > 3 { self.anim_num = 0; } } _ => (), } if let Some(parent) = self.get_parent_ref_mut(npc_list) { if self.direction == Direction::Left { self.x = parent.x + 0x2400; self.y = parent.y - 0x7200; } else { self.x = parent.x - 0x4000; self.y = parent.y - 0x6800; } } let dir_offset = if self.direction == Direction::Left { 0 } else { 4 }; self.anim_rect = state.constants.npc.n255_helicopter_blades[self.anim_num as usize + dir_offset]; Ok(()) } pub(crate) fn tick_n260_shovel_brigade_caged( &mut self, state: &mut SharedGameState, players: [&mut Player; 2], npc_list: &NPCList, ) -> GameResult { match self.action_num { 0 | 1 => { if self.action_num == 0 { self.x += 0x200; self.y -= 0x400; self.action_num = 1; self.anim_num = 0; self.anim_counter = 0; } if self.rng.range(0..160) == 1 { self.action_num = 2; self.action_counter = 0; self.anim_num = 1; } } 2 => { self.action_counter += 1; if self.action_counter > 12 { self.action_num = 1; self.anim_num = 0; } } 10 => { self.action_num = 11; self.anim_num = 2; // create heart let mut npc = NPC::create(87, &state.npc_table); npc.cond.set_alive(true); npc.x = self.x; npc.y = self.y - 0x2000; let _ = npc_list.spawn(0x100, npc); } _ => (), } let player = self.get_closest_player_ref(&players); self.face_player(player); let dir_offset = if self.direction == Direction::Left { 0 } else { 3 }; self.anim_rect = state.constants.npc.n260_shovel_brigade_caged[self.anim_num as usize + dir_offset]; Ok(()) } pub(crate) fn tick_n261_chie_caged( &mut self, state: &mut SharedGameState, players: [&mut Player; 2], ) -> GameResult { match self.action_num { 0 | 1 => { if self.action_num == 0 { self.x -= 0x200; self.y -= 0x400; self.action_num = 1; self.action_counter = 0; self.anim_num = 0; } if self.rng.range(0..160) == 1 { self.action_num = 2; self.action_counter = 0; self.anim_num = 1; } } 2 => { self.action_counter += 1; if self.action_counter > 12 { self.action_num = 1; self.anim_num = 0; } } _ => (), } let player = self.get_closest_player_ref(&players); self.face_player(player); let dir_offset = if self.direction == Direction::Left { 0 } else { 2 }; self.anim_rect = state.constants.npc.n261_chie_caged[self.anim_num as usize + dir_offset]; Ok(()) } pub(crate) fn tick_n262_chaco_caged( &mut self, state: &mut SharedGameState, players: [&mut Player; 2], ) -> GameResult { match self.action_num { 0 | 1 => { if self.action_num == 0 { self.x -= 0x200; self.y -= 0x400; self.action_num = 1; self.action_counter = 0; self.anim_num = 0; } if self.rng.range(0..160) == 1 { self.action_num = 2; self.action_counter = 0; self.anim_num = 1; } } 2 => { self.action_counter += 1; if self.action_counter > 12 { self.action_num = 1; self.anim_num = 0; } } _ => (), } let player = self.get_closest_player_ref(&players); self.face_player(player); let dir_offset = if self.direction == Direction::Left { 0 } else { 2 }; self.anim_rect = state.constants.npc.n262_chaco_caged[self.anim_num as usize + dir_offset]; Ok(()) } }