diff --git a/src/npc/ai/balcony.rs b/src/npc/ai/balcony.rs index 6f5a269..7f5af68 100644 --- a/src/npc/ai/balcony.rs +++ b/src/npc/ai/balcony.rs @@ -167,7 +167,7 @@ impl NPC { } let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); let dir_offset = if self.direction == Direction::Left { 0 } else { 3 }; @@ -176,7 +176,11 @@ impl NPC { Ok(()) } - pub(crate) fn tick_n261_chie_caged(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult { + 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 { @@ -204,7 +208,7 @@ impl NPC { } let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); let dir_offset = if self.direction == Direction::Left { 0 } else { 2 }; @@ -213,7 +217,11 @@ impl NPC { Ok(()) } - pub(crate) fn tick_n262_chaco_caged(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult { + 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 { @@ -241,7 +249,7 @@ impl NPC { } let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); let dir_offset = if self.direction == Direction::Left { 0 } else { 2 }; diff --git a/src/npc/ai/doctor.rs b/src/npc/ai/doctor.rs index 22e989f..a61f326 100644 --- a/src/npc/ai/doctor.rs +++ b/src/npc/ai/doctor.rs @@ -834,7 +834,7 @@ impl NPC { self.anim_num = 3; self.action_counter += 1; let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); if self.action_counter > 20 { self.action_num = 41; @@ -896,7 +896,7 @@ impl NPC { self.y = self.target_y; let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } } 103 => { @@ -926,7 +926,7 @@ impl NPC { self.target_x = self.x; let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } } 510 | 511 => { diff --git a/src/npc/ai/grasstown.rs b/src/npc/ai/grasstown.rs index 33d797c..1447fb4 100644 --- a/src/npc/ai/grasstown.rs +++ b/src/npc/ai/grasstown.rs @@ -412,7 +412,7 @@ impl NPC { } 5 => { self.animate(1, 2, 4); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); self.vel_x += (player.x - self.x).signum() * 0x10; self.vel_y += (self.target_y - self.y).signum() * 0x10; @@ -841,8 +841,7 @@ impl NPC { && self.action_num != 3 && self.action_counter > 10 && ((self.shock > 0) - || (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) - && self.rng.range(0..50) == 2) + || (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) && self.rng.range(0..50) == 2) { self.direction = if self.x >= player.x { Direction::Left } else { Direction::Right }; self.action_num = 10; @@ -1186,8 +1185,7 @@ impl NPC { && self.action_num != 3 && self.action_counter > 10 && ((self.shock > 0) - || (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) - && self.rng.range(0..50) == 2) + || (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) && self.rng.range(0..50) == 2) { self.direction = if self.x >= player.x { Direction::Left } else { Direction::Right }; self.action_num = 10; diff --git a/src/npc/ai/hell.rs b/src/npc/ai/hell.rs index 527d807..f7b08fc 100644 --- a/src/npc/ai/hell.rs +++ b/src/npc/ai/hell.rs @@ -38,9 +38,10 @@ impl NPC { } pub(crate) fn tick_n357_puppy_ghost(&mut self, state: &mut SharedGameState) -> GameResult { + self.anim_rect = state.constants.npc.n357_puppy_ghost; + match self.action_num { 0 => { - self.anim_rect = state.constants.npc.n357_puppy_ghost; self.action_counter += 1; } 10 | 11 => { @@ -51,7 +52,6 @@ impl NPC { } self.action_counter += 1; - self.anim_rect = state.constants.npc.n357_puppy_ghost; if self.action_counter & 2 != 0 { self.anim_rect.right = self.anim_rect.left; @@ -87,7 +87,6 @@ impl NPC { || (player.x < self.x + 0x24000 && player.x > self.x + 0x22000) { self.action_num = 10; - return Ok(()); } } 10 | 11 => { @@ -97,19 +96,9 @@ impl NPC { self.damage = 5; } - if self.x > player.x { - self.direction = Direction::Left; - self.vel_x2 -= 0x10; - } else { - self.direction = Direction::Right; - self.vel_x2 += 0x10; - } - - if self.y > player.y { - self.vel_y2 -= 0x10; - } else { - self.vel_y2 += 0x10; - } + self.face_player(player); + self.vel_x2 += 0x10 * self.direction.vector_x(); + self.vel_y2 += 0x10 * if self.y > player.y { -1 } else { 1 }; if self.vel_x2 < 0 && self.flags.hit_left_wall() { self.vel_x2 *= -1 @@ -161,8 +150,7 @@ impl NPC { self.npc_flags.set_invulnerable(true); } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; - + self.face_player(player); self.anim_counter = 0; if player.x > self.x - 0x10000 @@ -171,7 +159,6 @@ impl NPC { && player.y < self.y + 0x2000 { self.action_num = 10; - return Ok(()); } } 10 | 11 => { @@ -188,7 +175,6 @@ impl NPC { self.action_counter += 1; if self.action_counter > 30 { self.action_num = 20; - return Ok(()); } } 20 | 21 => { @@ -198,11 +184,10 @@ impl NPC { self.damage = 0; self.npc_flags.set_shootable(true); self.npc_flags.set_invulnerable(false); - - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } - self.vel_x = 0x400 * if self.direction == Direction::Left { -1 } else { 1 }; + self.vel_x = 0x400 * self.direction.vector_x(); self.animate(3, 0, 1); @@ -223,7 +208,7 @@ impl NPC { if self.vel_y > -0x80 { self.action_num = 31; self.anim_counter = 0; - self.anim_num = 0; + self.anim_num = 3; self.damage = 9; } } @@ -281,7 +266,7 @@ impl NPC { if (player.y > self.y - 0x14000 && player.y < self.y + 0x14000) && ((self.direction == Direction::Left && player.x > self.x - 0x28000 && player.x < self.x) - || (player.x > self.x && player.x < self.x + 0x28000)) + || (self.direction != Direction::Left && player.x > self.x && player.x < self.x + 0x28000)) { self.action_num = 10; } @@ -289,7 +274,7 @@ impl NPC { 10 | 11 => { self.action_num = 11; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); if player.x > self.x - 0x1C000 && player.x < self.x + 0x1C000 && player.y > self.y - 0x1000 { self.anim_num = 1; @@ -310,11 +295,7 @@ impl NPC { self.action_counter = 0; } - if self.action_counter2 == 0 { - self.animate(1, 1, 2); - } else { - self.animate(1, 4, 5); - } + self.animate(1, 1 + self.action_counter2 * 3, 2 + self.action_counter2 * 3); self.action_counter += 1; if self.action_counter > 30 { @@ -330,13 +311,13 @@ impl NPC { npc.cond.set_alive(true); npc.x = self.x; npc.y = self.y; - npc.vel_x = if self.direction == Direction::Left { -0x600 } else { 0x600 }; - npc.vel_y = if self.action_counter2 == 0 { 0 } else { -0x600 }; + npc.vel_x = 0x600 * self.direction.vector_x(); + npc.vel_y = self.action_counter2 as i32 * -0x600; npc.direction = self.direction; let _ = npc_list.spawn(0x100, npc); - self.anim_num = if self.action_counter2 == 0 { 3 } else { 6 }; + self.anim_num = 3 + self.action_counter2 * 3; } self.action_counter += 1; @@ -472,12 +453,7 @@ impl NPC { self.display_bounds.right = 0x1800; self.display_bounds.left = 0x1800; self.vel_y = -0x200; - - match self.direction { - Direction::Left => self.vel_x = 0x100, - Direction::Right => self.vel_x = -0x100, - _ => (), - }; + self.vel_x = 0x100 * self.direction.opposite().vector_x(); state.sound_manager.play_sfx(50); } 1 if self.flags.hit_bottom_wall() => { @@ -517,30 +493,13 @@ impl NPC { state: &mut SharedGameState, players: [&mut Player; 2], ) -> GameResult { - let player = self.get_closest_player_mut(players); - - self.animate(3, 0, 3); - match self.action_num { 0 | 1 => { if self.action_num == 0 { self.action_num = 1; - match self.direction { - Direction::Left => { - self.vel_x = -0x600; - } - Direction::Up => { - self.vel_y = -0x600; - } - Direction::Right => { - self.vel_x = 0x600; - } - Direction::Bottom => { - self.vel_y = 0x600; - } - _ => (), - } + self.vel_x = 0x600 * self.direction.vector_x(); + self.vel_y = 0x600 * self.direction.vector_y(); } self.action_counter += 1; @@ -555,6 +514,7 @@ impl NPC { self.action_num = 10 }; + let player = self.get_closest_player_ref(&players); if self.action_counter > 20 && ((self.direction == Direction::Left && self.x <= player.x + 0x4000) || (self.direction == Direction::Up && self.y <= player.y + 0x4000) @@ -576,6 +536,7 @@ impl NPC { _ => (), } + self.animate(3, 0, 3); self.anim_rect = state.constants.npc.n323_bute_spinning[self.anim_num as usize]; Ok(()) @@ -613,7 +574,7 @@ impl NPC { players: [&mut Player; 2], npc_list: &NPCList, ) -> GameResult { - let player = self.get_closest_player_mut(players); + let player = self.get_closest_player_ref(&players); match self.action_num { 0 | 1 | 2 => { @@ -628,7 +589,7 @@ impl NPC { self.anim_num = 0; self.action_counter = 0; } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); self.animate(40, 0, 1); self.action_counter += 1; @@ -703,12 +664,7 @@ impl NPC { self.action_num = 1; self.anim_num = 0; self.vel_y = -0x200; - - match self.direction { - Direction::Left => self.vel_x = 0x40, - Direction::Right => self.vel_x = -0x40, - _ => (), - }; + self.vel_x = 0x40 * self.direction.opposite().vector_x(); state.sound_manager.play_sfx(54); } 1 if self.flags.hit_bottom_wall() => { @@ -748,12 +704,11 @@ impl NPC { 0 => { if let Some(parent) = self.get_parent_ref_mut(npc_list) { self.y = parent.y + 0x1400; - self.x = parent.x + if parent.direction == Direction::Left { 0xE00 } else { -0xE00 }; + self.x = parent.x + 0xE00 * parent.direction.opposite().vector_x(); if parent.npc_type == 318 { npc_list.create_death_smoke(self.x, self.y, 0, 3, state, &self.rng); self.cond.set_alive(false); - return Ok(()); } if parent.anim_num != 2 { @@ -761,8 +716,7 @@ impl NPC { self.action_counter = 0; self.vel_y = -0x400; self.y = parent.y - 0x800; - - self.vel_x = if parent.direction == Direction::Left { -0x400 } else { 0x400 }; + self.vel_x = 0x400 * parent.direction.vector_x(); } } } @@ -784,7 +738,6 @@ impl NPC { state.sound_manager.play_sfx(12); npc_list.create_death_smoke(self.x, self.y, 0, 3, state, &self.rng); self.cond.set_alive(false); - return Ok(()); } } _ => (), diff --git a/src/npc/ai/igor.rs b/src/npc/ai/igor.rs index fb053ce..a6ea321 100644 --- a/src/npc/ai/igor.rs +++ b/src/npc/ai/igor.rs @@ -125,7 +125,7 @@ impl NPC { self.action_counter2 = 1; } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } self.action_counter += 1; @@ -220,7 +220,7 @@ impl NPC { self.action_counter = 0; let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } self.action_counter += 1; @@ -480,7 +480,7 @@ impl NPC { self.action_counter = 0; let player = self.get_closest_player_ref(&players); - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } self.action_counter += 1; @@ -512,7 +512,7 @@ impl NPC { if self.action_counter > 82 { self.action_num = 10; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } } _ => (), diff --git a/src/npc/ai/mimiga_village.rs b/src/npc/ai/mimiga_village.rs index 7e8bf60..b4cdb67 100644 --- a/src/npc/ai/mimiga_village.rs +++ b/src/npc/ai/mimiga_village.rs @@ -14,8 +14,6 @@ use crate::weapon::bullet::BulletManager; impl NPC { pub(crate) fn tick_n069_pignon(&mut self, state: &mut SharedGameState) -> GameResult { - let dir_offset = if self.direction == Direction::Left { 0 } else { 6 }; - match self.action_num { 0 | 1 => { if self.action_num == 0 { @@ -23,24 +21,18 @@ impl NPC { self.anim_num = 0; self.anim_counter = 0; self.vel_x = 0; - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; } if self.rng.range(0..100) == 1 { self.action_num = 2; self.action_counter = 0; self.anim_num = 1; - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; } if self.rng.range(0..150) == 1 { self.action_num = 3; self.action_counter = 50; self.anim_num = 0; - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; } } 2 => { @@ -48,8 +40,6 @@ impl NPC { if self.action_counter > 8 { self.action_num = 1; self.anim_num = 0; - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; } } 3 | 4 => { @@ -57,8 +47,6 @@ impl NPC { self.action_num = 4; self.anim_num = 2; self.anim_counter = 0; - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; } if self.action_counter > 0 { @@ -67,16 +55,7 @@ impl NPC { self.action_num = 0; } - self.anim_counter += 1; - if self.anim_counter > 2 { - self.anim_counter = 0; - self.anim_num += 1; - if self.anim_num > 4 { - self.anim_num = 2; - } - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; - } + self.animate(2, 2, 4); if self.flags.hit_left_wall() { self.direction = Direction::Right; @@ -86,7 +65,7 @@ impl NPC { self.direction = Direction::Left; } - self.vel_x = self.direction.vector_x() * 0x100; // 0.5fix9 + self.vel_x = self.direction.vector_x() * 0x100; } 5 => { if self.flags.hit_bottom_wall() { @@ -100,8 +79,6 @@ impl NPC { self.vel_y = -0x200; self.anim_num = 5; self.action_num = 5; - - self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; } self.vel_y += 0x40; @@ -113,6 +90,9 @@ impl NPC { self.x += self.vel_x; self.y += self.vel_y; + let dir_offset = if self.direction == Direction::Left { 0 } else { 6 }; + self.anim_rect = state.constants.npc.n069_pignon[self.anim_num as usize + dir_offset]; + Ok(()) } @@ -137,15 +117,7 @@ impl NPC { self.x += self.vel_x; self.y += self.vel_y; - self.anim_counter += 1; - if self.anim_counter > 4 { - self.anim_counter = 0; - self.anim_num += 1; - } - - if self.anim_num > 1 { - self.anim_num = 0; - } + self.animate(4, 0, 1); if self.shock > 0 { self.anim_num = 2; @@ -237,11 +209,7 @@ impl NPC { && (self.y - (0x4000) < player.y) && (self.y + (0x2000) > player.y) { - if self.x > player.x { - self.direction = Direction::Left; - } else { - self.direction = Direction::Right; - } + self.face_player(player); } } 3 => { @@ -285,10 +253,7 @@ impl NPC { self.anim_num = 0; let player = self.get_closest_player_mut(players); - if abs(player.x - self.x) < 0x10000 - && self.y - 0x6000 < player.y - && self.y + 0x4000 > player.y - { + if abs(player.x - self.x) < 0x10000 && self.y - 0x6000 < player.y && self.y + 0x4000 > player.y { self.anim_counter = 0; self.action_num = 2; } @@ -300,17 +265,10 @@ impl NPC { self.npc_flags.set_shootable(false); } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } 2 => { - self.anim_counter += 1; - if self.anim_counter > 6 { - self.anim_counter = 0; - self.anim_num += 1; - if self.anim_num > 3 { - self.anim_num = 0; - } - } + self.animate(6, 0, 3); let player = self.get_closest_player_mut(players); if abs(player.x - self.x) < 0x2000 { @@ -322,7 +280,7 @@ impl NPC { state.sound_manager.play_sfx(34); } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); self.vel_x = self.direction.vector_x() * 0x100; } 3 => { @@ -502,7 +460,7 @@ impl NPC { } if player.x > self.x - 0x4000 && player.x < self.x + 0x4000 { - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } } 2 => { @@ -521,7 +479,7 @@ impl NPC { } self.damage = 1; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); self.anim_num = 0; self.action_counter += 1; @@ -558,7 +516,7 @@ impl NPC { if (self.vel_x < 0 && self.flags.hit_left_wall()) || (self.vel_x > 0 && self.flags.hit_right_wall()) { self.vel_x *= -1 }; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); self.anim_num = if self.vel_y < -0x200 { 3 } else if self.vel_y > 0x200 { @@ -597,7 +555,7 @@ impl NPC { self.action_num = 210; self.anim_num = 6; - self.vel_x = if self.direction == Direction::Left { -0x5FF } else { 0x5FF }; + self.vel_x = 0x5FF * self.direction.vector_x(); state.sound_manager.play_sfx(25); self.npc_flags.set_shootable(false); @@ -645,7 +603,7 @@ impl NPC { if self.action_num == 300 { self.action_num = 301; self.anim_num = 9; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } self.animate(1, 9, 11); @@ -852,8 +810,7 @@ impl NPC { self.npc_flags.set_shootable(true); } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; - + self.face_player(player); self.action_counter += 1; if self.action_counter > 4 { self.action_num = 120; @@ -877,8 +834,7 @@ impl NPC { if (self.vel_x < 0 && self.flags.hit_left_wall()) || (self.vel_x > 0 && self.flags.hit_right_wall()) { self.vel_x *= -1 }; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; - + self.face_player(player); self.anim_num = if self.vel_y < -0x200 { 2 } else if self.vel_y > 0x200 { diff --git a/src/npc/boss/ballos.rs b/src/npc/boss/ballos.rs index 622cc67..f0390ac 100644 --- a/src/npc/boss/ballos.rs +++ b/src/npc/boss/ballos.rs @@ -266,7 +266,7 @@ impl NPC { self.action_counter3 += 1; } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; + self.face_player(player); } 200 | 201 | 202 => { if self.action_num == 200 { @@ -281,8 +281,7 @@ impl NPC { self.action_counter2 += 1; } - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; - + self.face_player(player); self.vel_x = 8 * self.vel_x / 9; self.vel_y = 8 * self.vel_y / 9; @@ -308,8 +307,7 @@ impl NPC { self.anim_counter = 0; self.damage = 10; - self.direction = if player.x < self.x { Direction::Left } else { Direction::Right }; - + self.face_player(player); state.sound_manager.play_sfx(25); } @@ -1580,12 +1578,12 @@ impl BossNPC { player.damage(16, state, npc_list); } - for sign in [-1, 1] { + for dir in [Direction::Left, Direction::Right] { let mut npc = NPC::create(332, &state.npc_table); npc.cond.set_alive(true); - npc.x = self.parts[0].x + 0x1800 * sign; + npc.x = self.parts[0].x + 0x1800 * dir.vector_x(); npc.y = self.parts[0].y + 0x6800; - npc.direction = if sign == -1 { Direction::Left } else { Direction::Right }; + npc.direction = dir; let _ = npc_list.spawn(0x100, npc); } @@ -1668,12 +1666,12 @@ impl BossNPC { npc.y = self.parts[0].y; let _ = npc_list.spawn(0x18, npc); - for sign in [-1, 1] { + for dir in [Direction::Left, Direction::Right] { let mut npc = NPC::create(344, &state.npc_table); npc.cond.set_alive(true); - npc.x = self.parts[0].x + 0x3000 * sign; + npc.x = self.parts[0].x + 0x3000 * dir.vector_x(); npc.y = self.parts[0].y + 0x4800; - npc.direction = if sign == -1 { Direction::Left } else { Direction::Right }; + npc.direction = dir; let _ = npc_list.spawn(0x20, npc); } } @@ -1774,12 +1772,12 @@ impl BossNPC { npc.y = self.parts[0].y; let _ = npc_list.spawn(0x18, npc); - for sign in [-1, 1] { + for dir in [Direction::Left, Direction::Right] { let mut npc = NPC::create(344, &state.npc_table); npc.cond.set_alive(true); - npc.x = self.parts[0].x + 0x3000 * sign; + npc.x = self.parts[0].x + 0x3000 * dir.vector_x(); npc.y = self.parts[0].y + 0x4800; - npc.direction = if sign == -1 { Direction::Left } else { Direction::Right }; + npc.direction = dir; let _ = npc_list.spawn(0x20, npc); } } diff --git a/src/npc/utils.rs b/src/npc/utils.rs index 2ee2281..2ebabe8 100644 --- a/src/npc/utils.rs +++ b/src/npc/utils.rs @@ -161,6 +161,7 @@ impl NPC { &players[idx] } + /// Sets direction of NPC to face towards Player. pub fn face_player(&mut self, player: &Player) { self.direction = if self.x > player.x { Direction::Left } else { Direction::Right }; }