use crate::StatContainer;
use crate::modifier::Modifier;
use std::fmt::{Display, Formatter};
use std::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
#[derive(PartialEq, Debug, Copy, Clone)]
#[cfg_attr(
feature = "bevy",
derive(bevy_reflect::Reflect),
reflect(PartialEq, Debug, Clone)
)]
pub struct Stat {
pub base: i32,
pub bonus: i32,
pub multiplier: f32,
}
impl Stat {
pub fn new(base: i32) -> Self {
Self {
base,
..Default::default()
}
}
pub fn total(&self) -> i32 {
((self.base + self.bonus) as f32 * self.multiplier) as i32
}
pub fn with_bonus(mut self, bonus: i32) -> Self {
self.bonus = bonus;
self
}
pub fn with_multiplier(mut self, multiplier: f32) -> Self {
self.multiplier = multiplier;
self
}
pub fn with_modifier(mut self, modifier: Modifier) -> Self {
self.bonus = modifier.bonus;
self.multiplier = modifier.multiplier;
self
}
pub fn apply(&mut self, modifier: Modifier) {
self.bonus += modifier.bonus;
self.multiplier *= modifier.multiplier;
}
pub fn apply_scaled(&mut self, modifier: Modifier, fraction: f32) {
self.bonus += (modifier.bonus as f32 * fraction) as i32;
self.multiplier *= (1.0 - fraction) * 1.0 + fraction * modifier.multiplier;
}
}
impl StatContainer for Stat {
fn reset_modifiers(&mut self) {
self.bonus = 0;
self.multiplier = 1.0;
}
}
impl Default for Stat {
fn default() -> Self {
Self {
base: 0,
bonus: 0,
multiplier: 1.0,
}
}
}
impl AddAssign<i32> for Stat {
fn add_assign(&mut self, rhs: i32) {
self.bonus += rhs;
}
}
impl SubAssign<i32> for Stat {
fn sub_assign(&mut self, rhs: i32) {
self.bonus -= rhs;
}
}
impl MulAssign<f32> for Stat {
fn mul_assign(&mut self, rhs: f32) {
self.multiplier *= rhs;
}
}
impl DivAssign<f32> for Stat {
fn div_assign(&mut self, rhs: f32) {
self.multiplier /= rhs;
}
}
impl Display for Stat {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if let Some(precision) = f.precision() {
write!(
f,
"({} + {}) x {:.*}",
self.base, self.bonus, precision, self.multiplier
)
} else {
write!(f, "({} + {}) x {}", self.base, self.bonus, self.multiplier)
}
}
}