some bullet fixes
This commit is contained in:
parent
ecfcf57847
commit
f87b791c87
|
@ -76,6 +76,7 @@ impl BulletManager {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Bullet {
|
||||
pub btype: u16,
|
||||
pub x: i32,
|
||||
|
@ -90,6 +91,7 @@ pub struct Bullet {
|
|||
pub lifetime: u16,
|
||||
pub damage: i16,
|
||||
pub counter1: u16,
|
||||
pub counter2: u16,
|
||||
pub rng: Xoroshiro32PlusPlus,
|
||||
pub owner: TargetPlayer,
|
||||
pub cond: Condition,
|
||||
|
@ -135,6 +137,7 @@ impl Bullet {
|
|||
lifetime: bullet.lifetime,
|
||||
damage: bullet.damage as i16,
|
||||
counter1: 0,
|
||||
counter2: 0,
|
||||
rng: Xoroshiro32PlusPlus::new(1),
|
||||
owner,
|
||||
cond: Condition(0x80),
|
||||
|
@ -668,25 +671,25 @@ impl Bullet {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.action_counter == 0 {
|
||||
self.action_counter = 1;
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
|
||||
match self.direction {
|
||||
Direction::Left => {
|
||||
self.vel_x = self.rng.range(-0x400..-0x200);
|
||||
self.vel_y = self.rng.range(-4..4) * 0x200 / 2;
|
||||
self.vel_y = (self.rng.range(-4..4) * 0x200) / 2;
|
||||
}
|
||||
Direction::Up => {
|
||||
self.vel_y = self.rng.range(-0x400..-0x200);
|
||||
self.vel_x = self.rng.range(-4..4) * 0x200 / 2;
|
||||
self.vel_x = (self.rng.range(-4..4) * 0x200) / 2;
|
||||
}
|
||||
Direction::Right => {
|
||||
self.vel_x = self.rng.range(0x200..0x400);
|
||||
self.vel_y = self.rng.range(-4..4) * 0x200 / 2;
|
||||
self.vel_y = (self.rng.range(-4..4) * 0x200) / 2;
|
||||
}
|
||||
Direction::Bottom => {
|
||||
self.vel_y = self.rng.range(0x80..0x100);
|
||||
self.vel_x = self.rng.range(-4..4) * 0x200 / 2;
|
||||
self.vel_x = (self.rng.range(-4..4) * 0x200) / 2;
|
||||
}
|
||||
Direction::FacingPlayer => unreachable!(),
|
||||
}
|
||||
|
@ -987,6 +990,178 @@ impl Bullet {
|
|||
}
|
||||
}
|
||||
|
||||
fn tick_super_missile(&mut self, state: &mut SharedGameState, players: [&Player; 2], new_bullets: &mut Vec<Bullet>) {
|
||||
let player = players[self.owner.index()];
|
||||
|
||||
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 match self.direction {
|
||||
Direction::Left if self.flags.hit_left_wall() => true,
|
||||
Direction::Left if self.flags.hit_left_slope() => true,
|
||||
Direction::Left if self.flags.flag_x80() => true,
|
||||
Direction::Right if self.flags.hit_right_wall() => true,
|
||||
Direction::Right if self.flags.hit_right_slope() => true,
|
||||
Direction::Right if self.flags.flag_x40() => true,
|
||||
Direction::Up if self.flags.hit_top_wall() => true,
|
||||
Direction::Bottom if self.flags.hit_bottom_wall() => true,
|
||||
_ => false,
|
||||
} {
|
||||
let bomb_bullet = match self.btype {
|
||||
28 => 31,
|
||||
29 => 32,
|
||||
30 => 33,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let bullet = Bullet::new(self.x, self.y, bomb_bullet, self.owner, self.direction, &state.constants);
|
||||
new_bullets.push(bullet);
|
||||
|
||||
self.cond.set_alive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.target_y = self.y;
|
||||
self.enemy_hit_height = 0x1000;
|
||||
self.hit_bounds.top = 0x1000;
|
||||
self.hit_bounds.bottom = 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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.btype == 30 {
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.vel_y = (self.y - player.y).signum() * 0x100;
|
||||
self.vel_x = self.rng.range(-0x200..0x200);
|
||||
}
|
||||
Direction::Up | Direction::Bottom => {
|
||||
self.vel_x = (self.x - player.x).signum() * 0x100;
|
||||
self.vel_y = self.rng.range(-0x200..0x200);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
self.counter1 = match self.counter1 {
|
||||
1 => 256,
|
||||
2 => 170,
|
||||
_ => 512,
|
||||
};
|
||||
}
|
||||
|
||||
match self.direction {
|
||||
Direction::Left => self.vel_x -= self.counter1 as i32,
|
||||
Direction::Up => self.vel_y -= self.counter1 as i32,
|
||||
Direction::Right => self.vel_x += self.counter1 as i32,
|
||||
Direction::Bottom => self.vel_y += self.counter1 as i32,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.btype == 30 {
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.vel_y = (player.y - self.y).signum() * 0x40;
|
||||
}
|
||||
Direction::Up | Direction::Bottom => {
|
||||
self.vel_x = (player.x - self.x).signum() * 0x40;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
self.vel_x = clamp(self.vel_x, -0x1400, 0x1400);
|
||||
self.vel_y = clamp(self.vel_y, -0x1400, 0x1400);
|
||||
|
||||
self.x += self.vel_x;
|
||||
self.y += self.vel_y;
|
||||
|
||||
self.counter2 += 1;
|
||||
|
||||
if self.counter2 > 2 {
|
||||
self.counter2 = 0;
|
||||
|
||||
match self.direction {
|
||||
Direction::Left => {
|
||||
state.create_caret(self.x + 0x1000, self.y, CaretType::Exhaust, self.direction.opposite());
|
||||
}
|
||||
Direction::Up => {
|
||||
state.create_caret(self.x, self.y + 0x1000, CaretType::Exhaust, self.direction.opposite());
|
||||
}
|
||||
Direction::Right => {
|
||||
state.create_caret(self.x - 0x1000, self.y, CaretType::Exhaust, self.direction.opposite());
|
||||
}
|
||||
Direction::Bottom => {
|
||||
state.create_caret(self.x, self.y - 0x1000, CaretType::Exhaust, self.direction.opposite());
|
||||
}
|
||||
Direction::FacingPlayer => {}
|
||||
}
|
||||
}
|
||||
|
||||
match self.btype {
|
||||
28 | 30 => {
|
||||
self.anim_rect = state.constants.weapon.bullet_rects.b028_super_missile_l1[self.direction as usize];
|
||||
}
|
||||
29 => {
|
||||
self.anim_rect = state.constants.weapon.bullet_rects.b029_super_missile_l2[self.direction as usize];
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn tick_super_missile_explosion(&mut self, state: &mut SharedGameState, npc_list: &NPCList) {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
|
||||
self.action_counter = match self.btype {
|
||||
31 => 10,
|
||||
32 => 14,
|
||||
33 => 6,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
state.sound_manager.play_sfx(44);
|
||||
}
|
||||
|
||||
if self.action_counter % 3 == 0 {
|
||||
let radius = match self.btype {
|
||||
31 => 16,
|
||||
32 => 32,
|
||||
33 => 40,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
npc_list.create_death_smoke_up(
|
||||
self.x + self.rng.range(-radius..radius) * 0x200,
|
||||
self.y + self.rng.range(-radius..radius) * 0x200,
|
||||
self.enemy_hit_width as usize,
|
||||
2,
|
||||
state,
|
||||
&self.rng,
|
||||
);
|
||||
}
|
||||
|
||||
self.action_counter -= 1;
|
||||
if self.action_counter == 0 {
|
||||
self.cond.set_alive(false);
|
||||
}
|
||||
}
|
||||
|
||||
fn tick_nemesis(&mut self, state: &mut SharedGameState, npc_list: &NPCList) {
|
||||
self.action_counter += 1;
|
||||
if self.action_counter > self.lifetime {
|
||||
|
@ -1214,6 +1389,8 @@ impl Bullet {
|
|||
25 => self.tick_blade_1(state),
|
||||
26 => self.tick_blade_2(state),
|
||||
27 => self.tick_blade_3(state, new_bullets),
|
||||
28 | 29 | 30 => self.tick_super_missile(state, players, new_bullets),
|
||||
31 | 32 | 33 => self.tick_super_missile_explosion(state, npc_list),
|
||||
34 | 35 | 36 => self.tick_nemesis(state, npc_list),
|
||||
37 | 38 | 39 => self.tick_spur(state, new_bullets),
|
||||
40 | 41 | 42 => self.tick_spur_trail(state),
|
||||
|
|
|
@ -2,8 +2,8 @@ use crate::caret::CaretType;
|
|||
use crate::common::Direction;
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::{Weapon, WeaponLevel};
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::weapon::{Weapon, WeaponLevel};
|
||||
|
||||
impl Weapon {
|
||||
pub(in crate::weapon) fn tick_fireball(
|
||||
|
@ -14,60 +14,52 @@ impl Weapon {
|
|||
state: &mut SharedGameState,
|
||||
) {
|
||||
let max_bullets = self.level as usize + 1;
|
||||
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,
|
||||
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 - 0x800, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
state.create_caret(player.x - 0x800, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(player.x + 0x800, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
state.create_caret(player.x + 0x800, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else if player.down {
|
||||
match player.direction {
|
||||
Direction::Left => {
|
||||
bullet_manager.create_bullet(player.x - 0x800, player.y + 0x1000, btype, player_id, Direction::Bottom, &state.constants);
|
||||
state.create_caret(player.x - 0x800, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(player.x + 0x800, player.y + 0x1000, btype, player_id, Direction::Bottom, &state.constants);
|
||||
state.create_caret(player.x + 0x800, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match player.direction {
|
||||
Direction::Left => {
|
||||
bullet_manager.create_bullet(player.x - 0xc00, player.y + 0x400, btype, player_id, Direction::Left, &state.constants);
|
||||
state.create_caret(player.x - 0x1800, player.y + 0x400, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(player.x + 0xc00, player.y + 0x400, btype, player_id, Direction::Right, &state.constants);
|
||||
state.create_caret(player.x + 0x1800, player.y + 0x400, CaretType::Shoot, Direction::Right);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
state.sound_manager.play_sfx(34)
|
||||
if !player.controller.trigger_shoot() || bullet_manager.count_bullets_multi(&[7, 8, 9], player_id) >= max_bullets {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
match player.direction {
|
||||
Direction::Left if player.up => {
|
||||
bullet_manager.create_bullet(player.x - 0x800, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
state.create_caret(player.x - 0x800, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right if player.up => {
|
||||
bullet_manager.create_bullet(player.x + 0x800, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
state.create_caret(player.x + 0x800, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Left if player.down => {
|
||||
bullet_manager.create_bullet(player.x - 0x800, player.y + 0x1000, btype, player_id, Direction::Bottom, &state.constants);
|
||||
state.create_caret(player.x - 0x800, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right if player.down => {
|
||||
bullet_manager.create_bullet(player.x + 0x800, player.y + 0x1000, btype, player_id, Direction::Bottom, &state.constants);
|
||||
state.create_caret(player.x + 0x800, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Left => {
|
||||
bullet_manager.create_bullet(player.x - 0xc00, player.y + 0x400, btype, player_id, Direction::Left, &state.constants);
|
||||
state.create_caret(player.x - 0x1800, player.y + 0x400, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(player.x + 0xc00, player.y + 0x400, btype, player_id, Direction::Right, &state.constants);
|
||||
state.create_caret(player.x + 0x1800, player.y + 0x400, CaretType::Shoot, Direction::Right);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
state.sound_manager.play_sfx(34)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::Direction;
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::weapon::bullet::{Bullet, BulletManager};
|
||||
use crate::weapon::{Weapon, WeaponLevel};
|
||||
|
||||
impl Weapon {
|
||||
|
@ -12,12 +14,162 @@ impl Weapon {
|
|||
state: &mut SharedGameState,
|
||||
) {
|
||||
const BULLETS: [u16; 6] = [28, 29, 30, 31, 32, 33];
|
||||
|
||||
|
||||
if !player.controller.trigger_shoot() {
|
||||
return;
|
||||
}
|
||||
|
||||
let btype = match self.level {
|
||||
WeaponLevel::Level1 => 28,
|
||||
WeaponLevel::Level2 => 29,
|
||||
WeaponLevel::Level3 => 30,
|
||||
WeaponLevel::None => unreachable!(),
|
||||
};
|
||||
|
||||
match self.level {
|
||||
WeaponLevel::Level1 if bullet_manager.count_bullets_multi(&BULLETS, player_id) > 0 => {
|
||||
return;
|
||||
}
|
||||
WeaponLevel::Level2 if bullet_manager.count_bullets_multi(&BULLETS, player_id) > 1 => {
|
||||
return;
|
||||
}
|
||||
WeaponLevel::Level3 if bullet_manager.count_bullets_multi(&BULLETS, player_id) > 3 => {
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if !self.consume_ammo(1) {
|
||||
state.sound_manager.play_sfx(37);
|
||||
// todo switch to first weapon
|
||||
return;
|
||||
}
|
||||
|
||||
fn increment(weapon: &mut Weapon, bullet: &mut Bullet) {
|
||||
weapon.counter2 = (weapon.counter2 + 1) % 3;
|
||||
bullet.counter1 = weapon.counter2;
|
||||
}
|
||||
|
||||
match player.direction {
|
||||
Direction::Left if player.up => {
|
||||
let mut bullet = Bullet::new(player.x - 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right if player.up => {
|
||||
let mut bullet = Bullet::new(player.x + 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Left if player.down => {
|
||||
let mut bullet = Bullet::new(player.x - 0x200, player.y + 0x1000, btype, player_id, Direction::Bottom, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right if player.down => {
|
||||
let mut bullet = Bullet::new(player.x + 0x200, player.y + 0x1000, btype, player_id, Direction::Bottom, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Left => {
|
||||
let mut bullet = Bullet::new(player.x - 0xc00, player.y, btype, player_id, Direction::Left, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x1800, player.y, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x - 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
let mut bullet = Bullet::new(player.x + 0xc00, player.y, btype, player_id, Direction::Right, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x1800, player.y, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
state.sound_manager.play_sfx(32)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue