PkmnLib_rs/src/static_data/natures.rs

114 lines
3.6 KiB
Rust
Executable File

use crate::static_data::Statistic;
use std::fmt::Debug;
use std::sync::Arc;
/// A nature is an attribute on a Pokemon that modifies the effective base stats on a Pokemon. They
/// can have an increased statistic and a decreased statistic, or be neutral.
pub trait Nature: Debug {
/// The stat that should receive the increased modifier.
fn increased_stat(&self) -> Statistic;
/// The stat that should receive the decreased modifier.
fn decreased_stat(&self) -> Statistic;
/// The amount that the increased stat gets modified by.
fn increased_modifier(&self) -> f32;
/// The amount that the decreased stat gets modified by.
fn decreased_modifier(&self) -> f32;
/// Calculates the modifier for a given stat. If it's the increased stat, returns the increased
/// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0
fn get_stat_modifier(&self, stat: Statistic) -> f32;
/// Checks if two natures are equal.
fn eq(&self, other: &dyn Nature) -> bool;
}
/// A nature is an attribute on a Pokemon that modifies the effective base stats on a Pokemon. They
/// can have an increased statistic and a decreased statistic, or be neutral.
#[derive(Debug)]
pub struct NatureImpl {
/// The stat that should receive the increased modifier.
increase_stat: Statistic,
/// The stat that should receive the decreased modifier.
decrease_stat: Statistic,
/// The amount by which the increased stat is multiplied.
increase_modifier: f32,
/// The amount by which the decreased stat is multiplied.
decrease_modifier: f32,
}
impl NatureImpl {
/// Instantiates a new nature.
pub fn new(
increase_stat: Statistic,
decrease_stat: Statistic,
increase_modifier: f32,
decrease_modifier: f32,
) -> Arc<Self> {
Arc::new(Self {
increase_stat,
decrease_stat,
increase_modifier,
decrease_modifier,
})
}
}
impl Nature for NatureImpl {
/// The stat that should receive the increased modifier.
fn increased_stat(&self) -> Statistic {
self.increase_stat
}
/// The stat that should receive the decreased modifier.
fn decreased_stat(&self) -> Statistic {
self.decrease_stat
}
fn increased_modifier(&self) -> f32 {
self.increase_modifier
}
fn decreased_modifier(&self) -> f32 {
self.decrease_modifier
}
/// Calculates the modifier for a given stat. If it's the increased stat, returns the increased
/// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0
fn get_stat_modifier(&self, stat: Statistic) -> f32 {
if stat == self.increase_stat && stat != self.decrease_stat {
self.increase_modifier
} else if stat == self.decrease_stat && stat != self.increase_stat {
self.decrease_modifier
} else {
1.0
}
}
fn eq(&self, other: &dyn Nature) -> bool {
std::ptr::eq(self, other as *const dyn Nature as *const Self)
}
}
#[cfg(test)]
#[allow(clippy::indexing_slicing)]
#[allow(clippy::unwrap_used)]
pub(crate) mod tests {
use super::*;
mockall::mock! {
#[derive(Debug)]
pub Nature {}
impl Nature for Nature {
fn increased_stat(&self) -> Statistic;
fn decreased_stat(&self) -> Statistic;
fn increased_modifier(&self) -> f32;
fn decreased_modifier(&self) -> f32;
fn get_stat_modifier(&self, stat: Statistic) -> f32;
fn eq(&self, other: &dyn Nature) -> bool;
}
}
}