add fireball and snake
This commit is contained in:
parent
01dfb7997a
commit
fbb4045f47
129
src/bullet.rs
129
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<usize>,
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,9 +104,13 @@ pub struct BulletData {
|
|||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct BulletRects {
|
||||
pub b001_snake_l1: [Rect<usize>; 8],
|
||||
pub b002_003_snake_l2_3: [Rect<usize>; 3],
|
||||
pub b004_polar_star_l1: [Rect<usize>; 2],
|
||||
pub b005_polar_star_l2: [Rect<usize>; 2],
|
||||
pub b006_polar_star_l3: [Rect<usize>; 2],
|
||||
pub b007_fireball_l1: [Rect<usize>; 8],
|
||||
pub b008_009_fireball_l2_3: [Rect<usize>; 6],
|
||||
pub b037_spur_l1: [Rect<usize>; 2],
|
||||
pub b038_spur_l2: [Rect<usize>; 2],
|
||||
pub b039_spur_l3: [Rect<usize>; 2],
|
||||
|
@ -201,6 +205,7 @@ pub struct NPCConsts {
|
|||
pub n077_yamashita: [Rect<usize>; 3],
|
||||
pub n078_pot: [Rect<usize>; 2],
|
||||
pub n079_mahin: [Rect<usize>; 6],
|
||||
pub n129_fireball_snake_trail: [Rect<usize>; 18],
|
||||
pub n211_small_spikes: [Rect<usize>; 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
|
||||
|
|
|
@ -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<usize>,
|
||||
}
|
||||
|
||||
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<u16, RefCell<NPC>>, &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(()) }
|
||||
}?;
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
124
src/weapon.rs
124
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 => {}
|
||||
|
|
Loading…
Reference in New Issue