diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index 3e76e55..1e4619d 100755 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -86,7 +86,7 @@ pub struct Pokemon { ability_index: AbilityIndex, /// An ability can be overriden to an arbitrary ability. This is for example used for the Mummy /// ability. - override_ability: Option, + override_ability: Option>, /// If in battle, we have additional data. battle_data: RwLock>, @@ -416,7 +416,7 @@ impl Pokemon { self.override_ability.is_some() } /// Returns the currently active ability. - pub fn active_ability(&self) -> &Ability { + pub fn active_ability(&self) -> &Arc { if let Some(v) = &self.override_ability { return v; } diff --git a/src/ffi/dynamic_data/models/pokemon.rs b/src/ffi/dynamic_data/models/pokemon.rs index 5652405..a9a56aa 100644 --- a/src/ffi/dynamic_data/models/pokemon.rs +++ b/src/ffi/dynamic_data/models/pokemon.rs @@ -260,8 +260,8 @@ extern "C" fn pokemon_is_ability_overriden(ptr: ExternPointer>) -> /// Returns the currently active ability. #[no_mangle] -extern "C" fn pokemon_active_ability(ptr: ExternPointer>) -> IdentifiablePointer { - (ptr.as_ref().active_ability() as *const Ability).into() +extern "C" fn pokemon_active_ability(ptr: ExternPointer>) -> IdentifiablePointer> { + ptr.as_ref().active_ability().clone().into() } /// Whether or not the Pokemon is allowed to gain experience. diff --git a/src/ffi/static_data/ability.rs b/src/ffi/static_data/ability.rs index d38b796..4b69618 100644 --- a/src/ffi/static_data/ability.rs +++ b/src/ffi/static_data/ability.rs @@ -1,5 +1,5 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr}; -use crate::static_data::{Ability, EffectParameter}; +use crate::static_data::{Ability, AbilityImpl, EffectParameter}; use crate::StringKey; use std::ffi::{c_char, CStr, CString}; use std::ptr::drop_in_place; @@ -12,7 +12,7 @@ unsafe extern "C" fn ability_new( effect: *const c_char, parameters: *const OwnedPtr, parameters_length: usize, -) -> IdentifiablePointer> { +) -> IdentifiablePointer> { let parameters = std::slice::from_raw_parts(parameters, parameters_length); let mut parameters_vec: Vec = Vec::with_capacity(parameters_length); for parameter in parameters { @@ -22,37 +22,38 @@ unsafe extern "C" fn ability_new( let name: StringKey = CStr::from_ptr(name).to_str().unwrap().into(); let effect: StringKey = CStr::from_ptr(effect).to_str().unwrap().into(); - Arc::new(Ability::new(&name, &effect, parameters_vec)).into() + let arc: Arc = Arc::new(AbilityImpl::new(&name, &effect, parameters_vec)); + arc.into() } /// Drops a reference counted ability. #[no_mangle] -unsafe extern "C" fn ability_drop(ptr: OwnedPtr>) { +unsafe extern "C" fn ability_drop(ptr: OwnedPtr>) { drop_in_place(ptr) } /// The name of the ability. #[no_mangle] -unsafe extern "C" fn ability_name(ptr: ExternPointer>) -> OwnedPtr { +unsafe extern "C" fn ability_name(ptr: ExternPointer>) -> OwnedPtr { CString::new(ptr.as_ref().name().str()).unwrap().into_raw() } /// The name of the script effect of the ability. #[no_mangle] -unsafe extern "C" fn ability_effect(ptr: ExternPointer>) -> OwnedPtr { +unsafe extern "C" fn ability_effect(ptr: ExternPointer>) -> OwnedPtr { CString::new(ptr.as_ref().effect().str()).unwrap().into_raw() } /// The length of the parameters for the script effect of the ability. #[no_mangle] -unsafe extern "C" fn ability_parameter_length(ptr: ExternPointer>) -> usize { +unsafe extern "C" fn ability_parameter_length(ptr: ExternPointer>) -> usize { ptr.as_ref().parameters().len() } /// Gets a parameter for the script effect of the ability. #[no_mangle] unsafe extern "C" fn ability_parameter_get( - ptr: ExternPointer>, + ptr: ExternPointer>, index: usize, ) -> IdentifiablePointer { if let Some(p) = ptr.as_ref().parameters().get(index) { diff --git a/src/ffi/static_data/libraries/mod.rs b/src/ffi/static_data/libraries/mod.rs index 429293e..4117053 100644 --- a/src/ffi/static_data/libraries/mod.rs +++ b/src/ffi/static_data/libraries/mod.rs @@ -74,5 +74,5 @@ macro_rules! library_interface { library_interface!(SpeciesLibrary, Species); library_interface!(MoveLibrary, MoveData); -library_interface!(AbilityLibrary, Ability); +library_interface!(AbilityLibrary, dyn Ability); library_interface!(ItemLibrary, dyn Item); diff --git a/src/ffi/static_data/nature.rs b/src/ffi/static_data/nature.rs index 3cba0bd..e11532d 100644 --- a/src/ffi/static_data/nature.rs +++ b/src/ffi/static_data/nature.rs @@ -10,13 +10,14 @@ extern "C" fn nature_new( decrease_stat: Statistic, increase_modifier: f32, decrease_modifier: f32, -) -> IdentifiablePointer> { - NatureImpl::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier).into() +) -> IdentifiablePointer> { + let arc: Arc = NatureImpl::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier); + arc.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) } diff --git a/src/static_data/libraries/ability_library.rs b/src/static_data/libraries/ability_library.rs index c9cf1a2..d6d244e 100755 --- a/src/static_data/libraries/ability_library.rs +++ b/src/static_data/libraries/ability_library.rs @@ -12,7 +12,7 @@ pub struct AbilityLibrary { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying map for the library. - map: IndexMap>, + map: IndexMap>, } impl AbilityLibrary { @@ -25,11 +25,11 @@ impl AbilityLibrary { } } -impl DataLibrary for AbilityLibrary { - fn map(&self) -> &IndexMap> { +impl DataLibrary for AbilityLibrary { + fn map(&self) -> &IndexMap> { &self.map } - fn get_modify(&mut self) -> &mut IndexMap> { + fn get_modify(&mut self) -> &mut IndexMap> { &mut self.map } } @@ -42,7 +42,7 @@ impl ValueIdentifiable for AbilityLibrary { #[cfg(test)] pub mod tests { - use crate::static_data::Ability; + use crate::static_data::AbilityImpl; use crate::static_data::AbilityLibrary; use crate::static_data::DataLibrary; use crate::StringKey; @@ -52,7 +52,11 @@ pub mod tests { let mut lib = AbilityLibrary::new(1); lib.add( &StringKey::new("test_ability"), - Arc::new(Ability::new(&"test_ability".into(), &"test_ability".into(), Vec::new())), + Arc::new(AbilityImpl::new( + &"test_ability".into(), + &"test_ability".into(), + Vec::new(), + )), ); lib } diff --git a/src/static_data/species_data/ability.rs b/src/static_data/species_data/ability.rs index 3318a51..6fb8e72 100755 --- a/src/static_data/species_data/ability.rs +++ b/src/static_data/species_data/ability.rs @@ -1,9 +1,20 @@ use crate::static_data::EffectParameter; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; +use std::fmt::Debug; + +/// An ability is a passive effect in battle that is attached to a Pokemon. +pub trait Ability: Debug + ValueIdentifiable { + /// The name of the ability. + fn name(&self) -> &StringKey; + /// The name of the script effect of the ability. + fn effect(&self) -> &StringKey; + /// The parameters for the script effect of the ability. + fn parameters(&self) -> &Vec; +} /// An ability is a passive effect in battle that is attached to a Pokemon. #[derive(Debug)] -pub struct Ability { +pub struct AbilityImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The name of the ability. @@ -14,7 +25,7 @@ pub struct Ability { parameters: Vec, } -impl Ability { +impl AbilityImpl { /// Instantiates a new ability. pub fn new(name: &StringKey, effect: &StringKey, parameters: Vec) -> Self { Self { @@ -24,22 +35,24 @@ impl Ability { parameters, } } +} +impl Ability for AbilityImpl { /// The name of the ability. - pub fn name(&self) -> &StringKey { + fn name(&self) -> &StringKey { &self.name } /// The name of the script effect of the ability. - pub fn effect(&self) -> &StringKey { + fn effect(&self) -> &StringKey { &self.effect } /// The parameters for the script effect of the ability. - pub fn parameters(&self) -> &Vec { + fn parameters(&self) -> &Vec { &self.parameters } } -impl ValueIdentifiable for Ability { +impl ValueIdentifiable for AbilityImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } diff --git a/src/static_data/species_data/form.rs b/src/static_data/species_data/form.rs index c98377a..d983240 100755 --- a/src/static_data/species_data/form.rs +++ b/src/static_data/species_data/form.rs @@ -116,7 +116,7 @@ impl Form { } /// Find the index of an ability that can be on this form. - pub fn find_ability_index(&self, ability: &Ability) -> Option { + pub fn find_ability_index(&self, ability: &dyn Ability) -> Option { for (index, a) in self.abilities.iter().enumerate() { if a == ability.name() { return Some(AbilityIndex { diff --git a/tests/common/library_loader.rs b/tests/common/library_loader.rs index 3201ab1..ecec0d9 100755 --- a/tests/common/library_loader.rs +++ b/tests/common/library_loader.rs @@ -16,7 +16,7 @@ use pkmn_lib::dynamic_data::Gen7DamageLibrary; 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, + AbilityImpl, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, GrowthRateLibrary, ItemImpl, ItemLibrary, LearnableMoves, LibrarySettings, LookupGrowthRate, MoveData, MoveLibrary, NatureImpl, NatureLibrary, SecondaryEffect, Species, StaticData, StaticStatisticSet, Statistic, TypeLibrary, }; @@ -161,7 +161,7 @@ pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) { } } - ability_library.add(&name, Arc::new(Ability::new(&name, &effect, parameters))); + ability_library.add(&name, Arc::new(AbilityImpl::new(&name, &effect, parameters))); } }