diff --git a/src/bullet.rs b/src/bullet.rs index 8a018f7..d67df26 100644 --- a/src/bullet.rs +++ b/src/bullet.rs @@ -5,6 +5,7 @@ use crate::common::{BulletFlag, Condition, Direction, Flag, Rect}; use crate::engine_constants::{BulletData, EngineConstants}; use crate::npc::NPCMap; use crate::physics::{OFF_X, OFF_Y, PhysicalEntity}; +use crate::player::TargetPlayer; use crate::shared_game_state::SharedGameState; use crate::stage::Stage; @@ -20,30 +21,30 @@ impl BulletManager { } } - pub fn create_bullet(&mut self, x: isize, y: isize, btype: u16, direction: Direction, constants: &EngineConstants) { - self.bullets.push(Bullet::new(x, y, btype, direction, constants)); + pub fn create_bullet(&mut self, x: isize, y: isize, btype: u16, owner: TargetPlayer, direction: Direction, constants: &EngineConstants) { + self.bullets.push(Bullet::new(x, y, btype, owner, direction, constants)); } - pub fn tick_bullets(&mut self, state: &mut SharedGameState, player: &dyn PhysicalEntity, stage: &mut Stage) { + pub fn tick_bullets(&mut self, state: &mut SharedGameState, players: [&dyn PhysicalEntity; 2], stage: &mut Stage) { for bullet in self.bullets.iter_mut() { if bullet.life < 1 { bullet.cond.set_alive(false); continue; } - bullet.tick(state, player); + bullet.tick(state, players); bullet.tick_map_collisions(state, stage); } self.bullets.retain(|b| !b.is_dead()); } - pub fn count_bullets(&self, btype: u16) -> usize { - self.bullets.iter().filter(|b| b.btype == btype).count() + pub fn count_bullets(&self, btype: u16, player_id: TargetPlayer) -> usize { + self.bullets.iter().filter(|b| b.owner == player_id && b.btype == btype).count() } - pub fn count_bullets_multi(&self, btypes: [u16; 3]) -> usize { - self.bullets.iter().filter(|b| btypes.contains(&b.btype)).count() + pub fn count_bullets_multi(&self, btypes: [u16; 3], player_id: TargetPlayer) -> usize { + self.bullets.iter().filter(|b| b.owner == player_id && btypes.contains(&b.btype)).count() } } @@ -60,6 +61,7 @@ pub struct Bullet { pub life: u16, pub lifetime: u16, pub damage: u16, + pub owner: TargetPlayer, pub cond: Condition, pub weapon_flags: BulletFlag, pub flags: Flag, @@ -76,7 +78,7 @@ pub struct Bullet { } impl Bullet { - pub fn new(x: isize, y: isize, btype: u16, direction: Direction, constants: &EngineConstants) -> Bullet { + pub fn new(x: isize, y: isize, btype: u16, owner: TargetPlayer, direction: Direction, constants: &EngineConstants) -> Bullet { let bullet = constants.weapon.bullet_table .get(btype as usize) .unwrap_or_else(|| &BulletData { @@ -104,6 +106,7 @@ impl Bullet { life: bullet.life as u16, lifetime: bullet.lifetime, damage: bullet.damage as u16, + owner, cond: Condition(0x80), weapon_flags: bullet.flags, flags: Flag(0), @@ -246,7 +249,7 @@ impl Bullet { } } - fn tick_fireball(&mut self, state: &mut SharedGameState, player: &dyn PhysicalEntity) { + fn tick_fireball(&mut self, state: &mut SharedGameState, players: [&dyn PhysicalEntity; 2]) { self.action_counter += 1; if self.action_counter > self.lifetime { self.cond.set_alive(false); @@ -284,7 +287,7 @@ impl Bullet { self.vel_x = 0x400; } Direction::Up => { - self.vel_x = player.vel_x(); + self.vel_x = players[self.owner.index()].vel_x(); self.direction = if self.vel_x < 0 { Direction::Left @@ -292,7 +295,7 @@ impl Bullet { Direction::Right }; - self.vel_x += if player.direction() == Direction::Left { + self.vel_x += if players[self.owner.index()].direction() == Direction::Left { -0x80 } else { 0x80 @@ -301,7 +304,7 @@ impl Bullet { self.vel_y = -0x5ff; } Direction::Bottom => { - self.vel_x = player.vel_x(); + self.vel_x = players[self.owner.index()].vel_x(); self.direction = if self.vel_x < 0 { Direction::Left @@ -365,7 +368,7 @@ impl Bullet { } } - pub fn tick(&mut self, state: &mut SharedGameState, player: &dyn PhysicalEntity) { + pub fn tick(&mut self, state: &mut SharedGameState, players: [&dyn PhysicalEntity; 2]) { if self.lifetime == 0 { self.cond.set_alive(false); return; @@ -374,16 +377,15 @@ impl Bullet { match self.btype { 1 => self.tick_snake_1(state), 4 | 5 | 6 => self.tick_polar_star(state), - 7 | 8 | 9 => self.tick_fireball(state, player), + 7 | 8 | 9 => self.tick_fireball(state, players), _ => self.cond.set_alive(false), } } pub fn vanish(&mut self, state: &mut SharedGameState) { - if self.btype != 37 && self.btype != 38 && self.btype != 39 { - state.sound_manager.play_sfx(28); - } else { - state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Up); + match self.btype { + 37 | 38 | 39 => state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Up), + _ => state.sound_manager.play_sfx(28), } self.cond.set_alive(false); @@ -554,7 +556,7 @@ impl PhysicalEntity for Bullet { false } - fn judge_hit_block(&mut self, state: &mut SharedGameState, x: isize, y: isize) { + fn judge_hit_block(&mut self, _state: &mut SharedGameState, x: isize, y: isize) { if (self.x - self.hit_bounds.left as isize) < (x * 16 + 8) * 0x200 && (self.x + self.hit_bounds.right as isize) > (x * 16 - 8) * 0x200 && (self.y - self.hit_bounds.top as isize) < (y * 16 + 8) * 0x200 diff --git a/src/scene/game_scene.rs b/src/scene/game_scene.rs index 1ff6ff1..84ecfc6 100644 --- a/src/scene/game_scene.rs +++ b/src/scene/game_scene.rs @@ -1062,7 +1062,7 @@ impl GameScene { self.tick_npc_bullet_collissions(state); self.npc_map.process_npc_changes(&self.player1, state); - self.bullet_manager.tick_bullets(state, &self.player1, &mut self.stage); + self.bullet_manager.tick_bullets(state, [&self.player1, &self.player2], &mut self.stage); state.tick_carets(); match self.frame.update_target { @@ -1103,11 +1103,11 @@ impl GameScene { if state.control_flags.control_enabled() { if let Some(weapon) = self.inventory_player1.get_current_weapon_mut() { - weapon.shoot_bullet(&self.player1, &mut self.bullet_manager, state); + weapon.shoot_bullet(&self.player1, TargetPlayer::Player1, &mut self.bullet_manager, state); } if let Some(weapon) = self.inventory_player2.get_current_weapon_mut() { - weapon.shoot_bullet(&self.player2, &mut self.bullet_manager, state); + weapon.shoot_bullet(&self.player2, TargetPlayer::Player2, &mut self.bullet_manager, state); } if self.player1.cond.alive() { diff --git a/src/weapon.rs b/src/weapon.rs index de55347..86b7c0b 100644 --- a/src/weapon.rs +++ b/src/weapon.rs @@ -3,7 +3,7 @@ use num_derive::FromPrimitive; use crate::bullet::BulletManager; use crate::caret::CaretType; use crate::common::Direction; -use crate::player::Player; +use crate::player::{Player, TargetPlayer}; use crate::shared_game_state::SharedGameState; #[derive(Debug, PartialEq, Eq, Copy, Clone, FromPrimitive)] @@ -84,8 +84,8 @@ impl Weapon { false } - fn shoot_bullet_snake(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { - if player.controller.trigger_shoot() && bullet_manager.count_bullets_multi([1, 2, 3]) < 4 { + fn shoot_bullet_snake(&mut self, player: &Player, player_id: TargetPlayer, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + if player.controller.trigger_shoot() && bullet_manager.count_bullets_multi([1, 2, 3], player_id) < 4 { let btype = match self.level { WeaponLevel::Level1 => { 1 } WeaponLevel::Level2 => { 2 } @@ -101,11 +101,11 @@ impl Weapon { if player.up { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 3 * 0x200, player.y - 10 * 0x200, btype, Direction::Up, &state.constants); + bullet_manager.create_bullet(player.x - 3 * 0x200, player.y - 10 * 0x200, btype, player_id, Direction::Up, &state.constants); state.create_caret(player.x - 3 * 0x200, player.y - 10 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 3 * 0x200, player.y - 10 * 0x200, btype, Direction::Up, &state.constants); + bullet_manager.create_bullet(player.x + 3 * 0x200, player.y - 10 * 0x200, btype, player_id, Direction::Up, &state.constants); state.create_caret(player.x + 3 * 0x200, player.y - 10 * 0x200, CaretType::Shoot, Direction::Left); } _ => {} @@ -113,11 +113,11 @@ impl Weapon { } else if player.down { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 3 * 0x200, player.y + 10 * 0x200, btype, Direction::Bottom, &state.constants); + bullet_manager.create_bullet(player.x - 3 * 0x200, player.y + 10 * 0x200, btype, player_id, Direction::Bottom, &state.constants); state.create_caret(player.x - 3 * 0x200, player.y + 10 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 3 * 0x200, player.y + 10 * 0x200, btype, Direction::Bottom, &state.constants); + bullet_manager.create_bullet(player.x + 3 * 0x200, player.y + 10 * 0x200, btype, player_id, Direction::Bottom, &state.constants); state.create_caret(player.x + 3 * 0x200, player.y + 10 * 0x200, CaretType::Shoot, Direction::Left); } _ => {} @@ -125,11 +125,11 @@ impl Weapon { } else { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 2 * 0x200, btype, Direction::Left, &state.constants); + bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 2 * 0x200, btype, player_id, Direction::Left, &state.constants); state.create_caret(player.x - 12 * 0x200, player.y + 2 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 6 * 0x200, player.y + 2 * 0x200, btype, Direction::Right, &state.constants); + bullet_manager.create_bullet(player.x + 6 * 0x200, player.y + 2 * 0x200, btype, player_id, Direction::Right, &state.constants); state.create_caret(player.x + 12 * 0x200, player.y + 2 * 0x200, CaretType::Shoot, Direction::Right); } _ => {} @@ -140,8 +140,8 @@ impl Weapon { } } - fn shoot_bullet_polar_star(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { - if player.controller.trigger_shoot() && bullet_manager.count_bullets_multi([4, 5, 6]) < 2 { + fn shoot_bullet_polar_star(&mut self, player: &Player, player_id: TargetPlayer, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + if player.controller.trigger_shoot() && bullet_manager.count_bullets_multi([4, 5, 6], player_id) < 2 { let btype = match self.level { WeaponLevel::Level1 => { 4 } WeaponLevel::Level2 => { 5 } @@ -157,11 +157,11 @@ impl Weapon { if player.up { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 0x200, player.y - 8 * 0x200, btype, Direction::Up, &state.constants); + bullet_manager.create_bullet(player.x - 0x200, player.y - 8 * 0x200, btype, player_id, Direction::Up, &state.constants); state.create_caret(player.x - 0x200, player.y - 8 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 0x200, player.y - 8 * 0x200, btype, Direction::Up, &state.constants); + bullet_manager.create_bullet(player.x + 0x200, player.y - 8 * 0x200, btype, player_id, Direction::Up, &state.constants); state.create_caret(player.x + 0x200, player.y - 8 * 0x200, CaretType::Shoot, Direction::Left); } _ => {} @@ -169,11 +169,11 @@ impl Weapon { } else if player.down { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 0x200, player.y + 8 * 0x200, btype, Direction::Bottom, &state.constants); + bullet_manager.create_bullet(player.x - 0x200, player.y + 8 * 0x200, btype, player_id, Direction::Bottom, &state.constants); state.create_caret(player.x - 0x200, player.y + 8 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 0x200, player.y + 8 * 0x200, btype, Direction::Bottom, &state.constants); + bullet_manager.create_bullet(player.x + 0x200, player.y + 8 * 0x200, btype, player_id, Direction::Bottom, &state.constants); state.create_caret(player.x + 0x200, player.y + 8 * 0x200, CaretType::Shoot, Direction::Left); } _ => {} @@ -181,11 +181,11 @@ impl Weapon { } else { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 3 * 0x200, btype, Direction::Left, &state.constants); + bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 3 * 0x200, btype, player_id, Direction::Left, &state.constants); state.create_caret(player.x - 6 * 0x200, player.y + 3 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 6 * 0x200, player.y + 3 * 0x200, btype, Direction::Right, &state.constants); + bullet_manager.create_bullet(player.x + 6 * 0x200, player.y + 3 * 0x200, btype, player_id, Direction::Right, &state.constants); state.create_caret(player.x + 6 * 0x200, player.y + 3 * 0x200, CaretType::Shoot, Direction::Right); } _ => {} @@ -201,9 +201,9 @@ impl Weapon { } - fn shoot_bullet_fireball(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + fn shoot_bullet_fireball(&mut self, player: &Player, player_id: TargetPlayer, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { let max_bullets = self.level as usize + 1; - if player.controller.trigger_shoot() && bullet_manager.count_bullets_multi([7, 8, 9]) < max_bullets { + if player.controller.trigger_shoot() && bullet_manager.count_bullets_multi([7, 8, 9], player_id) < max_bullets { let btype = match self.level { WeaponLevel::Level1 => { 7 } WeaponLevel::Level2 => { 8 } @@ -219,11 +219,11 @@ impl Weapon { if player.up { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 4 * 0x200, player.y - 8 * 0x200, btype, Direction::Up, &state.constants); + bullet_manager.create_bullet(player.x - 4 * 0x200, player.y - 8 * 0x200, btype, player_id, Direction::Up, &state.constants); state.create_caret(player.x - 4 * 0x200, player.y - 8 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 4 * 0x200, player.y - 8 * 0x200, btype, Direction::Up, &state.constants); + bullet_manager.create_bullet(player.x + 4 * 0x200, player.y - 8 * 0x200, btype, player_id, Direction::Up, &state.constants); state.create_caret(player.x + 4 * 0x200, player.y - 8 * 0x200, CaretType::Shoot, Direction::Left); } _ => {} @@ -231,11 +231,11 @@ impl Weapon { } else if player.down { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 4 * 0x200, player.y + 8 * 0x200, btype, Direction::Bottom, &state.constants); + bullet_manager.create_bullet(player.x - 4 * 0x200, player.y + 8 * 0x200, btype, player_id, Direction::Bottom, &state.constants); state.create_caret(player.x - 4 * 0x200, player.y + 8 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 4 * 0x200, player.y + 8 * 0x200, btype, Direction::Bottom, &state.constants); + bullet_manager.create_bullet(player.x + 4 * 0x200, player.y + 8 * 0x200, btype, player_id, Direction::Bottom, &state.constants); state.create_caret(player.x + 4 * 0x200, player.y + 8 * 0x200, CaretType::Shoot, Direction::Left); } _ => {} @@ -243,11 +243,11 @@ impl Weapon { } else { match player.direction { Direction::Left => { - bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 2 * 0x200, btype, Direction::Left, &state.constants); + bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 2 * 0x200, btype, player_id, Direction::Left, &state.constants); state.create_caret(player.x - 12 * 0x200, player.y + 2 * 0x200, CaretType::Shoot, Direction::Left); } Direction::Right => { - bullet_manager.create_bullet(player.x + 6 * 0x200, player.y + 2 * 0x200, btype, Direction::Right, &state.constants); + bullet_manager.create_bullet(player.x + 6 * 0x200, player.y + 2 * 0x200, btype, player_id, Direction::Right, &state.constants); state.create_caret(player.x + 12 * 0x200, player.y + 2 * 0x200, CaretType::Shoot, Direction::Right); } _ => {} @@ -258,16 +258,16 @@ impl Weapon { } } - pub fn shoot_bullet(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { - if player.cond.hidden() { + pub fn shoot_bullet(&mut self, player: &Player, player_id: TargetPlayer, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + if !player.cond.alive() || player.cond.hidden() { return; } match self.wtype { WeaponType::None => {} - WeaponType::Snake => self.shoot_bullet_snake(player, bullet_manager, state), - WeaponType::PolarStar => self.shoot_bullet_polar_star(player, bullet_manager, state), - WeaponType::Fireball => self.shoot_bullet_fireball(player, bullet_manager, state), + WeaponType::Snake => self.shoot_bullet_snake(player, player_id, bullet_manager, state), + WeaponType::PolarStar => self.shoot_bullet_polar_star(player, player_id, bullet_manager, state), + WeaponType::Fireball => self.shoot_bullet_fireball(player, player_id, bullet_manager, state), WeaponType::MachineGun => {} WeaponType::MissileLauncher => {} WeaponType::Bubbler => {}