From 996a35ffa42d540a1b317dda99fd9c0c40b9375b Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 27 Nov 2022 17:36:42 +0100 Subject: [PATCH] Make Nature a trait --- src/dynamic_data/models/pokemon.rs | 4 +-- src/ffi/dynamic_data/models/pokemon.rs | 2 +- .../static_data/libraries/nature_library.rs | 6 ++-- src/ffi/static_data/nature.rs | 14 ++++----- src/static_data/libraries/nature_library.rs | 28 +++++++++++------- src/static_data/natures.rs | 29 +++++++++++++++---- tests/common/library_loader.rs | 6 ++-- 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index 7137d57..3e76e55 100755 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -77,7 +77,7 @@ pub struct Pokemon { /// The [effort values](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon. effort_values: ClampedStatisticSet, /// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon. - nature: Arc, + nature: Arc, /// An optional nickname of the Pokemon. nickname: Option, @@ -443,7 +443,7 @@ impl Pokemon { } /// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon. - pub fn nature(&self) -> &Arc { + pub fn nature(&self) -> &Arc { &self.nature } diff --git a/src/ffi/dynamic_data/models/pokemon.rs b/src/ffi/dynamic_data/models/pokemon.rs index 6126e08..5652405 100644 --- a/src/ffi/dynamic_data/models/pokemon.rs +++ b/src/ffi/dynamic_data/models/pokemon.rs @@ -272,7 +272,7 @@ extern "C" fn pokemon_allowed_experience_gain(ptr: ExternPointer>) /// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon. #[no_mangle] -extern "C" fn pokemon_nature(ptr: ExternPointer>) -> IdentifiablePointer> { +extern "C" fn pokemon_nature(ptr: ExternPointer>) -> IdentifiablePointer> { ptr.as_ref().nature().clone().into() } diff --git a/src/ffi/static_data/libraries/nature_library.rs b/src/ffi/static_data/libraries/nature_library.rs index e999f53..602decf 100644 --- a/src/ffi/static_data/libraries/nature_library.rs +++ b/src/ffi/static_data/libraries/nature_library.rs @@ -21,7 +21,7 @@ unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr) { unsafe extern "C" fn nature_library_load_nature( mut ptr: ExternPointer, name: BorrowedPtr, - nature: OwnedPtr>, + nature: OwnedPtr>, ) { ptr.as_mut() .load_nature(CStr::from_ptr(name).into(), nature.as_ref().unwrap().clone()) @@ -32,7 +32,7 @@ unsafe extern "C" fn nature_library_load_nature( unsafe extern "C" fn nature_library_get_nature( ptr: ExternPointer, name: BorrowedPtr, -) -> IdentifiablePointer> { +) -> IdentifiablePointer> { if let Some(nature) = ptr.as_ref().get_nature(&CStr::from_ptr(name).into()) { nature.clone().into() } else { @@ -44,7 +44,7 @@ unsafe extern "C" fn nature_library_get_nature( #[no_mangle] unsafe extern "C" fn nature_library_get_nature_name( ptr: ExternPointer, - nature: BorrowedPtr>, + nature: BorrowedPtr>, ) -> OwnedPtr { CString::new(ptr.as_ref().get_nature_name(nature.as_ref().unwrap()).str()) .unwrap() diff --git a/src/ffi/static_data/nature.rs b/src/ffi/static_data/nature.rs index 22c7625..3cba0bd 100644 --- a/src/ffi/static_data/nature.rs +++ b/src/ffi/static_data/nature.rs @@ -1,5 +1,5 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr}; -use crate::static_data::{Nature, Statistic}; +use crate::static_data::{Nature, NatureImpl, Statistic}; use std::ptr::drop_in_place; use std::sync::Arc; @@ -10,31 +10,31 @@ extern "C" fn nature_new( decrease_stat: Statistic, increase_modifier: f32, decrease_modifier: f32, -) -> IdentifiablePointer> { - Nature::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier).into() +) -> IdentifiablePointer> { + NatureImpl::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier).into() } /// Reduce the reference count for a nature. #[no_mangle] -unsafe extern "C" fn nature_drop(ptr: OwnedPtr>) { +unsafe extern "C" fn nature_drop(ptr: OwnedPtr>) { drop_in_place(ptr) } /// The stat that should receive the increased modifier. #[no_mangle] -extern "C" fn nature_increased_stat(ptr: ExternPointer>) -> Statistic { +extern "C" fn nature_increased_stat(ptr: ExternPointer>) -> Statistic { ptr.as_ref().increased_stat() } /// The stat that should receive the decreased modifier. #[no_mangle] -extern "C" fn nature_decreased_stat(ptr: ExternPointer>) -> Statistic { +extern "C" fn nature_decreased_stat(ptr: ExternPointer>) -> Statistic { ptr.as_ref().decreased_stat() } /// 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 #[no_mangle] -extern "C" fn nature_get_stat_modifier(ptr: ExternPointer>, stat: Statistic) -> f32 { +extern "C" fn nature_get_stat_modifier(ptr: ExternPointer>, stat: Statistic) -> f32 { ptr.as_ref().get_stat_modifier(stat) } diff --git a/src/static_data/libraries/nature_library.rs b/src/static_data/libraries/nature_library.rs index 8b6b5bf..a71ce60 100644 --- a/src/static_data/libraries/nature_library.rs +++ b/src/static_data/libraries/nature_library.rs @@ -9,7 +9,7 @@ pub struct NatureLibrary { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying data structure. - map: HashMap>, + map: HashMap>, } impl NatureLibrary { @@ -22,21 +22,21 @@ impl NatureLibrary { } /// Adds a new nature with name to the library. - pub fn load_nature(&mut self, name: StringKey, nature: Arc) { + pub fn load_nature(&mut self, name: StringKey, nature: Arc) { self.map.insert(name, nature); } /// Gets a nature by name. - pub fn get_nature(&self, key: &StringKey) -> Option<&Arc> { + pub fn get_nature(&self, key: &StringKey) -> Option<&Arc> { self.map.get(key) } /// Finds a nature name by nature. - pub fn get_nature_name(&self, nature: &Nature) -> StringKey { + pub fn get_nature_name(&self, nature: &Arc) -> StringKey { for kv in &self.map { // As natures can't be copied, and should always be the same reference as the value // in the map, we just compare by reference. - if std::ptr::eq(Arc::as_ptr(kv.1), nature) { + if kv.1.value_identifier() == nature.value_identifier() { return kv.0.clone(); } } @@ -53,14 +53,14 @@ impl ValueIdentifiable for NatureLibrary { #[cfg(test)] pub mod tests { use crate::static_data::statistics::Statistic; - use crate::static_data::{Nature, NatureLibrary}; + use crate::static_data::{NatureImpl, NatureLibrary}; pub fn build() -> NatureLibrary { let mut lib = NatureLibrary::new(2); lib.load_nature( "test_nature".into(), - Nature::new(Statistic::HP, Statistic::Attack, 1.1, 0.9), + NatureImpl::new(Statistic::HP, Statistic::Attack, 1.1, 0.9), ); lib @@ -69,10 +69,13 @@ pub mod tests { #[test] fn create_nature_library_insert_and_retrieve() { let mut lib = NatureLibrary::new(2); - lib.load_nature("foo".into(), Nature::new(Statistic::HP, Statistic::Attack, 1.1, 0.9)); + lib.load_nature( + "foo".into(), + NatureImpl::new(Statistic::HP, Statistic::Attack, 1.1, 0.9), + ); lib.load_nature( "bar".into(), - Nature::new(Statistic::Attack, Statistic::Defense, 1.1, 0.9), + NatureImpl::new(Statistic::Attack, Statistic::Defense, 1.1, 0.9), ); let n1 = lib.get_nature(&"foo".into()).expect("Nature was not found"); assert_eq!(n1.increased_stat(), Statistic::HP); @@ -84,10 +87,13 @@ pub mod tests { #[test] fn create_nature_library_insert_and_get_name() { let mut lib = NatureLibrary::new(2); - lib.load_nature("foo".into(), Nature::new(Statistic::HP, Statistic::Attack, 1.1, 0.9)); + lib.load_nature( + "foo".into(), + NatureImpl::new(Statistic::HP, Statistic::Attack, 1.1, 0.9), + ); lib.load_nature( "bar".into(), - Nature::new(Statistic::Attack, Statistic::Defense, 1.1, 0.9), + NatureImpl::new(Statistic::Attack, Statistic::Defense, 1.1, 0.9), ); let n1 = lib.get_nature(&"foo".into()).expect("Nature was not found"); diff --git a/src/static_data/natures.rs b/src/static_data/natures.rs index c4b9180..0c8072a 100755 --- a/src/static_data/natures.rs +++ b/src/static_data/natures.rs @@ -1,11 +1,26 @@ use crate::static_data::Statistic; use crate::{ValueIdentifiable, ValueIdentifier}; +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: ValueIdentifiable + 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; + + /// 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; +} + /// 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 Nature { +pub struct NatureImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The stat that should receive the increased modifier. @@ -18,7 +33,7 @@ pub struct Nature { decrease_modifier: f32, } -impl Nature { +impl NatureImpl { /// Instantiates a new statistic. pub fn new( increase_stat: Statistic, @@ -34,20 +49,22 @@ impl Nature { decrease_modifier, }) } +} +impl Nature for NatureImpl { /// The stat that should receive the increased modifier. - pub fn increased_stat(&self) -> Statistic { + fn increased_stat(&self) -> Statistic { self.increase_stat } /// The stat that should receive the decreased modifier. - pub fn decreased_stat(&self) -> Statistic { + fn decreased_stat(&self) -> Statistic { self.decrease_stat } /// 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 - pub fn get_stat_modifier(&self, stat: Statistic) -> f32 { + 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 { @@ -58,7 +75,7 @@ impl Nature { } } -impl ValueIdentifiable for Nature { +impl ValueIdentifiable for NatureImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } diff --git a/tests/common/library_loader.rs b/tests/common/library_loader.rs index 948499f..3201ab1 100755 --- a/tests/common/library_loader.rs +++ b/tests/common/library_loader.rs @@ -17,7 +17,7 @@ use pkmn_lib::dynamic_data::Gen7MiscLibrary; use pkmn_lib::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver; use pkmn_lib::static_data::{ Ability, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, GrowthRateLibrary, ItemImpl, - ItemLibrary, LearnableMoves, LibrarySettings, LookupGrowthRate, MoveData, MoveLibrary, Nature, NatureLibrary, + ItemLibrary, LearnableMoves, LibrarySettings, LookupGrowthRate, MoveData, MoveLibrary, NatureImpl, NatureLibrary, SecondaryEffect, Species, StaticData, StaticStatisticSet, Statistic, TypeLibrary, }; use pkmn_lib::StringKey; @@ -80,13 +80,13 @@ pub fn load_natures(path: &String, nature_library: &mut NatureLibrary) { let increased_statistic_str = record.get(1).unwrap(); let decreased_statistic_str = record.get(2).unwrap(); if increased_statistic_str.is_empty() || decreased_statistic_str.is_empty() { - nature_library.load_nature(nature_name, Nature::new(Statistic::HP, Statistic::HP, 1.0, 1.0)); + nature_library.load_nature(nature_name, NatureImpl::new(Statistic::HP, Statistic::HP, 1.0, 1.0)); } else { let increased_statistic = serde_plain::from_str(increased_statistic_str).unwrap(); let decreased_statistic = serde_plain::from_str(decreased_statistic_str).unwrap(); nature_library.load_nature( nature_name, - Nature::new(increased_statistic, decreased_statistic, 1.1, 0.9), + NatureImpl::new(increased_statistic, decreased_statistic, 1.1, 0.9), ); } }