diff --git a/src/defines.rs b/src/defines.rs index 3335b8d..c14ebdc 100644 --- a/src/defines.rs +++ b/src/defines.rs @@ -1 +1,2 @@ pub type LevelInt = u8; +pub const MAX_MOVES: usize = 4; diff --git a/src/dynamic_data/libraries/battle_stat_calculator.rs b/src/dynamic_data/libraries/battle_stat_calculator.rs new file mode 100644 index 0000000..fc2cff7 --- /dev/null +++ b/src/dynamic_data/libraries/battle_stat_calculator.rs @@ -0,0 +1,5 @@ +use crate::dynamic_data::models::pokemon::Pokemon; + +pub trait BattleStatCalculator { + //fn is_critical(attack: &ExecutingMove, target: &Pokemon, hit: u8); +} diff --git a/src/dynamic_data/libraries/dynamic_library.rs b/src/dynamic_data/libraries/dynamic_library.rs new file mode 100644 index 0000000..3c8385d --- /dev/null +++ b/src/dynamic_data/libraries/dynamic_library.rs @@ -0,0 +1,19 @@ +use crate::static_data::libraries::static_data::StaticData; +use derive_getters::Getters; + +#[derive(Getters, Debug)] +pub struct DynamicLibrary<'a> { + static_data: StaticData<'a>, +} + +#[cfg(test)] +pub mod test { + use crate::dynamic_data::libraries::dynamic_library::DynamicLibrary; + use crate::static_data::libraries::static_data; + + pub fn build<'a>() -> DynamicLibrary<'a> { + DynamicLibrary { + static_data: static_data::test::build(), + } + } +} diff --git a/src/dynamic_data/libraries/mod.rs b/src/dynamic_data/libraries/mod.rs new file mode 100644 index 0000000..aa0bc6c --- /dev/null +++ b/src/dynamic_data/libraries/mod.rs @@ -0,0 +1,2 @@ +pub mod battle_stat_calculator; +pub mod dynamic_library; diff --git a/src/dynamic_data/mod.rs b/src/dynamic_data/mod.rs new file mode 100644 index 0000000..bf17f0d --- /dev/null +++ b/src/dynamic_data/mod.rs @@ -0,0 +1,3 @@ +pub mod libraries; +pub mod models; +pub mod script_handling; diff --git a/src/dynamic_data/models/battle.rs b/src/dynamic_data/models/battle.rs new file mode 100644 index 0000000..455a8c4 --- /dev/null +++ b/src/dynamic_data/models/battle.rs @@ -0,0 +1,2 @@ +#[derive(Debug)] +pub struct Battle {} diff --git a/src/dynamic_data/models/battle_side.rs b/src/dynamic_data/models/battle_side.rs new file mode 100644 index 0000000..ac78762 --- /dev/null +++ b/src/dynamic_data/models/battle_side.rs @@ -0,0 +1,2 @@ +#[derive(Debug)] +pub struct BattleSide {} diff --git a/src/dynamic_data/models/learned_move.rs b/src/dynamic_data/models/learned_move.rs new file mode 100644 index 0000000..d944840 --- /dev/null +++ b/src/dynamic_data/models/learned_move.rs @@ -0,0 +1 @@ +pub struct LearnedMove {} diff --git a/src/dynamic_data/models/mod.rs b/src/dynamic_data/models/mod.rs new file mode 100644 index 0000000..e230b40 --- /dev/null +++ b/src/dynamic_data/models/mod.rs @@ -0,0 +1,4 @@ +pub mod battle; +pub mod battle_side; +pub mod learned_move; +pub mod pokemon; diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs new file mode 100644 index 0000000..7fc23da --- /dev/null +++ b/src/dynamic_data/models/pokemon.rs @@ -0,0 +1,143 @@ +use crate::defines::{LevelInt, MAX_MOVES}; +use crate::dynamic_data::libraries::dynamic_library::DynamicLibrary; +use crate::dynamic_data::models::battle::Battle; +use crate::dynamic_data::models::battle_side::BattleSide; +use crate::dynamic_data::models::learned_move::LearnedMove; +use crate::dynamic_data::script_handling::script::Script; +use crate::dynamic_data::script_handling::script_set::ScriptSet; +use crate::static_data::items::item::Item; +use crate::static_data::species_data::ability_index::AbilityIndex; +use crate::static_data::species_data::form::Form; +use crate::static_data::species_data::gender::Gender; +use crate::static_data::species_data::species::Species; +use crate::static_data::statistic_set::StatisticSet; +use crate::static_data::statistics::Statistic; +use derive_getters::Getters; +use std::collections::HashSet; + +#[derive(Getters)] +pub struct PokemonBattleData<'a> { + battle: &'a Battle, + battle_side: &'a BattleSide, + on_battle_field: bool, + seen_opponents: HashSet>, +} + +#[derive(Getters)] +pub struct Pokemon<'a> { + library: &'a DynamicLibrary<'a>, + species: &'a Species<'a>, + form: &'a Form<'a>, + + display_species: Option<&'a Species<'a>>, + display_form: Option<&'a Form<'a>>, + + level: LevelInt, + experience: u32, + unique_identifier: u32, + gender: Gender, + coloring: u8, + held_item: Option<&'a Item>, + health: u32, + + stat_boost: StatisticSet, + flat_stats: StatisticSet, + boosted_stats: StatisticSet, + + nickname: Option, + + ability_index: AbilityIndex, + is_ability_overridden: bool, + overridden_ability_name: String, + + battle_data: Option>, + + moves: [Option; MAX_MOVES], + allowed_experience: bool, + + types: Vec, + + ability_script: Option>, + status_script: Option>, + volatile: ScriptSet, +} + +impl<'a> Pokemon<'a> { + pub fn new( + library: &'a DynamicLibrary, + species: &'a Species, + form: &'a Form, + ability: AbilityIndex, + level: LevelInt, + unique_identifier: u32, + gender: Gender, + coloring: u8, + ) -> Pokemon<'a> { + // Calculate experience from the level for the specified growth rate. + let experience = library + .static_data() + .growth_rates() + .calculate_experience(species.growth_rate(), level); + let health = form.get_base_stat(Statistic::HP) as u32; + Pokemon { + library, + species, + form, + display_species: None, + display_form: None, + level, + experience, + unique_identifier, + gender, + coloring, + held_item: None, + health, + stat_boost: Default::default(), + flat_stats: *form.base_stats(), + boosted_stats: *form.base_stats(), + nickname: None, + ability_index: ability, + is_ability_overridden: false, + overridden_ability_name: "".to_string(), + battle_data: None, + moves: [None, None, None, None], + allowed_experience: false, + types: form.types().to_vec(), + ability_script: None, + status_script: None, + volatile: ScriptSet {}, + } + } +} + +#[cfg(test)] +pub mod test { + use crate::dynamic_data::libraries::dynamic_library; + use crate::dynamic_data::models::pokemon::Pokemon; + use crate::static_data::libraries::data_library::DataLibrary; + use crate::static_data::species_data::ability_index::AbilityIndex; + use crate::static_data::species_data::gender::Gender; + + #[test] + fn construct_pokemon() { + let lib = dynamic_library::test::build(); + let species = lib.static_data().species().get("foo").unwrap(); + let form = species.get_form("default").unwrap(); + + let pokemon = Pokemon::new( + &lib, + species, + form, + AbilityIndex { + hidden: false, + index: 0, + }, + 10, + 0, + Gender::Male, + 0, + ); + assert_eq!(pokemon.species.name(), "foo"); + assert_eq!(pokemon.form.name(), "default"); + } +} diff --git a/src/dynamic_data/script_handling/mod.rs b/src/dynamic_data/script_handling/mod.rs new file mode 100644 index 0000000..5821ee2 --- /dev/null +++ b/src/dynamic_data/script_handling/mod.rs @@ -0,0 +1,2 @@ +pub mod script; +pub mod script_set; diff --git a/src/dynamic_data/script_handling/script.rs b/src/dynamic_data/script_handling/script.rs new file mode 100644 index 0000000..3f2da9d --- /dev/null +++ b/src/dynamic_data/script_handling/script.rs @@ -0,0 +1 @@ +pub trait Script {} diff --git a/src/dynamic_data/script_handling/script_set.rs b/src/dynamic_data/script_handling/script_set.rs new file mode 100644 index 0000000..8a1a6b4 --- /dev/null +++ b/src/dynamic_data/script_handling/script_set.rs @@ -0,0 +1 @@ +pub struct ScriptSet {} diff --git a/src/lib.rs b/src/lib.rs index 41acbc3..7fc7187 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,12 @@ // The too many arguments is annoying, especially for when we create constructors, disable. #![allow(clippy::too_many_arguments, clippy::needless_range_loop)] #![feature(nll)] +#![feature(in_band_lifetimes)] #[macro_use] extern crate maplit; pub mod defines; +pub mod dynamic_data; pub mod static_data; pub mod utils; diff --git a/src/static_data/libraries/growth_rate_library.rs b/src/static_data/libraries/growth_rate_library.rs index 6a11eae..c24e99e 100644 --- a/src/static_data/libraries/growth_rate_library.rs +++ b/src/static_data/libraries/growth_rate_library.rs @@ -33,12 +33,11 @@ impl Debug for GrowthRateLibrary { } #[cfg(test)] -mod tests { +pub mod tests { use crate::static_data::growth_rates::lookup_growth_rate::LookupGrowthRate; use crate::static_data::libraries::growth_rate_library::GrowthRateLibrary; - #[test] - fn add_growth_rate_to_library_and_calculate_level() { + pub fn build() -> GrowthRateLibrary { let mut lib = GrowthRateLibrary::new(1); // Borrow as mut so we can insert @@ -46,24 +45,20 @@ mod tests { w.add_growth_rate("foo", Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100]))); // Drops borrow as mut - // Borrow as read so we can read - let r = &lib; - assert_eq!(r.calculate_level("foo", 3), 1); - assert_eq!(r.calculate_level("foo", 50), 3); + lib + } + + #[test] + fn add_growth_rate_to_library_and_calculate_level() { + let lib = build(); + assert_eq!(lib.calculate_level("foo", 3), 1); + assert_eq!(lib.calculate_level("foo", 50), 3); } #[test] fn add_growth_rate_to_library_and_calculate_experience() { - let mut lib = GrowthRateLibrary::new(1); - - // Borrow as mut so we can insert - let w = &mut lib; - w.add_growth_rate("foo", Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100]))); - // Drops borrow as mut - - // Borrow as read so we can read - let r = &lib; - assert_eq!(r.calculate_experience("foo", 1), 0); - assert_eq!(r.calculate_experience("foo", 3), 10); + let lib = build(); + assert_eq!(lib.calculate_experience("foo", 1), 0); + assert_eq!(lib.calculate_experience("foo", 3), 10); } } diff --git a/src/static_data/libraries/item_library.rs b/src/static_data/libraries/item_library.rs index 6924ca0..470fbea 100644 --- a/src/static_data/libraries/item_library.rs +++ b/src/static_data/libraries/item_library.rs @@ -30,3 +30,33 @@ impl DataLibrary<'_, Item> for ItemLibrary { (&mut self.map, &mut self.list) } } + +#[cfg(test)] +pub mod tests { + use crate::static_data::items::item::Item; + use crate::static_data::items::item_category::{BattleItemCategory, ItemCategory}; + use crate::static_data::libraries::data_library::DataLibrary; + use crate::static_data::libraries::item_library::ItemLibrary; + use std::collections::HashSet; + + fn build_item() -> Item { + Item::new( + "foo", + ItemCategory::MiscItem, + BattleItemCategory::MiscBattleItem, + 100, + HashSet::new(), + ) + } + + pub fn build() -> ItemLibrary { + let mut lib = ItemLibrary::new(1); + let m = build_item(); + // Borrow as mut so we can insert + let w = &mut lib; + w.add("foo", m); + // Drops borrow as mut + + lib + } +} diff --git a/src/static_data/libraries/library_settings.rs b/src/static_data/libraries/library_settings.rs index be45ee5..d05e10e 100644 --- a/src/static_data/libraries/library_settings.rs +++ b/src/static_data/libraries/library_settings.rs @@ -3,6 +3,5 @@ use derive_getters::Getters; #[derive(Getters, Debug)] pub struct LibrarySettings { - maximum_level: LevelInt, - maximum_move_count: u8, + pub(crate) maximum_level: LevelInt, } diff --git a/src/static_data/libraries/move_library.rs b/src/static_data/libraries/move_library.rs index cf00d77..aa48fff 100644 --- a/src/static_data/libraries/move_library.rs +++ b/src/static_data/libraries/move_library.rs @@ -30,3 +30,38 @@ impl DataLibrary<'_, MoveData> for MoveLibrary { (&mut self.map, &mut self.list) } } + +#[cfg(test)] +pub mod tests { + use crate::static_data::libraries::data_library::DataLibrary; + use crate::static_data::libraries::move_library::MoveLibrary; + use crate::static_data::moves::move_data::{MoveCategory, MoveData, MoveTarget}; + use crate::static_data::moves::secondary_effect::SecondaryEffect; + use std::collections::HashSet; + + fn build_move() -> MoveData { + MoveData::new( + "foo", + 0, + MoveCategory::Physical, + 100, + 100, + 30, + MoveTarget::Any, + 0, + SecondaryEffect::empty(), + HashSet::new(), + ) + } + + pub fn build() -> MoveLibrary { + let mut lib = MoveLibrary::new(1); + let m = build_move(); + // Borrow as mut so we can insert + let w = &mut lib; + w.add("foo", m); + // Drops borrow as mut + + lib + } +} diff --git a/src/static_data/libraries/species_library.rs b/src/static_data/libraries/species_library.rs index 9f7cc79..2be91d1 100644 --- a/src/static_data/libraries/species_library.rs +++ b/src/static_data/libraries/species_library.rs @@ -32,7 +32,7 @@ impl<'a> DataLibrary<'a, Species<'a>> for SpeciesLibrary<'a> { } #[cfg(test)] -mod tests { +pub mod tests { use crate::static_data::libraries::data_library::DataLibrary; use crate::static_data::libraries::species_library::SpeciesLibrary; use crate::static_data::species_data::form::Form; @@ -64,16 +64,21 @@ mod tests { ) } - #[test] - fn add_species_to_library_and_fetch() { + pub fn build<'a>() -> SpeciesLibrary<'a> { let mut lib = SpeciesLibrary::new(1); let species = build_species(); - // Borrow as mut so we can insert let w = &mut lib; w.add("foo", species); // Drops borrow as mut + lib + } + + #[test] + fn add_species_to_library_and_fetch() { + let lib = build(); + // Borrow as read so we can read let r = &lib; let mon = r.get("foo"); @@ -85,14 +90,9 @@ mod tests { #[test] fn add_species_to_library_then_remove() { - let mut lib = SpeciesLibrary::new(1); - let species = build_species(); + let mut lib = build(); - // Borrow as mut so we can insert - let w = &mut lib; - w.add("foo", species); - w.remove("foo"); - // Drops borrow as mut + lib.remove("foo"); // Borrow as read so we can read let r = &lib; diff --git a/src/static_data/libraries/static_data.rs b/src/static_data/libraries/static_data.rs index 11587d6..0628acd 100644 --- a/src/static_data/libraries/static_data.rs +++ b/src/static_data/libraries/static_data.rs @@ -7,7 +7,7 @@ use crate::static_data::libraries::type_library::TypeLibrary; use derive_getters::Getters; #[derive(Getters, Debug)] -struct StaticData<'a> { +pub struct StaticData<'a> { settings: LibrarySettings, species: SpeciesLibrary<'a>, moves: MoveLibrary, @@ -15,3 +15,23 @@ struct StaticData<'a> { growth_rates: GrowthRateLibrary, types: TypeLibrary, } + +#[cfg(test)] +pub mod test { + use crate::static_data::libraries::library_settings::LibrarySettings; + use crate::static_data::libraries::static_data::StaticData; + use crate::static_data::libraries::{ + growth_rate_library, item_library, move_library, species_library, type_library, + }; + + pub fn build<'a>() -> StaticData<'a> { + StaticData { + settings: LibrarySettings { maximum_level: 100 }, + species: species_library::tests::build(), + moves: move_library::tests::build(), + items: item_library::tests::build(), + growth_rates: growth_rate_library::tests::build(), + types: type_library::tests::build(), + } + } +} diff --git a/src/static_data/libraries/type_library.rs b/src/static_data/libraries/type_library.rs index 0e1bb41..396adfd 100644 --- a/src/static_data/libraries/type_library.rs +++ b/src/static_data/libraries/type_library.rs @@ -46,10 +46,25 @@ impl TypeLibrary { } #[cfg(test)] -mod tests { +pub mod tests { use crate::static_data::libraries::type_library::TypeLibrary; use assert_approx_eq::assert_approx_eq; + pub fn build() -> TypeLibrary { + let mut lib = TypeLibrary::new(2); + + // Borrow as mut so we can insert + let w = &mut lib; + w.register_type("foo"); + w.register_type("bar"); + // Drops borrow as mut + + w.set_effectiveness(0, 1, 0.5); + w.set_effectiveness(1, 0, 2.0); + + lib + } + #[test] fn add_two_types_retrieve_them() { let mut lib = TypeLibrary::new(2); diff --git a/src/static_data/moves/move_data.rs b/src/static_data/moves/move_data.rs index ab53518..a210588 100644 --- a/src/static_data/moves/move_data.rs +++ b/src/static_data/moves/move_data.rs @@ -44,7 +44,7 @@ pub struct MoveData { impl MoveData { pub fn new( - name: String, + name: &str, move_type: u8, category: MoveCategory, base_power: u8, @@ -56,7 +56,7 @@ impl MoveData { flags: HashSet, ) -> MoveData { MoveData { - name, + name: name.to_string(), move_type, category, base_power, diff --git a/src/static_data/species_data/learnable_moves.rs b/src/static_data/species_data/learnable_moves.rs index 22976b0..dfc7ca1 100644 --- a/src/static_data/species_data/learnable_moves.rs +++ b/src/static_data/species_data/learnable_moves.rs @@ -47,7 +47,7 @@ mod tests { fn adds_level_moves() { let mut moves = LearnableMoves::new(); let move1 = MoveData::new( - "foo".to_string(), + "foo", 0, MoveCategory::Physical, 0, @@ -59,7 +59,7 @@ mod tests { Default::default(), ); let move2 = MoveData::new( - "bar".to_string(), + "bar", 0, MoveCategory::Physical, 0, @@ -83,7 +83,7 @@ mod tests { fn adds_two_same_moves_at_different_level() { let mut moves = LearnableMoves::new(); let move1 = MoveData::new( - "foo".to_string(), + "foo", 0, MoveCategory::Physical, 0, diff --git a/src/static_data/statistic_set.rs b/src/static_data/statistic_set.rs index 91ba01c..77ef274 100644 --- a/src/static_data/statistic_set.rs +++ b/src/static_data/statistic_set.rs @@ -2,7 +2,7 @@ use super::statistics::Statistic; use derive_getters::Getters; use num_traits::PrimInt; -#[derive(Default, Eq, PartialEq, Debug, Getters)] +#[derive(Default, Eq, PartialEq, Copy, Clone, Debug, Getters)] pub struct StatisticSet where T: PrimInt,