use crate::dynamic_data::models::pokemon::Pokemon; use crate::static_data::statistic_set::StatisticSet; use crate::static_data::statistics::Statistic; #[derive(Debug)] pub struct BattleStatCalculator {} impl BattleStatCalculator { pub fn calculate_flat_stats(&self, pokemon: &Pokemon) -> StatisticSet { StatisticSet::::new( self.calculate_health_stat(pokemon), self.calculate_other_stat(pokemon, Statistic::Attack), self.calculate_other_stat(pokemon, Statistic::Defense), self.calculate_other_stat(pokemon, Statistic::SpecialAttack), self.calculate_other_stat(pokemon, Statistic::SpecialDefense), self.calculate_other_stat(pokemon, Statistic::Speed), ) } pub fn calculate_flat_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32 { if stat == Statistic::HP { self.calculate_health_stat(pokemon) } else { self.calculate_other_stat(pokemon, stat) } } pub fn calculate_boosted_stats(&self, pokemon: &Pokemon) -> StatisticSet { StatisticSet::::new( self.calculate_boosted_stat(pokemon, Statistic::HP), self.calculate_boosted_stat(pokemon, Statistic::Attack), self.calculate_boosted_stat(pokemon, Statistic::Defense), self.calculate_boosted_stat(pokemon, Statistic::SpecialAttack), self.calculate_boosted_stat(pokemon, Statistic::SpecialDefense), self.calculate_boosted_stat(pokemon, Statistic::Speed), ) } pub fn calculate_boosted_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32 { (self.calculate_flat_stat(pokemon, stat) as f32 * self.get_stat_boost_modifier(pokemon, stat)) as u32 } fn calculate_health_stat(&self, pokemon: &Pokemon) -> u32 { let base = pokemon.form().get_base_stat(Statistic::HP) as u32; let iv = pokemon.individual_values().hp() as u32; let ev = pokemon.effort_values().hp() as u32; let level = pokemon.level() as u32; (((2 * base + iv + (ev / 4)) * level) / 100) + level + 10 } fn calculate_other_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32 { let base = pokemon.form().get_base_stat(stat) as u32; let iv = pokemon.individual_values().get_stat(stat) as u32; let ev = pokemon.effort_values().get_stat(stat) as u32; let level = pokemon.level() as u32; let unmodified = (((2 * base + iv + (ev / 4)) * level) / 100) + 5; return (unmodified as f32 * pokemon.nature().get_stat_modifier(stat)) as u32; } fn get_stat_boost_modifier(&self, pokemon: &Pokemon, stat: Statistic) -> f32 { let boost = pokemon.stat_boost().get_stat(stat); match boost { -6 => 2.0 / 8.0, -5 => 2.0 / 7.0, -4 => 2.0 / 6.0, -3 => 2.0 / 5.0, -2 => 2.0 / 4.0, -1 => 2.0 / 3.0, 0 => 1.0, 1 => 3.0 / 2.0, 2 => 4.0 / 2.0, 3 => 5.0 / 2.0, 4 => 6.0 / 2.0, 5 => 7.0 / 2.0, 6 => 8.0 / 2.0, _ => panic!("Stat boost was out of expected range of -6 to 6"), } } }