use crate::app_interface::{get_hash, StringKey}; use crate::handling::cached_value::CachedValue; use crate::handling::Cacheable; use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType}; use alloc::rc::Rc; #[repr(u8)] #[derive(Clone)] pub enum MoveCategory { Physical = 0, Special = 1, Status = 2, } #[repr(u8)] #[derive(Clone)] pub enum MoveTarget { Adjacent, AdjacentAlly, AdjacentAllySelf, AdjacentOpponent, All, AllAdjacent, AllAdjacentOpponent, AllAlly, AllOpponent, Any, RandomOpponent, OnSelf, } struct MoveDataInner { ptr: ExternRef, name: CachedValue, move_type: CachedValue, category: CachedValue, base_power: CachedValue, accuracy: CachedValue, base_usages: CachedValue, target: CachedValue, priority: CachedValue, } #[derive(Clone)] pub struct MoveData { inner: Rc, } impl MoveData { #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { MoveData::from_ref(ptr, &|ptr| Self { inner: Rc::new(MoveDataInner { ptr, name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }), move_type: cached_value!({ move_data_get_type(ptr) }), category: cached_value!({ move_data_get_category(ptr) }), base_power: cached_value!({ move_data_get_base_power(ptr) }), accuracy: cached_value!({ move_data_get_accuracy(ptr) }), base_usages: cached_value!({ move_data_get_base_power(ptr) }), target: cached_value!({ move_data_get_target(ptr) }), priority: cached_value!({ move_data_get_priority(ptr) }), }), }) } #[cfg(feature = "mock_data")] pub fn mock( name: &str, move_type: u8, category: MoveCategory, base_power: u8, accuracy: u8, base_usages: u8, target: MoveTarget, priority: i8, ) -> Self { Self { inner: Rc::new(MoveDataInner { ptr: ExternRef::mock(), name: StringKey::new(name).into(), move_type: move_type.into(), category: category.into(), base_power: base_power.into(), accuracy: accuracy.into(), base_usages: base_usages.into(), target: target.into(), priority: priority.into(), }), } } 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; } #[cfg(not(feature = "mock_data"))] pub fn has_flag(&self, flag: &str) -> bool { let hash = get_hash(flag); unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) } } } #[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for MoveData { fn from_extern_value(reference: ExternRef) -> Self { MoveData::new(reference) } } crate::handling::cacheable::cacheable!(MoveData); #[cfg(not(feature = "mock_data"))] extern "wasm" { fn move_data_get_name(ptr: ExternRef) -> ExternRef; fn move_data_get_type(ptr: ExternRef) -> u8; fn move_data_get_category(ptr: ExternRef) -> MoveCategory; fn move_data_get_base_power(ptr: ExternRef) -> u8; fn move_data_get_accuracy(ptr: ExternRef) -> u8; fn move_data_get_base_usages(ptr: ExternRef) -> u8; fn move_data_get_target(ptr: ExternRef) -> MoveTarget; fn move_data_get_priority(ptr: ExternRef) -> i8; fn move_data_has_flag_by_hash(ptr: ExternRef, flag_hash: u32) -> bool; }