From fbb4045f4721a9329b2a22ba55d21998c15dadd3 Mon Sep 17 00:00:00 2001 From: Alula Date: Fri, 2 Oct 2020 03:30:42 +0200 Subject: [PATCH] add fireball and snake --- src/bullet.rs | 129 ++++++++++++++++++++++++++++------------ src/engine_constants.rs | 63 ++++++++++++++++++++ src/npc/mod.rs | 6 +- src/npc/sand_zone.rs | 0 src/npc/weapon_trail.rs | 31 ++++++++++ src/scene/game_scene.rs | 2 +- src/weapon.rs | 124 ++++++++++++++++++++++++++++++++++++-- 7 files changed, 310 insertions(+), 45 deletions(-) create mode 100644 src/npc/sand_zone.rs create mode 100644 src/npc/weapon_trail.rs diff --git a/src/bullet.rs b/src/bullet.rs index 907620b..0689950 100644 --- a/src/bullet.rs +++ b/src/bullet.rs @@ -59,8 +59,8 @@ pub struct Bullet { pub lifetime: u16, pub damage: u16, pub cond: Condition, + pub weapon_flags: Flag, pub flags: Flag, - pub hit_flags: Flag, pub direction: Direction, pub anim_rect: Rect, pub enemy_hit_width: u32, @@ -101,8 +101,8 @@ impl Bullet { lifetime: bullet.lifetime, damage: bullet.damage as u16, cond: Condition(0x80), - flags: bullet.flags, - hit_flags: Flag(0), + weapon_flags: bullet.flags, + flags: Flag(0), direction, anim_rect: Rect::new(0, 0, 0, 0), enemy_hit_width: bullet.enemy_hit_width as u32 * 0x200, @@ -131,6 +131,38 @@ impl Bullet { !self.cond.alive() } + fn tick_snake_1(&mut self, state: &mut SharedGameState) { + self.action_counter += 1; + if self.action_counter > self.lifetime { + self.cond.set_alive(false); + state.create_caret(self.x, self.y, CaretType::Shoot, Direction::Left); + return; + } + + if self.action_num == 0 { + self.action_num = 1; + self.anim_num = state.game_rng.range(0..2) as u16; + + match self.direction { + Direction::Left => self.vel_x = -0x600, + Direction::Up => self.vel_y = -0x600, + Direction::Right => self.vel_x = 0x600, + Direction::Bottom => self.vel_y = 0x600, + Direction::FacingPlayer => unreachable!(), + } + } else { + self.x += self.vel_x; + self.y += self.vel_y; + } + + self.anim_num = (self.anim_num + 1) % 3; + + + let dir_offset = if self.direction == Direction::Left { 0 } else { 4 }; + + self.anim_rect = state.constants.weapon.bullet_rects.b001_snake_l1[self.anim_num as usize + dir_offset]; + } + fn tick_polar_star(&mut self, state: &mut SharedGameState) { self.action_counter += 1; if self.action_counter > self.lifetime { @@ -223,7 +255,7 @@ impl Bullet { || (self.flags.hit_top_wall() && self.flags.hit_bottom_wall()) { self.cond.set_alive(false); state.create_caret(self.x, self.y, CaretType::ProjectileDissipation, Direction::Left); - // todo play sound 28 + state.sound_manager.play_sfx(28); return; } @@ -296,30 +328,51 @@ impl Bullet { self.y += self.vel_y; if self.flags.hit_left_wall() || self.flags.hit_right_wall() || self.flags.hit_bottom_wall() { - // todo play sound 34 + state.sound_manager.play_sfx(34); } } self.anim_num += 1; if self.btype == 7 { // level 1 + if self.anim_num > 3 { + self.anim_num = 0; + } + + let dir_offset = if self.direction == Direction::Left { 0 } else { 4 }; + + self.anim_rect = state.constants.weapon.bullet_rects.b007_fireball_l1[self.anim_num as usize + dir_offset]; + } else { + if self.anim_num > 2 { + self.anim_num = 0; + } + + let dir_offset = if self.direction == Direction::Left { 0 } else { 3 }; + + self.anim_rect = state.constants.weapon.bullet_rects.b008_009_fireball_l2_3[self.anim_num as usize + dir_offset]; + + let mut npc = NPCMap::create_npc(129, &state.npc_table); + npc.cond.set_alive(true); + npc.x = self.x; + npc.y = self.y; + npc.vel_y = -0x200; + npc.action_counter2 = if self.btype == 9 { self.anim_num + 3 } else { self.anim_num }; + + state.new_npcs.push(npc); } } - pub fn tick(&mut self, state: &mut SharedGameState, player: &PhysicalEntity) { + pub fn tick(&mut self, state: &mut SharedGameState, player: &dyn PhysicalEntity) { if self.lifetime == 0 { self.cond.set_alive(false); return; } match self.btype { - 4 | 5 | 6 => { - self.tick_polar_star(state); - } - 7 | 8 | 9 => { - self.tick_fireball(state, player); - } - _ => { self.cond.set_alive(false); } + 1 => self.tick_snake_1(state), + 4 | 5 | 6 => self.tick_polar_star(state), + 7 | 8 | 9 => self.tick_fireball(state, player), + _ => self.cond.set_alive(false), } } @@ -340,7 +393,7 @@ impl Bullet { let block_y = (y * 16 + 8) * 0x200; for (i, &attr) in hit_attribs.iter().enumerate() { - if self.flags.snack_destroy() { + if self.weapon_flags.snack_destroy() { hits[i] = attr == 0x41 || attr == 0x61; } else { hits[i] = attr == 0x41 || attr == 0x43 || attr == 0x61; @@ -350,79 +403,79 @@ impl Bullet { // left wall if hits[0] && hits[2] { if (self.x - self.hit_bounds.left as isize) < block_x { - self.hit_flags.set_hit_left_wall(true); + self.flags.set_hit_left_wall(true); } } else if hits[0] && !hits[2] { if (self.x - self.hit_bounds.left as isize) < block_x && (self.y - self.hit_bounds.top as isize) < block_y - (3 * 0x200) { - self.hit_flags.set_hit_left_wall(true); + self.flags.set_hit_left_wall(true); } } else if !hits[0] && hits[2] && (self.x - self.hit_bounds.left as isize) < block_x && (self.y + self.hit_bounds.top as isize) > block_y + (3 * 0x200) { - self.hit_flags.set_hit_left_wall(true); + self.flags.set_hit_left_wall(true); } // right wall if hits[1] && hits[3] { if (self.x + self.hit_bounds.right as isize) > block_x { - self.hit_flags.set_hit_right_wall(true); + self.flags.set_hit_right_wall(true); } } else if hits[1] && !hits[3] { if (self.x + self.hit_bounds.right as isize) > block_x && (self.y - self.hit_bounds.top as isize) < block_y - (3 * 0x200) { - self.hit_flags.set_hit_right_wall(true); + self.flags.set_hit_right_wall(true); } } else if !hits[1] && hits[3] && (self.x + self.hit_bounds.right as isize) > block_x && (self.y + self.hit_bounds.top as isize) > block_y + (3 * 0x200) { - self.hit_flags.set_hit_right_wall(true); + self.flags.set_hit_right_wall(true); } // ceiling if hits[0] && hits[1] { if (self.y - self.hit_bounds.top as isize) < block_y { - self.hit_flags.set_hit_top_wall(true); + self.flags.set_hit_top_wall(true); } } else if hits[0] && !hits[1] { if (self.x - self.hit_bounds.left as isize) < block_x - (3 * 0x200) && (self.y - self.hit_bounds.top as isize) < block_y { - self.hit_flags.set_hit_top_wall(true); + self.flags.set_hit_top_wall(true); } } else if !hits[0] && hits[1] && (self.x + self.hit_bounds.right as isize) > block_x + (3 * 0x200) && (self.y - self.hit_bounds.top as isize) < block_y { - self.hit_flags.set_hit_top_wall(true); + self.flags.set_hit_top_wall(true); } // ground if hits[2] && hits[3] { if (self.y + self.hit_bounds.bottom as isize) > block_y { - self.hit_flags.set_hit_bottom_wall(true); + self.flags.set_hit_bottom_wall(true); } } else if hits[2] && !hits[3] { if (self.x - self.hit_bounds.left as isize) < block_x - (3 * 0x200) && (self.y + self.hit_bounds.bottom as isize) > block_y { - self.hit_flags.set_hit_bottom_wall(true); + self.flags.set_hit_bottom_wall(true); } } else if !hits[2] && hits[3] && (self.x + self.hit_bounds.right as isize) > block_x + (3 * 0x200) && (self.y + self.hit_bounds.bottom as isize) > block_y { - self.hit_flags.set_hit_bottom_wall(true); + self.flags.set_hit_bottom_wall(true); } - if self.flags.hit_bottom_wall() { - if self.hit_flags.hit_left_wall() { + if self.weapon_flags.hit_bottom_wall() { + if self.flags.hit_left_wall() { self.x = block_x + self.hit_bounds.right as isize; - } else if self.hit_flags.hit_right_wall() { + } else if self.flags.hit_right_wall() { self.x = block_x + self.hit_bounds.left as isize; - } else if self.hit_flags.hit_left_wall() { + } else if self.flags.hit_left_wall() { self.x = block_x + self.hit_bounds.right as isize; - } else if self.hit_flags.hit_right_wall() { + } else if self.flags.hit_right_wall() { self.x = block_x + self.hit_bounds.left as isize; } - } else if self.hit_flags.hit_left_wall() || self.hit_flags.hit_top_wall() - || self.hit_flags.hit_right_wall() || self.hit_flags.hit_bottom_wall() { + } else if self.flags.hit_left_wall() || self.flags.hit_top_wall() + || self.flags.hit_right_wall() || self.flags.hit_bottom_wall() { self.vanish(state); } } @@ -485,7 +538,7 @@ impl PhysicalEntity for Bullet { #[inline(always)] fn flags(&mut self) -> &mut Flag { - &mut self.hit_flags + &mut self.flags } #[inline(always)] @@ -504,7 +557,7 @@ impl PhysicalEntity for Bullet { && (self.y - self.hit_bounds.top as isize) < (y * 16 + 8) * 0x200 && (self.y + self.hit_bounds.bottom as isize) > (y * 16 - 8) * 0x200 { - self.hit_flags.set_weapon_hit_block(true); + self.flags.set_weapon_hit_block(true); } } @@ -514,7 +567,7 @@ impl PhysicalEntity for Bullet { let mut hit_attribs = [0u8; 4]; self.flags().0 = 0; - if self.flags.hit_right_wall() { // ??? + if self.weapon_flags.hit_right_wall() { // ??? return; } @@ -534,8 +587,8 @@ impl PhysicalEntity for Bullet { 0x43 => { self.judge_hit_block(state, x + ox, y + oy); - if self.hit_flags.0 != 0 && (self.flags.hit_left_slope() || self.flags.snack_destroy()) { - if !self.flags.snack_destroy() { + if self.flags.0 != 0 && (self.weapon_flags.hit_left_slope() || self.weapon_flags.snack_destroy()) { + if !self.weapon_flags.snack_destroy() { self.cond.set_alive(false); } diff --git a/src/engine_constants.rs b/src/engine_constants.rs index 2b88137..eca5bfd 100644 --- a/src/engine_constants.rs +++ b/src/engine_constants.rs @@ -104,9 +104,13 @@ pub struct BulletData { #[derive(Debug, Copy, Clone)] pub struct BulletRects { + pub b001_snake_l1: [Rect; 8], + pub b002_003_snake_l2_3: [Rect; 3], pub b004_polar_star_l1: [Rect; 2], pub b005_polar_star_l2: [Rect; 2], pub b006_polar_star_l3: [Rect; 2], + pub b007_fireball_l1: [Rect; 8], + pub b008_009_fireball_l2_3: [Rect; 6], pub b037_spur_l1: [Rect; 2], pub b038_spur_l2: [Rect; 2], pub b039_spur_l3: [Rect; 2], @@ -201,6 +205,7 @@ pub struct NPCConsts { pub n077_yamashita: [Rect; 3], pub n078_pot: [Rect; 2], pub n079_mahin: [Rect; 6], + pub n129_fireball_snake_trail: [Rect; 18], pub n211_small_spikes: [Rect; 4], } @@ -984,6 +989,31 @@ impl EngineConstants { Rect { left: 16, top: 16, right: 32, bottom: 32 }, Rect { left: 32, top: 16, right: 48, bottom: 32 }, ], + n129_fireball_snake_trail: [ + Rect { left: 128, top: 48, right: 144, bottom: 64 }, + Rect { left: 144, top: 48, right: 160, bottom: 64 }, + Rect { left: 160, top: 48, right: 176, bottom: 64 }, + + Rect { left: 128, top: 64, right: 144, bottom: 80 }, + Rect { left: 144, top: 64, right: 160, bottom: 80 }, + Rect { left: 160, top: 64, right: 176, bottom: 80 }, + + Rect { left: 128, top: 80, right: 144, bottom: 96 }, + Rect { left: 144, top: 80, right: 160, bottom: 96 }, + Rect { left: 160, top: 80, right: 176, bottom: 96 }, + + Rect { left: 176, top: 48, right: 192, bottom: 64 }, + Rect { left: 192, top: 48, right: 208, bottom: 64 }, + Rect { left: 208, top: 48, right: 224, bottom: 64 }, + + Rect { left: 176, top: 64, right: 192, bottom: 80 }, + Rect { left: 192, top: 64, right: 208, bottom: 80 }, + Rect { left: 208, top: 64, right: 224, bottom: 80 }, + + Rect { left: 176, top: 80, right: 192, bottom: 96 }, + Rect { left: 192, top: 80, right: 208, bottom: 96 }, + Rect { left: 208, top: 80, right: 224, bottom: 96 }, + ], n211_small_spikes: [ Rect { left: 256, top: 200, right: 272, bottom: 216 }, Rect { left: 272, top: 200, right: 288, bottom: 216 }, @@ -1061,6 +1091,21 @@ impl EngineConstants { BulletData { damage: 1, life: 1, lifetime: 1, flags: Flag(36), enemy_hit_width: 1, enemy_hit_height: 1, block_hit_width: 1, block_hit_height: 1, display_bounds: Rect { left: 1, top: 1, right: 1, bottom: 1 } }, ], bullet_rects: BulletRects { + b001_snake_l1: [ + Rect { left: 136, top: 80, right: 152, bottom: 80 }, // left + Rect { left: 120, top: 80, right: 136, bottom: 96 }, + Rect { left: 136, top: 64, right: 152, bottom: 80 }, + Rect { left: 120, top: 64, right: 136, bottom: 80 }, + Rect { left: 120, top: 64, right: 136, bottom: 80 }, // right + Rect { left: 136, top: 64, right: 152, bottom: 80 }, + Rect { left: 120, top: 80, right: 136, bottom: 96 }, + Rect { left: 136, top: 80, right: 152, bottom: 80 }, + ], + b002_003_snake_l2_3: [ + Rect { left: 192, top: 16, right: 208, bottom: 32 }, + Rect { left: 208, top: 16, right: 224, bottom: 32 }, + Rect { left: 224, top: 16, right: 240, bottom: 32 }, + ], b004_polar_star_l1: [ Rect { left: 128, top: 32, right: 144, bottom: 48 }, // horizontal Rect { left: 144, top: 32, right: 160, bottom: 48 }, // vertical @@ -1073,6 +1118,24 @@ impl EngineConstants { Rect { left: 128, top: 48, right: 144, bottom: 64 }, // horizontal Rect { left: 144, top: 48, right: 160, bottom: 64 }, // vertical ], + b007_fireball_l1: [ + Rect { left: 128, top: 0, right: 144, bottom: 16 }, // left + Rect { left: 144, top: 0, right: 160, bottom: 16 }, + Rect { left: 160, top: 0, right: 176, bottom: 16 }, + Rect { left: 176, top: 0, right: 192, bottom: 16 }, + Rect { left: 128, top: 16, right: 144, bottom: 32 }, // right + Rect { left: 144, top: 16, right: 160, bottom: 32 }, + Rect { left: 160, top: 16, right: 176, bottom: 32 }, + Rect { left: 176, top: 16, right: 192, bottom: 32 }, + ], + b008_009_fireball_l2_3: [ + Rect { left: 192, top: 16, right: 208, bottom: 32 }, // left + Rect { left: 208, top: 16, right: 224, bottom: 32 }, + Rect { left: 224, top: 16, right: 240, bottom: 32 }, + Rect { left: 224, top: 16, right: 240, bottom: 32 }, // right + Rect { left: 208, top: 16, right: 224, bottom: 32 }, + Rect { left: 192, top: 16, right: 208, bottom: 32 }, + ], b037_spur_l1: [ Rect { left: 128, top: 32, right: 144, bottom: 48 }, // horizontal Rect { left: 144, top: 32, right: 160, bottom: 48 }, // vertical diff --git a/src/npc/mod.rs b/src/npc/mod.rs index ad95699..f4fbe14 100644 --- a/src/npc/mod.rs +++ b/src/npc/mod.rs @@ -26,11 +26,14 @@ pub mod balrog; pub mod characters; pub mod egg_corridor; pub mod first_cave; +pub mod grasstown; pub mod mimiga_village; pub mod misc; pub mod misery; pub mod pickups; +pub mod sand_zone; pub mod toroko; +pub mod weapon_trail; bitfield! { #[derive(Clone, Copy)] @@ -87,7 +90,7 @@ pub struct NPC { pub anim_rect: Rect, } -static PARTICLE_NPCS: [u16; 4] = [1, 4, 73, 355]; +static PARTICLE_NPCS: [u16; 5] = [1, 4, 73, 129, 355]; impl NPC { pub fn get_start_index(&self) -> u16 { @@ -155,6 +158,7 @@ impl GameEntity<(&mut Player, &HashMap>, &mut Stage)> for NPC 77 => { self.tick_n077_yamashita(state) } 78 => { self.tick_n078_pot(state) } 79 => { self.tick_n079_mahin(state, player) } + 129 => { self.tick_n129_fireball_snake_trail(state) } 211 => { self.tick_n211_small_spikes(state) } _ => { Ok(()) } }?; diff --git a/src/npc/sand_zone.rs b/src/npc/sand_zone.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/npc/weapon_trail.rs b/src/npc/weapon_trail.rs new file mode 100644 index 0000000..e4ae889 --- /dev/null +++ b/src/npc/weapon_trail.rs @@ -0,0 +1,31 @@ +use nalgebra::clamp; + +use crate::common::Direction; +use crate::ggez::GameResult; +use crate::npc::NPC; +use crate::shared_game_state::SharedGameState; + +impl NPC { + pub(crate) fn tick_n129_fireball_snake_trail(&mut self, state: &mut SharedGameState) -> GameResult { + self.anim_counter += 1; + + if self.anim_counter > 1 { + self.anim_counter = 0; + + self.anim_num += 1; + if self.anim_num > 2 { + self.cond.set_alive(false); + return Ok(()); + } + } + + self.y += self.vel_y; + + if self.anim_counter == 1 { + let frame = (self.action_counter2 as usize % 6) * 3 + self.anim_num as usize; + self.anim_rect = state.constants.npc.n129_fireball_snake_trail[frame]; + } + + Ok(()) + } +} diff --git a/src/scene/game_scene.rs b/src/scene/game_scene.rs index 3f31cd6..e951fab 100644 --- a/src/scene/game_scene.rs +++ b/src/scene/game_scene.rs @@ -808,7 +808,7 @@ impl GameScene { // todo show damage } } - } else if !bullet.flags.hit_right_slope() + } else if !bullet.weapon_flags.hit_right_slope() && bullet.btype != 13 && bullet.btype != 14 && bullet.btype != 15 && bullet.btype != 28 && bullet.btype != 29 && bullet.btype != 30 { state.create_caret((bullet.x + npc.x) / 2, (bullet.y + npc.y) / 2, CaretType::ProjectileDissipation, Direction::Right); diff --git a/src/weapon.rs b/src/weapon.rs index 452e947..42823b6 100644 --- a/src/weapon.rs +++ b/src/weapon.rs @@ -6,7 +6,7 @@ use crate::common::Direction; use crate::player::Player; use crate::shared_game_state::SharedGameState; -#[derive(PartialEq, Eq, Copy, Clone, FromPrimitive)] +#[derive(Debug, PartialEq, Eq, Copy, Clone, FromPrimitive)] #[repr(u8)] pub enum WeaponType { None = 0, @@ -84,7 +84,63 @@ impl Weapon { false } - pub fn shoot_bullet_polar_star(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + fn shoot_bullet_snake(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + if state.key_trigger.fire() && bullet_manager.count_bullets_multi([1, 2, 3]) < 4 { + let btype = match self.level { + WeaponLevel::Level1 => { 1 } + WeaponLevel::Level2 => { 2 } + WeaponLevel::Level3 => { 3 } + WeaponLevel::None => { unreachable!() } + }; + + if !self.consume_ammo(1) { + // todo switch to first weapon + return; + } + + 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); + 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); + state.create_caret(player.x + 3 * 0x200, player.y - 10 * 0x200, CaretType::Shoot, Direction::Left); + } + _ => {} + } + } 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); + 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); + state.create_caret(player.x + 3 * 0x200, player.y + 10 * 0x200, CaretType::Shoot, Direction::Left); + } + _ => {} + } + } else { + match player.direction { + Direction::Left => { + bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 2 * 0x200, btype, 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); + state.create_caret(player.x + 12 * 0x200, player.y + 2 * 0x200, CaretType::Shoot, Direction::Right); + } + _ => {} + } + } + + state.sound_manager.play_sfx(33); + } + } + + fn shoot_bullet_polar_star(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { if state.key_trigger.fire() && bullet_manager.count_bullets_multi([4, 5, 6]) < 2 { let btype = match self.level { WeaponLevel::Level1 => { 4 } @@ -144,6 +200,64 @@ impl Weapon { } } + + fn shoot_bullet_fireball(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { + let max_bullets = self.level as usize + 1; + if state.key_trigger.fire() && bullet_manager.count_bullets_multi([7, 8, 9]) < max_bullets { + let btype = match self.level { + WeaponLevel::Level1 => { 7 } + WeaponLevel::Level2 => { 8 } + WeaponLevel::Level3 => { 9 } + WeaponLevel::None => { unreachable!() } + }; + + if !self.consume_ammo(1) { + // todo switch to first weapon + return; + } + + 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); + 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); + state.create_caret(player.x + 4 * 0x200, player.y - 8 * 0x200, CaretType::Shoot, Direction::Left); + } + _ => {} + } + } 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); + 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); + state.create_caret(player.x + 4 * 0x200, player.y + 8 * 0x200, CaretType::Shoot, Direction::Left); + } + _ => {} + } + } else { + match player.direction { + Direction::Left => { + bullet_manager.create_bullet(player.x - 6 * 0x200, player.y + 2 * 0x200, btype, 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); + state.create_caret(player.x + 12 * 0x200, player.y + 2 * 0x200, CaretType::Shoot, Direction::Right); + } + _ => {} + } + } + + state.sound_manager.play_sfx(34) + } + } + pub fn shoot_bullet(&mut self, player: &Player, bullet_manager: &mut BulletManager, state: &mut SharedGameState) { if player.cond.hidden() { return; @@ -151,9 +265,9 @@ impl Weapon { match self.wtype { WeaponType::None => {} - WeaponType::Snake => {} - WeaponType::PolarStar => { self.shoot_bullet_polar_star(player, bullet_manager, state) } - WeaponType::Fireball => {} + 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::MachineGun => {} WeaponType::MissileLauncher => {} WeaponType::Bubbler => {}