A lot of work on type registration
This commit is contained in:
		| @@ -1,18 +0,0 @@ | ||||
| use crate::app_interface::StaticData; | ||||
| use crate::{impl_extern_ctor, ExternRef}; | ||||
|  | ||||
| pub struct BattleLibrary { | ||||
|     ptr: ExternRef<BattleLibrary>, | ||||
| } | ||||
|  | ||||
| impl_extern_ctor!(BattleLibrary); | ||||
|  | ||||
| impl BattleLibrary { | ||||
|     pub fn data_library(&self) -> StaticData { | ||||
|         unsafe { StaticData::new(battle_library_get_static_data(self.ptr)) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn battle_library_get_static_data(ptr: ExternRef<BattleLibrary>) -> ExternRef<StaticData>; | ||||
| } | ||||
| @@ -1,5 +0,0 @@ | ||||
| mod battle_library; | ||||
| mod turn_choices; | ||||
|  | ||||
| pub use battle_library::BattleLibrary; | ||||
| pub use turn_choices::*; | ||||
| @@ -1 +0,0 @@ | ||||
| pub struct BaseTurnChoice {} | ||||
							
								
								
									
										72
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| use crate::app_interface::{BattleParty, BattleRandom, BattleSide, Pokemon}; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{ | ||||
|     cached_value, cached_value_getters, wasm_value_getters, DynamicLibrary, ExternRef, | ||||
|     ExternalReferenceType, ImmutableList, VecExternRef, | ||||
| }; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct BattleInner { | ||||
|     reference: ExternRef<Battle>, | ||||
|     library: CachedValue<DynamicLibrary>, | ||||
|     parties: CachedValue<ImmutableList<BattleParty>>, | ||||
|     sides: CachedValue<ImmutableList<BattleSide>>, | ||||
|     random: CachedValue<BattleRandom>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Battle { | ||||
|     inner: Rc<BattleInner>, | ||||
| } | ||||
|  | ||||
| impl Battle { | ||||
|     pub fn new(reference: ExternRef<Battle>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(BattleInner { | ||||
|                 reference, | ||||
|                 library: cached_value!({ battle_get_library(reference).get_value().unwrap() }), | ||||
|                 parties: cached_value!({ battle_get_parties(reference).get_immutable_list() }), | ||||
|                 sides: cached_value!({ battle_get_sides(reference).get_immutable_list() }), | ||||
|                 random: cached_value!({ battle_get_random(reference).get_value().unwrap() }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn library(&self) -> DynamicLibrary; | ||||
|         pub fn parties(&self) -> ImmutableList<BattleParty>; | ||||
|         pub fn sides(&self) -> ImmutableList<BattleSide>; | ||||
|     } | ||||
|  | ||||
|     pub fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon> { | ||||
|         unsafe { battle_get_pokemon(self.inner.reference, side, index).get_value() } | ||||
|     } | ||||
| } | ||||
|  | ||||
| wasm_value_getters! { | ||||
|     Battle, | ||||
|     pub fn can_flee(&self) -> bool; | ||||
|     pub fn number_of_sides(&self) -> u8; | ||||
|     pub fn pokemon_per_side(&self) -> u8; | ||||
|     pub fn has_ended(&self) -> bool; | ||||
|     pub fn has_ended_conclusively(&self) -> bool; | ||||
|     pub fn winning_side(&self) -> u8; | ||||
|     pub fn current_turn(&self) -> u32; | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(Battle); | ||||
|  | ||||
| impl ExternalReferenceType for Battle { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn battle_get_library(r: ExternRef<Battle>) -> ExternRef<DynamicLibrary>; | ||||
|     fn battle_get_parties(r: ExternRef<Battle>) -> VecExternRef<BattleParty>; | ||||
|     fn battle_get_sides(r: ExternRef<Battle>) -> VecExternRef<BattleSide>; | ||||
|     fn battle_get_random(r: ExternRef<Battle>) -> ExternRef<BattleRandom>; | ||||
|     fn battle_get_pokemon(r: ExternRef<Battle>, side: u8, index: u8) -> ExternRef<Pokemon>; | ||||
| } | ||||
| @@ -0,0 +1,42 @@ | ||||
| use crate::app_interface::Party; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType}; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct BattlePartyInner { | ||||
|     reference: ExternRef<BattleParty>, | ||||
|     party: CachedValue<Party>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct BattleParty { | ||||
|     inner: Rc<BattlePartyInner>, | ||||
| } | ||||
|  | ||||
| impl BattleParty { | ||||
|     pub fn new(reference: ExternRef<BattleParty>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(BattlePartyInner { | ||||
|                 reference, | ||||
|                 party: cached_value!({ battle_party_get_party(reference).get_value().unwrap() }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn party(&self) -> Party; | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(BattleParty); | ||||
|  | ||||
| impl ExternalReferenceType for BattleParty { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn battle_party_get_party(r: ExternRef<BattleParty>) -> ExternRef<Party>; | ||||
| } | ||||
| @@ -0,0 +1,32 @@ | ||||
| use crate::{ExternRef, ExternalReferenceType}; | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct BattleRandom { | ||||
|     reference: ExternRef<Self>, | ||||
| } | ||||
|  | ||||
| impl BattleRandom { | ||||
|     pub fn get(&self) -> i32 { | ||||
|         unsafe { battle_random_get(self.reference) } | ||||
|     } | ||||
|     pub fn get_max(&self, max: i32) -> i32 { | ||||
|         unsafe { battle_random_get_max(self.reference, max) } | ||||
|     } | ||||
|     pub fn get_between(&self, min: i32, max: i32) -> i32 { | ||||
|         unsafe { battle_random_get_between(self.reference, min, max) } | ||||
|     } | ||||
|     // TODO: effect_chance() | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for BattleRandom { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self { reference } | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn battle_random_get(r: ExternRef<BattleRandom>) -> i32; | ||||
|     fn battle_random_get_max(r: ExternRef<BattleRandom>, max: i32) -> i32; | ||||
|     fn battle_random_get_between(r: ExternRef<BattleRandom>, min: i32, max: i32) -> i32; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,63 @@ | ||||
| use crate::app_interface::{Battle, Pokemon}; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{ | ||||
|     cached_value, cached_value_getters, wasm_value_getters, ExternRef, ExternalReferenceType, | ||||
| }; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct BattleSideInner { | ||||
|     reference: ExternRef<BattleSide>, | ||||
|     side_index: CachedValue<u8>, | ||||
|     pokemon_per_side: CachedValue<u8>, | ||||
|     battle: CachedValue<Battle>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct BattleSide { | ||||
|     inner: Rc<BattleSideInner>, | ||||
| } | ||||
|  | ||||
| impl BattleSide { | ||||
|     pub fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(BattleSideInner { | ||||
|                 reference, | ||||
|                 side_index: cached_value!({ battleside_get_side_index(reference) }), | ||||
|                 pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }), | ||||
|                 battle: cached_value!({ battleside_get_battle(reference).get_value().unwrap() }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn side_index(&self) -> u8; | ||||
|         pub fn pokemon_per_side(&self) -> u8; | ||||
|         pub fn battle(&self) -> Battle; | ||||
|     } | ||||
|  | ||||
|     pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> { | ||||
|         unsafe { battleside_get_pokemon(self.inner.reference, index).get_value() } | ||||
|     } | ||||
| } | ||||
|  | ||||
| wasm_value_getters! { | ||||
|     BattleSide, | ||||
|     pub fn has_fled_battle(&self) -> bool; | ||||
|     pub fn is_defeated(&self) -> bool; | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(BattleSide); | ||||
|  | ||||
| impl ExternalReferenceType for BattleSide { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn battleside_get_side_index(r: ExternRef<BattleSide>) -> u8; | ||||
|     fn battleside_get_pokemon_per_side(r: ExternRef<BattleSide>) -> u8; | ||||
|     fn battleside_get_battle(r: ExternRef<BattleSide>) -> ExternRef<Battle>; | ||||
|     fn battleside_get_pokemon(r: ExternRef<BattleSide>, index: usize) -> ExternRef<Pokemon>; | ||||
| } | ||||
| @@ -0,0 +1,44 @@ | ||||
| use crate::app_interface::StaticData; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{cached_value, ExternRef, ExternalReferenceType}; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct DynamicLibraryInner { | ||||
|     ptr: ExternRef<DynamicLibrary>, | ||||
|     static_data: CachedValue<StaticData>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct DynamicLibrary { | ||||
|     inner: Rc<DynamicLibraryInner>, | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(DynamicLibrary); | ||||
|  | ||||
| impl DynamicLibrary { | ||||
|     pub(crate) fn new(ptr: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(ptr, &|ptr| Self { | ||||
|             inner: Rc::new(DynamicLibraryInner { | ||||
|                 ptr, | ||||
|                 static_data: cached_value!({ | ||||
|                     dynamic_library_get_static_data(ptr).get_value().unwrap() | ||||
|                 }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn data_library(&self) -> StaticData { | ||||
|         self.inner.static_data.value() | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for DynamicLibrary { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         DynamicLibrary::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn dynamic_library_get_static_data(ptr: ExternRef<DynamicLibrary>) -> ExternRef<StaticData>; | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| use crate::app_interface::MoveData; | ||||
| use crate::handling::cacheable::Cacheable; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::{ | ||||
|     cached_value, cached_value_getters, wasm_value_getters, ExternRef, ExternalReferenceType, | ||||
| }; | ||||
|  | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct LearnedMoveInner { | ||||
|     reference: ExternRef<LearnedMove>, | ||||
|     move_data: CachedValue<MoveData>, | ||||
|     learn_method: CachedValue<MoveLearnMethod>, | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone, Debug, Default)] | ||||
| #[repr(u8)] | ||||
| pub enum MoveLearnMethod { | ||||
|     /// We do not know the learn method. | ||||
|     #[default] | ||||
|     Unknown = 0, | ||||
|     /// The move was learned through level up. | ||||
|     Level = 1, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct LearnedMove { | ||||
|     inner: Rc<LearnedMoveInner>, | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(LearnedMove); | ||||
|  | ||||
| impl ExternalReferenceType for LearnedMove { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl LearnedMove { | ||||
|     pub fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(LearnedMoveInner { | ||||
|                 reference, | ||||
|                 move_data: cached_value!({ | ||||
|                     learned_move_get_move_data(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 learn_method: cached_value!({ learned_move_get_learn_method(reference) }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn move_data(&self) -> MoveData; | ||||
|         pub fn learn_method(&self) -> MoveLearnMethod; | ||||
|     } | ||||
|  | ||||
|     pub fn restore_all_uses(&self) { | ||||
|         unsafe { | ||||
|             learned_move_restore_all_uses(self.inner.reference); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn restore_uses(&self, uses: u8) { | ||||
|         unsafe { | ||||
|             learned_move_restore_uses(self.inner.reference, uses); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| wasm_value_getters! { | ||||
|     LearnedMove, | ||||
|     pub fn max_pp(&self) -> u8; | ||||
|     pub fn remaining_pp(&self) -> u8; | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn learned_move_get_move_data(r: ExternRef<LearnedMove>) -> ExternRef<MoveData>; | ||||
|     fn learned_move_get_learn_method(r: ExternRef<LearnedMove>) -> MoveLearnMethod; | ||||
|     fn learned_move_restore_uses(r: ExternRef<LearnedMove>, uses: u8); | ||||
|     fn learned_move_restore_all_uses(r: ExternRef<LearnedMove>); | ||||
| } | ||||
							
								
								
									
										21
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| mod battle; | ||||
| mod battle_party; | ||||
| mod battle_random; | ||||
| mod battle_side; | ||||
| mod dynamic_library; | ||||
| mod learned_move; | ||||
| mod party; | ||||
| mod pokemon; | ||||
| mod statistic_set; | ||||
| mod turn_choices; | ||||
|  | ||||
| pub use battle::*; | ||||
| pub use battle_party::*; | ||||
| pub use battle_random::*; | ||||
| pub use battle_side::*; | ||||
| pub use dynamic_library::DynamicLibrary; | ||||
| pub use learned_move::*; | ||||
| pub use party::*; | ||||
| pub use pokemon::*; | ||||
| pub use statistic_set::*; | ||||
| pub use turn_choices::*; | ||||
							
								
								
									
										27
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/party.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/party.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| use crate::app_interface::Pokemon; | ||||
| use crate::{ExternRef, ExternalReferenceType}; | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Party { | ||||
|     reference: ExternRef<Party>, | ||||
| } | ||||
|  | ||||
| impl Party { | ||||
|     pub fn new(reference: ExternRef<Party>) -> Self { | ||||
|         Self { reference } | ||||
|     } | ||||
|  | ||||
|     pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> { | ||||
|         unsafe { party_get_pokemon(self.reference, index).get_value() } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for Party { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn party_get_pokemon(r: ExternRef<Party>, index: usize) -> ExternRef<Pokemon>; | ||||
| } | ||||
							
								
								
									
										236
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,236 @@ | ||||
| use crate::app_interface::ability::{Ability, AbilityIndex}; | ||||
| use crate::app_interface::{ | ||||
|     Battle, ClampedStatisticSet, Form, Gender, Item, LearnedMove, LevelInt, Nature, Species, | ||||
|     Statistic, StatisticSet, | ||||
| }; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{ | ||||
|     cached_value, cached_value_getters, wasm_optional_reference_getters, wasm_reference_getters, | ||||
|     wasm_value_getters, DynamicLibrary, ExternRef, ExternalReferenceType, Script, | ||||
| }; | ||||
| use alloc::boxed::Box; | ||||
| use alloc::rc::Rc; | ||||
| use cstr_core::{c_char, CString}; | ||||
|  | ||||
| struct PokemonInner { | ||||
|     reference: ExternRef<Pokemon>, | ||||
|     library: CachedValue<DynamicLibrary>, | ||||
|     // We cache the reference to the data, not the values stored inside, which are dynamic. | ||||
|     flat_stats: CachedValue<StatisticSet<u32>>, | ||||
|     // We cache the reference to the data, not the values stored inside, which are dynamic. | ||||
|     stat_boosts: CachedValue<ClampedStatisticSet<i8>>, | ||||
|     // We cache the reference to the data, not the values stored inside, which are dynamic. | ||||
|     boosted_stats: CachedValue<StatisticSet<u32>>, | ||||
|     // We cache the reference to the data, not the values stored inside, which are dynamic. | ||||
|     individual_values: CachedValue<ClampedStatisticSet<u8>>, | ||||
|     // We cache the reference to the data, not the values stored inside, which are dynamic. | ||||
|     effort_values: CachedValue<ClampedStatisticSet<u8>>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Pokemon { | ||||
|     inner: Rc<PokemonInner>, | ||||
| } | ||||
|  | ||||
| impl Pokemon { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(PokemonInner { | ||||
|                 reference, | ||||
|                 library: cached_value!({ pokemon_get_library(reference).get_value().unwrap() }), | ||||
|                 flat_stats: cached_value!({ | ||||
|                     pokemon_get_flat_stats(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 stat_boosts: cached_value!({ | ||||
|                     pokemon_get_stat_boosts(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 boosted_stats: cached_value!({ | ||||
|                     pokemon_get_boosted_stats(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 individual_values: cached_value!({ | ||||
|                     pokemon_get_individual_values(reference) | ||||
|                         .get_value() | ||||
|                         .unwrap() | ||||
|                 }), | ||||
|                 effort_values: cached_value!({ | ||||
|                     pokemon_get_effort_values(reference).get_value().unwrap() | ||||
|                 }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn library(&self) -> DynamicLibrary; | ||||
|         pub fn flat_stats(&self) -> StatisticSet<u32>; | ||||
|         pub fn stat_boosts(&self) -> ClampedStatisticSet<i8>; | ||||
|         pub fn boosted_stats(&self) -> StatisticSet<u32>; | ||||
|         pub fn individual_values(&self) -> ClampedStatisticSet<u8>; | ||||
|         pub fn effort_values(&self) -> ClampedStatisticSet<u8>; | ||||
|     } | ||||
|  | ||||
|     pub fn has_held_item(&self, name: &str) -> bool { | ||||
|         let cstr = CString::new(name).unwrap(); | ||||
|         unsafe { pokemon_has_held_item(self.inner.reference, cstr.as_ptr()) } | ||||
|     } | ||||
|  | ||||
|     pub fn set_held_item(&self, item: &Item) -> Option<Item> { | ||||
|         unsafe { pokemon_set_held_item(self.inner.reference, item.reference()).get_value() } | ||||
|     } | ||||
|  | ||||
|     pub fn remove_held_item(&self) -> Option<Item> { | ||||
|         unsafe { pokemon_remove_held_item(self.inner.reference).get_value() } | ||||
|     } | ||||
|  | ||||
|     pub fn consume_held_item(&self) -> bool { | ||||
|         unsafe { pokemon_consume_held_item(self.inner.reference) } | ||||
|     } | ||||
|  | ||||
|     pub fn max_health(&self) -> u32 { | ||||
|         self.boosted_stats().hp() | ||||
|     } | ||||
|  | ||||
|     pub fn get_type(&self, index: usize) -> u8 { | ||||
|         unsafe { pokemon_get_type(self.inner.reference, index) } | ||||
|     } | ||||
|     pub fn has_type(&self, type_identifier: u8) -> bool { | ||||
|         unsafe { pokemon_has_type(self.inner.reference, type_identifier) } | ||||
|     } | ||||
|     pub fn has_type_by_name(&self, type_name: &str) -> bool { | ||||
|         let type_identifier = self | ||||
|             .library() | ||||
|             .data_library() | ||||
|             .type_library() | ||||
|             .get_type_from_name(type_name); | ||||
|         if let Some(type_identifier) = type_identifier { | ||||
|             return self.has_type(type_identifier); | ||||
|         } | ||||
|         false | ||||
|     } | ||||
|     pub fn get_learned_move(&self, index: usize) -> Option<LearnedMove> { | ||||
|         unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() } | ||||
|     } | ||||
|     pub fn change_stat_boost( | ||||
|         &self, | ||||
|         stat: Statistic, | ||||
|         diff_amount: i8, | ||||
|         self_inflicted: bool, | ||||
|     ) -> bool { | ||||
|         unsafe { | ||||
|             pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn ability_script(&self) -> Option<&Box<dyn Script>> { | ||||
|         unsafe { pokemon_get_ability_script(self.inner.reference).as_ref() } | ||||
|     } | ||||
|  | ||||
|     pub fn change_species(&self, species: Species, form: Form) { | ||||
|         unsafe { | ||||
|             pokemon_change_species(self.inner.reference, species.reference(), form.reference()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn change_form(&self, form: Form) { | ||||
|         unsafe { | ||||
|             pokemon_change_form(self.inner.reference, form.reference()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn is_fainted(&self) -> bool { | ||||
|         self.current_health() == 0 | ||||
|     } | ||||
|  | ||||
|     pub fn damage(&self, damage: u32, source: DamageSource) { | ||||
|         unsafe { pokemon_damage(self.inner.reference, damage, source) } | ||||
|     } | ||||
|  | ||||
|     pub fn heal(&self, amount: u32, allow_revive: bool) -> bool { | ||||
|         unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| wasm_reference_getters! { | ||||
|     Pokemon, | ||||
|     pub fn species(&self) -> Species; | ||||
|     pub fn form(&self) -> Form; | ||||
|     pub fn active_ability(&self) -> Ability; | ||||
|     pub fn nature(&self) -> Nature; | ||||
| } | ||||
|  | ||||
| wasm_optional_reference_getters! { | ||||
|     Pokemon, | ||||
|     pub fn display_species(&self) -> Option<Species>; | ||||
|     pub fn display_form(&self) -> Option<Form>; | ||||
|     pub fn held_item(&self) -> Option<Item>; | ||||
|     pub fn battle(&self) -> Option<Battle>; | ||||
| } | ||||
|  | ||||
| wasm_value_getters! { | ||||
|     Pokemon, | ||||
|     pub fn level(&self) -> LevelInt; | ||||
|     pub fn experience(&self) -> u32; | ||||
|     pub fn unique_identifier(&self) -> u32; | ||||
|     pub fn gender(&self) -> Gender; | ||||
|     pub fn coloring(&self) -> u8; | ||||
|     pub fn current_health(&self) -> u32; | ||||
|     pub fn weight(&self) -> f32; | ||||
|     pub fn height(&self) -> f32; | ||||
|     pub fn nickname(&self) -> *const c_char; | ||||
|     pub fn real_ability(&self) -> AbilityIndex; | ||||
|     pub fn types_length(&self) -> usize; | ||||
|     pub fn battle_side_index(&self) -> u8; | ||||
|     pub fn battle_index(&self) -> u8; | ||||
|     pub fn is_ability_overriden(&self) -> u8; | ||||
|     pub fn allowed_experience_gain(&self) -> bool; | ||||
|     pub fn is_usable(&self) -> bool; | ||||
| } | ||||
|  | ||||
| /// A source of damage. This should be as unique as possible. | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| #[repr(u8)] | ||||
| pub enum DamageSource { | ||||
|     /// The damage is done by a move. | ||||
|     MoveDamage = 0, | ||||
|     /// The damage is done by something else. | ||||
|     Misc = 1, | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(Pokemon); | ||||
|  | ||||
| impl ExternalReferenceType for Pokemon { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn pokemon_get_library(r: ExternRef<Pokemon>) -> ExternRef<DynamicLibrary>; | ||||
|     fn pokemon_get_flat_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>; | ||||
|     fn pokemon_get_stat_boosts(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<i8>>; | ||||
|     fn pokemon_get_boosted_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>; | ||||
|     fn pokemon_get_individual_values(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<u8>>; | ||||
|     fn pokemon_get_effort_values(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<u8>>; | ||||
|     fn pokemon_has_held_item(r: ExternRef<Pokemon>, name: *const c_char) -> bool; | ||||
|     fn pokemon_set_held_item(r: ExternRef<Pokemon>, item: ExternRef<Item>) -> ExternRef<Item>; | ||||
|     fn pokemon_remove_held_item(r: ExternRef<Pokemon>) -> ExternRef<Item>; | ||||
|     fn pokemon_consume_held_item(r: ExternRef<Pokemon>) -> bool; | ||||
|     fn pokemon_get_type(r: ExternRef<Pokemon>, index: usize) -> u8; | ||||
|     fn pokemon_has_type(r: ExternRef<Pokemon>, identifier: u8) -> bool; | ||||
|     fn pokemon_get_learned_move(r: ExternRef<Pokemon>, index: usize) -> ExternRef<LearnedMove>; | ||||
|     fn pokemon_change_stat_boost( | ||||
|         r: ExternRef<Pokemon>, | ||||
|         tat: Statistic, | ||||
|         diff_amount: i8, | ||||
|         self_inflicted: bool, | ||||
|     ) -> bool; | ||||
|     fn pokemon_get_ability_script(r: ExternRef<Pokemon>) -> *const Box<dyn Script>; | ||||
|     fn pokemon_change_species( | ||||
|         r: ExternRef<Pokemon>, | ||||
|         species: ExternRef<Species>, | ||||
|         form: ExternRef<Form>, | ||||
|     ); | ||||
|     fn pokemon_change_form(r: ExternRef<Pokemon>, form: ExternRef<Form>); | ||||
|     fn pokemon_damage(r: ExternRef<Pokemon>, damage: u32, source: DamageSource); | ||||
|     fn pokemon_heal(r: ExternRef<Pokemon>, amount: u32, allow_revive: bool) -> bool; | ||||
| } | ||||
| @@ -0,0 +1,194 @@ | ||||
| use crate::app_interface::Statistic; | ||||
| use crate::{ExternRef, ExternalReferenceType}; | ||||
| use core::convert::{TryFrom, TryInto}; | ||||
| use core::fmt::Debug; | ||||
| use core::marker::PhantomData; | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct StatisticSet<T> | ||||
| where | ||||
|     T: TryFrom<i64>, | ||||
|     T: TryInto<i64>, | ||||
| { | ||||
|     reference: ExternRef<Self>, | ||||
|     _p: PhantomData<T>, | ||||
| } | ||||
|  | ||||
| impl<T> StatisticSet<T> | ||||
| where | ||||
|     T: TryFrom<i64>, | ||||
|     T: TryInto<i64>, | ||||
|     <T as TryFrom<i64>>::Error: Debug, | ||||
|     <T as TryInto<i64>>::Error: Debug, | ||||
| { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self { | ||||
|             reference, | ||||
|             _p: Default::default(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn hp(&self) -> T { | ||||
|         self.get_stat(Statistic::HP) | ||||
|     } | ||||
|     pub fn attack(&self) -> T { | ||||
|         self.get_stat(Statistic::Attack) | ||||
|     } | ||||
|     pub fn defense(&self) -> T { | ||||
|         self.get_stat(Statistic::Defense) | ||||
|     } | ||||
|     pub fn special_attack(&self) -> T { | ||||
|         self.get_stat(Statistic::SpecialAttack) | ||||
|     } | ||||
|     pub fn special_defense(&self) -> T { | ||||
|         self.get_stat(Statistic::SpecialDefense) | ||||
|     } | ||||
|     pub fn speed(&self) -> T { | ||||
|         self.get_stat(Statistic::Speed) | ||||
|     } | ||||
|  | ||||
|     pub fn get_stat(&self, stat: Statistic) -> T { | ||||
|         unsafe { | ||||
|             statistic_set_get(self.reference.cast(), stat) | ||||
|                 .try_into() | ||||
|                 .unwrap() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn set_stat(&self, stat: Statistic, value: T) { | ||||
|         unsafe { statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) } | ||||
|     } | ||||
|  | ||||
|     pub fn increase_stat(&self, stat: Statistic, value: T) { | ||||
|         unsafe { | ||||
|             statistic_set_increase_stat(self.reference.cast(), stat, value.try_into().unwrap()) | ||||
|         } | ||||
|     } | ||||
|     pub fn decrease_stat(&self, stat: Statistic, value: T) { | ||||
|         unsafe { | ||||
|             statistic_set_decrease_stat(self.reference.cast(), stat, value.try_into().unwrap()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T> ExternalReferenceType for StatisticSet<T> | ||||
| where | ||||
|     T: TryFrom<i64>, | ||||
|     T: TryInto<i64>, | ||||
|     <T as TryFrom<i64>>::Error: Debug, | ||||
|     <T as TryInto<i64>>::Error: Debug, | ||||
| { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         StatisticSet::<T>::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct ClampedStatisticSet<T> | ||||
| where | ||||
|     T: TryFrom<i64>, | ||||
|     T: TryInto<i64>, | ||||
| { | ||||
|     reference: ExternRef<Self>, | ||||
|     _p: PhantomData<T>, | ||||
| } | ||||
|  | ||||
| impl<T> ClampedStatisticSet<T> | ||||
| where | ||||
|     T: TryFrom<i64>, | ||||
|     T: TryInto<i64>, | ||||
|     <T as TryFrom<i64>>::Error: Debug, | ||||
|     <T as TryInto<i64>>::Error: Debug, | ||||
| { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self { | ||||
|             reference, | ||||
|             _p: Default::default(), | ||||
|         } | ||||
|     } | ||||
|     pub fn hp(&self) -> T { | ||||
|         self.get_stat(Statistic::HP) | ||||
|     } | ||||
|     pub fn attack(&self) -> T { | ||||
|         self.get_stat(Statistic::Attack) | ||||
|     } | ||||
|     pub fn defense(&self) -> T { | ||||
|         self.get_stat(Statistic::Defense) | ||||
|     } | ||||
|     pub fn special_attack(&self) -> T { | ||||
|         self.get_stat(Statistic::SpecialAttack) | ||||
|     } | ||||
|     pub fn special_defense(&self) -> T { | ||||
|         self.get_stat(Statistic::SpecialDefense) | ||||
|     } | ||||
|     pub fn speed(&self) -> T { | ||||
|         self.get_stat(Statistic::Speed) | ||||
|     } | ||||
|  | ||||
|     pub fn get_stat(&self, stat: Statistic) -> T { | ||||
|         unsafe { | ||||
|             clamped_statistic_set_get(self.reference.cast(), stat) | ||||
|                 .try_into() | ||||
|                 .unwrap() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn set_stat(&self, stat: Statistic, value: T) { | ||||
|         unsafe { clamped_statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) } | ||||
|     } | ||||
|  | ||||
|     pub fn increase_stat(&self, stat: Statistic, value: T) -> bool { | ||||
|         unsafe { | ||||
|             clamped_statistic_set_increase_stat( | ||||
|                 self.reference.cast(), | ||||
|                 stat, | ||||
|                 value.try_into().unwrap(), | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
|     pub fn decrease_stat(&self, stat: Statistic, value: T) -> bool { | ||||
|         unsafe { | ||||
|             clamped_statistic_set_decrease_stat( | ||||
|                 self.reference.cast(), | ||||
|                 stat, | ||||
|                 value.try_into().unwrap(), | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T> ExternalReferenceType for ClampedStatisticSet<T> | ||||
| where | ||||
|     T: TryFrom<i64>, | ||||
|     T: TryInto<i64>, | ||||
|     <T as TryFrom<i64>>::Error: Debug, | ||||
|     <T as TryInto<i64>>::Error: Debug, | ||||
| { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         ClampedStatisticSet::<T>::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn statistic_set_get(r: ExternRef<StatisticSet<i64>>, stat: Statistic) -> i64; | ||||
|     fn statistic_set_set(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64); | ||||
|     fn statistic_set_increase_stat(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64); | ||||
|     fn statistic_set_decrease_stat(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64); | ||||
|  | ||||
|     fn clamped_statistic_set_get(r: ExternRef<ClampedStatisticSet<i64>>, stat: Statistic) -> i64; | ||||
|     fn clamped_statistic_set_set( | ||||
|         r: ExternRef<ClampedStatisticSet<i64>>, | ||||
|         stat: Statistic, | ||||
|         value: i64, | ||||
|     ); | ||||
|     fn clamped_statistic_set_increase_stat( | ||||
|         r: ExternRef<ClampedStatisticSet<i64>>, | ||||
|         stat: Statistic, | ||||
|         value: i64, | ||||
|     ) -> bool; | ||||
|     fn clamped_statistic_set_decrease_stat( | ||||
|         r: ExternRef<ClampedStatisticSet<i64>>, | ||||
|         stat: Statistic, | ||||
|         value: i64, | ||||
|     ) -> bool; | ||||
| } | ||||
| @@ -0,0 +1,78 @@ | ||||
| use crate::app_interface::Pokemon; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::temporary::Temporary; | ||||
| use crate::{cached_value, ExternRef, ExternalReferenceType}; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct BaseTurnChoiceData { | ||||
|     reference: ExternRef<TurnChoice>, | ||||
|     user: CachedValue<Pokemon>, | ||||
| } | ||||
|  | ||||
| struct MoveTurnChoiceDataInner { | ||||
|     base: BaseTurnChoiceData, | ||||
| } | ||||
| #[derive(Clone)] | ||||
| struct MoveTurnChoiceDataTemporary { | ||||
|     inner: Rc<MoveTurnChoiceDataInner>, | ||||
| } | ||||
| pub struct MoveTurnChoiceData { | ||||
|     temp: Temporary<MoveTurnChoiceDataTemporary>, | ||||
| } | ||||
|  | ||||
| pub enum TurnChoice { | ||||
|     Move(MoveTurnChoiceData), | ||||
|     Item(), | ||||
|     Switch(), | ||||
|     Flee, | ||||
|     Pass, | ||||
| } | ||||
|  | ||||
| impl TurnChoice { | ||||
|     pub fn user(&self) -> Pokemon { | ||||
|         match self { | ||||
|             TurnChoice::Move(data) => data.temp.value().inner.base.user.value(), | ||||
|             _ => panic!("Unknown turn choice type"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for TurnChoice { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         let kind = unsafe { turn_choice_get_kind(reference) }; | ||||
|         match kind { | ||||
|             0 => TurnChoice::Move(MoveTurnChoiceData { | ||||
|                 temp: Temporary::from_reference(reference.cast()), | ||||
|             }), | ||||
|             _ => panic!("Unknown turn choice type"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for MoveTurnChoiceDataTemporary { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self { | ||||
|             inner: Rc::new(MoveTurnChoiceDataInner { | ||||
|                 base: BaseTurnChoiceData { | ||||
|                     reference: reference.cast(), | ||||
|                     user: cached_value!({ | ||||
|                         turn_choice_get_user(reference.cast()).get_value().unwrap() | ||||
|                     }), | ||||
|                 }, | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8; | ||||
|     fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<Pokemon>; | ||||
| } | ||||
|  | ||||
| #[no_mangle] | ||||
| unsafe extern "wasm" fn turn_choice_mark_deleted(r: ExternRef<TurnChoice>, kind: u8) { | ||||
|     match kind { | ||||
|         0 => Temporary::<MoveTurnChoiceDataTemporary>::mark_as_deleted(r.cast()), | ||||
|         _ => panic!("Unknown turn choice type"), | ||||
|     } | ||||
| } | ||||
| @@ -1,73 +0,0 @@ | ||||
| use crate::{impl_extern_ctor, ExternRef, ExternalReferenceType, StringKey}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use move_library::MoveLibrary; | ||||
| use spin::rwlock::RwLock; | ||||
|  | ||||
| pub mod item_library; | ||||
| pub mod move_library; | ||||
|  | ||||
| use crate::handling::Cacheable; | ||||
| pub use item_library::*; | ||||
| pub use move_library::*; | ||||
|  | ||||
| pub struct StaticData { | ||||
|     ptr: ExternRef<Self>, | ||||
| } | ||||
|  | ||||
| impl_extern_ctor!(StaticData); | ||||
| impl StaticData { | ||||
|     pub fn move_library(&self) -> MoveLibrary { | ||||
|         unsafe { MoveLibrary::new(static_data_get_move_library(self.ptr)) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn static_data_get_move_library(ptr: ExternRef<StaticData>) -> ExternRef<MoveLibrary>; | ||||
| } | ||||
|  | ||||
| pub trait DataLibrary<T>: Cacheable | ||||
| where | ||||
|     T: ExternalReferenceType, | ||||
|     T: Clone, | ||||
| { | ||||
|     fn get_cache(&self) -> &RwLock<BTreeMap<u32, T>>; | ||||
|     fn get_self_ref(&self) -> ExternRef<Self> | ||||
|     where | ||||
|         Self: Sized; | ||||
|     fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<T> | ||||
|     where | ||||
|         Self: Sized; | ||||
|     fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<T> | ||||
|     where | ||||
|         Self: Sized; | ||||
|  | ||||
|     fn get(&self, name: &StringKey) -> Option<T> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         if let Some(v) = self.get_cache().read().get(&name.hash()) { | ||||
|             return Some(v.clone()); | ||||
|         } | ||||
|  | ||||
|         let v = Self::_get_ref_by_name(self.get_self_ref(), name.ptr()).get_value(); | ||||
|         if let Some(v) = &v { | ||||
|             self.get_cache().write().insert(name.hash(), v.clone()); | ||||
|         } | ||||
|         v | ||||
|     } | ||||
|  | ||||
|     fn get_by_hash(&self, hash: u32) -> Option<T> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         if let Some(v) = self.get_cache().read().get(&hash) { | ||||
|             return Some(v.clone()); | ||||
|         } | ||||
|  | ||||
|         let v = Self::_get_ref_by_hash(self.get_self_ref(), hash).get_value(); | ||||
|         if let Some(v) = &v { | ||||
|             self.get_cache().write().insert(hash, v.clone()); | ||||
|         } | ||||
|         v | ||||
|     } | ||||
| } | ||||
| @@ -1,149 +0,0 @@ | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{ | ||||
|     cached_value, ExternRef, ExternalReferenceType, FFIArray, ImmutableList, StringKey, | ||||
|     VecExternRef, | ||||
| }; | ||||
| use alloc::rc::Rc; | ||||
| use alloc::vec::Vec; | ||||
|  | ||||
| #[repr(u8)] | ||||
| pub enum Gender { | ||||
|     Male = 0, | ||||
|     Female = 1, | ||||
|     Genderless = 2, | ||||
| } | ||||
|  | ||||
| #[repr(u8)] | ||||
| pub enum Statistic { | ||||
|     HP = 0, | ||||
|     Attack = 1, | ||||
|     Defense = 2, | ||||
|     SpecialAttack = 3, | ||||
|     SpecialDefense = 4, | ||||
|     Speed = 5, | ||||
| } | ||||
|  | ||||
| pub struct ImmutableStatisticSetInner { | ||||
|     ptr: ExternRef<ImmutableStatisticSet>, | ||||
|     /// The health point stat value. | ||||
|     hp: CachedValue<u16>, | ||||
|     /// The physical attack stat value. | ||||
|     attack: CachedValue<u16>, | ||||
|     /// The physical defense stat value. | ||||
|     defense: CachedValue<u16>, | ||||
|     /// The special attack stat value. | ||||
|     special_attack: CachedValue<u16>, | ||||
|     /// The special defense stat value. | ||||
|     special_defense: CachedValue<u16>, | ||||
|     /// The speed stat value. | ||||
|     speed: CachedValue<u16>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct ImmutableStatisticSet { | ||||
|     inner: Rc<ImmutableStatisticSetInner>, | ||||
| } | ||||
|  | ||||
| impl ImmutableStatisticSet { | ||||
|     pub(crate) fn new(ptr: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(ptr, &|ptr| Self { | ||||
|             inner: Rc::new(ImmutableStatisticSetInner { | ||||
|                 ptr, | ||||
|                 hp: cached_value!({ static_statistics_set_get_hp(ptr) }), | ||||
|                 attack: cached_value!({ static_statistics_set_get_attack(ptr) }), | ||||
|                 defense: cached_value!({ static_statistics_set_get_defense(ptr) }), | ||||
|                 special_attack: cached_value!({ static_statistics_set_get_special_attack(ptr) }), | ||||
|                 special_defense: cached_value!({ static_statistics_set_get_special_defense(ptr) }), | ||||
|                 speed: cached_value!({ static_statistics_set_get_speed(ptr) }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn hp(&self) -> u16 { | ||||
|         self.inner.hp.value() | ||||
|     } | ||||
|     pub fn attack(&self) -> u16 { | ||||
|         self.inner.attack.value() | ||||
|     } | ||||
|     pub fn defense(&self) -> u16 { | ||||
|         self.inner.defense.value() | ||||
|     } | ||||
|     pub fn special_attack(&self) -> u16 { | ||||
|         self.inner.special_attack.value() | ||||
|     } | ||||
|     pub fn special_defense(&self) -> u16 { | ||||
|         self.inner.special_defense.value() | ||||
|     } | ||||
|     pub fn speed(&self) -> u16 { | ||||
|         self.inner.speed.value() | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct FormInner { | ||||
|     ptr: ExternRef<Form>, | ||||
|     name: CachedValue<StringKey>, | ||||
|     height: CachedValue<f32>, | ||||
|     weight: CachedValue<f32>, | ||||
|     types: CachedValue<Vec<u8>>, | ||||
|     base_experience: CachedValue<u32>, | ||||
|     base_stats: CachedValue<ImmutableStatisticSet>, | ||||
|     abilities: CachedValue<ImmutableList<StringKey>>, | ||||
|     hidden_abilities: CachedValue<ImmutableList<StringKey>>, | ||||
|     // moves: CachedValue<LearnableMoves>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Form { | ||||
|     inner: Rc<FormInner>, | ||||
| } | ||||
|  | ||||
| impl Form { | ||||
|     pub(crate) fn new(ptr: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(ptr, &|ptr| Self { | ||||
|             inner: Rc::new(FormInner { | ||||
|                 ptr, | ||||
|                 name: cached_value!({ form_get_name(ptr).get_value().unwrap() }), | ||||
|                 height: cached_value!({ form_get_height(ptr) }), | ||||
|                 weight: cached_value!({ form_get_weight(ptr) }), | ||||
|                 types: cached_value!({ | ||||
|                     let raw = form_get_types(ptr); | ||||
|                     Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len()) | ||||
|                 }), | ||||
|                 base_experience: cached_value!({ form_get_base_experience(ptr) }), | ||||
|                 base_stats: cached_value!({ form_get_base_stats(ptr).get_value().unwrap() }), | ||||
|                 abilities: cached_value!({ form_get_abilities(ptr).get_immutable_list() }), | ||||
|                 hidden_abilities: cached_value!({ | ||||
|                     form_get_hidden_abilities(ptr).get_immutable_list() | ||||
|                 }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for ImmutableStatisticSet { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         ImmutableStatisticSet::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(ImmutableStatisticSet); | ||||
| crate::handling::cacheable::cacheable!(Form); | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn static_statistics_set_get_hp(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_attack(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_defense(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_special_attack(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_special_defense(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_speed(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|  | ||||
|     fn form_get_name(r: ExternRef<Form>) -> ExternRef<StringKey>; | ||||
|     fn form_get_height(r: ExternRef<Form>) -> f32; | ||||
|     fn form_get_weight(r: ExternRef<Form>) -> f32; | ||||
|     fn form_get_types(r: ExternRef<Form>) -> FFIArray<u8>; | ||||
|     fn form_get_base_experience(r: ExternRef<Form>) -> u32; | ||||
|     fn form_get_base_stats(r: ExternRef<Form>) -> ExternRef<ImmutableStatisticSet>; | ||||
|     fn form_get_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>; | ||||
|     fn form_get_hidden_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>; | ||||
| } | ||||
| @@ -1,9 +1,9 @@ | ||||
| pub mod battling; | ||||
| pub mod library; | ||||
| pub mod dynamic_data; | ||||
| pub mod list; | ||||
| pub mod static_data; | ||||
| pub mod string_key; | ||||
|  | ||||
| pub use battling::*; | ||||
| pub use library::*; | ||||
| pub use dynamic_data::*; | ||||
| pub use static_data::*; | ||||
| pub use string_key::get_hash; | ||||
| pub use string_key::StringKey; | ||||
|   | ||||
							
								
								
									
										60
									
								
								pkmn_lib_interface/src/app_interface/static_data/ability.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								pkmn_lib_interface/src/app_interface/static_data/ability.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| use crate::handling::cacheable::Cacheable; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::{ | ||||
|     cached_value, cached_value_getters, EffectParameter, ExternRef, ExternalReferenceType, | ||||
|     ImmutableList, StringKey, VecExternRef, | ||||
| }; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct AbilityInner { | ||||
|     reference: ExternRef<Ability>, | ||||
|     name: CachedValue<StringKey>, | ||||
|     effect: CachedValue<StringKey>, | ||||
|     parameters: CachedValue<ImmutableList<EffectParameter>>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Ability { | ||||
|     inner: Rc<AbilityInner>, | ||||
| } | ||||
|  | ||||
| impl Ability { | ||||
|     pub fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(AbilityInner { | ||||
|                 reference, | ||||
|                 name: cached_value!({ ability_get_name(reference).get_value().unwrap() }), | ||||
|                 effect: cached_value!({ ability_get_effect(reference).get_value().unwrap() }), | ||||
|                 parameters: cached_value!({ | ||||
|                     ability_get_parameters(reference).get_immutable_list() | ||||
|                 }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn name(&self) -> StringKey; | ||||
|         pub fn effect(&self) -> StringKey; | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for Ability { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(Ability); | ||||
|  | ||||
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||||
| #[repr(C)] | ||||
| pub struct AbilityIndex { | ||||
|     pub hidden: bool, | ||||
|     pub index: u8, | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn ability_get_name(r: ExternRef<Ability>) -> ExternRef<StringKey>; | ||||
|     fn ability_get_effect(r: ExternRef<Ability>) -> ExternRef<StringKey>; | ||||
|     fn ability_get_parameters(r: ExternRef<Ability>) -> VecExternRef<EffectParameter>; | ||||
| } | ||||
| @@ -1,6 +1,5 @@ | ||||
| use crate::app_interface::{DataLibrary, Item}; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{ExternRef, StringKey}; | ||||
| use crate::{ExternRef, ExternalReferenceType, StringKey}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use alloc::rc::Rc; | ||||
| use spin::rwlock::RwLock; | ||||
| @@ -32,7 +31,7 @@ impl DataLibrary<Item> for ItemLibrary { | ||||
|     } | ||||
| 
 | ||||
|     fn get_self_ref(&self) -> ExternRef<Self> { | ||||
|         self.inner.ptr.clone() | ||||
|         self.inner.ptr | ||||
|     } | ||||
| 
 | ||||
|     fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<Item> { | ||||
| @@ -44,17 +43,14 @@ impl DataLibrary<Item> for ItemLibrary { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Cacheable for ItemLibrary { | ||||
|     fn get_cache<'a>() -> &'a mut BTreeMap<ExternRef<Self>, Self> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         unsafe { &mut CACHE } | ||||
| crate::handling::cacheable::cacheable!(ItemLibrary); | ||||
| 
 | ||||
| impl ExternalReferenceType for ItemLibrary { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static mut CACHE: BTreeMap<ExternRef<ItemLibrary>, ItemLibrary> = BTreeMap::new(); | ||||
| 
 | ||||
| extern "wasm" { | ||||
|     fn move_library_get_move( | ||||
|         ptr: ExternRef<ItemLibrary>, | ||||
| @@ -0,0 +1,149 @@ | ||||
| use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use alloc::rc::Rc; | ||||
| use move_library::MoveLibrary; | ||||
| use spin::rwlock::RwLock; | ||||
|  | ||||
| pub mod item_library; | ||||
| pub mod move_library; | ||||
| pub mod species_library; | ||||
| pub mod type_library; | ||||
|  | ||||
| use crate::app_interface::species_library::SpeciesLibrary; | ||||
| use crate::app_interface::type_library::TypeLibrary; | ||||
| use crate::app_interface::LevelInt; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| pub use item_library::*; | ||||
| pub use move_library::*; | ||||
|  | ||||
| struct StaticDataInner { | ||||
|     reference: ExternRef<StaticData>, | ||||
|     move_library: CachedValue<MoveLibrary>, | ||||
|     item_library: CachedValue<ItemLibrary>, | ||||
|     species_library: CachedValue<SpeciesLibrary>, | ||||
|     type_library: CachedValue<TypeLibrary>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct StaticData { | ||||
|     inner: Rc<StaticDataInner>, | ||||
| } | ||||
|  | ||||
| impl StaticData { | ||||
|     pub(crate) fn new(reference: ExternRef<StaticData>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(StaticDataInner { | ||||
|                 reference, | ||||
|                 move_library: cached_value!({ | ||||
|                     static_data_get_move_library(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 item_library: cached_value!({ | ||||
|                     static_data_get_item_library(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 species_library: cached_value!({ | ||||
|                     static_data_get_species_library(reference) | ||||
|                         .get_value() | ||||
|                         .unwrap() | ||||
|                 }), | ||||
|                 type_library: cached_value!({ | ||||
|                     static_data_get_type_library(reference).get_value().unwrap() | ||||
|                 }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn move_library(&self) -> MoveLibrary; | ||||
|         pub fn item_library(&self) -> ItemLibrary; | ||||
|         pub fn species_library(&self) -> SpeciesLibrary; | ||||
|         pub fn type_library(&self) -> TypeLibrary; | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(StaticData); | ||||
|  | ||||
| impl ExternalReferenceType for StaticData { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         StaticData::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct LibrarySettingsInner { | ||||
|     maximum_level: CachedValue<LevelInt>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct LibrarySettings { | ||||
|     inner: Rc<LibrarySettingsInner>, | ||||
| } | ||||
|  | ||||
| impl LibrarySettings { | ||||
|     pub(crate) fn new(ptr: ExternRef<LibrarySettings>) -> Self { | ||||
|         Self { | ||||
|             inner: Rc::new(LibrarySettingsInner { | ||||
|                 maximum_level: cached_value!({ library_settings_get_maximum_level(ptr) }), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn maximum_level(&self) -> LevelInt; | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn static_data_get_move_library(ptr: ExternRef<StaticData>) -> ExternRef<MoveLibrary>; | ||||
|     fn static_data_get_item_library(ptr: ExternRef<StaticData>) -> ExternRef<ItemLibrary>; | ||||
|     fn static_data_get_species_library(ptr: ExternRef<StaticData>) -> ExternRef<SpeciesLibrary>; | ||||
|     fn static_data_get_type_library(ptr: ExternRef<StaticData>) -> ExternRef<TypeLibrary>; | ||||
|  | ||||
|     fn library_settings_get_maximum_level(ptr: ExternRef<LibrarySettings>) -> LevelInt; | ||||
| } | ||||
|  | ||||
| pub trait DataLibrary<T>: Cacheable | ||||
| where | ||||
|     T: ExternalReferenceType, | ||||
|     T: Clone, | ||||
| { | ||||
|     fn get_cache(&self) -> &RwLock<BTreeMap<u32, T>>; | ||||
|     fn get_self_ref(&self) -> ExternRef<Self> | ||||
|     where | ||||
|         Self: Sized; | ||||
|     fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<T> | ||||
|     where | ||||
|         Self: Sized; | ||||
|     fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<T> | ||||
|     where | ||||
|         Self: Sized; | ||||
|  | ||||
|     fn get(&self, name: &StringKey) -> Option<T> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         if let Some(v) = self.get_cache().read().get(&name.hash()) { | ||||
|             return Some(v.clone()); | ||||
|         } | ||||
|  | ||||
|         let v = Self::_get_ref_by_name(self.get_self_ref(), name.ptr()).get_value(); | ||||
|         if let Some(v) = &v { | ||||
|             self.get_cache().write().insert(name.hash(), v.clone()); | ||||
|         } | ||||
|         v | ||||
|     } | ||||
|  | ||||
|     fn get_by_hash(&self, hash: u32) -> Option<T> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         if let Some(v) = self.get_cache().read().get(&hash) { | ||||
|             return Some(v.clone()); | ||||
|         } | ||||
|  | ||||
|         let v = Self::_get_ref_by_hash(self.get_self_ref(), hash).get_value(); | ||||
|         if let Some(v) = &v { | ||||
|             self.get_cache().write().insert(hash, v.clone()); | ||||
|         } | ||||
|         v | ||||
|     } | ||||
| } | ||||
| @@ -1,7 +1,6 @@ | ||||
| use crate::app_interface::data_libraries::DataLibrary; | ||||
| use crate::app_interface::{MoveData, StringKey}; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::ExternRef; | ||||
| use crate::{ExternRef, ExternalReferenceType}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use alloc::rc::Rc; | ||||
| use spin::RwLock; | ||||
| @@ -33,7 +32,7 @@ impl DataLibrary<MoveData> for MoveLibrary { | ||||
|     } | ||||
| 
 | ||||
|     fn get_self_ref(&self) -> ExternRef<Self> { | ||||
|         self.inner.ptr.clone() | ||||
|         self.inner.ptr | ||||
|     } | ||||
| 
 | ||||
|     fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<MoveData> { | ||||
| @@ -45,17 +44,14 @@ impl DataLibrary<MoveData> for MoveLibrary { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Cacheable for MoveLibrary { | ||||
|     fn get_cache<'a>() -> &'a mut BTreeMap<ExternRef<Self>, Self> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         unsafe { &mut CACHE } | ||||
| crate::handling::cacheable::cacheable!(MoveLibrary); | ||||
| 
 | ||||
| impl ExternalReferenceType for MoveLibrary { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static mut CACHE: BTreeMap<ExternRef<MoveLibrary>, MoveLibrary> = BTreeMap::new(); | ||||
| 
 | ||||
| extern "wasm" { | ||||
|     fn move_library_get_move( | ||||
|         ptr: ExternRef<MoveLibrary>, | ||||
| @@ -0,0 +1,63 @@ | ||||
| use crate::app_interface::{DataLibrary, Species}; | ||||
| use crate::{ExternRef, ExternalReferenceType, StringKey}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use alloc::rc::Rc; | ||||
| use spin::RwLock; | ||||
|  | ||||
| struct SpeciesLibraryInner { | ||||
|     ptr: ExternRef<SpeciesLibrary>, | ||||
|     cache: RwLock<BTreeMap<u32, Species>>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct SpeciesLibrary { | ||||
|     inner: Rc<SpeciesLibraryInner>, | ||||
| } | ||||
|  | ||||
| impl SpeciesLibrary { | ||||
|     pub(crate) fn new(ptr: ExternRef<SpeciesLibrary>) -> Self { | ||||
|         Self { | ||||
|             inner: Rc::new(SpeciesLibraryInner { | ||||
|                 ptr, | ||||
|                 cache: Default::default(), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl DataLibrary<Species> for SpeciesLibrary { | ||||
|     fn get_cache(&self) -> &spin::rwlock::RwLock<BTreeMap<u32, Species>> { | ||||
|         &self.inner.cache | ||||
|     } | ||||
|  | ||||
|     fn get_self_ref(&self) -> ExternRef<Self> { | ||||
|         self.inner.ptr | ||||
|     } | ||||
|  | ||||
|     fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<Species> { | ||||
|         unsafe { species_library_get_species(ptr, name) } | ||||
|     } | ||||
|  | ||||
|     fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<Species> { | ||||
|         unsafe { species_library_get_species_by_hash(ptr, hash) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(SpeciesLibrary); | ||||
|  | ||||
| impl ExternalReferenceType for SpeciesLibrary { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn species_library_get_species( | ||||
|         ptr: ExternRef<SpeciesLibrary>, | ||||
|         name: ExternRef<StringKey>, | ||||
|     ) -> ExternRef<Species>; | ||||
|     fn species_library_get_species_by_hash( | ||||
|         ptr: ExternRef<SpeciesLibrary>, | ||||
|         hash: u32, | ||||
|     ) -> ExternRef<Species>; | ||||
| } | ||||
| @@ -0,0 +1,93 @@ | ||||
| use crate::{ExternRef, ExternalReferenceType}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use alloc::rc::Rc; | ||||
| use alloc::string::{String, ToString}; | ||||
| use cstr_core::{c_char, CString}; | ||||
| use spin::RwLock; | ||||
|  | ||||
| struct TypeLibraryInner { | ||||
|     reference: ExternRef<TypeLibrary>, | ||||
|     name_to_type_cache: RwLock<BTreeMap<String, u8>>, | ||||
|     effectiveness_cache: RwLock<BTreeMap<(u8, u8), f32>>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct TypeLibrary { | ||||
|     inner: Rc<TypeLibraryInner>, | ||||
| } | ||||
|  | ||||
| impl TypeLibrary { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self { | ||||
|             inner: Rc::new(TypeLibraryInner { | ||||
|                 reference, | ||||
|                 name_to_type_cache: Default::default(), | ||||
|                 effectiveness_cache: Default::default(), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get_type_from_name(&self, name: &str) -> Option<u8> { | ||||
|         if let Some(cached) = self.inner.name_to_type_cache.read().get(name) { | ||||
|             return Some(*cached); | ||||
|         } | ||||
|         let cstr = CString::new(name).unwrap(); | ||||
|         let v = unsafe { type_library_get_type_by_name(self.inner.reference, cstr.as_ptr()) }; | ||||
|         if v == 255 { | ||||
|             return None; | ||||
|         } | ||||
|         self.inner | ||||
|             .name_to_type_cache | ||||
|             .write() | ||||
|             .insert(name.to_string(), v); | ||||
|         Some(v) | ||||
|     } | ||||
|  | ||||
|     pub fn get_single_effectiveness(&self, attacking_type: u8, defending_type: u8) -> f32 { | ||||
|         if let Some(cached) = self | ||||
|             .inner | ||||
|             .effectiveness_cache | ||||
|             .read() | ||||
|             .get(&(attacking_type, defending_type)) | ||||
|         { | ||||
|             return *cached; | ||||
|         } | ||||
|         let effectiveness = unsafe { | ||||
|             type_library_get_single_effectiveness( | ||||
|                 self.inner.reference, | ||||
|                 attacking_type, | ||||
|                 defending_type, | ||||
|             ) | ||||
|         }; | ||||
|         self.inner | ||||
|             .effectiveness_cache | ||||
|             .write() | ||||
|             .insert((attacking_type, defending_type), effectiveness); | ||||
|         effectiveness | ||||
|     } | ||||
|  | ||||
|     pub fn get_effectiveness(&self, attacking_type: u8, defending_types: &[u8]) -> f32 { | ||||
|         let mut f = 1.0; | ||||
|         for defending_type in defending_types { | ||||
|             f *= self.get_single_effectiveness(attacking_type, *defending_type); | ||||
|         } | ||||
|         f | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(TypeLibrary); | ||||
|  | ||||
| impl ExternalReferenceType for TypeLibrary { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn type_library_get_single_effectiveness( | ||||
|         r: ExternRef<TypeLibrary>, | ||||
|         attacking_type: u8, | ||||
|         defending_type: u8, | ||||
|     ) -> f32; | ||||
|     fn type_library_get_type_by_name(r: ExternRef<TypeLibrary>, name: *const c_char) -> u8; | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{cached_value, ExternRef, ExternalReferenceType, StringKey}; | ||||
| use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey}; | ||||
| use alloc::rc::Rc; | ||||
| 
 | ||||
| /// An item category defines which bag slot items are stored in.
 | ||||
| @@ -42,7 +42,7 @@ pub enum BattleItemCategory { | ||||
| } | ||||
| 
 | ||||
| struct ItemInner { | ||||
|     ptr: ExternRef<Item>, | ||||
|     reference: ExternRef<Item>, | ||||
|     name: CachedValue<StringKey>, | ||||
|     category: CachedValue<ItemCategory>, | ||||
|     battle_category: CachedValue<BattleItemCategory>, | ||||
| @@ -56,40 +56,35 @@ pub struct Item { | ||||
| } | ||||
| 
 | ||||
| impl Item { | ||||
|     pub(crate) fn new(ptr: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(ptr, &|ptr| Self { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(ItemInner { | ||||
|                 ptr, | ||||
|                 name: cached_value!({ StringKey::new(item_get_name(ptr)) }), | ||||
|                 category: cached_value!({ item_get_category(ptr) }), | ||||
|                 battle_category: cached_value!({ item_get_battle_category(ptr) }), | ||||
|                 price: cached_value!({ item_get_price(ptr) }), | ||||
|                 reference, | ||||
|                 name: cached_value!({ StringKey::new(item_get_name(reference)) }), | ||||
|                 category: cached_value!({ item_get_category(reference) }), | ||||
|                 battle_category: cached_value!({ item_get_battle_category(reference) }), | ||||
|                 price: cached_value!({ item_get_price(reference) }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) fn ptr(&self) -> ExternRef<Self> { | ||||
|         self.inner.ptr | ||||
|     pub(crate) fn reference(&self) -> ExternRef<Self> { | ||||
|         self.inner.reference | ||||
|     } | ||||
| 
 | ||||
|     /// The name of the item.
 | ||||
|     pub fn name(&self) -> StringKey { | ||||
|         self.inner.name.value() | ||||
|     } | ||||
|     /// Which bag slot items are stored in.
 | ||||
|     pub fn category(&self) -> ItemCategory { | ||||
|         self.inner.category.value() | ||||
|     } | ||||
|     /// How the item is categorized when in battle.
 | ||||
|     pub fn battle_category(&self) -> BattleItemCategory { | ||||
|         self.inner.battle_category.value() | ||||
|     } | ||||
|     /// The buying value of the item.
 | ||||
|     pub fn price(&self) -> i32 { | ||||
|         self.inner.price.value() | ||||
|     cached_value_getters! { | ||||
|         /// The name of the item.
 | ||||
|         pub fn name(&self) -> StringKey; | ||||
|         /// Which bag slot items are stored in.
 | ||||
|         pub fn category(&self) -> ItemCategory; | ||||
|         /// How the item is categorized when in battle.
 | ||||
|         pub fn battle_category(&self) -> BattleItemCategory; | ||||
|         /// The buying value of the item.
 | ||||
|         pub fn price(&self) -> i32; | ||||
|     } | ||||
| 
 | ||||
|     pub fn has_flag(&self, flag: &StringKey) -> bool { | ||||
|         unsafe { item_has_flag(self.ptr(), flag.ptr()) } | ||||
|         unsafe { item_has_flag(self.inner.reference, flag.ptr()) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @@ -1,11 +1,16 @@ | ||||
| pub mod ability; | ||||
| pub mod data_libraries; | ||||
| pub mod effect_parameter; | ||||
| pub mod item; | ||||
| pub mod move_data; | ||||
| mod nature; | ||||
| pub mod species; | ||||
| 
 | ||||
| pub use data_libraries::*; | ||||
| pub use effect_parameter::EffectParameter; | ||||
| pub use item::*; | ||||
| pub use move_data::*; | ||||
| pub use nature::*; | ||||
| pub use species::*; | ||||
| 
 | ||||
| pub type LevelInt = u8; | ||||
| @@ -1,8 +1,7 @@ | ||||
| use crate::app_interface::StringKey; | ||||
| use crate::app_interface::{get_hash, StringKey}; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{cached_value, ExternRef, ExternalReferenceType}; | ||||
| use alloc::collections::BTreeMap; | ||||
| use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType}; | ||||
| use alloc::rc::Rc; | ||||
| 
 | ||||
| #[repr(u8)] | ||||
| @@ -66,36 +65,20 @@ impl MoveData { | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|     pub(crate) fn ptr(&self) -> ExternRef<Self> { | ||||
|         self.inner.ptr | ||||
|     } | ||||
| 
 | ||||
|     pub fn name(&self) -> StringKey { | ||||
|         self.inner.name.value() | ||||
|     cached_value_getters! { | ||||
|         pub fn name(&self) -> StringKey; | ||||
|         pub fn move_type(&self) -> u8; | ||||
|         pub fn category(&self) -> MoveCategory; | ||||
|         pub fn base_power(&self) -> u8; | ||||
|         pub fn accuracy(&self) -> u8; | ||||
|         pub fn base_usages(&self) -> u8; | ||||
|         pub fn target(&self) -> MoveTarget; | ||||
|         pub fn priority(&self) -> i8; | ||||
|     } | ||||
|     pub fn move_type(&self) -> u8 { | ||||
|         self.inner.move_type.value() | ||||
|     } | ||||
|     pub fn category(&self) -> MoveCategory { | ||||
|         self.inner.category.value() | ||||
|     } | ||||
|     pub fn base_power(&self) -> u8 { | ||||
|         self.inner.base_power.value() | ||||
|     } | ||||
|     pub fn accuracy(&self) -> u8 { | ||||
|         self.inner.accuracy.value() | ||||
|     } | ||||
|     pub fn base_usages(&self) -> u8 { | ||||
|         self.inner.base_usages.value() | ||||
|     } | ||||
|     pub fn target(&self) -> MoveTarget { | ||||
|         self.inner.target.value() | ||||
|     } | ||||
|     pub fn priority(&self) -> i8 { | ||||
|         self.inner.priority.value() | ||||
|     } | ||||
|     pub fn has_flag(&self, flag: &StringKey) -> bool { | ||||
|         unsafe { move_data_has_flag(self.ptr(), flag.ptr()) } | ||||
|     pub fn has_flag<const N: usize>(&self, flag: &[u8; N]) -> bool { | ||||
|         let hash = get_hash(flag); | ||||
|         unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @@ -116,5 +99,5 @@ extern "wasm" { | ||||
|     fn move_data_get_base_usages(ptr: ExternRef<MoveData>) -> u8; | ||||
|     fn move_data_get_target(ptr: ExternRef<MoveData>) -> MoveTarget; | ||||
|     fn move_data_get_priority(ptr: ExternRef<MoveData>) -> i8; | ||||
|     fn move_data_has_flag(ptr: ExternRef<MoveData>, flag: ExternRef<StringKey>) -> bool; | ||||
|     fn move_data_has_flag_by_hash(ptr: ExternRef<MoveData>, flag_hash: u32) -> bool; | ||||
| } | ||||
							
								
								
									
										52
									
								
								pkmn_lib_interface/src/app_interface/static_data/nature.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								pkmn_lib_interface/src/app_interface/static_data/nature.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| use crate::app_interface::Statistic; | ||||
| use crate::handling::cacheable::Cacheable; | ||||
| use crate::{ExternRef, ExternalReferenceType}; | ||||
| use alloc::rc::Rc; | ||||
|  | ||||
| struct NatureInner { | ||||
|     reference: ExternRef<Nature>, | ||||
|     /// The stat that should receive the increased modifier. | ||||
|     increase_stat: Statistic, | ||||
|     /// The stat that should receive the decreased modifier. | ||||
|     decrease_stat: Statistic, | ||||
|     /// The amount by which the increased stat is multiplied. | ||||
|     increase_modifier: f32, | ||||
|     /// The amount by which the decreased stat is multiplied. | ||||
|     decrease_modifier: f32, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Nature { | ||||
|     inner: Rc<NatureInner>, | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(Nature); | ||||
|  | ||||
| impl Nature { | ||||
|     pub fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| unsafe { | ||||
|             Self { | ||||
|                 inner: Rc::new(NatureInner { | ||||
|                     reference, | ||||
|                     increase_stat: nature_get_increase_stat(reference), | ||||
|                     decrease_stat: nature_get_decrease_stat(reference), | ||||
|                     increase_modifier: nature_get_increase_modifier(reference), | ||||
|                     decrease_modifier: nature_get_decrease_modifier(reference), | ||||
|                 }), | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for Nature { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn nature_get_increase_stat(r: ExternRef<Nature>) -> Statistic; | ||||
|     fn nature_get_decrease_stat(r: ExternRef<Nature>) -> Statistic; | ||||
|     fn nature_get_increase_modifier(r: ExternRef<Nature>) -> f32; | ||||
|     fn nature_get_decrease_modifier(r: ExternRef<Nature>) -> f32; | ||||
| } | ||||
							
								
								
									
										270
									
								
								pkmn_lib_interface/src/app_interface/static_data/species.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								pkmn_lib_interface/src/app_interface/static_data/species.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,270 @@ | ||||
| use crate::app_interface::get_hash; | ||||
| use crate::handling::cached_value::CachedValue; | ||||
| use crate::handling::Cacheable; | ||||
| use crate::{ | ||||
|     cached_value, cached_value_getters, ExternRef, ExternalReferenceType, FFIArray, ImmutableList, | ||||
|     StringKey, VecExternRef, | ||||
| }; | ||||
| use alloc::collections::BTreeMap; | ||||
| use alloc::rc::Rc; | ||||
| use alloc::vec::Vec; | ||||
| use spin::RwLock; | ||||
|  | ||||
| #[repr(u8)] | ||||
| pub enum Gender { | ||||
|     Male = 0, | ||||
|     Female = 1, | ||||
|     Genderless = 2, | ||||
| } | ||||
|  | ||||
| #[repr(u8)] | ||||
| pub enum Statistic { | ||||
|     HP = 0, | ||||
|     Attack = 1, | ||||
|     Defense = 2, | ||||
|     SpecialAttack = 3, | ||||
|     SpecialDefense = 4, | ||||
|     Speed = 5, | ||||
| } | ||||
|  | ||||
| pub struct ImmutableStatisticSetInner { | ||||
|     reference: ExternRef<ImmutableStatisticSet>, | ||||
|     /// The health point stat value. | ||||
|     hp: CachedValue<u16>, | ||||
|     /// The physical attack stat value. | ||||
|     attack: CachedValue<u16>, | ||||
|     /// The physical defense stat value. | ||||
|     defense: CachedValue<u16>, | ||||
|     /// The special attack stat value. | ||||
|     special_attack: CachedValue<u16>, | ||||
|     /// The special defense stat value. | ||||
|     special_defense: CachedValue<u16>, | ||||
|     /// The speed stat value. | ||||
|     speed: CachedValue<u16>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct ImmutableStatisticSet { | ||||
|     inner: Rc<ImmutableStatisticSetInner>, | ||||
| } | ||||
|  | ||||
| impl ImmutableStatisticSet { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(ImmutableStatisticSetInner { | ||||
|                 reference, | ||||
|                 hp: cached_value!({ static_statistics_set_get_hp(reference) }), | ||||
|                 attack: cached_value!({ static_statistics_set_get_attack(reference) }), | ||||
|                 defense: cached_value!({ static_statistics_set_get_defense(reference) }), | ||||
|                 special_attack: cached_value!({ | ||||
|                     static_statistics_set_get_special_attack(reference) | ||||
|                 }), | ||||
|                 special_defense: cached_value!({ | ||||
|                     static_statistics_set_get_special_defense(reference) | ||||
|                 }), | ||||
|                 speed: cached_value!({ static_statistics_set_get_speed(reference) }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn hp(&self) -> u16 { | ||||
|         self.inner.hp.value() | ||||
|     } | ||||
|     pub fn attack(&self) -> u16 { | ||||
|         self.inner.attack.value() | ||||
|     } | ||||
|     pub fn defense(&self) -> u16 { | ||||
|         self.inner.defense.value() | ||||
|     } | ||||
|     pub fn special_attack(&self) -> u16 { | ||||
|         self.inner.special_attack.value() | ||||
|     } | ||||
|     pub fn special_defense(&self) -> u16 { | ||||
|         self.inner.special_defense.value() | ||||
|     } | ||||
|     pub fn speed(&self) -> u16 { | ||||
|         self.inner.speed.value() | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct FormInner { | ||||
|     reference: ExternRef<Form>, | ||||
|     name: CachedValue<StringKey>, | ||||
|     height: CachedValue<f32>, | ||||
|     weight: CachedValue<f32>, | ||||
|     types: CachedValue<Vec<u8>>, | ||||
|     base_experience: CachedValue<u32>, | ||||
|     base_stats: CachedValue<ImmutableStatisticSet>, | ||||
|     abilities: CachedValue<ImmutableList<StringKey>>, | ||||
|     hidden_abilities: CachedValue<ImmutableList<StringKey>>, | ||||
|     // moves: CachedValue<LearnableMoves>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Form { | ||||
|     inner: Rc<FormInner>, | ||||
| } | ||||
|  | ||||
| impl Form { | ||||
|     pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||
|         Self::from_ref(reference, &|reference| Self { | ||||
|             inner: Rc::new(FormInner { | ||||
|                 reference, | ||||
|                 name: cached_value!({ form_get_name(reference).get_value().unwrap() }), | ||||
|                 height: cached_value!({ form_get_height(reference) }), | ||||
|                 weight: cached_value!({ form_get_weight(reference) }), | ||||
|                 types: cached_value!({ | ||||
|                     let raw = form_get_types(reference); | ||||
|                     Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len()) | ||||
|                 }), | ||||
|                 base_experience: cached_value!({ form_get_base_experience(reference) }), | ||||
|                 base_stats: cached_value!({ form_get_base_stats(reference).get_value().unwrap() }), | ||||
|                 abilities: cached_value!({ form_get_abilities(reference).get_immutable_list() }), | ||||
|                 hidden_abilities: cached_value!({ | ||||
|                     form_get_hidden_abilities(reference).get_immutable_list() | ||||
|                 }), | ||||
|             }), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn reference(&self) -> ExternRef<Self> { | ||||
|         self.inner.reference | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         pub fn name(&self) -> StringKey; | ||||
|         pub fn height(&self) -> f32; | ||||
|         pub fn weight(&self) -> f32; | ||||
|         pub fn base_experience(&self) -> u32; | ||||
|         pub fn base_stats(&self) -> ImmutableStatisticSet; | ||||
|         pub fn abilities(&self) -> ImmutableList<StringKey>; | ||||
|         pub fn hidden_abilities(&self) -> ImmutableList<StringKey>; | ||||
|     } | ||||
|     pub fn types(&self) -> &Vec<u8> { | ||||
|         self.inner.types.value_ref() | ||||
|     } | ||||
|  | ||||
|     pub fn has_flag<const N: usize>(&self, flag: &[u8; N]) -> bool { | ||||
|         let hash = get_hash(flag); | ||||
|         unsafe { form_has_flag_by_hash(self.inner.reference, hash) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct SpeciesInner { | ||||
|     reference: ExternRef<Species>, | ||||
|     id: CachedValue<u16>, | ||||
|     name: CachedValue<StringKey>, | ||||
|     gender_rate: CachedValue<f32>, | ||||
|     growth_rate: CachedValue<StringKey>, | ||||
|     capture_rate: CachedValue<u8>, | ||||
|     forms: RwLock<BTreeMap<u32, Option<Form>>>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct Species { | ||||
|     inner: Rc<SpeciesInner>, | ||||
| } | ||||
|  | ||||
| impl Species { | ||||
|     pub(crate) fn new(reference: ExternRef<Species>) -> Self { | ||||
|         Self { | ||||
|             inner: Rc::new(SpeciesInner { | ||||
|                 reference, | ||||
|                 id: cached_value!({ species_get_id(reference) }), | ||||
|                 name: cached_value!({ species_get_name(reference).get_value().unwrap() }), | ||||
|                 gender_rate: cached_value!({ species_get_gender_rate(reference) }), | ||||
|                 growth_rate: cached_value!({ | ||||
|                     species_get_growth_rate(reference).get_value().unwrap() | ||||
|                 }), | ||||
|                 capture_rate: cached_value!({ species_get_capture_rate(reference) }), | ||||
|                 forms: Default::default(), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn reference(&self) -> ExternRef<Self> { | ||||
|         self.inner.reference | ||||
|     } | ||||
|  | ||||
|     cached_value_getters! { | ||||
|         /// The national dex identifier of the Pokemon. | ||||
|         pub fn id(&self) -> u16; | ||||
|         /// The name of the Pokemon species. | ||||
|         pub fn name(&self) -> StringKey; | ||||
|         /// The chance between 0.0 and 1.0 that a Pokemon is female. | ||||
|         pub fn gender_rate(&self) -> f32; | ||||
|         /// How much experience is required for a level. | ||||
|         pub fn growth_rate(&self) -> StringKey; | ||||
|         /// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is | ||||
|         /// uncatchable. | ||||
|         pub fn capture_rate(&self) -> u8; | ||||
|     } | ||||
|  | ||||
|     pub fn get_form<const N: usize>(&self, form_name: &[u8; N]) -> Option<Form> { | ||||
|         let hash = get_hash(form_name); | ||||
|         unsafe { | ||||
|             if let Some(v) = self.inner.forms.read().get(&hash) { | ||||
|                 v.clone() | ||||
|             } else { | ||||
|                 let r = species_get_form_by_hash(self.inner.reference, hash); | ||||
|                 let value = r.get_value(); | ||||
|                 self.inner.forms.write().insert(hash, value.clone()); | ||||
|                 value | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn has_flag<const N: usize>(&self, flag: &[u8; N]) -> bool { | ||||
|         let hash = get_hash(flag); | ||||
|         unsafe { species_has_flag_by_hash(self.inner.reference, hash) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for ImmutableStatisticSet { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for Form { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ExternalReferenceType for Species { | ||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||
|         Self::new(reference) | ||||
|     } | ||||
| } | ||||
|  | ||||
| crate::handling::cacheable::cacheable!(ImmutableStatisticSet); | ||||
| crate::handling::cacheable::cacheable!(Form); | ||||
| crate::handling::cacheable::cacheable!(Species); | ||||
|  | ||||
| extern "wasm" { | ||||
|     fn static_statistics_set_get_hp(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_attack(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_defense(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_special_attack(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_special_defense(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|     fn static_statistics_set_get_speed(r: ExternRef<ImmutableStatisticSet>) -> u16; | ||||
|  | ||||
|     fn form_get_name(r: ExternRef<Form>) -> ExternRef<StringKey>; | ||||
|     fn form_get_height(r: ExternRef<Form>) -> f32; | ||||
|     fn form_get_weight(r: ExternRef<Form>) -> f32; | ||||
|     fn form_get_types(r: ExternRef<Form>) -> FFIArray<u8>; | ||||
|     fn form_get_base_experience(r: ExternRef<Form>) -> u32; | ||||
|     fn form_get_base_stats(r: ExternRef<Form>) -> ExternRef<ImmutableStatisticSet>; | ||||
|     fn form_get_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>; | ||||
|     fn form_get_hidden_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>; | ||||
|     fn form_has_flag_by_hash(r: ExternRef<Form>, hash: u32) -> bool; | ||||
|  | ||||
|     fn species_get_id(r: ExternRef<Species>) -> u16; | ||||
|     fn species_get_name(r: ExternRef<Species>) -> ExternRef<StringKey>; | ||||
|     fn species_get_gender_rate(r: ExternRef<Species>) -> f32; | ||||
|     fn species_get_growth_rate(r: ExternRef<Species>) -> ExternRef<StringKey>; | ||||
|     fn species_get_capture_rate(r: ExternRef<Species>) -> u8; | ||||
|     fn species_get_form_by_hash(r: ExternRef<Species>, hash: u32) -> ExternRef<Form>; | ||||
|     fn species_has_flag_by_hash(r: ExternRef<Species>, flag_hash: u32) -> bool; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user