1
0
Fork 0
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:
Alula 2020-12-05 22:24:38 +01:00
parent c7622ea3b0
commit d2c5f2161a
No known key found for this signature in database
GPG key ID: 3E00485503A1D8BA
3 changed files with 55 additions and 53 deletions

View file

@ -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

View file

@ -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() {

View file

@ -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 => {}