mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-12-01 01:23:49 +00:00
Accuracy fixes for Waterway through Hell (#237)
* Accuracy fixes for Waterway through Balcony * Hell accuracy fixes
This commit is contained in:
parent
3468bcf5fd
commit
c2ad3dd643
|
@ -64,7 +64,7 @@ impl NPC {
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
let _ = npc_list.spawn(0x100, npc);
|
||||||
|
|
||||||
// chaco
|
// chaco
|
||||||
let mut npc = NPC::create(223, &state.npc_table);
|
let mut npc = NPC::create(93, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.x - 0x4600;
|
npc.x = self.x - 0x4600;
|
||||||
npc.y = self.y - 0x1c00;
|
npc.y = self.y - 0x1c00;
|
||||||
|
@ -116,6 +116,16 @@ impl NPC {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 };
|
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];
|
self.anim_rect = state.constants.npc.n255_helicopter_blades[self.anim_num as usize + dir_offset];
|
||||||
|
|
|
@ -364,8 +364,8 @@ impl NPC {
|
||||||
npc.y = self.y;
|
npc.y = self.y;
|
||||||
|
|
||||||
for i in (8..256).step_by(16) {
|
for i in (8..256).step_by(16) {
|
||||||
npc.vel_x = ((i as f64 * CDEG_RAD).cos() * -1024.0) as i32;
|
npc.vel_x = ((i as f64 * CDEG_RAD).cos() * 1024.0) as i32;
|
||||||
npc.vel_y = ((i as f64 * CDEG_RAD).sin() * -1024.0) as i32;
|
npc.vel_y = ((i as f64 * CDEG_RAD).sin() * 1024.0) as i32;
|
||||||
|
|
||||||
let _ = npc_list.spawn(0x100, npc.clone());
|
let _ = npc_list.spawn(0x100, npc.clone());
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,6 @@ impl NPC {
|
||||||
self.action_counter += 1;
|
self.action_counter += 1;
|
||||||
if self.action_counter > 50 {
|
if self.action_counter > 50 {
|
||||||
self.action_num = 100;
|
self.action_num = 100;
|
||||||
self.anim_num = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
100 | 101 => {
|
100 | 101 => {
|
||||||
|
@ -507,8 +506,8 @@ impl NPC {
|
||||||
self.target_x += self.vel_x;
|
self.target_x += self.vel_x;
|
||||||
|
|
||||||
let angle = self.action_counter2 as f64 * CDEG_RAD;
|
let angle = self.action_counter2 as f64 * CDEG_RAD;
|
||||||
self.x = self.target_x + self.action_counter as i32 * (angle.cos() * -512.0) as i32 / 8;
|
self.x = self.target_x + self.action_counter as i32 * (angle.cos() * 512.0) as i32 / 8;
|
||||||
self.y = self.target_y + self.action_counter as i32 * (angle.sin() * -512.0) as i32 / 2;
|
self.y = self.target_y + self.action_counter as i32 * (angle.sin() * 512.0) as i32 / 2;
|
||||||
|
|
||||||
let mut npc = NPC::create(265, &state.npc_table);
|
let mut npc = NPC::create(265, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
|
@ -652,7 +651,7 @@ impl NPC {
|
||||||
self.direction = if self.x > player.x { Direction::Left } else { Direction::Right };
|
self.direction = if self.x > player.x { Direction::Left } else { Direction::Right };
|
||||||
|
|
||||||
if self.flags.hit_bottom_wall() {
|
if self.flags.hit_bottom_wall() {
|
||||||
if self.life + 20 > self.action_counter3 {
|
if self.life + 20 >= self.action_counter3 {
|
||||||
self.animate(10, 1, 2);
|
self.animate(10, 1, 2);
|
||||||
} else if player.flags.hit_bottom_wall() && player.x > self.x - 0x6000 && player.x < self.x + 0x6000 && self.anim_num != 6
|
} else if player.flags.hit_bottom_wall() && player.x > self.x - 0x6000 && player.x < self.x + 0x6000 && self.anim_num != 6
|
||||||
{
|
{
|
||||||
|
@ -900,9 +899,8 @@ impl NPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
103 => {
|
103 => {
|
||||||
if self.action_counter > 0 {
|
self.action_counter = self.action_counter.saturating_sub(2);
|
||||||
self.action_counter -= 2;
|
if self.action_counter == 0 {
|
||||||
} else {
|
|
||||||
self.action_num = 16;
|
self.action_num = 16;
|
||||||
self.vel_x = 0;
|
self.vel_x = 0;
|
||||||
self.vel_y = -0x200;
|
self.vel_y = -0x200;
|
||||||
|
@ -936,7 +934,7 @@ impl NPC {
|
||||||
if self.action_counter / 2 % 2 != 0 {
|
if self.action_counter / 2 % 2 != 0 {
|
||||||
self.x = self.target_x;
|
self.x = self.target_x;
|
||||||
} else {
|
} else {
|
||||||
self.x = self.x.wrapping_add(0x200);
|
self.x = self.target_x.wrapping_add(0x200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
510 | 511 => {
|
510 | 511 => {
|
||||||
|
@ -1072,7 +1070,7 @@ impl NPC {
|
||||||
|
|
||||||
self.x += self.vel_x;
|
self.x += self.vel_x;
|
||||||
self.y += self.vel_y;
|
self.y += self.vel_y;
|
||||||
if self.action_counter > 50 || self.flags.any_flag() {
|
if self.action_counter > 50 || self.flags.hit_anything() {
|
||||||
self.cond.set_alive(false)
|
self.cond.set_alive(false)
|
||||||
}
|
}
|
||||||
} else if self.direction == Direction::Right {
|
} else if self.direction == Direction::Right {
|
||||||
|
|
|
@ -83,7 +83,7 @@ impl NPC {
|
||||||
self.action_num = 1;
|
self.action_num = 1;
|
||||||
|
|
||||||
if (self.direction == Direction::Left && player.x > self.x - 0x24000 && player.x < self.x - 0x22000)
|
if (self.direction == Direction::Left && player.x > self.x - 0x24000 && player.x < self.x - 0x22000)
|
||||||
|| (player.x < self.x + 0x24000 && player.x > self.x + 0x22000)
|
|| (self.direction != Direction::Left && player.x < self.x + 0x24000 && player.x > self.x + 0x22000)
|
||||||
{
|
{
|
||||||
self.action_num = 10;
|
self.action_num = 10;
|
||||||
}
|
}
|
||||||
|
@ -730,7 +730,7 @@ impl NPC {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.animate(1, 0, 2);
|
self.animate(0, 0, 2);
|
||||||
self.anim_rect = state.constants.npc.n319_mesa_block[self.anim_num as usize];
|
self.anim_rect = state.constants.npc.n319_mesa_block[self.anim_num as usize];
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -280,6 +280,7 @@ impl NPC {
|
||||||
0 | 1 => {
|
0 | 1 => {
|
||||||
if self.action_num == 0 {
|
if self.action_num == 0 {
|
||||||
self.action_num = 1;
|
self.action_num = 1;
|
||||||
|
state.sound_manager.play_sfx(72);
|
||||||
|
|
||||||
let player = self.get_closest_player_mut(players);
|
let player = self.get_closest_player_mut(players);
|
||||||
self.direction = if self.x > player.x { Direction::Left } else { Direction::Right };
|
self.direction = if self.x > player.x { Direction::Left } else { Direction::Right };
|
||||||
|
@ -428,7 +429,7 @@ impl NPC {
|
||||||
self.action_counter = 0;
|
self.action_counter = 0;
|
||||||
self.anim_num = 0;
|
self.anim_num = 0;
|
||||||
self.action_counter = 0;
|
self.action_counter = 0;
|
||||||
self.direction = if self.x < player.x { Direction::Right } else { Direction::Left };
|
self.direction = if self.x <= player.x { Direction::Right } else { Direction::Left };
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vel_x = self.direction.vector_x() * 0x200;
|
self.vel_x = self.direction.vector_x() * 0x200;
|
||||||
|
@ -495,8 +496,8 @@ impl NPC {
|
||||||
let deg = (if self.direction == Direction::Left { 0x88 } else { 0xf8 } + self.rng.range(-16..16))
|
let deg = (if self.direction == Direction::Left { 0x88 } else { 0xf8 } + self.rng.range(-16..16))
|
||||||
as f64
|
as f64
|
||||||
* CDEG_RAD;
|
* CDEG_RAD;
|
||||||
let vel_x = (deg.cos() * 1536.0) as i32;
|
let vel_x = (deg.cos() * 2560.0) as i32;
|
||||||
let vel_y = (deg.sin() * 1536.0) as i32;
|
let vel_y = (deg.sin() * 2560.0) as i32;
|
||||||
|
|
||||||
let mut npc = NPC::create(11, &state.npc_table);
|
let mut npc = NPC::create(11, &state.npc_table);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::game::npc::list::NPCList;
|
||||||
use crate::game::npc::NPC;
|
use crate::game::npc::NPC;
|
||||||
use crate::game::player::Player;
|
use crate::game::player::Player;
|
||||||
use crate::game::shared_game_state::SharedGameState;
|
use crate::game::shared_game_state::SharedGameState;
|
||||||
|
use crate::game::stage::Stage;
|
||||||
use crate::util::rng::RNG;
|
use crate::util::rng::RNG;
|
||||||
|
|
||||||
impl NPC {
|
impl NPC {
|
||||||
|
@ -103,7 +104,11 @@ impl NPC {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn tick_n242_bat_last_cave(&mut self, state: &mut SharedGameState) -> GameResult {
|
pub(crate) fn tick_n242_bat_last_cave(&mut self, state: &mut SharedGameState, stage: &mut Stage) -> GameResult {
|
||||||
|
if self.x < 0 || self.x > stage.map.width as i32 * state.tile_size.as_int() * 0x200 {
|
||||||
|
self.vanish(state);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
loop {
|
loop {
|
||||||
match self.action_num {
|
match self.action_num {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -183,7 +188,7 @@ impl NPC {
|
||||||
|
|
||||||
if hit {
|
if hit {
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
state.create_caret(self.x, self.y, CaretType::Bubble, Direction::Right);
|
state.create_caret(self.x, self.y + 0x800, CaretType::Bubble, Direction::Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
let player = self.get_closest_player_ref(&players);
|
let player = self.get_closest_player_ref(&players);
|
||||||
|
@ -289,7 +294,7 @@ impl NPC {
|
||||||
10 | 11 => {
|
10 | 11 => {
|
||||||
if self.action_num == 10 {
|
if self.action_num == 10 {
|
||||||
self.action_num = 11;
|
self.action_num = 11;
|
||||||
self.anim_num = 2;
|
self.anim_num = 3;
|
||||||
self.action_counter = 0;
|
self.action_counter = 0;
|
||||||
self.npc_flags.set_shootable(true);
|
self.npc_flags.set_shootable(true);
|
||||||
}
|
}
|
||||||
|
@ -297,6 +302,7 @@ impl NPC {
|
||||||
self.action_counter += 1;
|
self.action_counter += 1;
|
||||||
match self.action_counter {
|
match self.action_counter {
|
||||||
30 | 40 | 50 => {
|
30 | 40 | 50 => {
|
||||||
|
self.anim_num = 4;
|
||||||
let player = self.get_closest_player_ref(&players);
|
let player = self.get_closest_player_ref(&players);
|
||||||
|
|
||||||
let mut npc = NPC::create(277, &state.npc_table);
|
let mut npc = NPC::create(277, &state.npc_table);
|
||||||
|
@ -341,14 +347,15 @@ impl NPC {
|
||||||
self.action_counter += 1;
|
self.action_counter += 1;
|
||||||
match self.action_counter {
|
match self.action_counter {
|
||||||
30 | 40 | 50 => {
|
30 | 40 | 50 => {
|
||||||
|
self.anim_num = 6;
|
||||||
let player = self.get_closest_player_ref(&players);
|
let player = self.get_closest_player_ref(&players);
|
||||||
|
|
||||||
let mut npc = NPC::create(277, &state.npc_table);
|
let mut npc = NPC::create(277, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
npc.y = self.y;
|
npc.y = self.y - 0x1400;
|
||||||
|
|
||||||
let angle = f64::atan2((self.y - player.y) as f64, (self.x - player.x) as f64);
|
let angle = f64::atan2((self.y - 0x1400 - player.y) as f64, (self.x - player.x) as f64);
|
||||||
npc.vel_x = (-2048.0 * angle.cos()) as i32;
|
npc.vel_x = (-2048.0 * angle.cos()) as i32;
|
||||||
npc.vel_y = (-2048.0 * angle.sin()) as i32;
|
npc.vel_y = (-2048.0 * angle.sin()) as i32;
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ impl NPC {
|
||||||
self.target_y = npc.y;
|
self.target_y = npc.y;
|
||||||
|
|
||||||
let angle = ((self.y - self.target_y) as f64 / (self.x - self.target_x) as f64).atan();
|
let angle = ((self.y - self.target_y) as f64 / (self.x - self.target_x) as f64).atan();
|
||||||
self.vel_x = (angle.cos() * 1024.0) as i32;
|
self.vel_x = (angle.cos() * -1024.0) as i32;
|
||||||
self.vel_y = (angle.sin() * 1024.0) as i32;
|
self.vel_y = (angle.sin() * -1024.0) as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.action_counter2 == 0 {
|
if self.action_counter2 == 0 {
|
||||||
|
@ -144,6 +144,7 @@ impl NPC {
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
npc.y = self.y - 0x2000;
|
npc.y = self.y - 0x2000;
|
||||||
|
npc.parent_id = self.id; // This NPC doesn't do anything with its parent...but we'll set it anyways
|
||||||
|
|
||||||
let _ = npc_list.spawn(0, npc);
|
let _ = npc_list.spawn(0, npc);
|
||||||
}
|
}
|
||||||
|
@ -270,6 +271,7 @@ impl NPC {
|
||||||
let mut npc = NPC::create(66, &state.npc_table);
|
let mut npc = NPC::create(66, &state.npc_table);
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
npc.y = self.y - 0x2000;
|
npc.y = self.y - 0x2000;
|
||||||
|
npc.parent_id = self.id; // This NPC doesn't do anything with its parent...but we'll set it anyways
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
|
|
||||||
let _ = npc_list.spawn(0, npc);
|
let _ = npc_list.spawn(0, npc);
|
||||||
|
@ -612,7 +614,7 @@ impl NPC {
|
||||||
}
|
}
|
||||||
|
|
||||||
let player = self.get_closest_player_ref(&players);
|
let player = self.get_closest_player_ref(&players);
|
||||||
self.action_num = if player.x > self.x - 0xe000 && player.x <= self.x + 0xe000 { 100 } else { 160 };
|
self.action_num = if player.x >= self.x - 0xe000 && player.x <= self.x + 0xe000 { 100 } else { 160 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
160 | 161 => {
|
160 | 161 => {
|
||||||
|
@ -701,7 +703,7 @@ impl NPC {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn tick_n248_misery_boss_vanishing(&mut self, state: &mut SharedGameState) -> GameResult {
|
pub(crate) fn tick_n248_misery_boss_vanishing(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||||
if self.flags.any_flag() {
|
if self.flags.hit_anything() {
|
||||||
self.cond.set_alive(false);
|
self.cond.set_alive(false);
|
||||||
state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Left);
|
state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Left);
|
||||||
}
|
}
|
||||||
|
@ -815,7 +817,7 @@ impl NPC {
|
||||||
self.anim_num = (self.anim_num + 1) & 1;
|
self.anim_num = (self.anim_num + 1) & 1;
|
||||||
self.y += 0x1000;
|
self.y += 0x1000;
|
||||||
|
|
||||||
if self.flags.any_flag() {
|
if self.flags.hit_anything() {
|
||||||
npc_list.create_death_smoke(self.x, self.y, self.display_bounds.right as usize, 3, state, &self.rng);
|
npc_list.create_death_smoke(self.x, self.y, self.display_bounds.right as usize, 3, state, &self.rng);
|
||||||
self.cond.set_alive(false);
|
self.cond.set_alive(false);
|
||||||
}
|
}
|
||||||
|
@ -849,10 +851,10 @@ impl NPC {
|
||||||
|
|
||||||
if let Some(parent) = self.get_parent_ref_mut(npc_list) {
|
if let Some(parent) = self.get_parent_ref_mut(npc_list) {
|
||||||
self.x = parent.x
|
self.x = parent.x
|
||||||
+ self.action_counter as i32 * ((self.action_counter2 as f64 * CDEG_RAD).cos() * -512.0) as i32
|
+ self.action_counter as i32 * ((self.action_counter2 as f64 * CDEG_RAD).cos() * 512.0) as i32
|
||||||
/ 4;
|
/ 4;
|
||||||
self.y = parent.y
|
self.y = parent.y
|
||||||
+ self.action_counter as i32 * ((self.action_counter2 as f64 * CDEG_RAD).sin() * -512.0) as i32
|
+ self.action_counter as i32 * ((self.action_counter2 as f64 * CDEG_RAD).sin() * 512.0) as i32
|
||||||
/ 4;
|
/ 4;
|
||||||
|
|
||||||
if parent.action_num == 151 {
|
if parent.action_num == 151 {
|
||||||
|
@ -1198,6 +1200,7 @@ impl NPC {
|
||||||
|
|
||||||
if self.y > stage.map.height as i32 * state.tile_size.as_int() * 0x200 {
|
if self.y > stage.map.height as i32 * state.tile_size.as_int() * 0x200 {
|
||||||
self.vanish(state);
|
self.vanish(state);
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|
|
@ -537,8 +537,8 @@ impl NPC {
|
||||||
0 | 1 => {
|
0 | 1 => {
|
||||||
if self.action_num == 0 {
|
if self.action_num == 0 {
|
||||||
self.action_num = 1;
|
self.action_num = 1;
|
||||||
self.vel_x = ((self.rng.range(0..255) as f64 * CDEG_RAD).cos() * -512.0) as i32;
|
self.vel_x = ((self.rng.range(0..255) as f64 * CDEG_RAD).cos() * 512.0) as i32;
|
||||||
self.vel_y = ((self.rng.range(0..255) as f64 * CDEG_RAD).sin() * -512.0) as i32;
|
self.vel_y = ((self.rng.range(0..255) as f64 * CDEG_RAD).sin() * 512.0) as i32;
|
||||||
|
|
||||||
self.action_counter2 = 120;
|
self.action_counter2 = 120;
|
||||||
self.vel_y2 = self.rng.range(-32..32) * 0x200;
|
self.vel_y2 = self.rng.range(-32..32) * 0x200;
|
||||||
|
@ -902,7 +902,7 @@ impl NPC {
|
||||||
self.x += self.vel_x;
|
self.x += self.vel_x;
|
||||||
self.y += self.vel_y;
|
self.y += self.vel_y;
|
||||||
|
|
||||||
if self.flags.any_flag() {
|
if self.flags.hit_anything() {
|
||||||
let mut npc = NPC::create(4, &state.npc_table);
|
let mut npc = NPC::create(4, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
|
@ -994,9 +994,9 @@ impl NPC {
|
||||||
let mut npc = NPC::create(273, &state.npc_table);
|
let mut npc = NPC::create(273, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
npc.y = self.y;
|
npc.y = self.y - 0x1400;
|
||||||
|
|
||||||
let angle = f64::atan2((player.y - 0x1400 - self.y) as f64, (player.x - self.x) as f64);
|
let angle = f64::atan2((player.y + 0x1400 - self.y) as f64, (player.x - self.x) as f64);
|
||||||
npc.vel_x = (2048.0 * angle.cos()) as i32;
|
npc.vel_x = (2048.0 * angle.cos()) as i32;
|
||||||
npc.vel_y = (2048.0 * angle.sin()) as i32;
|
npc.vel_y = (2048.0 * angle.sin()) as i32;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl NPC {
|
||||||
self.anim_counter = 0;
|
self.anim_counter = 0;
|
||||||
let anim = self.anim_num as i32 + (self.direction.vector_x() * -1);
|
let anim = self.anim_num as i32 + (self.direction.vector_x() * -1);
|
||||||
if anim < 0 {
|
if anim < 0 {
|
||||||
self.anim_num = 4;
|
self.anim_num = 3;
|
||||||
} else if anim > 3 {
|
} else if anim > 3 {
|
||||||
self.anim_num = 0;
|
self.anim_num = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -106,7 +106,7 @@ impl NPC {
|
||||||
state.sound_manager.play_sfx(103);
|
state.sound_manager.play_sfx(103);
|
||||||
}
|
}
|
||||||
self.action_counter += 1;
|
self.action_counter += 1;
|
||||||
self.anim_num = (self.action_counter + 1) % 2;
|
self.anim_num = 1 - (self.action_counter & 2) / 2;
|
||||||
if self.direction == Direction::Left && self.action_counter == 20 {
|
if self.direction == Direction::Left && self.action_counter == 20 {
|
||||||
let mut npc = NPC::create(146, &state.npc_table);
|
let mut npc = NPC::create(146, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
|
@ -149,8 +149,8 @@ impl NPC {
|
||||||
|
|
||||||
if self.x < 0
|
if self.x < 0
|
||||||
|| self.y < 0
|
|| self.y < 0
|
||||||
|| self.x > (stage.map.width as i32) * state.tile_size.as_int() * 0x200 + 0x4000
|
|| self.x > (stage.map.width as i32) * state.tile_size.as_int() * 0x200
|
||||||
|| self.y > (stage.map.height as i32) * state.tile_size.as_int() * 0x200 + 0x4000
|
|| self.y > (stage.map.height as i32) * state.tile_size.as_int() * 0x200
|
||||||
{
|
{
|
||||||
self.vanish(state);
|
self.vanish(state);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -304,6 +304,7 @@ impl NPC {
|
||||||
self.action_counter = 0;
|
self.action_counter = 0;
|
||||||
self.anim_num = 6;
|
self.anim_num = 6;
|
||||||
self.anim_counter = 0;
|
self.anim_counter = 0;
|
||||||
|
self.vel_y = 0;
|
||||||
self.damage = 10;
|
self.damage = 10;
|
||||||
|
|
||||||
self.face_player(player);
|
self.face_player(player);
|
||||||
|
@ -352,6 +353,7 @@ impl NPC {
|
||||||
}
|
}
|
||||||
self.vel_y = if self.action_num == 221 { -0x800 } else { 0x800 };
|
self.vel_y = if self.action_num == 221 { -0x800 } else { 0x800 };
|
||||||
|
|
||||||
|
self.action_counter += 1;
|
||||||
self.anim_num = if self.action_counter & 0x02 != 0 { 8 } else { 9 };
|
self.anim_num = if self.action_counter & 0x02 != 0 { 8 } else { 9 };
|
||||||
|
|
||||||
if (self.y < 0x6000 && self.action_num == 221)
|
if (self.y < 0x6000 && self.action_num == 221)
|
||||||
|
@ -524,11 +526,12 @@ impl NPC {
|
||||||
// I think Pixel meant for the smoke radius to be 16 pixels (0x2000) instead of 16 units,
|
// 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
|
// 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);
|
npc_list.create_death_smoke(self.x, self.y, 16, 16, state, &self.rng);
|
||||||
|
state.sound_manager.play_sfx(72);
|
||||||
}
|
}
|
||||||
self.vel_y += 0x20;
|
self.vel_y += 0x20;
|
||||||
self.clamp_fall_speed();
|
self.clamp_fall_speed();
|
||||||
|
|
||||||
self.action_counter;
|
self.action_counter += 1;
|
||||||
self.x = self.target_x + if self.action_counter & 0x02 != 0 { 0x200 } else { -0x200 };
|
self.x = self.target_x + if self.action_counter & 0x02 != 0 { 0x200 } else { -0x200 };
|
||||||
if self.flags.hit_bottom_wall() {
|
if self.flags.hit_bottom_wall() {
|
||||||
self.action_num = 1002;
|
self.action_num = 1002;
|
||||||
|
@ -950,7 +953,6 @@ impl NPC {
|
||||||
self.npc_flags.set_ignore_solidity(false);
|
self.npc_flags.set_ignore_solidity(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.action_counter += 1;
|
|
||||||
if self.action_counter & 0x02 != 0 {
|
if self.action_counter & 0x02 != 0 {
|
||||||
let mut npc = NPC::create(4, &state.npc_table);
|
let mut npc = NPC::create(4, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
|
@ -958,6 +960,7 @@ impl NPC {
|
||||||
npc.y = self.y;
|
npc.y = self.y;
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
let _ = npc_list.spawn(0x100, npc);
|
||||||
}
|
}
|
||||||
|
self.action_counter += 1; // This gets incremented after the previous check for some reason
|
||||||
|
|
||||||
if self.flags.hit_bottom_wall() {
|
if self.flags.hit_bottom_wall() {
|
||||||
self.action_num = 110;
|
self.action_num = 110;
|
||||||
|
@ -981,7 +984,7 @@ impl NPC {
|
||||||
110 => {
|
110 => {
|
||||||
self.vel_y += 0x40;
|
self.vel_y += 0x40;
|
||||||
|
|
||||||
if self.y > (stage.map.height as i32) * state.tile_size.as_int() * 0x200 + 0x4000 {
|
if self.y > (stage.map.height as i32 + 2) * state.tile_size.as_int() * 0x200 {
|
||||||
self.cond.set_alive(false);
|
self.cond.set_alive(false);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -1013,7 +1016,9 @@ impl NPC {
|
||||||
0 | 10 => {
|
0 | 10 => {
|
||||||
if self.action_num == 0 {
|
if self.action_num == 0 {
|
||||||
self.action_num = 10;
|
self.action_num = 10;
|
||||||
|
// self.action_counter2 set by Ballos code, no need to set it here
|
||||||
self.action_counter3 = 192;
|
self.action_counter3 = 192;
|
||||||
|
self.vel_y2 = 0;
|
||||||
}
|
}
|
||||||
if self.action_counter3 >= 448 {
|
if self.action_counter3 >= 448 {
|
||||||
self.action_num = 11;
|
self.action_num = 11;
|
||||||
|
@ -1069,6 +1074,7 @@ impl NPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
100 => {
|
100 => {
|
||||||
|
self.vel_y2 = 0;
|
||||||
if boss.parts[0].action_num == 424 {
|
if boss.parts[0].action_num == 424 {
|
||||||
self.action_num = 30;
|
self.action_num = 30;
|
||||||
} else if boss.parts[0].action_num == 428 {
|
} else if boss.parts[0].action_num == 428 {
|
||||||
|
@ -1109,18 +1115,19 @@ impl NPC {
|
||||||
match self.action_num {
|
match self.action_num {
|
||||||
20 | 30 => {
|
20 | 30 => {
|
||||||
if self.action_counter2 % 4 == 0 {
|
if self.action_counter2 % 4 == 0 {
|
||||||
self.vel_y = (self.target_y - self.y) / 4;
|
self.vel_y2 = (self.target_y - self.y) / 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
40 | 50 => {
|
40 | 50 => {
|
||||||
if self.action_counter2 & 0x02 == 0 {
|
if self.action_counter2 & 0x02 == 0 {
|
||||||
self.vel_y = (self.target_y - self.y) / 2;
|
self.vel_y2 = (self.target_y - self.y) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.vel_y = self.target_y - self.y;
|
self.vel_y2 = self.target_y - self.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.vel_y = self.vel_y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.x += self.vel_x;
|
self.x += self.vel_x;
|
||||||
|
@ -1391,7 +1398,9 @@ impl NPC {
|
||||||
if stage.change_tile(x as usize, y as usize, 109) {
|
if stage.change_tile(x as usize, y as usize, 109) {
|
||||||
npc.x = x * state.tile_size.as_int() * 0x200;
|
npc.x = x * state.tile_size.as_int() * 0x200;
|
||||||
npc.y = y * state.tile_size.as_int() * 0x200;
|
npc.y = y * state.tile_size.as_int() * 0x200;
|
||||||
let _ = npc_list.spawn(0x100, npc.clone());
|
let _ = npc_list.spawn(0, npc.clone());
|
||||||
|
let _ = npc_list.spawn(0, npc.clone());
|
||||||
|
let _ = npc_list.spawn(0, npc.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1680,7 +1689,7 @@ impl BossNPC {
|
||||||
let mut npc = NPC::create(344, &state.npc_table);
|
let mut npc = NPC::create(344, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.parts[0].x + 0x3000 * dir.vector_x();
|
npc.x = self.parts[0].x + 0x3000 * dir.vector_x();
|
||||||
npc.y = self.parts[0].y + 0x4800;
|
npc.y = self.parts[0].y - 0x4800;
|
||||||
npc.direction = dir;
|
npc.direction = dir;
|
||||||
let _ = npc_list.spawn(0x20, npc);
|
let _ = npc_list.spawn(0x20, npc);
|
||||||
}
|
}
|
||||||
|
@ -1786,7 +1795,7 @@ impl BossNPC {
|
||||||
let mut npc = NPC::create(344, &state.npc_table);
|
let mut npc = NPC::create(344, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.parts[0].x + 0x3000 * dir.vector_x();
|
npc.x = self.parts[0].x + 0x3000 * dir.vector_x();
|
||||||
npc.y = self.parts[0].y + 0x4800;
|
npc.y = self.parts[0].y - 0x4800;
|
||||||
npc.direction = dir;
|
npc.direction = dir;
|
||||||
let _ = npc_list.spawn(0x20, npc);
|
let _ = npc_list.spawn(0x20, npc);
|
||||||
}
|
}
|
||||||
|
@ -1808,7 +1817,7 @@ impl BossNPC {
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = (((self.parts[0].action_counter as i32 / 30) * 2) + 2) * 0x2000;
|
npc.x = (((self.parts[0].action_counter as i32 / 30) * 2) + 2) * 0x2000;
|
||||||
npc.y = 0x2A000;
|
npc.y = 0x2A000;
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
let _ = npc_list.spawn(0x180, npc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.parts[0].action_counter / 3 % 2) > 0 {
|
if (self.parts[0].action_counter / 3 % 2) > 0 {
|
||||||
|
@ -1962,7 +1971,7 @@ impl BossNPC {
|
||||||
npc.x = self.parts[0].x + self.parts[0].rng.range(-40..40) * 0x200;
|
npc.x = self.parts[0].x + self.parts[0].rng.range(-40..40) * 0x200;
|
||||||
npc.y = self.parts[0].y + self.parts[0].rng.range(0..40) * 0x200;
|
npc.y = self.parts[0].y + self.parts[0].rng.range(0..40) * 0x200;
|
||||||
npc.direction = Direction::Bottom;
|
npc.direction = Direction::Bottom;
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
let _ = npc_list.spawn(0, npc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,8 @@ impl BossNPC {
|
||||||
// Need to calculate offset from the default starting location
|
// Need to calculate offset from the default starting location
|
||||||
for i in 0..7 {
|
for i in 0..7 {
|
||||||
stage.change_tile(i + 7, 14, 0);
|
stage.change_tile(i + 7, 14, 0);
|
||||||
npc_list.create_death_smoke((i as i32 + 7) * 0x2000, 0x1C000, 0, 1, state, &self.parts[0].rng);
|
// This should be called with an amount of 0, but change_tile also needs to make smoke
|
||||||
|
npc_list.create_death_smoke((i as i32 + 7) * 0x2000, 0x1C000, 0, 3, state, &self.parts[0].rng);
|
||||||
state.sound_manager.play_sfx(12);
|
state.sound_manager.play_sfx(12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl NPC {
|
||||||
pub(crate) fn tick_n196_ironhead_wall(&mut self, state: &mut SharedGameState) -> GameResult {
|
pub(crate) fn tick_n196_ironhead_wall(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||||
self.x -= 0xC00;
|
self.x -= 0xC00;
|
||||||
if self.x <= if !state.constants.is_switch { 0x26000 } else { 0x1E000 } {
|
if self.x <= if !state.constants.is_switch { 0x26000 } else { 0x1E000 } {
|
||||||
self.x += if !state.constants.is_switch { 0x2C000 } else { 0x3C000 };
|
self.x += if !state.constants.is_switch { 0x2C000 } else { 0x3B400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
let dir_offset = if self.direction == Direction::Left { 0 } else { 1 };
|
let dir_offset = if self.direction == Direction::Left { 0 } else { 1 };
|
||||||
|
@ -158,7 +158,7 @@ impl NPC {
|
||||||
}
|
}
|
||||||
10 => {
|
10 => {
|
||||||
self.action_counter += 1;
|
self.action_counter += 1;
|
||||||
if self.action_counter % 6 == 0 {
|
if self.action_counter % 4 == 1 {
|
||||||
let mut npc = NPC::create(335, &state.npc_table);
|
let mut npc = NPC::create(335, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
|
@ -269,6 +269,7 @@ impl BossNPC {
|
||||||
self.parts[0].action_num = 100;
|
self.parts[0].action_num = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.parts[0].direction == Direction::Left {
|
||||||
self.parts[0].action_counter += 1;
|
self.parts[0].action_counter += 1;
|
||||||
if [300, 310, 320].contains(&self.parts[0].action_counter) {
|
if [300, 310, 320].contains(&self.parts[0].action_counter) {
|
||||||
state.sound_manager.play_sfx(39);
|
state.sound_manager.play_sfx(39);
|
||||||
|
@ -283,6 +284,7 @@ impl BossNPC {
|
||||||
|
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
let _ = npc_list.spawn(0x100, npc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.parts[0].animate(2, 0, 7);
|
self.parts[0].animate(2, 0, 7);
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,8 +170,8 @@ impl NPC {
|
||||||
self.vel_x += self.direction.vector_x() * 0x15;
|
self.vel_x += self.direction.vector_x() * 0x15;
|
||||||
self.target_x += self.vel_x;
|
self.target_x += self.vel_x;
|
||||||
|
|
||||||
self.x = self.target_x + 4 * ((self.action_counter2 as f64).cos() * -512.0) as i32;
|
self.x = self.target_x + 4 * ((self.action_counter2 as f64).cos() * 512.0) as i32;
|
||||||
self.y = self.target_y + 6 * ((self.action_counter2 as f64).sin() * -512.0) as i32;
|
self.y = self.target_y + 6 * ((self.action_counter2 as f64).sin() * 512.0) as i32;
|
||||||
|
|
||||||
let mut npc = NPC::create(286, &state.npc_table);
|
let mut npc = NPC::create(286, &state.npc_table);
|
||||||
npc.cond.set_alive(true);
|
npc.cond.set_alive(true);
|
||||||
|
@ -292,12 +292,12 @@ impl NPC {
|
||||||
|
|
||||||
npc.x = self.x;
|
npc.x = self.x;
|
||||||
npc.y = self.y;
|
npc.y = self.y;
|
||||||
npc.vel_y = self.direction.vector_y() * 0x400;
|
npc.vel_y = self.direction.opposite().vector_y() * 0x400;
|
||||||
|
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
let _ = npc_list.spawn(0x100, npc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.x < 0x2000 || self.x > (stage.map.width as i32 + 1) * state.tile_size.as_int() * 0x200 {
|
if self.x < 0x2000 || self.x > (stage.map.width as i32 - 1) * state.tile_size.as_int() * 0x200 {
|
||||||
self.cond.set_alive(false);
|
self.cond.set_alive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,6 +400,10 @@ impl BossNPC {
|
||||||
self.parts[7].action_counter2 = 1;
|
self.parts[7].action_counter2 = 1;
|
||||||
self.parts[7].action_counter3 = 128;
|
self.parts[7].action_counter3 = 128;
|
||||||
|
|
||||||
|
for i in [2, 6, 7] {
|
||||||
|
self.hurt_sound[i] = self.hurt_sound[1];
|
||||||
|
}
|
||||||
|
|
||||||
self.parts[19].action_counter = self.parts[0].life;
|
self.parts[19].action_counter = self.parts[0].life;
|
||||||
|
|
||||||
for i in 0u16..20 {
|
for i in 0u16..20 {
|
||||||
|
@ -1043,7 +1047,7 @@ impl BossNPC {
|
||||||
|
|
||||||
part.vel_x += 0x20;
|
part.vel_x += 0x20;
|
||||||
part.x += part.vel_x;
|
part.x += part.vel_x;
|
||||||
if part.x > (stage.map.width as i32) * state.tile_size.as_int() * 0x200 + 0x4000 {
|
if part.x > (stage.map.width as i32 + 2) * state.tile_size.as_int() * 0x200 {
|
||||||
part.cond.set_alive(false);
|
part.cond.set_alive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,7 +493,7 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &mut BulletManager, &mu
|
||||||
239 => self.tick_n239_cage_bars(state),
|
239 => self.tick_n239_cage_bars(state),
|
||||||
240 => self.tick_n240_mimiga_jailed(state),
|
240 => self.tick_n240_mimiga_jailed(state),
|
||||||
241 => self.tick_n241_critter_red(state, players),
|
241 => self.tick_n241_critter_red(state, players),
|
||||||
242 => self.tick_n242_bat_last_cave(state),
|
242 => self.tick_n242_bat_last_cave(state, stage),
|
||||||
243 => self.tick_n243_bat_generator(state, npc_list),
|
243 => self.tick_n243_bat_generator(state, npc_list),
|
||||||
244 => self.tick_n244_lava_drop(state, players),
|
244 => self.tick_n244_lava_drop(state, players),
|
||||||
245 => self.tick_n245_lava_drop_generator(state, npc_list),
|
245 => self.tick_n245_lava_drop_generator(state, npc_list),
|
||||||
|
|
Loading…
Reference in a new issue