mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-03-25 03:19:27 +00:00
make bullets aware of player who shot them
This commit is contained in:
parent
c7622ea3b0
commit
d2c5f2161a
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 => {}
|
||||
|
|
Loading…
Reference in a new issue