doukutsu-rs/src/weapon.rs

281 lines
12 KiB
Rust

use num_derive::FromPrimitive;
use crate::bullet::BulletManager;
use crate::caret::CaretType;
use crate::common::Direction;
use crate::player::Player;
use crate::shared_game_state::SharedGameState;
#[derive(Debug, PartialEq, Eq, Copy, Clone, FromPrimitive)]
#[repr(u8)]
pub enum WeaponType {
None = 0,
Snake = 1,
PolarStar = 2,
Fireball = 3,
MachineGun = 4,
MissileLauncher = 5,
Bubbler = 7,
Blade = 9,
SuperMissileLauncher = 10,
Nemesis = 12,
Spur = 13,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
pub enum WeaponLevel {
None = 0,
Level1 = 1,
Level2 = 2,
Level3 = 3,
}
impl WeaponLevel {
pub fn next(self) -> WeaponLevel {
match self {
WeaponLevel::None => { WeaponLevel::Level1 }
WeaponLevel::Level1 => { WeaponLevel::Level2 }
WeaponLevel::Level2 => { WeaponLevel::Level3 }
WeaponLevel::Level3 => { WeaponLevel::Level3 }
}
}
pub fn prev(self) -> WeaponLevel {
match self {
WeaponLevel::None => { WeaponLevel::Level1 }
WeaponLevel::Level1 => { WeaponLevel::Level1 }
WeaponLevel::Level2 => { WeaponLevel::Level1 }
WeaponLevel::Level3 => { WeaponLevel::Level2 }
}
}
}
#[derive(Clone)]
pub struct Weapon {
pub wtype: WeaponType,
pub level: WeaponLevel,
pub experience: u16,
pub ammo: u16,
pub max_ammo: u16,
}
impl Weapon {
pub fn new(wtype: WeaponType, level: WeaponLevel, experience: u16, ammo: u16, max_ammo: u16) -> Weapon {
Weapon {
wtype,
level,
experience,
ammo,
max_ammo,
}
}
pub fn consume_ammo(&mut self, ammo: u16) -> bool {
if self.max_ammo == 0 {
return true;
}
if self.ammo >= ammo {
self.ammo -= ammo;
return true;
}
false
}
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 }
WeaponLevel::Level2 => { 5 }
WeaponLevel::Level3 => { 6 }
WeaponLevel::None => { unreachable!() }
};
if !self.consume_ammo(1) {
state.sound_manager.play_sfx(37);
return;
}
if player.up {
match player.direction {
Direction::Left => {
bullet_manager.create_bullet(player.x - 0x200, player.y - 8 * 0x200, btype, 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);
state.create_caret(player.x + 0x200, player.y - 8 * 0x200, CaretType::Shoot, Direction::Left);
}
_ => {}
}
} 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);
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);
state.create_caret(player.x + 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 + 3 * 0x200, btype, 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);
state.create_caret(player.x + 6 * 0x200, player.y + 3 * 0x200, CaretType::Shoot, Direction::Right);
}
_ => {}
}
}
if self.level == WeaponLevel::Level3 {
state.sound_manager.play_sfx(49);
} else {
state.sound_manager.play_sfx(32);
}
}
}
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;
}
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::MachineGun => {}
WeaponType::MissileLauncher => {}
WeaponType::Bubbler => {}
WeaponType::Blade => {}
WeaponType::SuperMissileLauncher => {}
WeaponType::Nemesis => {}
WeaponType::Spur => {}
}
}
}