XilonenImpact/gameserver/src/creature/fight_prop_comp.rs

119 lines
4.1 KiB
Rust

use paste::paste;
use std::collections::{BTreeMap, HashMap};
use data::{ElementType, FightPropType};
pub type FightPropValue = f32;
#[derive(Default)]
pub struct FightPropComp {
pub fight_cur_prop_map: BTreeMap<FightPropType, FightPropValue>,
pub fight_cal_prop_map: BTreeMap<FightPropType, FightPropValue>,
}
macro_rules! impl_get_cur {
($($ty: ident;)*) => {
paste! {
$(pub fn [<get_cur_ $ty:lower>](&self) -> FightPropValue {
let percent = self.get_prop_value(FightPropType::[<$ty Percent>]) + 1.0;
let percent = FightPropValue::max(percent, 0.0);
let base = percent * self.get_prop_value(FightPropType::[<Base $ty>]);
base + self.get_prop_value(FightPropType::$ty)
})*
}
};
}
impl FightPropComp {
pub fn get_fight_prop_value_map(&self) -> HashMap<u32, f32> {
let mut all_map: HashMap<u32, f32> = self
.fight_cur_prop_map
.iter()
.map(|(t, v)| (*t as u32, *v))
.collect();
all_map.extend(
self.fight_cal_prop_map
.iter()
.map(|(t, v)| (*t as u32, *v))
.collect::<HashMap<_, _>>(),
);
all_map
}
pub fn get_prop_value(&self, ty: FightPropType) -> FightPropValue {
match ty {
FightPropType::CurAttack => self.get_cur_attack(),
FightPropType::CurDefense => self.get_cur_defense(),
FightPropType::CurSpeed => self.get_cur_speed(),
ty if Self::is_cur_prop_type(ty) => self
.fight_cur_prop_map
.get(&ty)
.cloned()
.unwrap_or_default(),
ty => self.find_cal_prop_value(ty),
}
}
impl_get_cur! { Attack; Defense; }
pub fn get_cur_speed(&self) -> FightPropValue {
let percent = self.get_prop_value(FightPropType::SpeedPercent) + 1.0;
let percent = FightPropValue::max(percent, 0.0);
percent * self.get_prop_value(FightPropType::BaseSpeed)
}
pub fn set_cur_hp(&mut self, hp: FightPropValue) {
self.fight_cur_prop_map.insert(FightPropType::CurHp, hp);
}
pub fn set_max_energy(&mut self, elem_type: ElementType, max_energy: f32) {
self.fight_cal_prop_map
.insert(Self::get_max_energy_type(elem_type), max_energy);
}
pub fn set_cur_energy(&mut self, elem_type: ElementType, energy: f32) {
self.fight_cur_prop_map
.insert(Self::get_cur_energy_type(elem_type), energy);
}
fn find_cal_prop_value(&self, ty: FightPropType) -> FightPropValue {
self.fight_cal_prop_map
.get(&ty)
.cloned()
.unwrap_or_default()
}
fn is_cur_prop_type(ty: FightPropType) -> bool {
ty >= FightPropType::CurFireEnergy
&& ty <= FightPropType::CurSpeed
&& ty != FightPropType::MaxHp
}
fn get_cur_energy_type(elem_type: ElementType) -> FightPropType {
match elem_type {
ElementType::Fire => FightPropType::CurFireEnergy,
ElementType::Water => FightPropType::CurWaterEnergy,
ElementType::Grass => FightPropType::CurGrassEnergy,
ElementType::Electric => FightPropType::CurElecEnergy,
ElementType::Ice => FightPropType::CurIceEnergy,
ElementType::Wind => FightPropType::CurWindEnergy,
ElementType::Rock => FightPropType::CurRockEnergy,
_ => FightPropType::None,
}
}
fn get_max_energy_type(elem_type: ElementType) -> FightPropType {
match elem_type {
ElementType::Fire => FightPropType::MaxFireEnergy,
ElementType::Water => FightPropType::MaxWaterEnergy,
ElementType::Grass => FightPropType::MaxGrassEnergy,
ElementType::Electric => FightPropType::MaxElecEnergy,
ElementType::Ice => FightPropType::MaxIceEnergy,
ElementType::Wind => FightPropType::MaxWindEnergy,
ElementType::Rock => FightPropType::MaxRockEnergy,
_ => FightPropType::None,
}
}
}