Initial work on adding documentation, reorganises modules
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2022-06-19 21:34:08 +02:00
parent 715f16e2b8
commit 314e9dbe1a
49 changed files with 806 additions and 473 deletions

View File

@@ -1,63 +1,28 @@
use crate::dynamic_data::models::pokemon::Pokemon;
use crate::static_data::statistic_set::StatisticSet;
use crate::static_data::statistics::Statistic;
use std::fmt::Debug;
use std::sync::atomic::AtomicU32;
use crate::dynamic_data::Pokemon;
use crate::static_data::Statistic;
use crate::static_data::StatisticSet;
/// A battle stat calculator is used to calculate stats for a pokemon.
pub trait BattleStatCalculator: Debug {
/// Calculate all the flat stats of a Pokemon, disregarding stat boosts.
fn calculate_flat_stats(&self, pokemon: &Pokemon, stats: &StatisticSet<AtomicU32>);
/// Calculate a single flat stat of a Pokemon, disregarding stat boost
fn calculate_flat_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32;
/// Calculate all the boosted stats of a pokemon, including stat boosts.
fn calculate_boosted_stats(&self, pokemon: &Pokemon, stats: &StatisticSet<AtomicU32>);
/// Calculate a single boosted stat of a Pokemon, including stat boosts.
fn calculate_boosted_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32;
}
/// A basic implementation of the Gen 7 stat calculator.
#[derive(Debug)]
pub struct BattleStatCalculator {}
impl BattleStatCalculator {
pub fn calculate_flat_stats(&self, pokemon: &Pokemon, stats: &StatisticSet<AtomicU32>) {
stats.set_stat(Statistic::HP, self.calculate_health_stat(pokemon));
stats.set_stat(Statistic::Attack, self.calculate_other_stat(pokemon, Statistic::Attack));
stats.set_stat(
Statistic::Defense,
self.calculate_other_stat(pokemon, Statistic::Defense),
);
stats.set_stat(
Statistic::SpecialAttack,
self.calculate_other_stat(pokemon, Statistic::SpecialAttack),
);
stats.set_stat(
Statistic::SpecialDefense,
self.calculate_other_stat(pokemon, Statistic::SpecialDefense),
);
stats.set_stat(Statistic::Speed, 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, stats: &StatisticSet<AtomicU32>) {
stats.set_stat(Statistic::HP, self.calculate_boosted_stat(pokemon, Statistic::HP));
stats.set_stat(
Statistic::Attack,
self.calculate_boosted_stat(pokemon, Statistic::Attack),
);
stats.set_stat(
Statistic::Defense,
self.calculate_boosted_stat(pokemon, Statistic::Defense),
);
stats.set_stat(
Statistic::SpecialAttack,
self.calculate_boosted_stat(pokemon, Statistic::SpecialAttack),
);
stats.set_stat(
Statistic::SpecialDefense,
self.calculate_boosted_stat(pokemon, Statistic::SpecialDefense),
);
stats.set_stat(Statistic::Speed, 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
}
pub struct Gen7BattleStatCalculator {}
impl Gen7BattleStatCalculator {
/// The calculation used for health points.
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;
@@ -66,6 +31,7 @@ impl BattleStatCalculator {
(((2 * base + iv + (ev / 4)) * level) / 100) + level + 10
}
/// The calculation used for all other stats
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;
@@ -75,6 +41,7 @@ impl BattleStatCalculator {
return (unmodified as f32 * pokemon.nature().get_stat_modifier(stat)) as u32;
}
/// This functions returns the modifier we need to do to a stat for a given stat boost.
fn get_stat_boost_modifier(&self, pokemon: &Pokemon, stat: Statistic) -> f32 {
let boost = pokemon.stat_boost().get_stat(stat);
match boost {
@@ -95,3 +62,56 @@ impl BattleStatCalculator {
}
}
}
impl BattleStatCalculator for Gen7BattleStatCalculator {
fn calculate_flat_stats(&self, pokemon: &Pokemon, stats: &StatisticSet<AtomicU32>) {
stats.set_stat(Statistic::HP, self.calculate_health_stat(pokemon));
stats.set_stat(Statistic::Attack, self.calculate_other_stat(pokemon, Statistic::Attack));
stats.set_stat(
Statistic::Defense,
self.calculate_other_stat(pokemon, Statistic::Defense),
);
stats.set_stat(
Statistic::SpecialAttack,
self.calculate_other_stat(pokemon, Statistic::SpecialAttack),
);
stats.set_stat(
Statistic::SpecialDefense,
self.calculate_other_stat(pokemon, Statistic::SpecialDefense),
);
stats.set_stat(Statistic::Speed, self.calculate_other_stat(pokemon, Statistic::Speed));
}
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)
}
}
fn calculate_boosted_stats(&self, pokemon: &Pokemon, stats: &StatisticSet<AtomicU32>) {
stats.set_stat(Statistic::HP, self.calculate_boosted_stat(pokemon, Statistic::HP));
stats.set_stat(
Statistic::Attack,
self.calculate_boosted_stat(pokemon, Statistic::Attack),
);
stats.set_stat(
Statistic::Defense,
self.calculate_boosted_stat(pokemon, Statistic::Defense),
);
stats.set_stat(
Statistic::SpecialAttack,
self.calculate_boosted_stat(pokemon, Statistic::SpecialAttack),
);
stats.set_stat(
Statistic::SpecialDefense,
self.calculate_boosted_stat(pokemon, Statistic::SpecialDefense),
);
stats.set_stat(Statistic::Speed, self.calculate_boosted_stat(pokemon, Statistic::Speed));
}
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
}
}

View File

