From d23ad6984e78261d3818bd874662b251ce559751 Mon Sep 17 00:00:00 2001 From: Alula <6276139+alula@users.noreply.github.com> Date: Wed, 5 May 2021 18:34:23 +0200 Subject: [PATCH] unfuck physics --- src/caret.rs | 2 +- src/common.rs | 16 ++-- src/engine_constants/mod.rs | 44 +++++----- src/live_debugger.rs | 8 +- src/npc/boss/balfrog.rs | 50 +++++------ src/npc/boss/monster_x.rs | 34 ++++---- src/npc/boss/omega.rs | 42 ++++----- src/npc/utils.rs | 4 +- src/physics.rs | 169 ++++++++++++++++++------------------ src/player/mod.rs | 34 ++++---- src/player/player_hit.rs | 73 +++++++++------- src/scene/game_scene.rs | 8 +- src/shared_game_state.rs | 8 +- src/text_script.rs | 22 ++--- src/weapon/bullet.rs | 64 +++++++------- 15 files changed, 293 insertions(+), 285 deletions(-) diff --git a/src/caret.rs b/src/caret.rs index 05a9d67..43593cc 100644 --- a/src/caret.rs +++ b/src/caret.rs @@ -332,7 +332,7 @@ impl Caret { self.anim_rect = constants.caret.little_particles_rects[self.anim_num as usize / 2 % len]; if self.direction == Direction::Right { - self.x -= 4 * 0x200; + self.x -= 0x800; } } CaretType::Unknown => { diff --git a/src/common.rs b/src/common.rs index 28ce1d1..1c7e70b 100644 --- a/src/common.rs +++ b/src/common.rs @@ -50,10 +50,10 @@ bitfield! { pub force_up, set_force_up: 13; // 0x2000 pub force_right, set_force_right: 14; // 0x4000 pub force_down, set_force_down: 15; // 0x8000 - pub hit_left_bigger_half, set_hit_left_bigger_half: 16; // 0x10000 - pub hit_left_smaller_half, set_hit_left_smaller_half: 17; // 0x20000 - pub hit_right_smaller_half, set_hit_right_smaller_half: 18; // 0x40000 - pub hit_right_bigger_half, set_hit_right_bigger_half: 19; // 0x80000 + pub hit_left_higher_half, set_hit_left_higher_half: 16; // 0x10000 + pub hit_left_lower_half, set_hit_left_lower_half: 17; // 0x20000 + pub hit_right_lower_half, set_hit_right_lower_half: 18; // 0x40000 + pub hit_right_higher_half, set_hit_right_higher_half: 19; // 0x80000 } impl Flag { @@ -130,11 +130,11 @@ bitfield! { impl Debug; pub flag_x01, set_flag_x01: 0; // 0x01 pub flag_x02, set_flag_x02: 1; // 0x02 - pub flag_x04, set_flag_x04: 2; // 0x04 - pub flag_x08, set_flag_x08: 3; // 0x08 + pub no_collision_checks, set_no_collision_checks: 2; // 0x04 + pub bounce_from_walls, set_bounce_from_walls: 3; // 0x08 pub flag_x10, set_flag_x10: 4; // 0x10 pub flag_x20, set_flag_x20: 5; // 0x20 - pub flag_x40, set_flag_x40: 6; // 0x40 + pub can_destroy_snack, set_can_destroy_snack: 6; // 0x40 pub flag_x80, set_flag_x80: 7; // 0x80 } @@ -377,7 +377,7 @@ fn lerp_f64(v1: f64, v2: f64, t: f64) -> f64 { } pub fn interpolate_fix9_scale(old_val: i32, val: i32, frame_delta: f64) -> f32 { - if abs(old_val - val) > 8 * 0x200 { + if abs(old_val - val) > 0x1000 { return val as f32 / 512.0; } diff --git a/src/engine_constants/mod.rs b/src/engine_constants/mod.rs index 343d136..c7d7d4e 100644 --- a/src/engine_constants/mod.rs +++ b/src/engine_constants/mod.rs @@ -35,7 +35,7 @@ pub struct BoosterConsts { } #[derive(Debug, Copy, Clone)] -pub struct MyCharConsts { +pub struct PlayerConsts { pub display_bounds: Rect, pub hit_bounds: Rect, pub life: u16, @@ -232,7 +232,7 @@ pub struct EngineConstants { pub is_cs_plus: bool, pub is_switch: bool, pub supports_og_textures: bool, - pub my_char: MyCharConsts, + pub player: PlayerConsts, pub booster: BoosterConsts, pub caret: CaretConsts, pub world: WorldConsts, @@ -255,7 +255,7 @@ impl Clone for EngineConstants { is_cs_plus: self.is_cs_plus, is_switch: self.is_switch, supports_og_textures: self.supports_og_textures, - my_char: self.my_char, + player: self.player, booster: self.booster, caret: self.caret.clone(), world: self.world, @@ -280,9 +280,9 @@ impl EngineConstants { is_cs_plus: false, is_switch: false, supports_og_textures: false, - my_char: MyCharConsts { - display_bounds: Rect { left: 8 * 0x200, top: 8 * 0x200, right: 8 * 0x200, bottom: 8 * 0x200 }, - hit_bounds: Rect { left: 5 * 0x200, top: 8 * 0x200, right: 5 * 0x200, bottom: 8 * 0x200 }, + player: PlayerConsts { + display_bounds: Rect { left: 0x1000, top: 0x1000, right: 0x1000, bottom: 0x1000 }, + hit_bounds: Rect { left: 5 * 0x200, top: 0x1000, right: 5 * 0x200, bottom: 0x1000 }, life: 3, max_life: 3, control_mode: ControlMode::Normal, @@ -350,23 +350,23 @@ impl EngineConstants { caret: CaretConsts { offsets: [ (0, 0), - (4 * 0x200, 4 * 0x200), - (8 * 0x200, 8 * 0x200), - (8 * 0x200, 8 * 0x200), - (8 * 0x200, 8 * 0x200), - (4 * 0x200, 4 * 0x200), - (8 * 0x200, 8 * 0x200), - (4 * 0x200, 4 * 0x200), - (8 * 0x200, 8 * 0x200), - (8 * 0x200, 8 * 0x200), - (28 * 0x200, 8 * 0x200), - (4 * 0x200, 4 * 0x200), - (16 * 0x200, 16 * 0x200), - (4 * 0x200, 4 * 0x200), + (0x800, 0x800), + (0x1000, 0x1000), + (0x1000, 0x1000), + (0x1000, 0x1000), + (0x800, 0x800), + (0x1000, 0x1000), + (0x800, 0x800), + (0x1000, 0x1000), + (0x1000, 0x1000), + (28 * 0x200, 0x1000), + (0x800, 0x800), + (0x2000, 0x2000), + (0x800, 0x800), (20 * 0x200, 20 * 0x200), - (4 * 0x200, 4 * 0x200), - (20 * 0x200, 4 * 0x200), - (52 * 0x200, 4 * 0x200), + (0x800, 0x800), + (20 * 0x200, 0x800), + (52 * 0x200, 0x800), ], bubble_left_rects: vec![ Rect { left: 0, top: 64, right: 8, bottom: 72 }, diff --git a/src/live_debugger.rs b/src/live_debugger.rs index 384bd84..74a585d 100644 --- a/src/live_debugger.rs +++ b/src/live_debugger.rs @@ -168,16 +168,16 @@ impl LiveDebugger { scene.inventory_player2 = game_scene.inventory_player2.clone(); scene.player1 = game_scene.player1.clone(); - scene.player1.x = scene.stage.map.width as i32 / 2 * 16 * 0x200; - scene.player1.y = scene.stage.map.height as i32 / 2 * 16 * 0x200; + scene.player1.x = scene.stage.map.width as i32 / 2 * 0x2000; + scene.player1.y = scene.stage.map.height as i32 / 2 * 0x2000; if scene.player1.life == 0 { scene.player1.life = scene.player1.max_life; } scene.player2 = game_scene.player2.clone(); - scene.player2.x = scene.stage.map.width as i32 / 2 * 16 * 0x200; - scene.player2.y = scene.stage.map.height as i32 / 2 * 16 * 0x200; + scene.player2.x = scene.stage.map.width as i32 / 2 * 0x2000; + scene.player2.y = scene.stage.map.height as i32 / 2 * 0x2000; if scene.player2.life == 0 { scene.player2.life = scene.player1.max_life; diff --git a/src/npc/boss/balfrog.rs b/src/npc/boss/balfrog.rs index a80a476..c55cfa8 100644 --- a/src/npc/boss/balfrog.rs +++ b/src/npc/boss/balfrog.rs @@ -40,20 +40,20 @@ impl BossNPC { match self.parts[0].action_num { 0 => { self.hurt_sound[0] = 52; - self.parts[0].x = 6 * 16 * 0x200; - self.parts[0].y = 12 * 16 * 0x200; + self.parts[0].x = 6 * 0x2000; + self.parts[0].y = 12 * 0x2000; self.parts[0].direction = Direction::Right; self.parts[0].display_bounds = Rect { left: 48 * 0x200, top: 48 * 0x200, right: 32 * 0x200, - bottom: 16 * 0x200, + bottom: 0x2000, }; self.parts[0].hit_bounds = Rect { left: 24 * 0x200, - top: 16 * 0x200, + top: 0x2000, right: 24 * 0x200, - bottom: 16 * 0x200, + bottom: 0x2000, }; self.parts[0].size = 3; self.parts[0].exp = 1; @@ -131,7 +131,7 @@ impl BossNPC { self.parts[0].action_num = 104; self.parts[0].anim_num = 5; self.parts[0].vel_x = self.parts[0].direction.vector_x() * 0x200; - self.parts[0].vel_y = -2 * 0x200; + self.parts[0].vel_y = -0x400; self.parts[0].display_bounds.top = 64 * 0x200; self.parts[0].display_bounds.bottom = 24 * 0x200; @@ -153,7 +153,7 @@ impl BossNPC { self.parts[0].action_num = 100; self.parts[0].anim_num = 1; self.parts[0].display_bounds.top = 48 * 0x200; - self.parts[0].display_bounds.bottom = 16 * 0x200; + self.parts[0].display_bounds.bottom = 0x2000; let player = self.parts[0].get_closest_player_mut(players); if self.parts[0].direction == Direction::Left && self.parts[0].x < player.x { @@ -168,8 +168,8 @@ impl BossNPC { let mut npc = NPC::create(110, &state.npc_table); npc.cond.set_alive(true); - npc.x = self.parts[0].rng.range(4..16) as i32 * 16 * 0x200; - npc.y = self.parts[0].rng.range(0..4) as i32 * 16 * 0x200; + npc.x = self.parts[0].rng.range(4..16) as i32 * 0x2000; + npc.y = self.parts[0].rng.range(0..4) as i32 * 0x2000; npc.direction = Direction::FacingPlayer; let _ = npc_list.spawn(0x80, npc); @@ -241,16 +241,16 @@ impl BossNPC { self.parts[0].vel_x2 = self.parts[0].vel_x2.saturating_sub(1); let player = self.parts[0].get_closest_player_mut(players); - let px = self.parts[0].x + self.parts[0].direction.vector_x() * 2 * 16 * 0x200 - player.x; - let py = self.parts[0].y - 8 * 0x200 - player.y; + let px = self.parts[0].x + self.parts[0].direction.vector_x() * 2 * 0x2000 - player.x; + let py = self.parts[0].y - 0x1000 - player.y; let deg = f64::atan2(py as f64, px as f64) + self.parts[0].rng.range(-16..16) as f64 * CDEG_RAD; let mut npc = NPC::create(108, &state.npc_table); npc.cond.set_alive(true); - npc.x = self.parts[0].x + self.parts[0].direction.vector_x() * 2 * 16 * 0x200; - npc.y = self.parts[0].y - 8 * 0x200; + npc.x = self.parts[0].x + self.parts[0].direction.vector_x() * 2 * 0x2000; + npc.y = self.parts[0].y - 0x1000; npc.vel_x = (deg.cos() * -512.0) as i32; npc.vel_y = (deg.sin() * -512.0) as i32; @@ -327,8 +327,8 @@ impl BossNPC { let mut npc = NPC::create(104, &state.npc_table); for _ in 0..2 { npc.cond.set_alive(true); - npc.x = self.parts[0].rng.range(4..16) as i32 * 16 * 0x200; - npc.y = self.parts[0].rng.range(0..4) as i32 * 16 * 0x200; + npc.x = self.parts[0].rng.range(4..16) as i32 * 0x2000; + npc.y = self.parts[0].rng.range(0..4) as i32 * 0x2000; npc.direction = Direction::FacingPlayer; let _ = npc_list.spawn(0x80, npc.clone()); @@ -337,8 +337,8 @@ impl BossNPC { let mut npc = NPC::create(110, &state.npc_table); for _ in 0..6 { npc.cond.set_alive(true); - npc.x = self.parts[0].rng.range(4..16) as i32 * 16 * 0x200; - npc.y = self.parts[0].rng.range(0..4) as i32 * 16 * 0x200; + npc.x = self.parts[0].rng.range(4..16) as i32 * 0x2000; + npc.y = self.parts[0].rng.range(0..4) as i32 * 0x2000; npc.direction = Direction::FacingPlayer; let _ = npc_list.spawn(0x80, npc.clone()); @@ -434,7 +434,7 @@ impl BossNPC { left: 48 * 0x200, top: 48 * 0x200, right: 32 * 0x200, - bottom: 16 * 0x200, + bottom: 0x2000, }; } @@ -503,10 +503,10 @@ impl BossNPC { self.parts[1].size = 3; self.parts[1].npc_flags.set_invulnerable(true); self.parts[1].hit_bounds = Rect { - left: 16 * 0x200, - top: 16 * 0x200, - right: 16 * 0x200, - bottom: 16 * 0x200, + left: 0x2000, + top: 0x2000, + right: 0x2000, + bottom: 0x2000, }; self.hurt_sound[2] = 52; @@ -514,9 +514,9 @@ impl BossNPC { self.parts[2].npc_flags.set_invulnerable(true); self.parts[2].hit_bounds = Rect { left: 24 * 0x200, - top: 16 * 0x200, + top: 0x2000, right: 24 * 0x200, - bottom: 16 * 0x200, + bottom: 0x2000, }; } 1 => { @@ -535,7 +535,7 @@ impl BossNPC { } 3 | 4 => { self.parts[1].x = self.parts[0].x + self.parts[0].direction.vector_x() * 24 * 0x200; - self.parts[1].y = self.parts[0].y - 16 * 0x200; + self.parts[1].y = self.parts[0].y - 0x2000; self.parts[2].x = self.parts[0].x; self.parts[2].y = self.parts[0].y; diff --git a/src/npc/boss/monster_x.rs b/src/npc/boss/monster_x.rs index f90eb4a..470a722 100644 --- a/src/npc/boss/monster_x.rs +++ b/src/npc/boss/monster_x.rs @@ -178,7 +178,7 @@ impl BossNPC { self.parts[3].size = 2; self.parts[3].target_x = 0; self.parts[3].display_bounds = - Rect { left: 8 * 0x200, top: 8 * 0x200, right: 8 * 0x200, bottom: 8 * 0x200 }; + Rect { left: 0x1000, top: 0x1000, right: 0x1000, bottom: 0x1000 }; self.parts[3].hit_bounds = Rect { left: 5 * 0x200, top: 5 * 0x200, right: 5 * 0x200, bottom: 5 * 0x200 }; self.parts[3].npc_flags.set_ignore_solidity(true); @@ -203,7 +203,7 @@ impl BossNPC { self.parts[7].display_bounds = Rect { left: 52 * 0x200, top: 24 * 0x200, right: 52 * 0x200, bottom: 24 * 0x200 }; self.parts[7].hit_bounds = - Rect { left: 8 * 0x200, top: 24 * 0x200, right: 8 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 0x1000, top: 24 * 0x200, right: 0x1000, bottom: 0x2000 }; self.parts[7].npc_flags.set_ignore_solidity(true); self.parts[9].cond.set_alive(true); @@ -213,9 +213,9 @@ impl BossNPC { self.parts[9].action_num = 0; self.parts[9].direction = Direction::Up; self.parts[9].display_bounds = - Rect { left: 36 * 0x200, top: 8 * 0x200, right: 36 * 0x200, bottom: 24 * 0x200 }; + Rect { left: 36 * 0x200, top: 0x1000, right: 36 * 0x200, bottom: 24 * 0x200 }; self.parts[9].hit_bounds = - Rect { left: 28 * 0x200, top: 8 * 0x200, right: 28 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 28 * 0x200, top: 0x1000, right: 28 * 0x200, bottom: 0x2000 }; self.hurt_sound[9] = 52; self.parts[9].npc_flags.set_rear_and_top_not_hurt(true); self.parts[9].npc_flags.set_ignore_solidity(true); @@ -230,16 +230,16 @@ impl BossNPC { self.parts[11].y = self.parts[0].y + 56 * 0x200; self.parts[11].direction = Direction::Bottom; self.parts[11].display_bounds.top = 24 * 0x200; - self.parts[11].display_bounds.bottom = 8 * 0x200; - self.parts[11].hit_bounds.top = 16 * 0x200; - self.parts[11].hit_bounds.bottom = 8 * 0x200; + self.parts[11].display_bounds.bottom = 0x1000; + self.parts[11].hit_bounds.top = 0x2000; + self.parts[11].hit_bounds.bottom = 0x1000; self.parts[12] = self.parts[11].clone(); self.parts[12].x = self.parts[0].x + 64 * 0x200; self.parts[13] = self.parts[9].clone(); self.parts[13].display_bounds = - Rect { left: 30 * 0x200, top: 16 * 0x200, right: 42 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 30 * 0x200, top: 0x2000, right: 42 * 0x200, bottom: 0x2000 }; self.parts[13].action_counter2 = 9; self.parts[13].anim_num = 0; self.parts[13].npc_flags.0 = 0; @@ -254,8 +254,8 @@ impl BossNPC { self.parts[15] = self.parts[13].clone(); self.parts[15].action_counter2 = 11; self.parts[15].anim_num = 2; - self.parts[15].display_bounds.top = 16 * 0x200; - self.parts[15].display_bounds.bottom = 16 * 0x200; + self.parts[15].display_bounds.top = 0x2000; + self.parts[15].display_bounds.bottom = 0x2000; self.parts[16] = self.parts[15].clone(); self.parts[16].action_counter2 = 12; @@ -696,7 +696,7 @@ impl BossNPC { } let player_idx = self.parts[i].get_closest_player_idx_mut(players); - if self.parts[i].action_num >= 100 && abs(players[player_idx].y - self.parts[i].y) < 4 * 0x200 { + if self.parts[i].action_num >= 100 && abs(players[player_idx].y - self.parts[i].y) < 0x800 { self.parts[i].damage = 10; self.parts[i].npc_flags.set_rear_and_top_not_hurt(true); } else { @@ -733,22 +733,22 @@ impl BossNPC { 0 => { npc.direction = Direction::Bottom; npc.x = self.parts[i].x + -30 * 0x200; - npc.y = self.parts[i].y + 6 * 0x200; + npc.y = self.parts[i].y + 0xc00; } 1 => { npc.direction = Direction::Right; npc.x = self.parts[i].x + 30 * 0x200; - npc.y = self.parts[i].y + 6 * 0x200; + npc.y = self.parts[i].y + 0xc00; } 2 => { npc.direction = Direction::Left; npc.x = self.parts[i].x - 30 * 0x200; - npc.y = self.parts[i].y - 6 * 0x200; + npc.y = self.parts[i].y - 0xc00; } 3 => { npc.direction = Direction::Up; npc.x = self.parts[i].x + 30 * 0x200; - npc.y = self.parts[i].y - 6 * 0x200; + npc.y = self.parts[i].y - 0xc00; } _ => {} } @@ -878,11 +878,11 @@ impl BossNPC { match self.parts[i].target_x { 0 => { self.parts[i].x = self.parts[0].x - 22 * 0x200; - self.parts[i].y = self.parts[0].y - 16 * 0x200; + self.parts[i].y = self.parts[0].y - 0x2000; } 1 => { self.parts[i].x = self.parts[0].x + 28 * 0x200; - self.parts[i].y = self.parts[0].y - 16 * 0x200; + self.parts[i].y = self.parts[0].y - 0x2000; } 2 => { self.parts[i].x = self.parts[0].x - 15 * 0x200; diff --git a/src/npc/boss/omega.rs b/src/npc/boss/omega.rs index c27e548..2d2b933 100644 --- a/src/npc/boss/omega.rs +++ b/src/npc/boss/omega.rs @@ -68,18 +68,18 @@ impl BossNPC { self.parts[0].npc_flags.set_show_damage(true); self.parts[0].npc_flags.set_event_when_killed(true); self.parts[0].npc_flags.set_ignore_solidity(true); - self.parts[0].x = 219 * 16 * 0x200; - self.parts[0].y = 16 * 16 * 0x200; + self.parts[0].x = 219 * 0x2000; + self.parts[0].y = 16 * 0x2000; self.parts[0].target_x = self.parts[0].x; self.parts[0].target_y = self.parts[0].y; self.parts[0].display_bounds = - Rect { left: 40 * 0x200, top: 40 * 0x200, right: 40 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 40 * 0x200, top: 40 * 0x200, right: 40 * 0x200, bottom: 0x2000 }; self.parts[0].hit_bounds = - Rect { left: 8 * 0x200, top: 24 * 0x200, right: 8 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 0x1000, top: 24 * 0x200, right: 0x1000, bottom: 0x2000 }; self.parts[1].cond.set_alive(true); self.parts[1].display_bounds = - Rect { left: 12 * 0x200, top: 8 * 0x200, right: 12 * 0x200, bottom: 8 * 0x200 }; + Rect { left: 12 * 0x200, top: 0x1000, right: 12 * 0x200, bottom: 0x1000 }; self.parts[1].npc_flags.set_ignore_solidity(true); self.parts[1].direction = Direction::Left; @@ -91,12 +91,12 @@ impl BossNPC { self.parts[3].cond.set_alive(true); self.parts[3].npc_flags.set_ignore_solidity(true); self.parts[3].direction = Direction::Left; - self.parts[3].x = self.parts[0].x + 16 * 0x200; + self.parts[3].x = self.parts[0].x + 0x2000; self.parts[3].y = self.parts[0].y; self.parts[3].display_bounds = - Rect { left: 24 * 0x200, top: 16 * 0x200, right: 16 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 24 * 0x200, top: 0x2000, right: 0x2000, bottom: 0x2000 }; self.parts[3].hit_bounds = - Rect { left: 8 * 0x200, top: 8 * 0x200, right: 8 * 0x200, bottom: 8 * 0x200 }; + Rect { left: 0x1000, top: 0x1000, right: 0x1000, bottom: 0x1000 }; self.hurt_sound[3] = 52; self.parts[4].cond.set_alive(true); @@ -136,7 +136,7 @@ impl BossNPC { self.parts[4].npc_flags.set_ignore_solidity(false); self.parts[3].action_num = 3; self.parts[4].action_num = 3; - self.parts[5].hit_bounds.top = 16 * 0x200; + self.parts[5].hit_bounds.top = 0x2000; } } } @@ -146,7 +146,7 @@ impl BossNPC { self.parts[0].action_counter = 0; self.parts[0].action_num = 50; self.parts[0].anim_counter = 0; - self.parts[5].hit_bounds.top = 16 * 0x200; + self.parts[5].hit_bounds.top = 0x2000; state.sound_manager.play_sfx(102); } @@ -161,8 +161,8 @@ impl BossNPC { self.parts[0].action_num = 60; self.parts[0].action_counter = 0; self.parts[0].npc_flags.set_shootable(true); - self.parts[0].hit_bounds.left = 16 * 0x200; - self.parts[0].hit_bounds.right = 16 * 0x200; + self.parts[0].hit_bounds.left = 0x2000; + self.parts[0].hit_bounds.right = 0x2000; } } } @@ -172,7 +172,7 @@ impl BossNPC { let mut npc = NPC::create(48, &state.npc_table); npc.cond.set_alive(true); npc.x = self.parts[0].x; - npc.y = self.parts[0].y - 16 * 0x200; + npc.y = self.parts[0].y - 0x2000; npc.vel_x = self.parts[0].rng.range(-0x100..0x100) as i32; npc.vel_y = -0x333; npc.direction = if self.parts[0].rng.range(0..9) <= 7 { Direction::Left } else { Direction::Right }; @@ -249,8 +249,8 @@ impl BossNPC { if self.parts[0].anim_num == 3 { self.parts[0].action_num = 120; self.parts[0].action_counter = 0; - self.parts[0].hit_bounds.left = 16 * 0x200; - self.parts[0].hit_bounds.right = 16 * 0x200; + self.parts[0].hit_bounds.left = 0x2000; + self.parts[0].hit_bounds.right = 0x2000; } } 120 => { @@ -267,7 +267,7 @@ impl BossNPC { let mut npc = NPC::create(48, &state.npc_table); npc.cond.set_alive(true); npc.x = self.parts[0].x; - npc.y = self.parts[0].y - 16 * 0x200; + npc.y = self.parts[0].y - 0x2000; npc.vel_x = self.parts[0].rng.range(-0x155..0x155) as i32; npc.vel_y = -0x333; npc.direction = Direction::Left; @@ -287,8 +287,8 @@ impl BossNPC { 0 => { self.parts[0].action_num = 140; self.parts[0].npc_flags.set_shootable(true); - self.parts[0].hit_bounds.left = 16 * 0x200; - self.parts[0].hit_bounds.right = 16 * 0x200; + self.parts[0].hit_bounds.left = 0x2000; + self.parts[0].hit_bounds.right = 0x2000; let player = self.parts[0].get_closest_player_mut(players); self.parts[0].vel_x = (player.x - self.parts[0].x).signum() * 0x100; self.parts[0].vel_y = -0x5ff; @@ -320,7 +320,7 @@ impl BossNPC { self.parts[0].action_num = 110; self.parts[0].action_counter = 0; self.parts[0].anim_counter = 0; - self.parts[5].hit_bounds.top = 16 * 0x200; + self.parts[5].hit_bounds.top = 0x2000; self.parts[5].damage = 0; state.sound_manager.play_sfx(26); @@ -404,7 +404,7 @@ impl BossNPC { } for &i in [1, 2].iter() { - self.parts[i].x = self.parts[0].x + self.parts[i].direction.vector_x() * 16 * 0x200; + self.parts[i].x = self.parts[0].x + self.parts[i].direction.vector_x() * 0x2000; self.parts[i].y = (self.parts[0].y + self.parts[i + 2].y - 0x1000) / 2; let dir_offset = if self.parts[i].direction == Direction::Left { 0 } else { 1 }; @@ -417,7 +417,7 @@ impl BossNPC { self.parts[5].npc_flags.set_solid_soft(true); self.parts[5].npc_flags.set_ignore_solidity(true); self.parts[5].hit_bounds = - Rect { left: 20 * 0x200, top: 36 * 0x200, right: 20 * 0x200, bottom: 16 * 0x200 }; + Rect { left: 20 * 0x200, top: 36 * 0x200, right: 20 * 0x200, bottom: 0x2000 }; } self.parts[5].x = self.parts[0].x; diff --git a/src/npc/utils.rs b/src/npc/utils.rs index 0d0236b..af15b4f 100644 --- a/src/npc/utils.rs +++ b/src/npc/utils.rs @@ -87,8 +87,8 @@ impl NPC { let mut npc = NPC::create(data.npc_type, table); npc.id = data.id; - npc.x = data.x as i32 * 16 * 0x200; - npc.y = data.y as i32 * 16 * 0x200; + npc.x = data.x as i32 * 0x2000; + npc.y = data.y as i32 * 0x2000; npc.flag_num = data.flag_num; npc.event_num = data.event_num; npc.npc_flags = NPCFlag(data.flags | npc.npc_flags.0); diff --git a/src/physics.rs b/src/physics.rs index ae66e2e..15a020a 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -41,15 +41,16 @@ pub trait PhysicalEntity { fn player_left_pressed(&self) -> bool { false } fn player_right_pressed(&self) -> bool { false } - fn judge_hit_block(&mut self, state: &mut SharedGameState, x: i32, y: i32) { - let bounds_x = if self.is_player() { 5 } else { 5 }; - let bounds_y = if self.is_player() { 4 } else { 5 }; + fn test_block_hit(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + let bounds_x = if self.is_player() { 0x600 } else { 0x600 }; + let bounds_y = if self.is_player() { 0x800 } else { 0x600 }; + // left wall - if (self.y() - self.hit_bounds().top as i32) < (y * 16 + bounds_y) * 0x200 - && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 - bounds_y) * 0x200 - && (self.x() - self.hit_bounds().right as i32) < (x * 16 + 8) * 0x200 - && (self.x() - self.hit_bounds().right as i32) > x * 16 * 0x200 { - self.set_x(((x * 16 + 8) * 0x200) + self.hit_bounds().right as i32); + if (self.y() - self.hit_bounds().top as i32) < ((y * 2 + 1) * 0x1000 - bounds_y) + && (self.y() + self.hit_bounds().bottom as i32) > ((y * 2 - 1) * 0x1000 + bounds_y) + && (self.x() - self.hit_bounds().right as i32) < (x * 2 + 1) * 0x1000 + && (self.x() - self.hit_bounds().right as i32) > x * 0x2000 { + self.set_x(((x * 2 + 1) * 0x1000) + self.hit_bounds().right as i32); if self.is_player() { if self.vel_x() < -0x180 { @@ -65,11 +66,11 @@ pub trait PhysicalEntity { } // right wall - if (self.y() - self.hit_bounds().top as i32) < (y * 16 + bounds_y) * 0x200 - && self.y() + self.hit_bounds().bottom as i32 > (y * 16 - bounds_y) * 0x200 - && (self.x() + self.hit_bounds().right as i32) > (x * 16 - 8) * 0x200 - && (self.x() + self.hit_bounds().right as i32) < x * 16 * 0x200 { - self.set_x(((x * 16 - 8) * 0x200) - self.hit_bounds().right as i32); + if (self.y() - self.hit_bounds().top as i32) < ((y * 2 + 1) * 0x1000 - bounds_y) + && (self.y() + self.hit_bounds().bottom as i32) > ((y * 2 - 1) * 0x1000 + bounds_y) + && (self.x() + self.hit_bounds().right as i32) > (x * 2 - 1) * 0x1000 + && (self.x() + self.hit_bounds().right as i32) < x * 0x2000 { + self.set_x(((x * 2 - 1) * 0x1000) - self.hit_bounds().right as i32); if self.is_player() { if self.vel_x() > 0x180 { @@ -85,11 +86,11 @@ pub trait PhysicalEntity { } // ceiling - if (self.x() - self.hit_bounds().right as i32) < (x * 16 + bounds_x) * 0x200 - && (self.x() + self.hit_bounds().right as i32) > (x * 16 - bounds_x) * 0x200 - && (self.y() - self.hit_bounds().top as i32) < (y * 16 + 8) * 0x200 - && (self.y() - self.hit_bounds().top as i32) > y * 16 * 0x200 { - self.set_y(((y * 16 + 8) * 0x200) + self.hit_bounds().top as i32); + if ((self.x() - self.hit_bounds().right as i32) < (x * 2 + 1) * 0x1000 - bounds_x) + && ((self.x() + self.hit_bounds().right as i32) > (x * 2 - 1) * 0x1000 + bounds_x) + && (self.y() - self.hit_bounds().top as i32) < (y * 2 + 1) * 0x1000 + && (self.y() - self.hit_bounds().top as i32) > y * 0x2000 { + self.set_y(((y * 2 + 1) * 0x1000) + self.hit_bounds().top as i32); if self.is_player() { if !self.cond().hidden() && self.vel_y() < -0x200 { @@ -109,11 +110,11 @@ pub trait PhysicalEntity { } // floor - if ((self.x() - self.hit_bounds().right as i32) < (x * 16 + bounds_x) * 0x200) - && ((self.x() + self.hit_bounds().right as i32) > (x * 16 - bounds_x) * 0x200) - && ((self.y() + self.hit_bounds().bottom as i32) > ((y * 16 - 8) * 0x200)) - && ((self.y() + self.hit_bounds().bottom as i32) < (y * 16 * 0x200)) { - self.set_y(((y * 16 - 8) * 0x200) - self.hit_bounds().bottom as i32); + if ((self.x() - self.hit_bounds().right as i32) < (x * 2 + 1) * 0x1000 - bounds_x) + && ((self.x() + self.hit_bounds().right as i32) > (x * 2 - 1) * 0x1000 + bounds_x) + && ((self.y() + self.hit_bounds().bottom as i32) > ((y * 2 - 1) * 0x1000)) + && ((self.y() + self.hit_bounds().bottom as i32) < (y * 0x2000)) { + self.set_y(((y * 2 - 1) * 0x1000) - self.hit_bounds().bottom as i32); if self.is_player() { if self.vel_y() > 0x400 { @@ -132,12 +133,12 @@ pub trait PhysicalEntity { } // upper left slope (bigger half) - fn judge_hit_triangle_a(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + fn test_hit_upper_left_slope_high(&mut self, state: &mut SharedGameState, x: i32, y: i32) { if self.x() < (x * 16 + 8) * 0x200 && self.x() > (x * 16 - 8) * 0x200 - && (self.y() - self.hit_bounds().top as i32) < (y * 16 * 0x200) - (self.x() - x * 16 * 0x200) / 2 + 0x800 + && (self.y() - self.hit_bounds().top as i32) < (y * 0x2000) - (self.x() - x * 0x2000) / 2 + 0x800 && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 - 8) * 0x200 { - self.set_y((y * 16 * 0x200) - ((self.x() - x * 16 * 0x200) / 2) + 0x800 + self.hit_bounds().top as i32); + self.set_y((y * 0x2000) - ((self.x() - x * 0x2000) / 2) + 0x800 + self.hit_bounds().top as i32); if self.is_player() && !self.cond().hidden() && self.vel_y() < -0x200 { state.sound_manager.play_sfx(3); @@ -154,12 +155,12 @@ pub trait PhysicalEntity { } // upper left slope (smaller half) - fn judge_hit_triangle_b(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + fn test_hit_upper_left_slope_low(&mut self, state: &mut SharedGameState, x: i32, y: i32) { if self.x() < (x * 16 + 8) * 0x200 && self.x() > (x * 16 - 8) * 0x200 - && (self.y() - self.hit_bounds().top as i32) < (y * 16 * 0x200) - (self.x() - x * 16 * 0x200) / 2 - 0x800 + && (self.y() - self.hit_bounds().top as i32) < (y * 0x2000) - (self.x() - x * 0x2000) / 2 - 0x800 && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 - 8) * 0x200 { - self.set_y((y * 16 * 0x200) - ((self.x() - x * 16 * 0x200) / 2) - 0x800 + self.hit_bounds().top as i32); + self.set_y((y * 0x2000) - ((self.x() - x * 0x2000) / 2) - 0x800 + self.hit_bounds().top as i32); if self.is_player() && !self.cond().hidden() && self.vel_y() < -0x200 { state.sound_manager.play_sfx(3); @@ -176,12 +177,12 @@ pub trait PhysicalEntity { } // upper right slope (smaller half) - fn judge_hit_triangle_c(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + fn test_hit_upper_right_slope_low(&mut self, state: &mut SharedGameState, x: i32, y: i32) { if self.x() < (x * 16 + 8) * 0x200 && self.x() > (x * 16 - 8) * 0x200 - && (self.y() - self.hit_bounds().top as i32) < (y * 16 * 0x200) + (self.x() - x * 16 * 0x200) / 2 - 0x800 + && (self.y() - self.hit_bounds().top as i32) < (y * 0x2000) + (self.x() - x * 0x2000) / 2 - 0x800 && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 - 8) * 0x200 { - self.set_y((y * 16 * 0x200) + ((self.x() - x * 16 * 0x200) / 2) - 0x800 + self.hit_bounds().top as i32); + self.set_y((y * 0x2000) + ((self.x() - x * 0x2000) / 2) - 0x800 + self.hit_bounds().top as i32); if self.is_player() && !self.cond().hidden() && self.vel_y() < -0x200 { state.sound_manager.play_sfx(3); @@ -198,12 +199,12 @@ pub trait PhysicalEntity { } // upper right slope (bigger half) - fn judge_hit_triangle_d(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + fn test_hit_upper_right_slope_high(&mut self, state: &mut SharedGameState, x: i32, y: i32) { if (self.x() < (x * 16 + 8) * 0x200) && (self.x() > (x * 16 - 8) * 0x200) - && (self.y() - self.hit_bounds().top as i32) < (y * 16 * 0x200) + (self.x() - x * 16 * 0x200) / 2 + 0x800 + && (self.y() - self.hit_bounds().top as i32) < (y * 0x2000) + (self.x() - x * 0x2000) / 2 + 0x800 && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 - 8) * 0x200 { - self.set_y((y * 16 * 0x200) + ((self.x() - x * 16 * 0x200) / 2) + 0x800 + self.hit_bounds().top as i32); + self.set_y((y * 0x2000) + ((self.x() - x * 0x2000) / 2) + 0x800 + self.hit_bounds().top as i32); if self.is_player() && !self.cond().hidden() && self.vel_y() < -0x200 { state.sound_manager.play_sfx(3); @@ -220,14 +221,14 @@ pub trait PhysicalEntity { } // lower left half (bigger) - fn judge_hit_triangle_e(&mut self, state: &mut SharedGameState, x: i32, y: i32) { - self.flags().set_hit_left_bigger_half(true); + fn test_hit_lower_left_slope_high(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + self.flags().set_hit_left_higher_half(true); if (self.x() < (x * 16 + 8) * 0x200) && (self.x() > (x * 16 - 8) * 0x200) - && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 * 0x200) + (self.x() - x * 16 * 0x200) / 2 - 0x800 + && (self.y() + self.hit_bounds().bottom as i32) > (y * 0x2000) + (self.x() - x * 0x2000) / 2 - 0x800 && (self.y() - self.hit_bounds().top as i32) < (y * 16 + 8) * 0x200 { - self.set_y((y * 16 * 0x200) + ((self.x() - x * 16 * 0x200) / 2) - 0x800 - self.hit_bounds().bottom as i32); + self.set_y((y * 0x2000) + ((self.x() - x * 0x2000) / 2) - 0x800 - self.hit_bounds().bottom as i32); if self.is_player() && self.vel_y() > 0x400 { state.sound_manager.play_sfx(23); @@ -243,14 +244,14 @@ pub trait PhysicalEntity { } // lower left half (smaller) - fn judge_hit_triangle_f(&mut self, state: &mut SharedGameState, x: i32, y: i32) { - self.flags().set_hit_left_smaller_half(true); + fn test_hit_lower_left_slope_low(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + self.flags().set_hit_left_lower_half(true); if (self.x() < (x * 16 + 8) * 0x200) && (self.x() > (x * 16 - 8) * 0x200) - && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 * 0x200) + (self.x() - x * 16 * 0x200) / 2 + 0x800 + && (self.y() + self.hit_bounds().bottom as i32) > (y * 0x2000) + (self.x() - x * 0x2000) / 2 + 0x800 && (self.y() - self.hit_bounds().top as i32) < (y * 16 + 8) * 0x200 { - self.set_y((y * 16 * 0x200) + ((self.x() - x * 16 * 0x200) / 2) + 0x800 - self.hit_bounds().bottom as i32); + self.set_y((y * 0x2000) + ((self.x() - x * 0x2000) / 2) + 0x800 - self.hit_bounds().bottom as i32); if self.is_player() && self.vel_y() > 0x400 { state.sound_manager.play_sfx(23); @@ -266,14 +267,14 @@ pub trait PhysicalEntity { } // lower right half (smaller) - fn judge_hit_triangle_g(&mut self, state: &mut SharedGameState, x: i32, y: i32) { - self.flags().set_hit_right_smaller_half(true); + fn test_hit_lower_right_slope_low(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + self.flags().set_hit_right_lower_half(true); if (self.x() < (x * 16 + 8) * 0x200) && (self.x() > (x * 16 - 8) * 0x200) - && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 * 0x200) - (self.x() - x * 16 * 0x200) / 2 + 0x800 + && (self.y() + self.hit_bounds().bottom as i32) > (y * 0x2000) - (self.x() - x * 0x2000) / 2 + 0x800 && (self.y() - self.hit_bounds().top as i32) < (y * 16 + 8) * 0x200 { - self.set_y((y * 16 * 0x200) - ((self.x() - x * 16 * 0x200) / 2) + 0x800 - self.hit_bounds().bottom as i32); + self.set_y((y * 0x2000) - ((self.x() - x * 0x2000) / 2) + 0x800 - self.hit_bounds().bottom as i32); if self.is_player() && self.vel_y() > 0x400 { state.sound_manager.play_sfx(23); @@ -289,14 +290,14 @@ pub trait PhysicalEntity { } // lower right half (bigger) - fn judge_hit_triangle_h(&mut self, state: &mut SharedGameState, x: i32, y: i32) { - self.flags().set_hit_right_bigger_half(true); + fn test_hit_lower_right_slope_high(&mut self, state: &mut SharedGameState, x: i32, y: i32) { + self.flags().set_hit_right_higher_half(true); if (self.x() < (x * 16 + 8) * 0x200) && (self.x() > (x * 16 - 8) * 0x200) - && (self.y() + self.hit_bounds().bottom as i32) > (y * 16 * 0x200) - (self.x() - x * 16 * 0x200) / 2 - 0x800 + && (self.y() + self.hit_bounds().bottom as i32) > (y * 0x2000) - (self.x() - x * 0x2000) / 2 - 0x800 && (self.y() - self.hit_bounds().top as i32) < (y * 16 + 8) * 0x200 { - self.set_y((y * 16 * 0x200) - ((self.x() - x * 16 * 0x200) / 2) - 0x800 - self.hit_bounds().bottom as i32); + self.set_y((y * 0x2000) - ((self.x() - x * 0x2000) / 2) - 0x800 - self.hit_bounds().bottom as i32); if self.is_player() && self.vel_y() > 0x400 { state.sound_manager.play_sfx(23); @@ -311,7 +312,7 @@ pub trait PhysicalEntity { } } - fn judge_hit_water(&mut self, x: i32, y: i32) { + fn test_hit_water(&mut self, x: i32, y: i32) { let bounds_x = if self.is_player() { 5 } else { 6 }; let bounds_up = if self.is_player() { 5 } else { 6 }; let bounds_down = if self.is_player() { 0 } else { 6 }; @@ -323,7 +324,7 @@ pub trait PhysicalEntity { } } - fn judge_hit_spike(&mut self, x: i32, y: i32, water: bool) { + fn test_hit_spike(&mut self, x: i32, y: i32, water: bool) { if (self.x() - 0x800) < (x * 16 + 4) * 0x200 && (self.x() + 0x800) > (x * 16 - 4) * 0x200 && (self.y() - 0x800) < (y * 16 + 3) * 0x200 @@ -335,7 +336,7 @@ pub trait PhysicalEntity { } } - fn judge_hit_force(&mut self, x: i32, y: i32, direction: Direction, water: bool) { + fn test_hit_force(&mut self, x: i32, y: i32, direction: Direction, water: bool) { if (self.x() - self.hit_bounds().left as i32) < (x * 16 + 6) * 0x200 && (self.x() + self.hit_bounds().right as i32) > (x * 16 - 6) * 0x200 && (self.y() - self.hit_bounds().top as i32) < (y * 16 + 6) * 0x200 @@ -371,82 +372,82 @@ pub trait PhysicalEntity { match attrib { // Spikes 0x62 | 0x42 if self.is_player() => { - self.judge_hit_spike(x + ox, y + oy, attrib & 0x20 != 0); + self.test_hit_spike(x + ox, y + oy, attrib & 0x20 != 0); } // Blocks 0x02 | 0x60 => { - self.judge_hit_water(x + ox, y + oy); + self.test_hit_water(x + ox, y + oy); } 0x62 if !self.is_player() => { - self.judge_hit_water(x + ox, y + oy); + self.test_hit_water(x + ox, y + oy); } 0x61 => { - self.judge_hit_block(state, x + ox, y + oy); - self.judge_hit_water(x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); + self.test_hit_water(x + ox, y + oy); } 0x04 | 0x64 if !self.is_player() => { - self.judge_hit_block(state, x + ox, y + oy); - self.judge_hit_water(x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); + self.test_hit_water(x + ox, y + oy); } 0x05 | 0x41 | 0x43 | 0x46 if self.is_player() => { - self.judge_hit_block(state, x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); } 0x03 | 0x05 | 0x41 | 0x43 if !self.is_player() => { - self.judge_hit_block(state, x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); } 0x44 => { if !self.ignore_tile_44() { - self.judge_hit_block(state, x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); } } // Slopes 0x50 | 0x70 => { - self.judge_hit_triangle_a(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_upper_left_slope_high(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x51 | 0x71 => { - self.judge_hit_triangle_b(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_upper_left_slope_low(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x52 | 0x72 => { - self.judge_hit_triangle_c(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_upper_right_slope_low(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x53 | 0x73 => { - self.judge_hit_triangle_d(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_upper_right_slope_high(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x54 | 0x74 => { - self.judge_hit_triangle_e(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_lower_left_slope_high(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x55 | 0x75 => { - self.judge_hit_triangle_f(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_lower_left_slope_low(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x56 | 0x76 => { - self.judge_hit_triangle_g(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_lower_right_slope_low(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } 0x57 | 0x77 => { - self.judge_hit_triangle_h(state, x + ox, y + oy); - if attrib & 0x20 != 0 { self.judge_hit_water(x + ox, y + oy); } + self.test_hit_lower_right_slope_high(state, x + ox, y + oy); + if attrib & 0x20 != 0 { self.test_hit_water(x + ox, y + oy); } } // Forces 0x80 | 0xa0 if self.is_player() => { - self.judge_hit_force(x + ox, y + oy, Direction::Left, attrib & 0x20 != 0); + self.test_hit_force(x + ox, y + oy, Direction::Left, attrib & 0x20 != 0); } 0x81 | 0xa1 if self.is_player() => { - self.judge_hit_force(x + ox, y + oy, Direction::Up, attrib & 0x20 != 0); + self.test_hit_force(x + ox, y + oy, Direction::Up, attrib & 0x20 != 0); } 0x82 | 0xa2 if self.is_player() => { - self.judge_hit_force(x + ox, y + oy, Direction::Right, attrib & 0x20 != 0); + self.test_hit_force(x + ox, y + oy, Direction::Right, attrib & 0x20 != 0); } 0x83 | 0xa3 if self.is_player() => { - self.judge_hit_force(x + ox, y + oy, Direction::Bottom, attrib & 0x20 != 0); + self.test_hit_force(x + ox, y + oy, Direction::Bottom, attrib & 0x20 != 0); } 0x80 | 0xa0 if !self.is_player() => { self.flags().set_force_left(true); diff --git a/src/player/mod.rs b/src/player/mod.rs index 7609d12..f927434 100644 --- a/src/player/mod.rs +++ b/src/player/mod.rs @@ -99,15 +99,15 @@ impl Player { target_y: 0, prev_x: 0, prev_y: 0, - life: constants.my_char.life, - max_life: constants.my_char.max_life, + life: constants.player.life, + max_life: constants.player.max_life, cond: Condition(0), flags: Flag(0), equip: Equipment(0), direction: Direction::Right, - display_bounds: constants.my_char.display_bounds, - hit_bounds: constants.my_char.hit_bounds, - control_mode: constants.my_char.control_mode, + display_bounds: constants.player.display_bounds, + hit_bounds: constants.player.hit_bounds, + control_mode: constants.player.control_mode, question: false, booster_fuel: 0, camera_target_x: 0, @@ -130,7 +130,7 @@ impl Player { damage_taken: 0, anim_num: 0, anim_counter: 0, - anim_rect: constants.my_char.frames_right[0], + anim_rect: constants.player.frames_right[0], weapon_rect: Rect::new(0, 0, 0, 0), } } @@ -173,9 +173,9 @@ impl Player { } let physics = if self.flags.in_water() { - state.constants.my_char.water_physics + state.constants.player.water_physics } else { - state.constants.my_char.air_physics + state.constants.player.air_physics }; self.question = false; @@ -393,12 +393,12 @@ impl Player { self.vel_y -= 0x20; if self.controller.trigger_jump() || self.booster_fuel % 3 == 1 { - state.create_caret(self.x, self.y + 6 * 0x200, CaretType::Exhaust, Direction::Bottom); + state.create_caret(self.x, self.y + 0xc00, CaretType::Exhaust, Direction::Bottom); state.sound_manager.play_sfx(113); } } 3 if self.controller.trigger_jump() || self.booster_fuel % 3 == 1 => { - state.create_caret(self.x, self.y + 6 * 0x200, CaretType::Exhaust, Direction::Up); + state.create_caret(self.x, self.y + 0xc00, CaretType::Exhaust, Direction::Up); state.sound_manager.play_sfx(113); } _ => {} @@ -437,11 +437,11 @@ impl Player { self.vel_y = self.vel_x; } - if (self.flags.hit_bottom_wall() && self.flags.hit_right_bigger_half() && self.vel_x < 0) - || (self.flags.hit_bottom_wall() && self.flags.hit_left_bigger_half() && self.vel_x > 0) + if (self.flags.hit_bottom_wall() && self.flags.hit_right_higher_half() && self.vel_x < 0) + || (self.flags.hit_bottom_wall() && self.flags.hit_left_higher_half() && self.vel_x > 0) || (self.flags.hit_bottom_wall() - && self.flags.hit_left_smaller_half() - && self.flags.hit_right_smaller_half()) + && self.flags.hit_left_lower_half() + && self.flags.hit_right_lower_half()) { self.vel_y = 0x400; // 2.0fix9 } @@ -453,9 +453,9 @@ impl Player { || self.flags.force_right() || self.flags.force_down()) { - state.constants.my_char.water_physics.max_move + state.constants.player.water_physics.max_move } else { - state.constants.my_char.air_physics.max_move + state.constants.player.air_physics.max_move }; self.vel_x = clamp(self.vel_x, -max_move, max_move); @@ -835,7 +835,7 @@ impl GameEntity<&NPCList> for Player { self.y - frame.y - 12 * 0x200, state.frame_time, ), - &state.constants.my_char.frames_bubble[(self.tick / 2 % 2) as usize], + &state.constants.player.frames_bubble[(self.tick / 2 % 2) as usize], ); batch.draw(ctx)?; } diff --git a/src/player/player_hit.rs b/src/player/player_hit.rs index a164751..c6667db 100644 --- a/src/player/player_hit.rs +++ b/src/player/player_hit.rs @@ -11,6 +11,7 @@ use crate::npc::NPC; use crate::physics::PhysicalEntity; use crate::player::{ControlMode, Player, TargetPlayer}; use crate::shared_game_state::SharedGameState; +use crate::weapon::WeaponType; impl PhysicalEntity for Player { #[inline(always)] @@ -92,11 +93,11 @@ impl PhysicalEntity for Player { } impl Player { - fn judge_hit_npc_solid_soft(&mut self, npc: &NPC) -> Flag { + fn test_hit_npc_solid_soft(&mut self, npc: &NPC) -> Flag { let mut flags = Flag(0); - if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 3 * 0x200)) - && ((self.y + self.hit_bounds.top as i32) > (npc.y - npc.hit_bounds.bottom as i32 + 3 * 0x200)) + if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 0x600)) + && ((self.y + self.hit_bounds.top as i32) > (npc.y - npc.hit_bounds.bottom 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) { if self.vel_x < 0x200 { @@ -106,8 +107,8 @@ impl Player { flags.set_hit_left_wall(true); } - if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 3 * 0x200)) - && ((self.y + self.hit_bounds.top as i32) > (npc.y - npc.hit_bounds.bottom as i32 + 3 * 0x200)) + if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 0x600)) + && ((self.y + self.hit_bounds.top as i32) > (npc.y - npc.hit_bounds.bottom 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) { if self.vel_x > -0x200 { @@ -118,8 +119,8 @@ impl Player { } - if ((self.x - self.hit_bounds.right as i32) < (npc.x + npc.hit_bounds.right as i32 - 3 * 0x200)) - && ((self.x + self.hit_bounds.right as i32) > (npc.x - npc.hit_bounds.right as i32 + 3 * 0x200)) + if ((self.x - self.hit_bounds.right as i32) < (npc.x + npc.hit_bounds.right as i32 - 0x600)) + && ((self.x + self.hit_bounds.right as i32) > (npc.x - npc.hit_bounds.right as i32 + 0x600)) && ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32)) && ((self.y - self.hit_bounds.top as i32) > npc.y) { if self.vel_y < 0 { @@ -129,10 +130,10 @@ impl Player { flags.set_hit_top_wall(true); } - if ((self.x - self.hit_bounds.right as i32) < (npc.x + npc.hit_bounds.right as i32 - 3 * 0x200)) - && ((self.x + self.hit_bounds.right as i32) > (npc.x - npc.hit_bounds.right as i32 + 3 * 0x200)) - && ((self.y + self.hit_bounds.bottom as i32 - 0x200) > (npc.y - npc.hit_bounds.top as i32)) - && ((self.y + self.hit_bounds.bottom as i32 - 0x200) < (npc.y + 3 * 0x200)) { + if ((self.x - self.hit_bounds.right as i32) < (npc.x + npc.hit_bounds.right as i32 - 0x600)) + && ((self.x + self.hit_bounds.right as i32) > (npc.x - npc.hit_bounds.right as i32 + 0x600)) + && ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.top as i32)) + && ((self.y + self.hit_bounds.bottom as i32) < (npc.y + 0x600)) { if npc.npc_flags.bouncy() { self.vel_y = npc.vel_y - 0x200; flags.set_hit_bottom_wall(true); @@ -147,7 +148,7 @@ impl Player { flags } - fn judge_hit_npc_solid_hard(&mut self, npc: &NPC, state: &mut SharedGameState) -> Flag { + fn test_hit_npc_solid_hard(&mut self, npc: &NPC, state: &mut SharedGameState) -> Flag { let mut flags = Flag(0); let fx1 = abs(self.x - npc.x) as f32; @@ -199,8 +200,8 @@ impl Player { } if (self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.top as i32) - && (self.y + self.hit_bounds.bottom as i32) < (npc.y + 3 * 0x200) { - if self.vel_y - npc.vel_y > 2 * 0x200 { + && (self.y + self.hit_bounds.bottom as i32) < (npc.y + 0x600) { + if self.vel_y - npc.vel_y > 0x400 { state.sound_manager.play_sfx(23); } @@ -211,9 +212,9 @@ impl Player { self.vel_y = npc.vel_y - 0x200; flags.set_hit_bottom_wall(true); } else if !self.flags.hit_bottom_wall() && self.vel_y > npc.vel_y { + self.x += npc.vel_x; self.y = npc.y - npc.hit_bounds.top as i32 - self.hit_bounds.bottom as i32 + 0x200; self.vel_y = npc.vel_y; - self.x += npc.vel_x; flags.set_hit_bottom_wall(true); } @@ -223,15 +224,15 @@ impl Player { flags } - fn judge_hit_npc_non_solid(&mut self, npc: &NPC) -> Flag { + fn test_hit_npc_non_solid(&mut self, npc: &NPC) -> Flag { let mut flags = Flag(0); let hit_left = if npc.direction == Direction::Left { npc.hit_bounds.left } else { npc.hit_bounds.right } as i32; let hit_right = if npc.direction == Direction::Left { npc.hit_bounds.right } else { npc.hit_bounds.left } as i32; - if self.x + (2 * 0x200) > npc.x - hit_left - && self.x - (2 * 0x200) < npc.x + hit_right - && self.y + (2 * 0x200) > npc.y - npc.hit_bounds.top as i32 - && self.y - (2 * 0x200) < npc.y + npc.hit_bounds.bottom as i32 { + if self.x + 0x400 > npc.x - hit_left + && self.x - 0x400 < npc.x + hit_right + && self.y + 0x400 > npc.y - npc.hit_bounds.top as i32 + && self.y - 0x400 < npc.y + npc.hit_bounds.bottom as i32 { flags.set_hit_left_wall(true); } @@ -242,13 +243,13 @@ impl Player { let flags: Flag; if npc.npc_flags.solid_soft() { - flags = self.judge_hit_npc_solid_soft(npc.borrow()); + flags = self.test_hit_npc_solid_soft(npc.borrow()); self.flags.0 |= flags.0; } else if npc.npc_flags.solid_hard() { - flags = self.judge_hit_npc_solid_hard(npc.borrow(), state); + flags = self.test_hit_npc_solid_hard(npc.borrow(), state); self.flags.0 |= flags.0; } else { - flags = self.judge_hit_npc_non_solid(npc.borrow()); + flags = self.test_hit_npc_non_solid(npc.borrow()); } if !npc.cond.drs_boss() && flags.0 != 0 { @@ -262,6 +263,12 @@ impl Player { // missile pickup 86 => { // todo add bullets + if let Some(weapon) = inventory.get_weapon_by_type_mut(WeaponType::MissileLauncher) { + weapon.refill_ammo(npc.exp); + } else if let Some(weapon) = inventory.get_weapon_by_type_mut(WeaponType::SuperMissileLauncher) { + weapon.refill_ammo(npc.exp); + } + npc.cond.set_alive(false); state.sound_manager.play_sfx(42); @@ -282,16 +289,6 @@ impl Player { state.touch_controls.interact_icon = true; } - if npc.npc_flags.interactable() && !state.control_flags.interactions_disabled() && flags.0 != 0 && self.cond.interacted() { - state.control_flags.set_tick_world(true); - state.control_flags.set_interactions_disabled(true); - state.textscript_vm.executor_player = id; - state.textscript_vm.start_script(npc.event_num); - self.cond.set_interacted(false); - self.vel_x = 0; - self.question = false; - } - if npc.npc_flags.event_when_touched() && !state.control_flags.interactions_disabled() && flags.0 != 0 { state.control_flags.set_tick_world(true); state.control_flags.set_interactions_disabled(true); @@ -311,6 +308,16 @@ impl Player { self.damage(npc.damage as i32, state, npc_list); } } + + if npc.npc_flags.interactable() && !state.control_flags.interactions_disabled() && flags.0 != 0 && self.cond.interacted() { + state.control_flags.set_tick_world(true); + state.control_flags.set_interactions_disabled(true); + state.textscript_vm.executor_player = id; + state.textscript_vm.start_script(npc.event_num); + self.cond.set_interacted(false); + self.vel_x = 0; + self.question = false; + } } pub fn tick_npc_collisions(&mut self, id: TargetPlayer, state: &mut SharedGameState, npc_list: &NPCList, boss: &mut BossNPC, inventory: &mut Inventory) { diff --git a/src/scene/game_scene.rs b/src/scene/game_scene.rs index df46486..a0a7007 100644 --- a/src/scene/game_scene.rs +++ b/src/scene/game_scene.rs @@ -1374,8 +1374,8 @@ impl GameScene { let hit_rect_size = npc.hit_rect_size().clamp(1, 4); let hit_rect_size = hit_rect_size * hit_rect_size; - let x = (npc.x + npc.offset_x()) / (16 * 0x200); - let y = (npc.y + npc.offset_y()) / (16 * 0x200); + let x = (npc.x + npc.offset_x()) / (0x2000); + let y = (npc.y + npc.offset_y()) / (0x2000); let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "Caret")?; let caret_rect = Rect::new_size(2, 74, 4, 4); @@ -1671,7 +1671,7 @@ impl Scene for GameScene { ); let y = y.clamp(8.0, state.canvas_size.1 - 8.0 - state.font.line_height(&state.constants)); - if self.player2.x + 8 * 0x200 < self.frame.x { + if self.player2.x + 0x1000 < self.frame.x { state.font.draw_colored_text( P2_LEFT_TEXT.chars(), 9.0, @@ -1691,7 +1691,7 @@ impl Scene for GameScene { &mut state.texture_set, ctx, )?; - } else if self.player2.x - 8 * 0x200 > self.frame.x + state.canvas_size.0 as i32 * 0x200 { + } else if self.player2.x - 0x1000 > self.frame.x + state.canvas_size.0 as i32 * 0x200 { let width = state.font.text_width(P2_RIGHT_TEXT.chars(), &state.constants); state.font.draw_colored_text( diff --git a/src/shared_game_state.rs b/src/shared_game_state.rs index 31837b1..9f83d61 100644 --- a/src/shared_game_state.rs +++ b/src/shared_game_state.rs @@ -240,8 +240,8 @@ impl SharedGameState { pub fn start_new_game(&mut self, ctx: &mut Context) -> GameResult { let mut next_scene = GameScene::new(self, ctx, 13)?; next_scene.player1.cond.set_alive(true); - next_scene.player1.x = 10 * 16 * 0x200; - next_scene.player1.y = 8 * 16 * 0x200; + next_scene.player1.x = 10 * 0x2000; + next_scene.player1.y = 8 * 0x2000; self.reset_map_flags(); self.fade_state = FadeState::Hidden; @@ -258,8 +258,8 @@ impl SharedGameState { pub fn start_intro(&mut self, ctx: &mut Context) -> GameResult { let mut next_scene = GameScene::new(self, ctx, 72)?; next_scene.player1.cond.set_hidden(true); - next_scene.player1.x = 3 * 16 * 0x200; - next_scene.player1.y = 3 * 16 * 0x200; + next_scene.player1.x = 3 * 0x2000; + next_scene.player1.y = 3 * 0x2000; next_scene.intro_mode = true; self.reset_map_flags(); diff --git a/src/text_script.rs b/src/text_script.rs index deeda42..9cbf327 100644 --- a/src/text_script.rs +++ b/src/text_script.rs @@ -1098,8 +1098,8 @@ impl TextScriptVM { if game_scene.stage.change_tile(pos_x, pos_y, tile_type) { let mut npc = NPC::create(4, &state.npc_table); npc.cond.set_alive(true); - npc.x = pos_x as i32 * 16 * 0x200; - npc.y = pos_y as i32 * 16 * 0x200; + npc.x = pos_x as i32 * 0x2000; + npc.y = pos_y as i32 * 0x2000; let _ = game_scene.npc_list.spawn(0x100, npc.clone()); let _ = game_scene.npc_list.spawn(0x100, npc); @@ -1201,8 +1201,8 @@ impl TextScriptVM { OpCode::TRA => { let map_id = read_cur_varint(&mut cursor)? as usize; let event_num = read_cur_varint(&mut cursor)? as u16; - let pos_x = read_cur_varint(&mut cursor)? as i32 * 16 * 0x200; - let pos_y = read_cur_varint(&mut cursor)? as i32 * 16 * 0x200; + let pos_x = read_cur_varint(&mut cursor)? as i32 * 0x2000; + let pos_y = read_cur_varint(&mut cursor)? as i32 * 0x2000; let mut new_scene = GameScene::new(state, ctx, map_id)?; new_scene.intro_mode = game_scene.intro_mode; @@ -1236,8 +1236,8 @@ impl TextScriptVM { exec_state = TextScriptExecutionState::Running(event_num, 0); } OpCode::MOV => { - let pos_x = read_cur_varint(&mut cursor)? as i32 * 16 * 0x200; - let pos_y = read_cur_varint(&mut cursor)? as i32 * 16 * 0x200; + let pos_x = read_cur_varint(&mut cursor)? as i32 * 0x2000; + let pos_y = read_cur_varint(&mut cursor)? as i32 * 0x2000; for player in [&mut game_scene.player1, &mut game_scene.player2].iter_mut() { player.vel_x = 0; @@ -1260,7 +1260,7 @@ impl TextScriptVM { 0 | 1 => { partner.vel_x = 0; partner.vel_y = 0; - partner.x = executor.x + if param == 0 { -16 * 0x200 } else { 16 * 0x200 }; + partner.x = executor.x + if param == 0 { -0x2000 } else { 0x2000 }; partner.y = executor.y; } 2..=10 => { @@ -1515,8 +1515,8 @@ impl TextScriptVM { for npc in game_scene.npc_list.iter_alive() { if npc.event_num == event_num { - npc.x = x * 16 * 0x200; - npc.y = y * 16 * 0x200; + npc.x = x * 0x2000; + npc.y = y * 0x2000; npc.tsc_direction = tsc_direction as u16; if direction == Direction::FacingPlayer { @@ -1541,8 +1541,8 @@ impl TextScriptVM { let mut npc = NPC::create(npc_type, &state.npc_table); npc.cond.set_alive(true); - npc.x = x * 16 * 0x200; - npc.y = y * 16 * 0x200; + npc.x = x * 0x2000; + npc.y = y * 0x2000; npc.tsc_direction = tsc_direction as u16; if direction == Direction::FacingPlayer { diff --git a/src/weapon/bullet.rs b/src/weapon/bullet.rs index f641f6a..314c3da 100644 --- a/src/weapon/bullet.rs +++ b/src/weapon/bullet.rs @@ -391,8 +391,7 @@ impl Bullet { self.direction = if self.vel_x < 0 { Direction::Left } else { Direction::Right }; - self.vel_x += if players[self.owner.index()].direction() == Direction::Left { -0x80 } else { 0x80 }; - + self.vel_x += players[self.owner.index()].direction().vector_x() * 0x80; self.vel_y = -0x5ff; } Direction::Bottom => { @@ -822,7 +821,7 @@ impl Bullet { } if self.action_counter == 3 { - self.weapon_flags.set_flag_x04(false); + self.weapon_flags.set_no_collision_checks(false); } if self.action_counter % 5 == 1 { @@ -867,7 +866,7 @@ impl Bullet { } if self.action_counter == 3 { - self.weapon_flags.set_flag_x04(false); + self.weapon_flags.set_no_collision_checks(false); } if self.action_counter % 7 == 1 { @@ -939,7 +938,7 @@ impl Bullet { self.counter1 += 1; if self.counter1 == 5 { - self.weapon_flags.set_flag_x04(false); + self.weapon_flags.set_no_collision_checks(false); } if self.counter1 > self.lifetime { @@ -1398,6 +1397,7 @@ impl Bullet { pub fn vanish(&mut self, state: &mut SharedGameState) { match self.btype { + // spur is a special case 37 | 38 | 39 => state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Up), _ => state.sound_manager.play_sfx(28), } @@ -1406,13 +1406,13 @@ impl Bullet { state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Right); } - fn judge_hit_block_destroy(&mut self, x: i32, y: i32, hit_attribs: &[u8; 4], state: &mut SharedGameState) { + fn test_hit_block_destructible(&mut self, x: i32, y: i32, attributes: &[u8; 4], state: &mut SharedGameState) { let mut hits = [false; 4]; let block_x = (x * 16 + 8) * 0x200; let block_y = (y * 16 + 8) * 0x200; - for (i, &attr) in hit_attribs.iter().enumerate() { - if self.weapon_flags.flag_x40() { + for (i, &attr) in attributes.iter().enumerate() { + if self.weapon_flags.can_destroy_snack() { hits[i] = attr == 0x41 || attr == 0x61; } else { hits[i] = attr == 0x41 || attr == 0x43 || attr == 0x61; @@ -1425,10 +1425,10 @@ impl Bullet { self.flags.set_hit_left_wall(true); } } else if hits[0] && !hits[2] { - if (self.x - self.hit_bounds.left as i32) < block_x && (self.y - self.hit_bounds.top as i32) < block_y - (3 * 0x200) { + if (self.x - self.hit_bounds.left as i32) < block_x && (self.y - self.hit_bounds.top as i32) < block_y - (0x600) { self.flags.set_hit_left_wall(true); } - } else if !hits[0] && hits[2] && (self.x - self.hit_bounds.left as i32) < block_x && (self.y + self.hit_bounds.top as i32) > block_y + (3 * 0x200) { + } else if !hits[0] && hits[2] && (self.x - self.hit_bounds.left as i32) < block_x && (self.y + self.hit_bounds.top as i32) > block_y + (0x600) { self.flags.set_hit_left_wall(true); } @@ -1438,10 +1438,10 @@ impl Bullet { self.flags.set_hit_right_wall(true); } } else if hits[1] && !hits[3] { - if (self.x + self.hit_bounds.right as i32) > block_x && (self.y - self.hit_bounds.top as i32) < block_y - (3 * 0x200) { + if (self.x + self.hit_bounds.right as i32) > block_x && (self.y - self.hit_bounds.top as i32) < block_y - (0x600) { self.flags.set_hit_right_wall(true); } - } else if !hits[1] && hits[3] && (self.x + self.hit_bounds.right as i32) > block_x && (self.y + self.hit_bounds.top as i32) > block_y + (3 * 0x200) { + } else if !hits[1] && hits[3] && (self.x + self.hit_bounds.right as i32) > block_x && (self.y + self.hit_bounds.top as i32) > block_y + (0x600) { self.flags.set_hit_right_wall(true); } @@ -1451,10 +1451,10 @@ impl Bullet { self.flags.set_hit_top_wall(true); } } else if hits[0] && !hits[1] { - if (self.x - self.hit_bounds.left as i32) < block_x - (3 * 0x200) && (self.y - self.hit_bounds.top as i32) < block_y { + if (self.x - self.hit_bounds.left as i32) < block_x - (0x600) && (self.y - self.hit_bounds.top as i32) < block_y { self.flags.set_hit_top_wall(true); } - } else if !hits[0] && hits[1] && (self.x + self.hit_bounds.right as i32) > block_x + (3 * 0x200) && (self.y - self.hit_bounds.top as i32) < block_y { + } else if !hits[0] && hits[1] && (self.x + self.hit_bounds.right as i32) > block_x + (0x600) && (self.y - self.hit_bounds.top as i32) < block_y { self.flags.set_hit_top_wall(true); } @@ -1464,14 +1464,14 @@ impl Bullet { self.flags.set_hit_bottom_wall(true); } } else if hits[2] && !hits[3] { - if (self.x - self.hit_bounds.left as i32) < block_x - (3 * 0x200) && (self.y + self.hit_bounds.bottom as i32) > block_y { + if (self.x - self.hit_bounds.left as i32) < block_x - (0x600) && (self.y + self.hit_bounds.bottom as i32) > block_y { self.flags.set_hit_bottom_wall(true); } - } else if !hits[2] && hits[3] && (self.x + self.hit_bounds.right as i32) > block_x + (3 * 0x200) && (self.y + self.hit_bounds.bottom as i32) > block_y { + } else if !hits[2] && hits[3] && (self.x + self.hit_bounds.right as i32) > block_x + (0x600) && (self.y + self.hit_bounds.bottom as i32) > block_y { self.flags.set_hit_bottom_wall(true); } - if self.weapon_flags.flag_x08() { + if self.weapon_flags.bounce_from_walls() { if self.flags.hit_left_wall() { self.x = block_x + self.hit_bounds.right as i32; } else if self.flags.hit_right_wall() { @@ -1557,7 +1557,7 @@ impl PhysicalEntity for Bullet { false } - fn judge_hit_block(&mut self, _state: &mut SharedGameState, x: i32, y: i32) { + fn test_block_hit(&mut self, _state: &mut SharedGameState, x: i32, y: i32) { if (self.x - self.hit_bounds.left as i32) < (x * 16 + 8) * 0x200 && (self.x + self.hit_bounds.right as i32) > (x * 16 - 8) * 0x200 && (self.y - self.hit_bounds.top as i32) < (y * 16 + 8) * 0x200 @@ -1569,7 +1569,7 @@ impl PhysicalEntity for Bullet { fn tick_map_collisions(&mut self, state: &mut SharedGameState, npc_list: &NPCList, stage: &mut Stage) { self.flags().0 = 0; - if self.weapon_flags.flag_x04() { + if self.weapon_flags.no_collision_checks() { // ??? return; } @@ -1589,15 +1589,15 @@ impl PhysicalEntity for Bullet { match attrib { // Blocks 0x41 | 0x44 | 0x61 | 0x64 => { - self.judge_hit_block(state, x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); } 0x43 => { let old_hit = self.flags; self.flags.0 = 0; - self.judge_hit_block(state, x + ox, y + oy); + self.test_block_hit(state, x + ox, y + oy); - if self.flags.weapon_hit_block() && (self.weapon_flags.flag_x20() || self.weapon_flags.flag_x40()) { - if !self.weapon_flags.flag_x40() { + if self.flags.weapon_hit_block() && (self.weapon_flags.flag_x20() || self.weapon_flags.can_destroy_snack()) { + if !self.weapon_flags.can_destroy_snack() { self.cond.set_alive(false); } @@ -1626,33 +1626,33 @@ impl PhysicalEntity for Bullet { } // Slopes 0x50 | 0x70 => { - self.judge_hit_triangle_a(state, x + ox, y + oy); + self.test_hit_upper_left_slope_high(state, x + ox, y + oy); } 0x51 | 0x71 => { - self.judge_hit_triangle_b(state, x + ox, y + oy); + self.test_hit_upper_left_slope_low(state, x + ox, y + oy); } 0x52 | 0x72 => { - self.judge_hit_triangle_c(state, x + ox, y + oy); + self.test_hit_upper_right_slope_low(state, x + ox, y + oy); } 0x53 | 0x73 => { - self.judge_hit_triangle_d(state, x + ox, y + oy); + self.test_hit_upper_right_slope_high(state, x + ox, y + oy); } 0x54 | 0x74 => { - self.judge_hit_triangle_e(state, x + ox, y + oy); + self.test_hit_lower_left_slope_high(state, x + ox, y + oy); } 0x55 | 0x75 => { - self.judge_hit_triangle_f(state, x + ox, y + oy); + self.test_hit_lower_left_slope_low(state, x + ox, y + oy); } 0x56 | 0x76 => { - self.judge_hit_triangle_g(state, x + ox, y + oy); + self.test_hit_lower_right_slope_low(state, x + ox, y + oy); } 0x57 | 0x77 => { - self.judge_hit_triangle_h(state, x + ox, y + oy); + self.test_hit_lower_right_slope_high(state, x + ox, y + oy); } _ => {} } } - self.judge_hit_block_destroy(x, y, &hit_attribs, state); + self.test_hit_block_destructible(x, y, &hit_attribs, state); } }