diff --git a/src/game/npc/ai/balrog.rs b/src/game/npc/ai/balrog.rs index bcdeff3..9283f19 100644 --- a/src/game/npc/ai/balrog.rs +++ b/src/game/npc/ai/balrog.rs @@ -679,7 +679,7 @@ impl NPC { self.vel_x2 -= 1; self.action_counter = 0; - let angle = f64::atan2((self.y - player.y) as f64, (self.x - player.x) as f64) + let angle = f64::atan2((self.y + 0x800 - player.y) as f64, (self.x - player.x) as f64) + self.rng.range(-16..16) as f64 * CDEG_RAD; let mut npc = NPC::create(11, &state.npc_table); @@ -739,7 +739,7 @@ impl NPC { self.anim_num = 3; } - self.vel_y += ((self.target_y - self.y).signum() | 1) * 0x40; + self.vel_y += if self.y < self.target_y { 0x40 } else { -0x40 }; self.vel_y = clamp(self.vel_y, -0x200, 0x200); } 6 => { @@ -1016,9 +1016,8 @@ impl NPC { } } - if self.action_counter > 0 { - self.action_counter -= 1; - } else { + self.action_counter = self.action_counter.saturating_sub(1); + if self.action_counter == 0 { self.action_num = 2; self.action_counter3 += 1; } @@ -1247,7 +1246,7 @@ impl NPC { self.x + 0x1000 * self.direction.opposite().vector_x(), self.y, CaretType::Exhaust, - self.direction, + self.direction.opposite(), ); } diff --git a/src/game/npc/ai/curly.rs b/src/game/npc/ai/curly.rs index b754d09..f517631 100644 --- a/src/game/npc/ai/curly.rs +++ b/src/game/npc/ai/curly.rs @@ -865,57 +865,47 @@ impl NPC { players: [&mut Player; 2], npc_list: &NPCList, ) -> GameResult { - match self.action_num { - 0 => { - if self.action_num == 0 { - let player = &players[0]; - self.x = player.x; - self.y = player.y; + let player = &players[0]; - let mut npc = NPC::create(321, &state.npc_table); - npc.cond.set_alive(true); - npc.parent_id = self.id; - let _ = npc_list.spawn(0x100, npc); + if self.action_num == 0 { + self.x = player.x; + self.y = player.y; - self.action_num = 1; - } - } - 1 => { - let player = &players[0]; + let mut npc = NPC::create(321, &state.npc_table); + npc.cond.set_alive(true); + npc.parent_id = self.id; + let _ = npc_list.spawn(0x100, npc); - self.direction = player.direction.opposite(); - let grounded = player.flags.hit_bottom_wall(); - - self.target_x = player.x; - - if player.up { - self.target_y = player.y + if grounded { -0x1800 } else { 0x1000 }; - self.anim_num = if grounded { 1 } else { 2 }; - self.direction = if grounded { Direction::Up } else { Direction::Bottom }; - } else if player.down && !grounded { - self.target_y = player.y - 0x1000; - self.anim_num = 1; - self.direction = Direction::Up; - } else { - self.target_x += if self.direction == Direction::Right { 0xE00 } else { -0xE00 }; - self.target_y = player.y - 0x600; - self.anim_num = 0; - } - - self.x += (self.target_x - self.x) / 2; - self.y += (self.target_y - self.y) / 2; - - if (player.anim_num & 1) != 0 { - self.y -= 0x200 - }; - - let dir_offset = if player.direction.opposite() == Direction::Left { 0 } else { 3 }; - - self.anim_rect = state.constants.npc.n320_curly_carried[self.anim_num as usize + dir_offset]; - } - _ => (), + self.action_num = 1; } + let grounded = player.flags.hit_bottom_wall(); + + self.target_x = player.x; + + if player.up { + self.target_y = player.y + if grounded { -0x1400 } else { 0x1000 }; + self.anim_num = if grounded { 1 } else { 2 }; + } else if player.down && !grounded { + self.target_y = player.y - 0x1000; + self.anim_num = 1; + } else { + self.target_x += if player.direction == Direction::Left { 0xE00 } else { -0xE00 }; + self.target_y = player.y - 0x600; + self.anim_num = 0; + } + + self.x += (self.target_x - self.x) / 2; + self.y += (self.target_y - self.y) / 2; + + if (player.anim_num & 1) != 0 { + self.y -= 0x200 + }; + + let dir_offset = if player.direction.opposite() == Direction::Left { 0 } else { 3 }; + + self.anim_rect = state.constants.npc.n320_curly_carried[self.anim_num as usize + dir_offset]; + Ok(()) } @@ -929,21 +919,20 @@ impl NPC { if let Some(npc) = self.get_parent_ref_mut(npc_list) { let player = &players[0]; - self.direction = npc.direction; self.x = npc.x; self.y = npc.y; - match self.direction { - Direction::Right => { - self.x += 0x1000; + match npc.anim_num { + 0 => { + self.direction = player.direction.opposite(); + self.x += 0x1000 * self.direction.vector_x(); } - Direction::Left => { - self.x -= 0x1000; - } - Direction::Up => { + 1 => { + self.direction = Direction::Up; self.y -= 0x1400; } - Direction::Bottom => { + 2 => { + self.direction = Direction::Bottom; self.y += 0x1400; } _ => (), diff --git a/src/game/npc/ai/doctor.rs b/src/game/npc/ai/doctor.rs index 0eebfd4..ad26510 100644 --- a/src/game/npc/ai/doctor.rs +++ b/src/game/npc/ai/doctor.rs @@ -654,7 +654,7 @@ impl NPC { if self.flags.hit_bottom_wall() { if self.life + 20 > self.action_counter3 { self.animate(10, 1, 2); - } else if player.flags.hit_bottom_wall() && player.x > self.x - 0x6000 && player.x < self.x + 0x6000 + } else if player.flags.hit_bottom_wall() && player.x > self.x - 0x6000 && player.x < self.x + 0x6000 && self.anim_num != 6 { self.anim_num = 6; state.quake_counter = 10; diff --git a/src/game/npc/ai/hell.rs b/src/game/npc/ai/hell.rs index 7479f89..8e99e24 100644 --- a/src/game/npc/ai/hell.rs +++ b/src/game/npc/ai/hell.rs @@ -488,47 +488,44 @@ impl NPC { state: &mut SharedGameState, players: [&mut Player; 2], ) -> GameResult { - match self.action_num { - 0 | 1 => { - if self.action_num == 0 { - self.action_num = 1; + if self.action_num == 0 || self.action_num == 1 { + if self.action_num == 0 { + self.action_num = 1; - self.vel_x = 0x600 * self.direction.vector_x(); - self.vel_y = 0x600 * self.direction.vector_y(); - } - - self.action_counter += 1; - if self.action_counter == 16 { - self.npc_flags.set_ignore_solidity(false) - }; - - self.x += self.vel_x; - self.y += self.vel_y; - - if self.flags.hit_anything() { - 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) - || (self.direction == Direction::Right && self.x <= player.x - 0x4000) - || (self.direction == Direction::Bottom && self.y <= player.y - 0x4000)) - { - self.action_num = 10 - } + self.vel_x = 0x600 * self.direction.vector_x(); + self.vel_y = 0x600 * self.direction.vector_y(); } - 10 => { - self.npc_type = 309; - self.anim_num = 0; - self.action_num = 11; - self.npc_flags.set_shootable(true); - self.npc_flags.set_ignore_solidity(false); - self.damage = 5; - self.display_bounds.top = 0x1000; + + self.action_counter += 1; + if self.action_counter == 16 { + self.npc_flags.set_ignore_solidity(false) + }; + + self.x += self.vel_x; + self.y += self.vel_y; + + if self.flags.hit_anything() { + 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) + || (self.direction == Direction::Right && self.x >= player.x - 0x4000) + || (self.direction == Direction::Bottom && self.y >= player.y - 0x4000)) + { + self.action_num = 10 } - _ => (), + } + if self.action_num == 10 { + self.npc_type = 309; + self.anim_num = 0; + self.action_num = 11; + self.npc_flags.set_shootable(true); + self.npc_flags.set_ignore_solidity(false); + self.damage = 5; + self.display_bounds.top = 0x1000; } self.animate(3, 0, 3); diff --git a/src/game/npc/ai/mimiga_village.rs b/src/game/npc/ai/mimiga_village.rs index 3e6a26f..d2f1b53 100644 --- a/src/game/npc/ai/mimiga_village.rs +++ b/src/game/npc/ai/mimiga_village.rs @@ -27,12 +27,15 @@ impl NPC { self.action_num = 2; self.action_counter = 0; self.anim_num = 1; - } - - if self.rng.range(0..150) == 1 { - self.action_num = 3; - self.action_counter = 50; - self.anim_num = 0; + } else { + if self.rng.range(0..150) == 1 { + self.direction = self.direction.opposite(); + } + if self.rng.range(0..150) == 1 { + self.action_num = 3; + self.action_counter = 50; + self.anim_num = 0; + } } } 2 => { @@ -49,9 +52,8 @@ impl NPC { self.anim_counter = 0; } - if self.action_counter > 0 { - self.action_counter -= 1; - } else { + self.action_counter = self.action_counter.saturating_sub(1); + if self.action_counter == 0 { self.action_num = 0; } @@ -371,9 +373,8 @@ impl NPC { self.anim_counter = 0; } - if self.action_counter > 0 { - self.action_counter -= 1; - } else { + self.action_counter = self.action_counter.saturating_sub(1); + if self.action_counter == 0 { self.action_num = 0; } diff --git a/src/game/npc/ai/misc.rs b/src/game/npc/ai/misc.rs index 97fa4a9..b990f51 100644 --- a/src/game/npc/ai/misc.rs +++ b/src/game/npc/ai/misc.rs @@ -190,6 +190,7 @@ impl NPC { pub(crate) fn tick_n016_save_point(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult { if self.action_num == 0 { + self.npc_flags.set_interactable(true); self.action_num = 1; if self.direction == Direction::Right { @@ -200,7 +201,7 @@ impl NPC { let mut npc = NPC::create(4, &state.npc_table); npc.cond.set_alive(true); - for _ in 0..3 { + for _ in 0..4 { npc.x = self.x + self.rng.range(-12..12) as i32 * 0x200; npc.y = self.y + self.rng.range(-12..12) as i32 * 0x200; npc.vel_x = self.rng.range(-341..341) as i32; @@ -211,7 +212,7 @@ impl NPC { } } - if self.flags.hit_bottom_wall() { + if self.action_num == 1 && self.flags.hit_bottom_wall() { self.npc_flags.set_interactable(true); } @@ -233,11 +234,13 @@ impl NPC { //Creates smoke when spawned in a shelter if self.direction == Direction::Right { + self.vel_y = -0x200; + //Creates smoke let mut npc = NPC::create(4, &state.npc_table); npc.cond.set_alive(true); - for _ in 0..3 { + for _ in 0..4 { npc.x = self.x + self.rng.range(-12..12) as i32 * 0x200; npc.y = self.y + self.rng.range(-12..12) as i32 * 0x200; npc.vel_x = self.rng.range(-341..341) as i32; @@ -267,9 +270,8 @@ impl NPC { self.anim_rect = state.constants.npc.n017_health_refill[0]; self.anim_num = 0; - if self.action_counter > 0 { - self.action_counter -= 1; - } else { + self.action_counter = self.action_counter.saturating_sub(1); + if self.action_counter == 0 { self.action_num = 1; } } @@ -284,9 +286,8 @@ impl NPC { self.anim_rect = state.constants.npc.n017_health_refill[0]; } - if self.action_counter > 0 { - self.action_counter -= 1; - } else { + self.action_counter = self.action_counter.saturating_sub(1); + if self.action_counter == 0 { self.action_num = 1; } } @@ -294,9 +295,8 @@ impl NPC { self.anim_num = 1; self.anim_rect = state.constants.npc.n017_health_refill[1]; - if self.action_counter > 0 { - self.action_counter -= 1; - } else { + self.action_counter = self.action_counter.saturating_sub(1); + if self.action_counter == 0 { self.action_num = 1; } } @@ -2056,7 +2056,7 @@ impl NPC { stage: &mut Stage, ) -> GameResult { match self.action_num { - 0 => { + 0 | 10 | 11 => { if self.action_num == 0 { match self.direction { Direction::Left => { @@ -2079,31 +2079,19 @@ impl NPC { } } - if self.direction == Direction::Up { - self.action_num = 11; - self.action_counter = 16; - - if self.action_counter > 0 { - self.action_counter = self.action_counter.saturating_sub(2); - } else { + if self.action_num != 0 || self.direction == Direction::Up { + if self.action_num == 10 { + self.action_num = 11; + self.action_counter = 16; + } + + self.action_counter = self.action_counter.saturating_sub(2); + if self.action_counter == 0 { self.action_num = 100; self.npc_flags.set_invulnerable(true); } } } - 10 | 11 => { - if self.action_num == 10 { - self.action_num = 11; - self.action_counter = 16; - } - - if self.action_counter > 0 { - self.action_counter = self.action_counter.saturating_sub(2); - } else { - self.action_num = 100; - self.npc_flags.set_invulnerable(true); - } - } 100 => { self.vel_y += 0x40; if self.vel_y > 0x700 { @@ -2154,7 +2142,7 @@ impl NPC { if self.action_num == 11 { self.anim_rect.top += self.action_counter; - self.anim_rect.bottom += self.action_counter; + self.anim_rect.bottom -= self.action_counter; self.display_bounds.top = (16u32).saturating_sub(self.action_counter as u32) * 0x200; } diff --git a/src/game/npc/ai/misery.rs b/src/game/npc/ai/misery.rs index bf1d226..facc416 100644 --- a/src/game/npc/ai/misery.rs +++ b/src/game/npc/ai/misery.rs @@ -318,7 +318,8 @@ impl NPC { 27 => { self.action_counter += 1; if self.action_counter == 50 { - self.action_num = 14; + self.action_num = 0; + self.anim_num = 0; } } 30 | 31 => { @@ -363,6 +364,10 @@ impl NPC { let _ = npc_list.spawn(0x100, npc); } + + if self.action_counter > 50 { + self.action_num = 0; + } } 50 => { self.anim_num = 8; @@ -919,7 +924,7 @@ impl NPC { match self.action_num { 0 | 1 => { - if self.action_num == 9 { + if self.action_num == 0 { self.action_num = 1; self.y -= 0x1000; state.sound_manager.play_sfx(29); @@ -933,7 +938,7 @@ impl NPC { self.anim_num = 9; } 20 | 21 => { - if self.action_num == 21 { + if self.action_num == 20 { self.action_num = 21; self.action_counter = 0; self.anim_num = 0; @@ -954,10 +959,10 @@ impl NPC { let player = self.get_closest_player_ref(&players); - self.direction = if player.x > self.x { Direction::Left } else { Direction::Right }; + self.direction = if player.x > self.x { Direction::Right } else { Direction::Left }; } 30 | 31 => { - if self.action_num == 31 { + if self.action_num == 30 { self.action_num = 31; self.action_counter = 0; self.anim_num = 2; @@ -997,6 +1002,8 @@ impl NPC { self.vel_x = 0; self.vel_y = 0; + state.sound_manager.play_sfx(103); + let player = self.get_closest_player_ref(&players); self.direction = if self.x > player.x { Direction::Left } else { Direction::Right }; self.action_counter3 = if player.y >= 0x14000 { 289 } else { 290 }; @@ -1045,7 +1052,7 @@ impl NPC { if self.action_counter > 50 { self.action_num = 30; self.vel_y = -0x200; - self.vel_x = self.direction.vector_x() * 0x200; + self.vel_x = self.direction.opposite().vector_x() * 0x200; } } 50 | 51 => { @@ -1070,17 +1077,17 @@ impl NPC { let mut npc = NPC::create(301, &state.npc_table); npc.cond.set_alive(true); - npc.x = self.x + 0x1400 * self.direction.vector_x(); + npc.x = self.x + 0x1400 * self.direction.opposite().vector_x(); npc.y = self.y; npc.tsc_direction = match ((self.action_counter / 6) & 3, self.direction) { - (0, Direction::Left) => 0x58, - (1, Direction::Left) => 0x6C, - (2, Direction::Left) => 0x94, - (3, Direction::Left) => 0xA8, - (0, _) => 0xD8, - (1, _) => 0xEC, - (2, _) => 0x14, - (3, _) => 0x28, + (0, Direction::Left) => 0xD8, + (1, Direction::Left) => 0xEC, + (2, Direction::Left) => 0x14, + (3, Direction::Left) => 0x28, + (0, _) => 0x58, + (1, _) => 0x6C, + (2, _) => 0x94, + (3, _) => 0xA8, _ => unsafe { unreachable_unchecked(); }, diff --git a/src/game/npc/ai/sue.rs b/src/game/npc/ai/sue.rs index 2eee2df..451bbbc 100644 --- a/src/game/npc/ai/sue.rs +++ b/src/game/npc/ai/sue.rs @@ -340,7 +340,7 @@ impl NPC { stage: &mut Stage, boss: &mut BossNPC, ) -> GameResult { - if self.action_num < 100 && (!boss.parts[0].cond.alive() || self.life < 400) { + if self.action_num < 100 && (!boss.parts[0].cond.alive() || self.life < 500) { self.action_num = 100; } @@ -403,7 +403,7 @@ impl NPC { let player = self.get_closest_player_ref(&players); - self.direction = if player.x > self.x { Direction::Left } else { Direction::Right }; + self.direction = if player.x > self.x { Direction::Right } else { Direction::Left }; if self.life + 50 < self.action_counter3 { self.action_counter3 = self.life; @@ -451,7 +451,7 @@ impl NPC { let half_h = stage.map.height as i32 * state.tile_size.as_int() * 0x200 / 2; if ((self.x < half_w && self.vel_x > 0) || (self.x > half_w && self.vel_x < 0)) - || ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0)) + && ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0)) { self.npc_flags.set_ignore_solidity(true); } @@ -486,7 +486,7 @@ impl NPC { let half_h = stage.map.height as i32 * state.tile_size.as_int() * 0x200 / 2; if ((self.x < half_w && self.vel_x > 0) || (self.x > half_w && self.vel_x < 0)) - || ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0)) + && ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0)) { self.npc_flags.set_ignore_solidity(true); } @@ -524,7 +524,7 @@ impl NPC { self.action_num = 42; self.action_counter = 0; - self.vel_x = self.direction.vector_x() * 0x200; + self.vel_x = self.direction.opposite().vector_x() * 0x200; self.vel_y = -0x200; } } @@ -561,6 +561,7 @@ impl NPC { self.damage = 0; self.npc_flags.set_shootable(false); self.npc_flags.set_ignore_solidity(true); + self.vel_y = -0x200; self.shock += 50; boss.parts[0].anim_num += 1; } diff --git a/src/game/npc/ai/toroko.rs b/src/game/npc/ai/toroko.rs index 86fac6f..74ab6f3 100644 --- a/src/game/npc/ai/toroko.rs +++ b/src/game/npc/ai/toroko.rs @@ -193,10 +193,10 @@ impl NPC { self.vel_x = 0x100 * self.direction.vector_x(); - self.action_counter += 1; if self.action_counter != 0 && self.flags.hit_bottom_wall() { self.action_num = 2; } + self.action_counter += 1; } 2 | 3 => { if self.action_num == 2 { @@ -240,11 +240,11 @@ impl NPC { 4 => { self.vel_x = 0x100 * self.direction.vector_x(); - self.action_counter += 1; if self.action_counter != 0 && self.flags.hit_bottom_wall() { self.action_num = 5; self.npc_flags.set_interactable(true); } + self.action_counter += 1; } 5 => { self.vel_x = 0; diff --git a/src/game/npc/boss/ballos.rs b/src/game/npc/boss/ballos.rs index 2775f75..3367455 100644 --- a/src/game/npc/boss/ballos.rs +++ b/src/game/npc/boss/ballos.rs @@ -176,6 +176,7 @@ impl NPC { match self.action_num { 0 | 1 => { if self.action_num == 0 { + self.action_num = 1; self.action_counter = self.rng.range(0..40) as u16; } if self.action_counter > 0 { @@ -362,13 +363,13 @@ impl NPC { } if self.action_num == 231 { - self.direction = if self.action_num == 220 { Direction::Left } else { Direction::Right }; + self.face_player(player); } self.action_num += 1; self.action_counter = 0; self.damage = 3; - let sign = self.direction.vector_x(); + let sign = if self.action_num == 221 { -1 } else { 1 }; for _ in 0..8 { let mut npc = NPC::create(4, &state.npc_table); @@ -435,7 +436,7 @@ impl NPC { self.action_counter = 0; self.anim_num = 3; - self.direction = if self.action_num == 220 { Direction::Left } else { Direction::Right }; + self.face_player(player); } } 242 => { @@ -520,6 +521,8 @@ impl NPC { self.target_x = self.x; self.vel_x = 0; self.npc_flags.set_shootable(false); + // I think Pixel meant for the smoke radius to be 16 pixels (0x2000) instead of 16 units, + // because as it is, this just gets divided by 0x200 units/px and becomes 0 npc_list.create_death_smoke(self.x, self.y, 16, 16, state, &self.rng); } self.vel_y += 0x20; @@ -657,7 +660,7 @@ impl NPC { } if self.action_counter2 < 2 { - self.action_counter2 += 512; + self.action_counter2 += 512 - 2; // Still have to subtract 2 first :) } else { self.action_counter2 -= 2; } @@ -672,7 +675,7 @@ impl NPC { if self.life < 900 { self.action_num = 22; self.npc_flags.set_shootable(false); - npc_list.create_death_smoke(self.x, self.y, 16, 32, state, &self.rng); + npc_list.create_death_smoke(self.x, self.y, 0x2000, 32, state, &self.rng); state.sound_manager.play_sfx(71); } @@ -686,7 +689,7 @@ impl NPC { self.anim_num = 2; if self.action_counter2 < 2 { - self.action_counter2 += 512; + self.action_counter2 += 512 - 2; } else { self.action_counter2 -= 2; } @@ -699,7 +702,7 @@ impl NPC { self.anim_num = 2; if self.action_counter2 < 4 { - self.action_counter2 += 512; + self.action_counter2 += 512 - 4; } else { self.action_counter2 -= 4; } @@ -753,6 +756,8 @@ impl NPC { self.damage = 5; self.npc_flags.set_ignore_solidity(false); self.npc_flags.set_shootable(false); + npc_list.create_death_smoke(self.x, self.y, 0x2000, 32, state, &self.rng); + state.sound_manager.play_sfx(71); } if self.flags.hit_left_wall() { @@ -793,7 +798,7 @@ impl NPC { self.anim_num = 0; } } else { - npc_list.create_death_smoke(self.x, self.y, 16, 32, state, &self.rng); + npc_list.create_death_smoke(self.x, self.y, 0x2000, 32, state, &self.rng); state.sound_manager.play_sfx(71); self.vanish(state); return Ok(()); @@ -816,6 +821,8 @@ impl NPC { npc.x = self.x - 0x1000; npc.y = self.y + 0x1800; let _ = npc_list.spawn(0x100, npc); + + state.sound_manager.play_sfx(26); } (Direction::Up, 268) => { let mut npc = NPC::create(4, &state.npc_table); @@ -829,6 +836,8 @@ impl NPC { npc.x = self.x - 0x1800; npc.y = self.y - 0x1000; let _ = npc_list.spawn(0x100, npc); + + state.sound_manager.play_sfx(26); } (Direction::Right, 396) => { let mut npc = NPC::create(4, &state.npc_table); @@ -848,6 +857,8 @@ impl NPC { npc.x = self.x - 0x1000; npc.y = self.y - 0x1800; let _ = npc_list.spawn(0x100, npc); + + state.sound_manager.play_sfx(26); } (Direction::Bottom, 12) => { let mut npc = NPC::create(4, &state.npc_table); @@ -861,6 +872,8 @@ impl NPC { npc.x = self.x + 0x1800; npc.y = self.y - 0x1000; let _ = npc_list.spawn(0x100, npc); + + state.sound_manager.play_sfx(26); } _ => (), } @@ -1017,7 +1030,7 @@ impl NPC { if self.action_counter2 > 0 { self.action_counter2 -= 1; } else { - self.action_counter2 += 0x400; + self.action_counter2 += 0x400 - 1; } if boss.parts[0].action_num == 421 { @@ -1040,7 +1053,7 @@ impl NPC { if self.action_counter2 > 1 { self.action_counter2 -= 2; } else { - self.action_counter2 += 0x400; + self.action_counter2 += 0x400 - 2; } if boss.parts[0].action_num == 422 { @@ -1108,8 +1121,6 @@ impl NPC { self.vel_y = self.target_y - self.y; } } - } else { - self.vel_y = 0; } self.x += self.vel_x; @@ -1432,7 +1443,7 @@ impl BossNPC { self.parts[3].cond.set_alive(true); self.parts[3].cond.set_damage_boss(true); - self.parts[3].npc_flags.set_solid_hard(true); // This should be soft -- investigate bug with large soft collision boxes? + self.parts[3].npc_flags.set_solid_soft(true); self.parts[3].npc_flags.set_invulnerable(true); self.parts[3].npc_flags.set_ignore_solidity(true); self.parts[3].display_bounds = Rect { left: 0x7800, top: 0x7800, right: 0x7800, bottom: 0x7800 }; diff --git a/src/game/npc/boss/core.rs b/src/game/npc/boss/core.rs index 2e4be32..62476ff 100644 --- a/src/game/npc/boss/core.rs +++ b/src/game/npc/boss/core.rs @@ -16,7 +16,7 @@ impl NPC { self.cond.set_alive(false); } - if (self.y - 0x800) > state.water_level { + if self.flags.in_water() { self.x += self.vel_x / 2; self.y += self.vel_y / 2; } else { diff --git a/src/game/npc/boss/monster_x.rs b/src/game/npc/boss/monster_x.rs index 26cb5d9..2ba8ac4 100644 --- a/src/game/npc/boss/monster_x.rs +++ b/src/game/npc/boss/monster_x.rs @@ -38,7 +38,8 @@ impl NPC { self.y += self.vel_y; let player = self.get_closest_player_mut(players); - let direction = f64::atan2(-(self.y - player.y) as f64, -(self.x - player.x) as f64); + // Get angle between 0 and 2*PI + let direction = f64::atan2((self.y - player.y) as f64, (self.x - player.x) as f64) + std::f64::consts::PI; if direction < radians { if radians - direction < std::f64::consts::PI { diff --git a/src/game/npc/boss/sisters.rs b/src/game/npc/boss/sisters.rs index 8c0e220..baa5e30 100644 --- a/src/game/npc/boss/sisters.rs +++ b/src/game/npc/boss/sisters.rs @@ -316,6 +316,15 @@ impl BossNPC { part.hit_bounds.left = 0x2000; state.sound_manager.play_sfx(51); + + npc_list.create_death_smoke( + part.x, + part.y, + part.display_bounds.right as usize, + 4, + state, + &part.rng + ); } } 220 => { @@ -328,11 +337,11 @@ impl BossNPC { npc.y = part.y; let player = part.get_closest_player_ref(players); - let angle = f64::atan2((player.y - npc.y) as f64, (player.x - npc.x) as f64) + let angle = f64::atan2((part.y - player.y) as f64, (part.x - player.x) as f64) + (part.rng.range(-6..6) as f64 * CDEG_RAD); - npc.vel_x = (angle.cos() * 512.0) as i32; - npc.vel_y = (angle.sin() * 512.0) as i32; + npc.vel_x = (angle.cos() * -512.0) as i32; + npc.vel_y = (angle.sin() * -512.0) as i32; let _ = npc_list.spawn(0x100, npc); @@ -375,14 +384,14 @@ impl BossNPC { npc.cond.set_alive(true); let player = part.get_closest_player_ref(players); - let angle = f64::atan2((player.y - npc.y) as f64, (player.x - npc.x) as f64) + let angle = f64::atan2((part.y - player.y) as f64, (part.x - player.x) as f64) + (part.rng.range(-6..6) as f64 * CDEG_RAD); npc.x = part.x + 0x1000 * part.direction.vector_x(); npc.y = part.y; - npc.vel_x = (angle.cos() * 512.0) as i32; - npc.vel_y = (angle.sin() * 512.0) as i32; + npc.vel_x = (angle.cos() * -512.0) as i32; + npc.vel_y = (angle.sin() * -512.0) as i32; let _ = npc_list.spawn(0x100, npc); @@ -390,6 +399,7 @@ impl BossNPC { } } 1000 => { + part.npc_flags.set_shootable(false); part.anim_num = 3; } _ => (), diff --git a/src/game/npc/boss/undead_core.rs b/src/game/npc/boss/undead_core.rs index bdd9a19..7f9410d 100644 --- a/src/game/npc/boss/undead_core.rs +++ b/src/game/npc/boss/undead_core.rs @@ -20,7 +20,7 @@ impl NPC { if self.action_num == 0 { self.action_num = 20; self.target_y = self.y; - self.vel_y = if self.rng.range(0..100) & 1 == 0 { -0x100 } else { 0x100 }; + self.vel_y = if self.rng.range(0..100) & 1 != 0 { -0x100 } else { 0x100 }; } if self.action_num == 20 { @@ -525,6 +525,7 @@ impl BossNPC { self.parts[10].npc_flags.set_invulnerable(true); self.parts[11].npc_flags.set_shootable(true); self.parts[19].action_counter = self.parts[0].life; + v19 = true; state.quake_counter = 100; state.quake_rumble_counter = 100; diff --git a/src/game/npc/utils.rs b/src/game/npc/utils.rs index c9acf0d..bf8e9b6 100644 --- a/src/game/npc/utils.rs +++ b/src/game/npc/utils.rs @@ -362,9 +362,9 @@ impl NPCList { state.set_flag(npc.flag_num as usize, true); match npc.size { - 1 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 3, state, &npc.rng), - 2 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 7, state, &npc.rng), - 3 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 12, state, &npc.rng), + 1 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 4, state, &npc.rng), + 2 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 8, state, &npc.rng), + 3 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 16, state, &npc.rng), _ => {} }; } diff --git a/src/game/player/mod.rs b/src/game/player/mod.rs index c43a110..a469fb7 100644 --- a/src/game/player/mod.rs +++ b/src/game/player/mod.rs @@ -746,7 +746,7 @@ impl Player { if self.flags.hit_bottom_wall() { if self.cond.interacted() { self.skin.set_state(PlayerAnimationState::Examining); - self.anim_num = 0; + self.anim_num = 11; self.anim_counter = 0; } else if state.control_flags.control_enabled() && (self.controller.move_up() || self.strafe_up) @@ -794,7 +794,7 @@ impl Player { self.cond.set_fallen(false); self.skin.set_state(PlayerAnimationState::LookingUp); - self.anim_num = 0; + self.anim_num = 5; self.anim_counter = 0; } else { if self.cond.fallen() { @@ -806,19 +806,15 @@ impl Player { self.anim_num = 0; self.anim_counter = 0; } - } else if state.control_flags.control_enabled() - && (self.controller.look_up() || self.strafe_up) - && self.control_mode == ControlMode::Normal + } else if self.up { self.skin.set_state(PlayerAnimationState::FallingLookingUp); - self.anim_num = 0; + self.anim_num = 6; self.anim_counter = 0; - } else if state.control_flags.control_enabled() - && self.controller.look_down() - && self.control_mode == ControlMode::Normal + } else if self.down { self.skin.set_state(PlayerAnimationState::FallingLookingDown); - self.anim_num = 0; + self.anim_num = 10; self.anim_counter = 0; } else { if self.vel_y > 0 { diff --git a/src/game/player/player_hit.rs b/src/game/player/player_hit.rs index d115746..fb79d9c 100644 --- a/src/game/player/player_hit.rs +++ b/src/game/player/player_hit.rs @@ -106,7 +106,7 @@ impl Player { let mut flags = Flag(0); if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 0x600)) - && ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.bottom as i32 + 0x600)) + && ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.top as i32 + 0x600)) && ((self.x - self.hit_bounds.right as i32) < (npc.x + npc.hit_bounds.right as i32)) && ((self.x - self.hit_bounds.right as i32) > npc.x) { @@ -118,7 +118,7 @@ impl Player { } if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 0x600)) - && ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.bottom as i32 + 0x600)) + && ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.top as i32 + 0x600)) && ((self.x + self.hit_bounds.right as i32 - 0x200) > (npc.x - npc.hit_bounds.right as i32)) && ((self.x + self.hit_bounds.right as i32 - 0x200) < npc.x) { diff --git a/src/game/player/skin/basic.rs b/src/game/player/skin/basic.rs index 0f8b597..25556f4 100644 --- a/src/game/player/skin/basic.rs +++ b/src/game/player/skin/basic.rs @@ -142,8 +142,8 @@ impl PlayerSkin for BasicPlayerSkin { PlayerAnimationState::Examining => 7, PlayerAnimationState::Sitting => 8, PlayerAnimationState::Collapsed => 9, - PlayerAnimationState::Jumping => 1, - PlayerAnimationState::Falling => 2, + PlayerAnimationState::Jumping => 2, + PlayerAnimationState::Falling => 1, PlayerAnimationState::FallingLookingUp => 4, PlayerAnimationState::FallingLookingDown => 6, PlayerAnimationState::FallingUpsideDown => 10, diff --git a/src/game/scripting/tsc/text_script.rs b/src/game/scripting/tsc/text_script.rs index f7536f9..4219364 100644 --- a/src/game/scripting/tsc/text_script.rs +++ b/src/game/scripting/tsc/text_script.rs @@ -764,8 +764,19 @@ impl TextScriptVM { TSCOpCode::MYD => { let new_direction = read_cur_varint(&mut cursor)? as usize; if let Some(direction) = Direction::from_int(new_direction) { - game_scene.player1.direction = direction; - game_scene.player2.direction = direction; + if direction != Direction::Bottom { + game_scene.player1.direction = direction; + game_scene.player2.direction = direction; + } + } else if new_direction >= 10 { + for npc in game_scene.npc_list.iter_alive() { + // The vanilla game treats this as a 1-byte value lol + //if npc.event_num == (new_direction & 0xFF) as u16 { + if npc.event_num == new_direction as u16 { + game_scene.player1.direction = if game_scene.player1.x > npc.x { Direction::Left } else { Direction::Right }; + game_scene.player2.direction = if game_scene.player2.x > npc.x { Direction::Left } else { Direction::Right }; + } + } } game_scene.player1.cond.set_interacted(new_direction == 3); game_scene.player2.cond.set_interacted(new_direction == 3); @@ -1185,6 +1196,11 @@ impl TextScriptVM { new_scene.frame.wait = game_scene.frame.wait; new_scene.nikumaru = game_scene.nikumaru; new_scene.replay = game_scene.replay.clone(); + // Reset player invincibility (kind of hacky, but oh well) + if state.constants.textscript.reset_invicibility_on_any_script { + new_scene.player1.shock_counter = 0; + new_scene.player2.shock_counter = 0; + } let skip = state.textscript_vm.flags.cutscene_skip(); state.control_flags.set_tick_world(true); diff --git a/src/game/weapon/bubbler.rs b/src/game/weapon/bubbler.rs index 7779439..6024d1c 100644 --- a/src/game/weapon/bubbler.rs +++ b/src/game/weapon/bubbler.rs @@ -84,7 +84,7 @@ impl Weapon { } Direction::Left => { bullet_manager.create_bullet( - player.x - 0x1800, + player.x - 0xC00, player.y + 0x600, btype, player_id, @@ -95,7 +95,7 @@ impl Weapon { } Direction::Right => { bullet_manager.create_bullet( - player.x + 0x1800, + player.x + 0xC00, player.y + 0x600, btype, player_id, @@ -126,7 +126,7 @@ impl Weapon { return; } - self.counter2 = 0; // recharge time counter + // self.counter2 : recharge time counter self.counter1 += 1; // autofire counter if self.counter1 > 6 { diff --git a/src/game/weapon/bullet.rs b/src/game/weapon/bullet.rs index 38637ce..3e9568a 100644 --- a/src/game/weapon/bullet.rs +++ b/src/game/weapon/bullet.rs @@ -617,21 +617,23 @@ impl Bullet { if self.btype == 15 { match self.direction { Direction::Left | Direction::Right => { - self.vel_y = (self.y - player.y).signum() * 0x100; + self.vel_y = if self.y > player.y { 0x100 } else { -0x100 }; self.vel_x = self.rng.range(-0x200..0x200); } Direction::Up | Direction::Bottom => { - self.vel_x = (self.x - player.x).signum() * 0x100; + self.vel_x = if self.x > player.x { 0x100 } else { -0x100 }; self.vel_y = self.rng.range(-0x200..0x200); } _ => {} } + // offset by 1 because we 'increment' late self.counter1 = match self.counter2 { - 1 => 64, - 2 => 51, - _ => 128, + 1 => 51, + 2 => 128, + _ => 64, }; + self.counter2 = 0; } else { self.counter1 = 128; } @@ -649,10 +651,10 @@ impl Bullet { if self.btype == 15 { match self.direction { Direction::Left | Direction::Right => { - self.vel_y = (player.y - self.y).signum() * 0x20; + self.vel_y += if self.y < self.target_y { 0x20 } else { -0x20 }; } Direction::Up | Direction::Bottom => { - self.vel_x = (player.x - self.x).signum() * 0x20; + self.vel_x += if self.x < self.target_x { 0x20 } else { -0x20 }; } _ => {} } @@ -938,14 +940,10 @@ impl Bullet { match self.direction { Direction::Left => { - let val = self.rng.range(10..16); - // what the fuck - self.vel_x = (((val * -0x200).rotate_left(1) & 1) - val * 0x200) / 2; + self.vel_x = (self.rng.range(10..16) * -0x200) / 2; } Direction::Up => { - let val = self.rng.range(10..16); - // what the fuck - self.vel_y = (((val * -0x200).rotate_left(1) & 1) - val * 0x200) / 2; + self.vel_y = (self.rng.range(10..16) * -0x200) / 2; } Direction::Right => { self.vel_x = (self.rng.range(10..16) * 0x200) / 2; @@ -1256,21 +1254,23 @@ impl Bullet { if self.btype == 30 { match self.direction { Direction::Left | Direction::Right => { - self.vel_y = (self.y - player.y).signum() * 0x100; + self.vel_y = if self.y > player.y { 0x100 } else { -0x100 }; self.vel_x = self.rng.range(-0x200..0x200); } Direction::Up | Direction::Bottom => { - self.vel_x = (self.x - player.x).signum() * 0x100; + self.vel_x = if self.x > player.x { 0x100 } else { -0x100 }; self.vel_y = self.rng.range(-0x200..0x200); } _ => {} } + // offset by 1 because we 'increment' late self.counter1 = match self.counter2 { - 1 => 256, - 2 => 170, - _ => 512, + 1 => 170, + 2 => 512, + _ => 256, }; + self.counter2 = 0; } else { self.counter1 = 512; } @@ -1288,10 +1288,10 @@ impl Bullet { if self.btype == 30 { match self.direction { Direction::Left | Direction::Right => { - self.vel_y = (player.y - self.y).signum() * 0x40; + self.vel_y += if self.y < self.target_y { 0x40 } else { -0x40 }; } Direction::Up | Direction::Bottom => { - self.vel_x = (player.x - self.x).signum() * 0x40; + self.vel_x += if self.x < self.target_x { 0x40 } else { -0x40 }; } _ => {} } diff --git a/src/game/weapon/machine_gun.rs b/src/game/weapon/machine_gun.rs index 8a42c5e..1109348 100644 --- a/src/game/weapon/machine_gun.rs +++ b/src/game/weapon/machine_gun.rs @@ -30,7 +30,7 @@ impl Weapon { return; } - self.counter2 = 0; // recharge time counter + // self.counter2 : recharge time counter self.counter1 += 1; // autofire counter if self.counter1 > 5 { diff --git a/src/game/weapon/missile_launcher.rs b/src/game/weapon/missile_launcher.rs index d896498..cf44e80 100644 --- a/src/game/weapon/missile_launcher.rs +++ b/src/game/weapon/missile_launcher.rs @@ -44,49 +44,42 @@ impl Weapon { return; } - fn increment(weapon: &mut Weapon, bullet: &mut Bullet) { - weapon.counter2 = (weapon.counter2 + 1) % 3; - bullet.counter2 = weapon.counter2; - } - match player.direction { Direction::Left if player.up => { let mut bullet = Bullet::new(player.x - 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants); - increment(self, &mut bullet); - + bullet_manager.push_bullet(bullet.clone()); state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { - bullet.x = player.x - 0x600; + bullet.x = player.x + 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); - bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.x = player.x - 0x600; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } Direction::Right if player.up => { let mut bullet = Bullet::new(player.x + 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { - bullet.x = player.x - 0x600; + bullet.x = player.x + 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); - bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.x = player.x - 0x600; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } @@ -99,20 +92,19 @@ impl Weapon { Direction::Bottom, &state.constants, ); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { - bullet.x = player.x - 0x600; + bullet.x = player.x + 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); - bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.x = player.x - 0x600; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } @@ -125,7 +117,6 @@ impl Weapon { Direction::Bottom, &state.constants, ); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); @@ -134,53 +125,53 @@ impl Weapon { if self.level == WeaponLevel::Level3 { bullet.x = player.x - 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } Direction::Left => { + let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200; let mut bullet = - Bullet::new(player.x - 0xc00, player.y, btype, player_id, Direction::Left, &state.constants); - increment(self, &mut bullet); + Bullet::new(player.x - 0xc00, player.y + yoffset, btype, player_id, Direction::Left, &state.constants); bullet_manager.push_bullet(bullet.clone()); - state.create_caret(player.x - 0x1800, player.y, CaretType::Shoot, Direction::Left); + state.create_caret(player.x - 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { bullet.x = player.x; bullet.y = player.y - 0x1000; - increment(self, &mut bullet); - bullet_manager.push_bullet(bullet.clone()); - - bullet.x = player.x - 0x800; - bullet.y = player.y - 0x200; - increment(self, &mut bullet); - bullet_manager.push_bullet(bullet); - } - } - Direction::Right => { - let mut bullet = - Bullet::new(player.x + 0xc00, player.y, btype, player_id, Direction::Right, &state.constants); - increment(self, &mut bullet); - - bullet_manager.push_bullet(bullet.clone()); - - state.create_caret(player.x + 0x1800, player.y, CaretType::Shoot, Direction::Left); - - if self.level == WeaponLevel::Level3 { - bullet.x = player.x; - bullet.y = player.y - 0x1000; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); bullet.x = player.x + 0x800; bullet.y = player.y - 0x200; - increment(self, &mut bullet); + bullet.counter2 = 2; + bullet_manager.push_bullet(bullet); + } + } + Direction::Right => { + let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200; + let mut bullet = + Bullet::new(player.x + 0xc00, player.y + yoffset, btype, player_id, Direction::Right, &state.constants); + + bullet_manager.push_bullet(bullet.clone()); + + state.create_caret(player.x + 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left); + + if self.level == WeaponLevel::Level3 { + bullet.x = player.x; + bullet.y = player.y - 0x1000; + bullet.counter2 = 1; + bullet_manager.push_bullet(bullet.clone()); + + bullet.x = player.x - 0x800; + bullet.y = player.y - 0x200; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } diff --git a/src/game/weapon/nemesis.rs b/src/game/weapon/nemesis.rs index af24b4b..9555eb9 100644 --- a/src/game/weapon/nemesis.rs +++ b/src/game/weapon/nemesis.rs @@ -28,7 +28,7 @@ impl Weapon { if !self.consume_ammo(1) { state.sound_manager.play_sfx(37); - // todo spawn "empty" text + // The vanilla game doesn't spawn "empty" text for some reason return; } @@ -36,11 +36,11 @@ impl Weapon { match player.direction { Direction::Left => { bullet_manager.create_bullet(player.x - 0x200, player.y - 0x1800, btype, player_id, Direction::Up, &state.constants); - state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left); + state.create_caret(player.x - 0x200, player.y - 0x1800, CaretType::Shoot, Direction::Left); } Direction::Right => { bullet_manager.create_bullet(player.x + 0x200, player.y - 0x1800, btype, player_id, Direction::Up, &state.constants); - state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left); + state.create_caret(player.x + 0x200, player.y - 0x1800, CaretType::Shoot, Direction::Left); } _ => {} } @@ -48,11 +48,11 @@ impl Weapon { match player.direction { Direction::Left => { bullet_manager.create_bullet(player.x - 0x200, player.y + 0x1800, btype, player_id, Direction::Bottom, &state.constants); - state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left); + state.create_caret(player.x - 0x200, player.y + 0x1800, CaretType::Shoot, Direction::Left); } Direction::Right => { bullet_manager.create_bullet(player.x + 0x200, player.y + 0x1800, btype, player_id, Direction::Bottom, &state.constants); - state.create_caret(player.x + 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left); + state.create_caret(player.x + 0x200, player.y + 0x1800, CaretType::Shoot, Direction::Left); } _ => {} } diff --git a/src/game/weapon/super_missile_launcher.rs b/src/game/weapon/super_missile_launcher.rs index 78705b9..4d6c3f8 100644 --- a/src/game/weapon/super_missile_launcher.rs +++ b/src/game/weapon/super_missile_launcher.rs @@ -44,49 +44,42 @@ impl Weapon { return; } - fn increment(weapon: &mut Weapon, bullet: &mut Bullet) { - weapon.counter2 = (weapon.counter2 + 1) % 3; - bullet.counter2 = weapon.counter2; - } - match player.direction { Direction::Left if player.up => { let mut bullet = Bullet::new(player.x - 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { - bullet.x = player.x - 0x600; - bullet.y = player.y; - increment(self, &mut bullet); - bullet_manager.push_bullet(bullet.clone()); - bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.y = player.y; + bullet.counter2 = 1; + bullet_manager.push_bullet(bullet.clone()); + + bullet.x = player.x - 0x600; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } Direction::Right if player.up => { let mut bullet = Bullet::new(player.x + 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { - bullet.x = player.x - 0x600; + bullet.x = player.x + 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); - bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.x = player.x - 0x600; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } @@ -99,20 +92,19 @@ impl Weapon { Direction::Bottom, &state.constants, ); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { - bullet.x = player.x - 0x600; + bullet.x = player.x + 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); - bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.x = player.x - 0x600; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } @@ -125,7 +117,6 @@ impl Weapon { Direction::Bottom, &state.constants, ); - increment(self, &mut bullet); bullet_manager.push_bullet(bullet.clone()); @@ -134,53 +125,53 @@ impl Weapon { if self.level == WeaponLevel::Level3 { bullet.x = player.x - 0x600; bullet.y = player.y; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); bullet.x = player.x + 0x600; - increment(self, &mut bullet); + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } } Direction::Left => { + let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200; let mut bullet = - Bullet::new(player.x - 0xc00, player.y, btype, player_id, Direction::Left, &state.constants); - increment(self, &mut bullet); + Bullet::new(player.x - 0xc00, player.y + yoffset, btype, player_id, Direction::Left, &state.constants); bullet_manager.push_bullet(bullet.clone()); - state.create_caret(player.x - 0x1800, player.y, CaretType::Shoot, Direction::Left); + state.create_caret(player.x - 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left); if self.level == WeaponLevel::Level3 { bullet.x = player.x; bullet.y = player.y - 0x1000; - increment(self, &mut bullet); - bullet_manager.push_bullet(bullet.clone()); - - bullet.x = player.x - 0x800; - bullet.y = player.y - 0x200; - increment(self, &mut bullet); - bullet_manager.push_bullet(bullet); - } - } - Direction::Right => { - let mut bullet = - Bullet::new(player.x + 0xc00, player.y, btype, player_id, Direction::Right, &state.constants); - increment(self, &mut bullet); - - bullet_manager.push_bullet(bullet.clone()); - - state.create_caret(player.x + 0x1800, player.y, CaretType::Shoot, Direction::Left); - - if self.level == WeaponLevel::Level3 { - bullet.x = player.x; - bullet.y = player.y - 0x1000; - increment(self, &mut bullet); + bullet.counter2 = 1; bullet_manager.push_bullet(bullet.clone()); bullet.x = player.x + 0x800; bullet.y = player.y - 0x200; - increment(self, &mut bullet); + bullet.counter2 = 2; + bullet_manager.push_bullet(bullet); + } + } + Direction::Right => { + let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200; + let mut bullet = + Bullet::new(player.x + 0xc00, player.y + yoffset, btype, player_id, Direction::Right, &state.constants); + + bullet_manager.push_bullet(bullet.clone()); + + state.create_caret(player.x + 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left); + + if self.level == WeaponLevel::Level3 { + bullet.x = player.x; + bullet.y = player.y - 0x1000; + bullet.counter2 = 1; + bullet_manager.push_bullet(bullet.clone()); + + bullet.x = player.x - 0x800; + bullet.y = player.y - 0x200; + bullet.counter2 = 2; bullet_manager.push_bullet(bullet); } }