@@ -1,9 +1,10 @@
use crate::dynamic_data::models::executing_move::{ExecutingMove, HitData};
use crate::dynamic_data::models::pokemon::Pokemon;
use std::sync::Arc;
use crate::dynamic_data::script_handling::ScriptSource;
use crate::dynamic_data::Pokemon;
use crate::dynamic_data::{ExecutingMove, HitData};
use crate::script_hook;
use crate::static_data::{MoveCategory, Statistic};
use std::sync::Arc;
pub trait DamageLibrary: std::fmt::Debug {
fn has_randomness(&self) -> bool;

View File

@@ -1,19 +1,20 @@
use std::ops::Deref;
use std::sync::Arc;
use crate::dynamic_data::libraries::battle_stat_calculator::BattleStatCalculator;
use crate::dynamic_data::libraries::damage_library::DamageLibrary;
use crate::dynamic_data::libraries::misc_library::MiscLibrary;
use crate::dynamic_data::libraries::script_resolver::ScriptCategory;
use crate::dynamic_data::script_handling::item_script::ItemScript;
use crate::dynamic_data::script_handling::script::Script;
use crate::static_data::items::item::Item;
use crate::static_data::libraries::static_data::StaticData;
use crate::dynamic_data::ItemScript;
use crate::dynamic_data::Script;
use crate::static_data::Item;
use crate::static_data::StaticData;
use crate::{PkmnResult, StringKey};
use std::ops::Deref;
use std::sync::Arc;
#[derive(Debug)]
pub struct DynamicLibrary {
static_data: StaticData,
stat_calculator: BattleStatCalculator,
stat_calculator: Box<dyn BattleStatCalculator>,
damage_calculator: Box<dyn DamageLibrary>,
misc_library: Box<dyn MiscLibrary<'static>>,
}
@@ -25,7 +26,7 @@ unsafe impl Send for DynamicLibrary {}
impl DynamicLibrary {
pub fn new(
static_data: StaticData,
stat_calculator: BattleStatCalculator,
stat_calculator: Box<dyn BattleStatCalculator>,
damage_calculator: Box<dyn DamageLibrary>,
misc_library: Box<dyn MiscLibrary<'static>>,
) -> Self {
@@ -40,8 +41,8 @@ impl DynamicLibrary {
pub fn static_data(&self) -> &StaticData {
&self.static_data
}
pub fn stat_calculator(&self) -> &BattleStatCalculator {
&self.stat_calculator
pub fn stat_calculator(&self) -> &dyn BattleStatCalculator {
self.stat_calculator.deref()
}
pub fn damage_calculator(&self) -> &dyn DamageLibrary {
self.damage_calculator.deref()
@@ -60,16 +61,15 @@ impl DynamicLibrary {
#[cfg(test)]
pub mod test {
use crate::dynamic_data::libraries::battle_stat_calculator::BattleStatCalculator;
use crate::dynamic_data::libraries::battle_stat_calculator::Gen7BattleStatCalculator;
use crate::dynamic_data::libraries::damage_library::Gen7DamageLibrary;
use crate::dynamic_data::libraries::dynamic_library::DynamicLibrary;
use crate::dynamic_data::libraries::misc_library::Gen7MiscLibrary;
use crate::static_data::libraries::static_data;
pub fn build() -> DynamicLibrary {
DynamicLibrary {
static_data: static_data::test::build(),
stat_calculator: BattleStatCalculator {},
static_data: crate::static_data::libraries::static_data::test::build(),
stat_calculator: Box::new(Gen7BattleStatCalculator {}),
damage_calculator: Box::new(Gen7DamageLibrary::new(false)),
misc_library: Box::new(Gen7MiscLibrary::new()),
}

View File

@@ -1,16 +1,18 @@
use crate::dynamic_data::choices::{MoveChoice, SwitchChoice, TurnChoice};
use crate::dynamic_data::models::battle::Battle;
use crate::dynamic_data::models::executing_move::ExecutingMove;
use crate::dynamic_data::models::learned_move::{LearnedMove, MoveLearnMethod};
use crate::dynamic_data::models::pokemon::Pokemon;
use crate::dynamic_data::script_handling::ScriptSource;
use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
use crate::{script_hook, StringKey};
use hashbrown::HashSet;
use std::fmt::{Debug, Formatter};
use std::fmt::Debug;
use std::sync::Arc;
pub trait MiscLibrary<'library> {
use hashbrown::HashSet;
use crate::dynamic_data::choices::{MoveChoice, SwitchChoice, TurnChoice};
use crate::dynamic_data::script_handling::ScriptSource;
use crate::dynamic_data::Battle;
use crate::dynamic_data::ExecutingMove;
use crate::dynamic_data::Pokemon;
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
use crate::{script_hook, StringKey};
pub trait MiscLibrary<'library>: Debug {
fn is_critical(
&self,
battle: &Battle,
@@ -29,12 +31,6 @@ pub trait MiscLibrary<'library> {
// TODO: get time
}
impl<'library> Debug for dyn MiscLibrary<'library> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("MiscLibrary")
}
}
#[derive(Debug)]
pub struct Gen7MiscLibrary<'library> {
struggle_data: *const MoveData,

View File

@@ -1,5 +1,16 @@
pub mod battle_stat_calculator;
pub mod damage_library;
pub mod dynamic_library;
pub mod misc_library;
pub mod script_resolver;
#[doc(inline)]
pub use battle_stat_calculator::*;
#[doc(inline)]
pub use damage_library::*;
#[doc(inline)]
pub use dynamic_library::*;
#[doc(inline)]
pub use misc_library::*;
#[doc(inline)]
pub use script_resolver::*;
mod battle_stat_calculator;
mod damage_library;
pub(crate) mod dynamic_library;
mod misc_library;
mod script_resolver;