2020-09-12 23:45:36 +00:00
|
|
|
use crate::engine_constants::EngineConstants;
|
2020-09-20 15:27:31 +00:00
|
|
|
use crate::shared_game_state::SharedGameState;
|
2020-09-12 00:42:44 +00:00
|
|
|
use crate::weapon::{Weapon, WeaponLevel, WeaponType};
|
2020-09-10 10:27:33 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy)]
|
2020-09-21 22:07:13 +00:00
|
|
|
/// (id, amount)
|
|
|
|
pub struct Item(u16, u16);
|
2020-09-10 10:27:33 +00:00
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Inventory {
|
|
|
|
current_item: u16,
|
|
|
|
current_weapon: u16,
|
|
|
|
items: Vec<Item>,
|
|
|
|
weapons: Vec<Weapon>,
|
|
|
|
}
|
|
|
|
|
2020-09-12 23:45:36 +00:00
|
|
|
#[derive(Clone, Copy)]
|
|
|
|
pub enum AddExperienceResult {
|
|
|
|
None,
|
|
|
|
LevelUp,
|
|
|
|
AddStar,
|
|
|
|
}
|
|
|
|
|
2020-09-10 10:27:33 +00:00
|
|
|
impl Inventory {
|
|
|
|
#[allow(clippy::new_without_default)]
|
|
|
|
pub fn new() -> Inventory {
|
|
|
|
Inventory {
|
|
|
|
current_item: 0,
|
|
|
|
current_weapon: 0,
|
|
|
|
items: Vec::with_capacity(16),
|
|
|
|
weapons: Vec::with_capacity(16),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_item(&mut self, item_id: u16) {
|
|
|
|
if !self.has_item(item_id) {
|
2020-09-21 22:07:13 +00:00
|
|
|
self.items.push(Item(item_id, 1));
|
2020-09-10 10:27:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-21 22:07:13 +00:00
|
|
|
pub fn consume_item(&mut self, item_id: u16) {
|
|
|
|
if let Some(item) = self.get_item(item_id) {
|
|
|
|
if item.1 > 1 {
|
|
|
|
item.1 -= 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.remove_item(item_id);
|
|
|
|
}
|
|
|
|
|
2020-09-10 10:27:33 +00:00
|
|
|
pub fn remove_item(&mut self, item_id: u16) {
|
|
|
|
self.items.retain(|item| item.0 != item_id);
|
|
|
|
}
|
2020-08-20 18:31:47 +00:00
|
|
|
|
2020-09-21 22:07:13 +00:00
|
|
|
pub fn get_item(&mut self, item_id: u16) -> Option<&mut Item> {
|
|
|
|
self.items.iter_mut().by_ref().find(|item| item.0 == item_id)
|
|
|
|
}
|
|
|
|
|
2020-09-10 10:27:33 +00:00
|
|
|
pub fn has_item(&self, item_id: u16) -> bool {
|
|
|
|
self.items.iter().any(|item| item.0 == item_id)
|
|
|
|
}
|
2020-09-10 13:24:04 +00:00
|
|
|
|
2020-09-12 00:42:44 +00:00
|
|
|
pub fn add_weapon(&mut self, weapon_id: WeaponType, max_ammo: u16) {
|
2020-09-10 13:24:04 +00:00
|
|
|
if !self.has_weapon(weapon_id) {
|
2020-09-12 00:42:44 +00:00
|
|
|
self.weapons.push(Weapon::new(
|
|
|
|
weapon_id,
|
|
|
|
WeaponLevel::Level1,
|
|
|
|
0,
|
|
|
|
max_ammo,
|
2020-09-10 13:24:04 +00:00
|
|
|
max_ammo,
|
2020-09-12 00:42:44 +00:00
|
|
|
));
|
2020-09-10 13:24:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-12 00:42:44 +00:00
|
|
|
pub fn remove_weapon(&mut self, wtype: WeaponType) {
|
|
|
|
self.weapons.retain(|weapon| weapon.wtype != wtype);
|
2020-09-10 13:24:04 +00:00
|
|
|
}
|
|
|
|
|
2020-09-11 00:55:07 +00:00
|
|
|
pub fn get_weapon(&self, idx: usize) -> Option<&Weapon> {
|
|
|
|
self.weapons.get(idx)
|
|
|
|
}
|
|
|
|
|
2020-09-12 23:45:36 +00:00
|
|
|
pub fn get_current_weapon(&self) -> Option<&Weapon> {
|
|
|
|
self.weapons.get(self.current_weapon as usize)
|
|
|
|
}
|
|
|
|
|
2020-09-11 00:55:07 +00:00
|
|
|
pub fn get_current_weapon_mut(&mut self) -> Option<&mut Weapon> {
|
2020-09-10 13:24:04 +00:00
|
|
|
self.weapons.get_mut(self.current_weapon as usize)
|
|
|
|
}
|
|
|
|
|
2020-09-20 23:55:52 +00:00
|
|
|
pub fn next_weapon(&mut self) {
|
|
|
|
if (1 + self.current_weapon as usize) < self.weapons.len() {
|
|
|
|
self.current_weapon += 1;
|
|
|
|
} else {
|
|
|
|
self.current_weapon = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn prev_weapon(&mut self) {
|
|
|
|
if self.current_weapon as usize > 0 {
|
|
|
|
self.current_weapon -= 1;
|
|
|
|
} else {
|
|
|
|
self.current_weapon = self.weapons.len().saturating_sub(1) as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-10 13:24:04 +00:00
|
|
|
pub fn refill_all_ammo(&mut self) {
|
|
|
|
for weapon in self.weapons.iter_mut() {
|
|
|
|
weapon.ammo = weapon.max_ammo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn reset_all_weapon_xp(&mut self) {
|
|
|
|
for weapon in self.weapons.iter_mut() {
|
2020-09-12 00:42:44 +00:00
|
|
|
weapon.level = WeaponLevel::Level1;
|
2020-09-10 13:24:04 +00:00
|
|
|
weapon.experience = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-12 23:45:36 +00:00
|
|
|
pub fn add_xp(&mut self, exp: u16, state: &mut SharedGameState) -> AddExperienceResult {
|
|
|
|
let mut result = AddExperienceResult::None;
|
|
|
|
|
|
|
|
if let Some(weapon) = self.get_current_weapon_mut() {
|
|
|
|
let curr_level_idx = weapon.level as usize - 1;
|
|
|
|
let lvl_table = state.constants.weapon.level_table[weapon.wtype as usize];
|
|
|
|
|
|
|
|
weapon.experience += exp;
|
|
|
|
|
|
|
|
if weapon.level == WeaponLevel::Level3 {
|
|
|
|
if weapon.experience > lvl_table[2] {
|
|
|
|
weapon.experience = lvl_table[2];
|
|
|
|
result = AddExperienceResult::AddStar;
|
|
|
|
}
|
2020-09-21 22:10:12 +00:00
|
|
|
} else if weapon.experience > lvl_table[curr_level_idx] {
|
|
|
|
weapon.level = weapon.level.next();
|
|
|
|
weapon.experience = 0;
|
|
|
|
|
|
|
|
if weapon.wtype != WeaponType::Spur {
|
|
|
|
result = AddExperienceResult::LevelUp;
|
2020-09-12 23:45:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2020-09-13 00:29:11 +00:00
|
|
|
/// Get current experience state. Returns a (exp, max exp, max level/exp) tuple.
|
|
|
|
pub fn get_current_max_exp(&self, constants: &EngineConstants) -> (u16, u16, bool) {
|
2020-09-12 23:45:36 +00:00
|
|
|
if let Some(weapon) = self.weapons.get(self.current_weapon as usize) {
|
|
|
|
if weapon.level == WeaponLevel::None {
|
2020-09-13 00:29:11 +00:00
|
|
|
return (0, 0, false);
|
2020-09-12 23:45:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let level_idx = weapon.level as usize - 1;
|
|
|
|
let max_exp = constants.weapon.level_table[weapon.wtype as usize][level_idx];
|
2020-09-13 00:29:11 +00:00
|
|
|
let max = weapon.level == WeaponLevel::Level3 && weapon.experience == max_exp;
|
2020-09-12 23:45:36 +00:00
|
|
|
|
2020-09-13 00:29:11 +00:00
|
|
|
(weapon.experience, max_exp, max)
|
2020-09-12 23:45:36 +00:00
|
|
|
} else {
|
2020-09-13 00:29:11 +00:00
|
|
|
(0, 0, false)
|
2020-09-12 23:45:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-13 00:29:11 +00:00
|
|
|
/// Get current ammunition state. Returns a (ammo, max ammo) tuple.
|
2020-09-11 00:55:07 +00:00
|
|
|
pub fn get_current_ammo(&self) -> (u16, u16) {
|
|
|
|
if let Some(weapon) = self.weapons.get(self.current_weapon as usize) {
|
|
|
|
(weapon.ammo, weapon.max_ammo)
|
|
|
|
} else {
|
|
|
|
(0, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-12 00:42:44 +00:00
|
|
|
pub fn get_current_level(&self) -> WeaponLevel {
|
2020-09-11 00:55:07 +00:00
|
|
|
if let Some(weapon) = self.weapons.get(self.current_weapon as usize) {
|
|
|
|
weapon.level
|
|
|
|
} else {
|
2020-09-12 00:42:44 +00:00
|
|
|
WeaponLevel::None
|
2020-09-11 00:55:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_current_weapon_idx(&self) -> u16 {
|
|
|
|
self.current_weapon
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_weapon_count(&self) -> usize {
|
|
|
|
self.weapons.len()
|
|
|
|
}
|
|
|
|
|
2020-09-12 00:42:44 +00:00
|
|
|
pub fn has_weapon(&self, wtype: WeaponType) -> bool {
|
|
|
|
self.weapons.iter().any(|weapon| weapon.wtype == wtype)
|
2020-09-10 13:24:04 +00:00
|
|
|
}
|
2020-08-20 18:31:47 +00:00
|
|
|
}
|