From 5909fedf336ab6292d6d85f11fefe1dfb2a82461 Mon Sep 17 00:00:00 2001 From: dawnDus <96957561+dawndus@users.noreply.github.com> Date: Thu, 24 Feb 2022 21:00:10 -0500 Subject: [PATCH] Fixed fireball sfx and missiles going through walls (#37) --- src/common.rs | 4 ++-- src/physics.rs | 32 ++++++++++++++++----------- src/weapon/bullet.rs | 51 ++++++++++++++++++++++---------------------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/common.rs b/src/common.rs index ef5bf9a..2298748 100644 --- a/src/common.rs +++ b/src/common.rs @@ -39,9 +39,9 @@ bitfield! { /// Set if entity stays on left slope. (corresponds to flag & 0x20) pub hit_left_slope, set_hit_left_slope: 5; /// Used only in bullet code, set if a bullet hits upper right slope (corresponds to flag & 0x40) - pub hit_right_upper_slope, set_hit_right_upper_slope: 6; + pub hit_upper_right_slope, set_hit_upper_right_slope: 6; /// Used only in bullet code, set if a bullet hits upper left slope (corresponds to flag & 0x80) - pub hit_left_upper_slope, set_hit_left_upper_slope: 7; + pub hit_upper_left_slope, set_hit_upper_left_slope: 7; /// Set if entity is in water. (corresponds to flag & 0x100) pub in_water, set_in_water: 8; pub weapon_hit_block, set_weapon_hit_block: 9; // 0x200 diff --git a/src/physics.rs b/src/physics.rs index da9ff46..93993cb 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -126,7 +126,8 @@ pub trait PhysicalEntity { let half_tile_size = state.tile_size.as_int() * 0x100; if (self.y() - self.hit_bounds().top as i32) < ((y * 2 + 1) * half_tile_size - bounds_top) - && (self.y() + self.hit_bounds().bottom as i32) > ((y * 2 - 1) * half_tile_size + bounds_bottom) { + && (self.y() + self.hit_bounds().bottom as i32) > ((y * 2 - 1) * half_tile_size + bounds_bottom) + { // left wall if (self.x() - self.hit_bounds().right as i32) < (x * 2 + 1) * half_tile_size && (self.x() - self.hit_bounds().right as i32) > (x * 2) * half_tile_size @@ -167,7 +168,8 @@ pub trait PhysicalEntity { } if ((self.x() - self.hit_bounds().right as i32) < (x * 2 + 1) * half_tile_size - bounds_x) - && ((self.x() + self.hit_bounds().right as i32) > (x * 2 - 1) * half_tile_size + bounds_x) { + && ((self.x() + self.hit_bounds().right as i32) > (x * 2 - 1) * half_tile_size + bounds_x) + { // ceiling if (self.y() - self.hit_bounds().top as i32) < (y * 2 + 1) * half_tile_size && (self.y() - self.hit_bounds().top as i32) > (y * 2) * half_tile_size @@ -287,6 +289,7 @@ pub trait PhysicalEntity { } self.flags().set_hit_top_wall(true); + self.flags().set_hit_upper_left_slope(true); } } @@ -327,6 +330,7 @@ pub trait PhysicalEntity { } self.flags().set_hit_top_wall(true); + self.flags().set_hit_upper_left_slope(true); } } @@ -367,6 +371,7 @@ pub trait PhysicalEntity { } self.flags().set_hit_top_wall(true); + self.flags().set_hit_upper_right_slope(true); } } @@ -407,6 +412,7 @@ pub trait PhysicalEntity { } self.flags().set_hit_top_wall(true); + self.flags().set_hit_upper_right_slope(true); } } @@ -551,9 +557,7 @@ pub trait PhysicalEntity { && (self.y() - self.hit_bounds().top as i32) < (y * tile_size) - (self.x() - x * tile_size) && (self.y() + self.hit_bounds().bottom as i32) > (y * 2 - 1) * half_tile_size { - self.set_y( - (y * tile_size) - (self.x() - x * tile_size) + self.hit_bounds().top as i32 - ); + self.set_y((y * tile_size) - (self.x() - x * tile_size) + self.hit_bounds().top as i32); if self.is_player() && !self.cond().hidden() && self.vel_y() < -0x200 { state.sound_manager.play_sfx(3); @@ -589,9 +593,7 @@ pub trait PhysicalEntity { && (self.y() - self.hit_bounds().top as i32) < (y * tile_size) + (self.x() - x * tile_size) && (self.y() + self.hit_bounds().bottom as i32) > (y * 2 - 1) * half_tile_size { - self.set_y( - (y * tile_size) + (self.x() - x * tile_size) + self.hit_bounds().top as i32 - ); + self.set_y((y * tile_size) + (self.x() - x * tile_size) + self.hit_bounds().top as i32); if self.is_player() && !self.cond().hidden() && self.vel_y() < -0x200 { state.sound_manager.play_sfx(3); @@ -627,10 +629,13 @@ pub trait PhysicalEntity { if self.x() < (x * 2 + 1) * half_tile_size && self.x() > (x * 2 - 1) * half_tile_size - && (self.y() + self.hit_bounds().bottom as i32) > (y * tile_size) + (self.x() - x * tile_size) - quarter_tile_size + && (self.y() + self.hit_bounds().bottom as i32) + > (y * tile_size) + (self.x() - x * tile_size) - quarter_tile_size && (self.y() - self.hit_bounds().top as i32) < (y * 2 + 1) * half_tile_size { - self.set_y((y * tile_size) + (self.x() - x * tile_size) - quarter_tile_size - self.hit_bounds().bottom as i32); + self.set_y( + (y * tile_size) + (self.x() - x * tile_size) - quarter_tile_size - self.hit_bounds().bottom as i32, + ); if self.is_player() && self.vel_y() > 0x400 { state.sound_manager.play_sfx(23); @@ -655,10 +660,13 @@ pub trait PhysicalEntity { if (self.x() < (x * 2 + 1) * half_tile_size) && (self.x() > (x * 2 - 1) * half_tile_size) - && (self.y() + self.hit_bounds().bottom as i32) > (y * tile_size) - (self.x() - x * tile_size) - quarter_tile_size + && (self.y() + self.hit_bounds().bottom as i32) + > (y * tile_size) - (self.x() - x * tile_size) - quarter_tile_size && (self.y() - self.hit_bounds().top as i32) < (y * 2 + 1) * half_tile_size { - self.set_y((y * tile_size) - (self.x() - x * tile_size) - quarter_tile_size - self.hit_bounds().bottom as i32); + self.set_y( + (y * tile_size) - (self.x() - x * tile_size) - quarter_tile_size - self.hit_bounds().bottom as i32, + ); if self.is_player() && self.vel_y() > 0x400 { state.sound_manager.play_sfx(23); diff --git a/src/weapon/bullet.rs b/src/weapon/bullet.rs index 542ea14..68528dc 100644 --- a/src/weapon/bullet.rs +++ b/src/weapon/bullet.rs @@ -580,10 +580,10 @@ impl Bullet { _ if self.life != 10 => true, Direction::Left if self.flags.hit_left_wall() => true, Direction::Left if self.flags.hit_left_slope() => true, - Direction::Left if self.flags.hit_left_upper_slope() => true, + Direction::Left if self.flags.hit_upper_left_slope() => true, Direction::Right if self.flags.hit_right_wall() => true, Direction::Right if self.flags.hit_right_slope() => true, - Direction::Right if self.flags.hit_right_upper_slope() => true, + Direction::Right if self.flags.hit_upper_right_slope() => true, Direction::Up if self.flags.hit_top_wall() => true, Direction::Bottom if self.flags.hit_bottom_wall() => true, _ => false, @@ -1213,10 +1213,10 @@ impl Bullet { _ if self.life != 10 => true, Direction::Left if self.flags.hit_left_wall() => true, Direction::Left if self.flags.hit_left_slope() => true, - Direction::Left if self.flags.hit_left_upper_slope() => true, + Direction::Left if self.flags.hit_upper_left_slope() => true, Direction::Right if self.flags.hit_right_wall() => true, Direction::Right if self.flags.hit_right_slope() => true, - Direction::Right if self.flags.hit_right_upper_slope() => true, + Direction::Right if self.flags.hit_upper_right_slope() => true, Direction::Up if self.flags.hit_top_wall() => true, Direction::Bottom if self.flags.hit_bottom_wall() => true, _ => false, @@ -1241,14 +1241,14 @@ impl Bullet { Direction::Left | Direction::Right => { self.target_y = self.y; self.enemy_hit_height = 0x1000; - self.hit_bounds.top = 0x1000; - self.hit_bounds.bottom = 0x1000; + self.hit_bounds.left = 0x1000; + self.hit_bounds.right = 0x1000; } Direction::Up | Direction::Bottom => { self.target_x = self.x; self.enemy_hit_width = 0x1000; - self.hit_bounds.left = 0x1000; - self.hit_bounds.right = 0x1000; + self.hit_bounds.top = 0x1000; + self.hit_bounds.bottom = 0x1000; } _ => {} } @@ -1470,7 +1470,6 @@ impl Bullet { Direction::Bottom => self.vel_y = 0x1000, Direction::FacingPlayer => unreachable!(), } - } else { if self.action_counter % 4 == 1 { let mut npc = NPC::create(4, &state.npc_table); @@ -1705,6 +1704,7 @@ impl Bullet { fn test_hit_block_destructible(&mut self, x: i32, y: i32, attributes: &[u8; 16], state: &mut SharedGameState) { let mut hits = [false; 16]; + let mut temp_flags = Flag(0); let (block_x, block_y, max_attr) = match state.tile_size { TileSize::Tile8x8 => ((x * 2 + 1) * 0x800, (y * 2 + 1) * 0x800, 4), @@ -1726,87 +1726,88 @@ impl Bullet { // left wall if hits[0] && hits[2] { if (self.x - self.hit_bounds.left as i32) < block_x { - self.flags.set_hit_left_wall(true); + temp_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 - (0x600) { - self.flags.set_hit_left_wall(true); + temp_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 + (0x600) { - self.flags.set_hit_left_wall(true); + temp_flags.set_hit_left_wall(true); } // right wall if hits[1] && hits[3] { if (self.x + self.hit_bounds.right as i32) > block_x { - self.flags.set_hit_right_wall(true); + temp_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 - (0x600) { - self.flags.set_hit_right_wall(true); + temp_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 + (0x600) { - self.flags.set_hit_right_wall(true); + temp_flags.set_hit_right_wall(true); } // ceiling if hits[0] && hits[1] { if (self.y - self.hit_bounds.top as i32) < block_y { - self.flags.set_hit_top_wall(true); + temp_flags.set_hit_top_wall(true); } } else if hits[0] && !hits[1] { 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); + temp_flags.set_hit_top_wall(true); } } 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); + temp_flags.set_hit_top_wall(true); } // ground if hits[2] && hits[3] { if (self.y + self.hit_bounds.bottom as i32) > block_y { - self.flags.set_hit_bottom_wall(true); + temp_flags.set_hit_bottom_wall(true); } } else if hits[2] && !hits[3] { 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); + temp_flags.set_hit_bottom_wall(true); } } 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); + temp_flags.set_hit_bottom_wall(true); } + self.flags.0 |= temp_flags.0; if self.weapon_flags.bounce_from_walls() { - if self.flags.hit_left_wall() { + if temp_flags.hit_left_wall() { self.x = block_x + self.hit_bounds.right as i32; - } else if self.flags.hit_right_wall() { + } else if temp_flags.hit_right_wall() { self.x = block_x - self.hit_bounds.left as i32; - } else if self.flags.hit_top_wall() { + } else if temp_flags.hit_top_wall() { self.y = block_y + self.hit_bounds.bottom as i32; - } else if self.flags.hit_bottom_wall() { + } else if temp_flags.hit_bottom_wall() { self.y = block_y - self.hit_bounds.top as i32; } } else if self.flags.hit_left_wall()