Rework in line with PkmnLib for moving towards Result
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -8,12 +8,11 @@ edition = "2021"
|
||||
mock_data = ["mockall"]
|
||||
|
||||
[dependencies]
|
||||
cstr_core = { version = "0.2.6", features = ["nightly"]}
|
||||
cstr_core = { version = "0.2.6", features = ["nightly"] }
|
||||
enumflags2 = { version = "0.7.5", default-features = false }
|
||||
spin = { version = "0.9.4", default-features = false, features = ["rwlock"] }
|
||||
paste = { version = "1.0.7" }
|
||||
hashbrown = { version = "0.12.3" }
|
||||
hashbrown = { version = "0.13.2" }
|
||||
dlmalloc = { version = "0.2.4", features = ["global"] }
|
||||
mockall = { version = "0.11.2", optional = true, features = ["nightly"] }
|
||||
|
||||
|
||||
num-traits = { version = "0.2", default-features = false }
|
||||
@@ -1,28 +1,28 @@
|
||||
use alloc::rc::Rc;
|
||||
|
||||
use crate::app_interface::list::ImmutableList;
|
||||
use crate::app_interface::{
|
||||
BattleParty, BattleRandom, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, StringKey,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait BattleTrait {
|
||||
fn library(&self) -> DynamicLibrary;
|
||||
fn parties(&self) -> ImmutableList<BattleParty>;
|
||||
fn sides(&self) -> ImmutableList<BattleSide>;
|
||||
fn parties(&self) -> Vec<BattleParty>;
|
||||
fn sides(&self) -> Vec<BattleSide>;
|
||||
fn random(&self) -> BattleRandom;
|
||||
fn choice_queue(&self) -> ChoiceQueue;
|
||||
fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon>;
|
||||
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> Option<BattleParty>;
|
||||
fn weather_name(&self) -> Option<StringKey>;
|
||||
fn has_weather(&self, name: &str) -> bool;
|
||||
fn can_flee(&self) -> bool;
|
||||
fn number_of_sides(&self) -> u8;
|
||||
fn pokemon_per_side(&self) -> u8;
|
||||
fn has_ended(&self) -> bool;
|
||||
fn has_ended_conclusively(&self) -> bool;
|
||||
fn winning_side(&self) -> u8;
|
||||
fn current_turn(&self) -> u32;
|
||||
fn get_pokemon(&self, side: u8, index: u8) -> PkmnResult<Option<Pokemon>>;
|
||||
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> PkmnResult<Option<BattleParty>>;
|
||||
fn weather_name(&self) -> PkmnResult<Option<StringKey>>;
|
||||
fn has_weather(&self, name: &str) -> PkmnResult<bool>;
|
||||
fn can_flee(&self) -> PkmnResult<bool>;
|
||||
fn number_of_sides(&self) -> PkmnResult<u8>;
|
||||
fn pokemon_per_side(&self) -> PkmnResult<u8>;
|
||||
fn has_ended(&self) -> PkmnResult<bool>;
|
||||
fn has_ended_conclusively(&self) -> PkmnResult<bool>;
|
||||
fn winning_side(&self) -> PkmnResult<u8>;
|
||||
fn current_turn(&self) -> PkmnResult<u32>;
|
||||
}
|
||||
|
||||
pub type Battle = Rc<dyn BattleTrait>;
|
||||
@@ -33,26 +33,26 @@ pub type MockBattle = MockBattleTrait;
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::dynamic_data::dynamic_library::DynamicLibraryImpl;
|
||||
use crate::app_interface::list::{
|
||||
BattlePartyImmutableList, BattleSideImmutableList, ImmutableListWasm,
|
||||
};
|
||||
use crate::app_interface::PokemonImpl;
|
||||
use crate::app_interface::{
|
||||
BattleParty, BattlePartyImpl, BattleRandom, BattleRandomImpl, BattleSide, BattleSideImpl,
|
||||
ChoiceQueue, ChoiceQueueImpl, Pokemon,
|
||||
};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::ffi_array::FFIArray;
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs,
|
||||
ExternRef, ExternalReferenceType, StringKey, VecExternRef,
|
||||
ExternRef, ExternalReferenceType, PkmnResult, StringKey,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
struct BattleInner {
|
||||
reference: ExternRef<BattleImpl>,
|
||||
library: CachedValue<DynamicLibrary>,
|
||||
parties: CachedValue<ImmutableList<BattleParty>>,
|
||||
sides: CachedValue<ImmutableList<BattleSide>>,
|
||||
parties: CachedValue<Vec<BattleParty>>,
|
||||
sides: CachedValue<Vec<BattleSide>>,
|
||||
random: CachedValue<Rc<BattleRandomImpl>>,
|
||||
choice_queue: CachedValue<Rc<ChoiceQueueImpl>>,
|
||||
}
|
||||
@@ -69,21 +69,39 @@ mod implementation {
|
||||
inner: Rc::new(BattleInner {
|
||||
reference,
|
||||
library: cached_value!({
|
||||
Rc::new(battle_get_library(reference).get_value().unwrap())
|
||||
Rc::new(battle_get_library(reference).unwrap().get_value().unwrap())
|
||||
}),
|
||||
parties: cached_value!({
|
||||
let reference = battle_get_parties(reference);
|
||||
Rc::new(BattlePartyImmutableList::from_ref(reference))
|
||||
let parties: FFIArray<ExternRef<BattlePartyImpl>> =
|
||||
FFIArray::from_u64(battle_get_parties(reference).unwrap());
|
||||
let parties =
|
||||
Vec::from_raw_parts(parties.ptr(), parties.len(), parties.len());
|
||||
let parties = parties
|
||||
.into_iter()
|
||||
.map::<BattleParty, _>(|r| Rc::new(BattlePartyImpl::new(r)))
|
||||
.collect::<Vec<_>>();
|
||||
parties
|
||||
}),
|
||||
sides: cached_value!({
|
||||
let reference = battle_get_sides(reference);
|
||||
Rc::new(BattleSideImmutableList::from_ref(reference))
|
||||
let sides: FFIArray<ExternRef<BattleSideImpl>> =
|
||||
FFIArray::from_u64(battle_get_sides(reference).unwrap());
|
||||
let sides = Vec::from_raw_parts(sides.ptr(), sides.len(), sides.len());
|
||||
let sides = sides
|
||||
.into_iter()
|
||||
.map::<BattleSide, _>(|r| Rc::new(BattleSideImpl::new(r)))
|
||||
.collect::<Vec<_>>();
|
||||
sides
|
||||
}),
|
||||
random: cached_value!({
|
||||
Rc::new(battle_get_random(reference).get_value().unwrap())
|
||||
Rc::new(battle_get_random(reference).unwrap().get_value().unwrap())
|
||||
}),
|
||||
choice_queue: cached_value!({
|
||||
Rc::new(battle_get_choice_queue(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
battle_get_choice_queue(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -94,46 +112,53 @@ mod implementation {
|
||||
impl BattleTrait for BattleImpl {
|
||||
cached_value_getters! {
|
||||
fn library(&self) -> DynamicLibrary;
|
||||
fn parties(&self) -> ImmutableList<BattleParty>;
|
||||
fn sides(&self) -> ImmutableList<BattleSide>;
|
||||
fn parties(&self) -> Vec<BattleParty>;
|
||||
fn sides(&self) -> Vec<BattleSide>;
|
||||
fn random(&self) -> BattleRandom;
|
||||
fn choice_queue(&self) -> ChoiceQueue;
|
||||
}
|
||||
|
||||
fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon> {
|
||||
fn get_pokemon(&self, side: u8, index: u8) -> PkmnResult<Option<Pokemon>> {
|
||||
unsafe {
|
||||
let v = battle_get_pokemon(self.inner.reference, side, index).get_value();
|
||||
let v = battle_get_pokemon(self.inner.reference, side, index)
|
||||
.as_res()?
|
||||
.get_value();
|
||||
if let Some(v) = v {
|
||||
Some(Rc::new(v))
|
||||
Ok(Some(Rc::new(v)))
|
||||
} else {
|
||||
None
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> Option<BattleParty> {
|
||||
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> PkmnResult<Option<BattleParty>> {
|
||||
unsafe {
|
||||
let b =
|
||||
battle_find_party_for_pokemon(self.inner.reference, pokemon.reference().into())
|
||||
.as_res()?
|
||||
.get_value();
|
||||
if let Some(b) = b {
|
||||
Ok(if let Some(b) = b {
|
||||
Some(Rc::new(b))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn weather_name(&self) -> Option<StringKey> {
|
||||
unsafe { battle_get_weather_name(self.inner.reference).get_value() }
|
||||
fn weather_name(&self) -> PkmnResult<Option<StringKey>> {
|
||||
unsafe {
|
||||
Ok(battle_get_weather_name(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value())
|
||||
}
|
||||
}
|
||||
fn has_weather(&self, name: &str) -> bool {
|
||||
if let Some(weather) = self.weather_name() {
|
||||
fn has_weather(&self, name: &str) -> PkmnResult<bool> {
|
||||
if let Some(weather) = self.weather_name()? {
|
||||
if weather.equals_str(name) {
|
||||
return true;
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
false
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
wasm_value_getters_funcs! {
|
||||
@@ -170,24 +195,29 @@ mod implementation {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn battle_get_library(r: ExternRef<BattleImpl>) -> ExternRef<DynamicLibraryImpl>;
|
||||
fn battle_get_parties(r: ExternRef<BattleImpl>) -> VecExternRef<BattlePartyImpl>;
|
||||
fn battle_get_sides(r: ExternRef<BattleImpl>) -> VecExternRef<BattleSideImpl>;
|
||||
fn battle_get_random(r: ExternRef<BattleImpl>) -> ExternRef<BattleRandomImpl>;
|
||||
fn battle_get_choice_queue(r: ExternRef<BattleImpl>) -> ExternRef<ChoiceQueueImpl>;
|
||||
fn battle_get_library(
|
||||
r: ExternRef<BattleImpl>,
|
||||
) -> WasmResult<ExternRef<DynamicLibraryImpl>>;
|
||||
fn battle_get_parties(r: ExternRef<BattleImpl>) -> WasmResult<u64>;
|
||||
fn battle_get_sides(r: ExternRef<BattleImpl>) -> WasmResult<u64>;
|
||||
fn battle_get_random(r: ExternRef<BattleImpl>) -> WasmResult<ExternRef<BattleRandomImpl>>;
|
||||
fn battle_get_choice_queue(
|
||||
r: ExternRef<BattleImpl>,
|
||||
) -> WasmResult<ExternRef<ChoiceQueueImpl>>;
|
||||
fn battle_get_pokemon(
|
||||
r: ExternRef<BattleImpl>,
|
||||
side: u8,
|
||||
index: u8,
|
||||
) -> ExternRef<PokemonImpl>;
|
||||
) -> WasmResult<ExternRef<PokemonImpl>>;
|
||||
fn battle_find_party_for_pokemon(
|
||||
r: ExternRef<BattleImpl>,
|
||||
mon: ExternRef<PokemonImpl>,
|
||||
) -> ExternRef<BattlePartyImpl>;
|
||||
) -> WasmResult<ExternRef<BattlePartyImpl>>;
|
||||
|
||||
fn battle_get_weather_name(r: ExternRef<BattleImpl>) -> ExternRef<StringKey>;
|
||||
fn battle_get_weather_name(r: ExternRef<BattleImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -15,6 +15,7 @@ mod implementation {
|
||||
use crate::app_interface::{BattlePartyTrait, Party, PartyImpl};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters};
|
||||
use alloc::rc::Rc;
|
||||
@@ -35,7 +36,12 @@ mod implementation {
|
||||
inner: Rc::new(BattlePartyInner {
|
||||
reference,
|
||||
party: cached_value!({
|
||||
Rc::new(battle_party_get_party(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
battle_party_get_party(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -59,7 +65,9 @@ mod implementation {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn battle_party_get_party(r: ExternRef<BattlePartyImpl>) -> ExternRef<PartyImpl>;
|
||||
fn battle_party_get_party(
|
||||
r: ExternRef<BattlePartyImpl>,
|
||||
) -> WasmResult<ExternRef<PartyImpl>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::PkmnResult;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait BattleRandomTrait {
|
||||
fn get(&self) -> i32;
|
||||
fn get_max(&self, max: i32) -> i32;
|
||||
fn get_between(&self, min: i32, max: i32) -> i32;
|
||||
fn get(&self) -> PkmnResult<i32>;
|
||||
fn get_max(&self, max: i32) -> PkmnResult<i32>;
|
||||
fn get_between(&self, min: i32, max: i32) -> PkmnResult<i32>;
|
||||
}
|
||||
|
||||
pub type BattleRandom = Rc<dyn BattleRandomTrait>;
|
||||
@@ -17,6 +18,7 @@ pub use implementation::*;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -26,16 +28,16 @@ mod implementation {
|
||||
|
||||
impl BattleRandomTrait for BattleRandomImpl {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
fn get(&self) -> i32 {
|
||||
unsafe { battle_random_get(self.reference) }
|
||||
fn get(&self) -> PkmnResult<i32> {
|
||||
unsafe { battle_random_get(self.reference).as_res() }
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
fn get_max(&self, max: i32) -> i32 {
|
||||
unsafe { battle_random_get_max(self.reference, max) }
|
||||
fn get_max(&self, max: i32) -> PkmnResult<i32> {
|
||||
unsafe { battle_random_get_max(self.reference, max).as_res() }
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
fn get_between(&self, min: i32, max: i32) -> i32 {
|
||||
unsafe { battle_random_get_between(self.reference, min, max) }
|
||||
fn get_between(&self, min: i32, max: i32) -> PkmnResult<i32> {
|
||||
unsafe { battle_random_get_between(self.reference, min, max).as_res() }
|
||||
}
|
||||
// TODO: effect_chance()
|
||||
}
|
||||
@@ -48,9 +50,13 @@ mod implementation {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn battle_random_get(r: ExternRef<BattleRandomImpl>) -> i32;
|
||||
fn battle_random_get_max(r: ExternRef<BattleRandomImpl>, max: i32) -> i32;
|
||||
fn battle_random_get_between(r: ExternRef<BattleRandomImpl>, min: i32, max: i32) -> i32;
|
||||
fn battle_random_get(r: ExternRef<BattleRandomImpl>) -> WasmResult<i32>;
|
||||
fn battle_random_get_max(r: ExternRef<BattleRandomImpl>, max: i32) -> WasmResult<i32>;
|
||||
fn battle_random_get_between(
|
||||
r: ExternRef<BattleRandomImpl>,
|
||||
min: i32,
|
||||
max: i32,
|
||||
) -> WasmResult<i32>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ pub trait BattleSideTrait: WithVolatile {
|
||||
fn pokemon_per_side(&self) -> u8;
|
||||
fn battle(&self) -> Battle;
|
||||
fn get_pokemon(&self, index: usize) -> Option<Pokemon>;
|
||||
fn has_fled_battle(&self) -> bool;
|
||||
fn is_defeated(&self) -> bool;
|
||||
fn has_fled_battle(&self) -> PkmnResult<bool>;
|
||||
fn is_defeated(&self) -> PkmnResult<bool>;
|
||||
}
|
||||
|
||||
pub type BattleSide = Rc<dyn BattleSideTrait>;
|
||||
@@ -18,10 +18,11 @@ mod implementation {
|
||||
use crate::app_interface::{BattleImpl, PokemonImpl};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::wasm_result::{WasmResult, WasmVoidResult};
|
||||
use crate::handling::{Cacheable, Script};
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs,
|
||||
ScriptPtr,
|
||||
PkmnResult, ScriptPtr,
|
||||
};
|
||||
use alloc::boxed::Box;
|
||||
use cstr_core::{c_char, CString};
|
||||
@@ -43,10 +44,17 @@ mod implementation {
|
||||
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) }),
|
||||
side_index: cached_value!({ battleside_get_side_index(reference).unwrap() }),
|
||||
pokemon_per_side: cached_value!({
|
||||
battleside_get_pokemon_per_side(reference).unwrap()
|
||||
}),
|
||||
battle: cached_value!({
|
||||
Rc::new(battleside_get_battle(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
battleside_get_battle(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -62,7 +70,9 @@ mod implementation {
|
||||
|
||||
fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
||||
unsafe {
|
||||
let p = battleside_get_pokemon(self.inner.reference, index).get_value();
|
||||
let p = battleside_get_pokemon(self.inner.reference, index)
|
||||
.unwrap()
|
||||
.get_value();
|
||||
if let Some(p) = p {
|
||||
Some(Rc::new(p))
|
||||
} else {
|
||||
@@ -79,39 +89,51 @@ mod implementation {
|
||||
}
|
||||
|
||||
impl WithVolatile for BattleSideImpl {
|
||||
fn has_volatile(&self, script_name: &str) -> bool {
|
||||
fn has_volatile(&self, script_name: &str) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
let script_name = CString::new(script_name).unwrap();
|
||||
battleside_has_volatile(self.inner.reference, script_name.as_ptr())
|
||||
battleside_has_volatile(self.inner.reference, script_name.as_ptr()).as_res()
|
||||
}
|
||||
}
|
||||
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
|
||||
fn add_volatile(&self, script: Box<dyn Script>) -> PkmnResult<&dyn Script> {
|
||||
unsafe {
|
||||
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
||||
.val()
|
||||
.unwrap()
|
||||
Ok(
|
||||
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
||||
.as_res()?
|
||||
.val()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
|
||||
fn add_volatile_by_name(&self, script_name: &str) -> PkmnResult<&dyn Script> {
|
||||
unsafe {
|
||||
let ptr = CString::new(script_name).unwrap();
|
||||
battleside_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
|
||||
.val()
|
||||
.unwrap()
|
||||
Ok(
|
||||
battleside_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
|
||||
.as_res()?
|
||||
.val()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_volatile(&self, script: &dyn Script) {
|
||||
fn remove_volatile(&self, script: &dyn Script) -> PkmnResult<()> {
|
||||
unsafe {
|
||||
let name = CString::new(script.get_name()).unwrap();
|
||||
battleside_remove_volatile(self.inner.reference, name.as_ptr());
|
||||
battleside_remove_volatile(self.inner.reference, name.as_ptr()).as_res()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script> {
|
||||
fn get_volatile_script(&self, script_name: &str) -> PkmnResult<Option<&dyn Script>> {
|
||||
let script_name = CString::new(script_name).unwrap();
|
||||
unsafe { battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val() }
|
||||
unsafe {
|
||||
Ok(
|
||||
battleside_get_volatile(self.inner.reference, script_name.as_ptr())
|
||||
.as_res()?
|
||||
.val(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,24 +152,38 @@ mod implementation {
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> u8;
|
||||
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSideImpl>) -> u8;
|
||||
fn battleside_get_battle(r: ExternRef<BattleSideImpl>) -> ExternRef<BattleImpl>;
|
||||
fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> WasmResult<u8>;
|
||||
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSideImpl>) -> WasmResult<u8>;
|
||||
fn battleside_get_battle(r: ExternRef<BattleSideImpl>)
|
||||
-> WasmResult<ExternRef<BattleImpl>>;
|
||||
fn battleside_get_pokemon(
|
||||
r: ExternRef<BattleSideImpl>,
|
||||
index: usize,
|
||||
) -> ExternRef<PokemonImpl>;
|
||||
) -> WasmResult<ExternRef<PokemonImpl>>;
|
||||
|
||||
fn battleside_add_volatile_by_name(
|
||||
r: ExternRef<BattleSideImpl>,
|
||||
name: *const c_char,
|
||||
) -> ScriptPtr;
|
||||
fn battleside_add_volatile(r: ExternRef<BattleSideImpl>, script: ScriptPtr) -> ScriptPtr;
|
||||
fn battleside_has_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> bool;
|
||||
fn battleside_remove_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char);
|
||||
fn battleside_get_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> ScriptPtr;
|
||||
) -> WasmResult<ScriptPtr>;
|
||||
fn battleside_add_volatile(
|
||||
r: ExternRef<BattleSideImpl>,
|
||||
script: ScriptPtr,
|
||||
) -> WasmResult<ScriptPtr>;
|
||||
fn battleside_has_volatile(
|
||||
r: ExternRef<BattleSideImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmResult<bool>;
|
||||
fn battleside_remove_volatile(
|
||||
r: ExternRef<BattleSideImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmVoidResult;
|
||||
fn battleside_get_volatile(
|
||||
r: ExternRef<BattleSideImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmResult<ScriptPtr>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -3,7 +3,7 @@ use alloc::rc::Rc;
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait ChoiceQueueTrait {
|
||||
fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool;
|
||||
fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> PkmnResult<bool>;
|
||||
}
|
||||
|
||||
pub type ChoiceQueue = Rc<dyn ChoiceQueueTrait>;
|
||||
@@ -14,7 +14,8 @@ pub type MockChoiceQueue = MockChoiceQueueTrait;
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::PokemonImpl;
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::{ExternRef, ExternalReferenceType, PkmnResult};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChoiceQueueImpl {
|
||||
@@ -28,9 +29,10 @@ mod implementation {
|
||||
}
|
||||
|
||||
impl ChoiceQueueTrait for ChoiceQueueImpl {
|
||||
fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool {
|
||||
fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
choice_queue_move_pokemon_choice_next(self.reference, pokemon.reference().into())
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,9 +47,10 @@ mod implementation {
|
||||
fn choice_queue_move_pokemon_choice_next(
|
||||
r: ExternRef<ChoiceQueueImpl>,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
) -> bool;
|
||||
) -> WasmResult<bool>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -15,6 +15,7 @@ mod implementation {
|
||||
use crate::cached_value;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::handling::Cacheable;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
@@ -36,7 +37,12 @@ mod implementation {
|
||||
inner: Rc::new(DynamicLibraryInner {
|
||||
ptr,
|
||||
static_data: cached_value!({
|
||||
Rc::new(dynamic_library_get_static_data(ptr).get_value().unwrap())
|
||||
Rc::new(
|
||||
dynamic_library_get_static_data(ptr)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -58,7 +64,7 @@ mod implementation {
|
||||
extern "wasm" {
|
||||
fn dynamic_library_get_static_data(
|
||||
ptr: ExternRef<DynamicLibraryImpl>,
|
||||
) -> ExternRef<StaticDataImpl>;
|
||||
) -> WasmResult<ExternRef<StaticDataImpl>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::app_interface::{LearnedMove, MoveData, Pokemon};
|
||||
use crate::handling::Script;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
@@ -8,25 +9,25 @@ pub trait ExecutingMoveTrait {
|
||||
fn user(&self) -> Pokemon;
|
||||
fn chosen_move(&self) -> LearnedMove;
|
||||
fn use_move(&self) -> MoveData;
|
||||
fn move_script<'a>(&'a self) -> Option<&'a dyn Script>;
|
||||
fn number_of_targets(&self) -> usize;
|
||||
fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool;
|
||||
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData;
|
||||
fn move_script<'a>(&'a self) -> PkmnResult<Option<&'a Box<dyn Script>>>;
|
||||
fn number_of_targets(&self) -> PkmnResult<usize>;
|
||||
fn is_pokemon_target(&self, pokemon: &Pokemon) -> PkmnResult<bool>;
|
||||
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> PkmnResult<HitData>;
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait HitDataTrait {
|
||||
fn is_critical(&self) -> bool;
|
||||
fn base_power(&self) -> u8;
|
||||
fn effectiveness(&self) -> f32;
|
||||
fn damage(&self) -> u32;
|
||||
fn move_type(&self) -> u8;
|
||||
fn has_failed(&self) -> bool;
|
||||
fn set_critical(&self, critical: bool);
|
||||
fn set_effectiveness(&self, effectiveness: f32);
|
||||
fn set_damage(&self, damage: u32);
|
||||
fn set_move_type(&self, move_type: u8);
|
||||
fn fail(&self);
|
||||
fn is_critical(&self) -> PkmnResult<bool>;
|
||||
fn base_power(&self) -> PkmnResult<u8>;
|
||||
fn effectiveness(&self) -> PkmnResult<f32>;
|
||||
fn damage(&self) -> PkmnResult<u32>;
|
||||
fn move_type(&self) -> PkmnResult<u8>;
|
||||
fn has_failed(&self) -> PkmnResult<bool>;
|
||||
fn set_critical(&self, critical: bool) -> PkmnResult<()>;
|
||||
fn set_effectiveness(&self, effectiveness: f32) -> PkmnResult<()>;
|
||||
fn set_damage(&self, damage: u32) -> PkmnResult<()>;
|
||||
fn set_move_type(&self, move_type: u8) -> PkmnResult<()>;
|
||||
fn fail(&self) -> PkmnResult<()>;
|
||||
}
|
||||
|
||||
pub type ExecutingMove = Rc<dyn ExecutingMoveTrait>;
|
||||
@@ -37,6 +38,7 @@ pub type HitData = Rc<dyn HitDataTrait>;
|
||||
#[cfg(feature = "mock_data")]
|
||||
pub type MockHitData = MockHitDataTrait;
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -44,10 +46,12 @@ pub use implementation::*;
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::{LearnedMoveImpl, MoveDataImpl, PokemonImpl};
|
||||
use crate::cached_value;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::temporary::Temporary;
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::{cached_value, PkmnResult};
|
||||
use alloc::boxed::Box;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExecutingMoveImpl {
|
||||
@@ -71,20 +75,31 @@ mod implementation {
|
||||
ExecutingMoveInner {
|
||||
reference,
|
||||
number_of_hits: cached_value!({
|
||||
executing_move_get_number_of_hits(reference)
|
||||
executing_move_get_number_of_hits(reference).unwrap()
|
||||
}),
|
||||
user: cached_value!({
|
||||
Rc::new(executing_move_get_user(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
executing_move_get_user(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
chosen_move: cached_value!({
|
||||
Rc::new(
|
||||
executing_move_get_chosen_move(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
use_move: cached_value!({
|
||||
Rc::new(executing_move_get_use_move(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
executing_move_get_use_move(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
},
|
||||
),
|
||||
@@ -106,31 +121,39 @@ mod implementation {
|
||||
fn use_move(&self) -> MoveData {
|
||||
self.inner.value().use_move.value()
|
||||
}
|
||||
fn move_script(&self) -> Option<&dyn Script> {
|
||||
unsafe { executing_move_get_script(self.inner.value().reference).as_ref() }
|
||||
fn move_script(&self) -> PkmnResult<Option<&Box<dyn Script>>> {
|
||||
unsafe {
|
||||
Ok(
|
||||
(executing_move_get_script(self.inner.value().reference).as_res()?
|
||||
as *const Box<dyn Script>)
|
||||
.as_ref(),
|
||||
)
|
||||
}
|
||||
}
|
||||
fn number_of_targets(&self) -> usize {
|
||||
unsafe { executing_move_get_number_of_targets(self.inner.value().reference) }
|
||||
fn number_of_targets(&self) -> PkmnResult<usize> {
|
||||
unsafe { executing_move_get_number_of_targets(self.inner.value().reference).as_res() }
|
||||
}
|
||||
fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool {
|
||||
fn is_pokemon_target(&self, pokemon: &Pokemon) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
executing_move_is_pokemon_target(
|
||||
self.inner.value().reference,
|
||||
pokemon.reference().into(),
|
||||
)
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData {
|
||||
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> PkmnResult<HitData> {
|
||||
unsafe {
|
||||
Rc::new(
|
||||
Ok(Rc::new(
|
||||
executing_move_get_hit_data(
|
||||
self.inner.value().reference,
|
||||
pokemon.reference().into(),
|
||||
hit,
|
||||
)
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,39 +165,39 @@ mod implementation {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl HitDataTrait for HitDataImpl {
|
||||
fn is_critical(&self) -> bool {
|
||||
unsafe { hit_data_is_critical(self.reference) }
|
||||
fn is_critical(&self) -> PkmnResult<bool> {
|
||||
unsafe { hit_data_is_critical(self.reference).as_res() }
|
||||
}
|
||||
fn base_power(&self) -> u8 {
|
||||
unsafe { hit_data_get_base_power(self.reference) }
|
||||
fn base_power(&self) -> PkmnResult<u8> {
|
||||
unsafe { hit_data_get_base_power(self.reference).as_res() }
|
||||
}
|
||||
fn effectiveness(&self) -> f32 {
|
||||
unsafe { hit_data_get_effectiveness(self.reference) }
|
||||
fn effectiveness(&self) -> PkmnResult<f32> {
|
||||
unsafe { hit_data_get_effectiveness(self.reference).as_res() }
|
||||
}
|
||||
fn damage(&self) -> u32 {
|
||||
unsafe { hit_data_get_damage(self.reference) }
|
||||
fn damage(&self) -> PkmnResult<u32> {
|
||||
unsafe { hit_data_get_damage(self.reference).as_res() }
|
||||
}
|
||||
fn move_type(&self) -> u8 {
|
||||
unsafe { hit_data_get_move_type(self.reference) }
|
||||
fn move_type(&self) -> PkmnResult<u8> {
|
||||
unsafe { hit_data_get_move_type(self.reference).as_res() }
|
||||
}
|
||||
fn has_failed(&self) -> bool {
|
||||
unsafe { hit_data_is_critical(self.reference) }
|
||||
fn has_failed(&self) -> PkmnResult<bool> {
|
||||
unsafe { hit_data_is_critical(self.reference).as_res() }
|
||||
}
|
||||
|
||||
fn set_critical(&self, critical: bool) {
|
||||
unsafe { hit_data_set_critical(self.reference, critical) }
|
||||
fn set_critical(&self, critical: bool) -> PkmnResult<()> {
|
||||
unsafe { hit_data_set_critical(self.reference, critical).as_res() }
|
||||
}
|
||||
fn set_effectiveness(&self, effectiveness: f32) {
|
||||
unsafe { hit_data_set_effectiveness(self.reference, effectiveness) }
|
||||
fn set_effectiveness(&self, effectiveness: f32) -> PkmnResult<()> {
|
||||
unsafe { hit_data_set_effectiveness(self.reference, effectiveness).as_res() }
|
||||
}
|
||||
fn set_damage(&self, damage: u32) {
|
||||
unsafe { hit_data_set_damage(self.reference, damage) }
|
||||
fn set_damage(&self, damage: u32) -> PkmnResult<()> {
|
||||
unsafe { hit_data_set_damage(self.reference, damage).as_res() }
|
||||
}
|
||||
fn set_move_type(&self, move_type: u8) {
|
||||
unsafe { hit_data_set_move_type(self.reference, move_type) }
|
||||
fn set_move_type(&self, move_type: u8) -> PkmnResult<()> {
|
||||
unsafe { hit_data_set_move_type(self.reference, move_type).as_res() }
|
||||
}
|
||||
fn fail(&self) {
|
||||
unsafe { hit_data_fail(self.reference) }
|
||||
fn fail(&self) -> PkmnResult<()> {
|
||||
unsafe { hit_data_fail(self.reference).as_res() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,38 +217,47 @@ mod implementation {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn executing_move_get_number_of_targets(r: ExternRef<ExecutingMoveImpl>) -> usize;
|
||||
fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMoveImpl>) -> u8;
|
||||
fn executing_move_get_user(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<PokemonImpl>;
|
||||
fn executing_move_get_number_of_targets(
|
||||
r: ExternRef<ExecutingMoveImpl>,
|
||||
) -> WasmResult<usize>;
|
||||
fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMoveImpl>) -> WasmResult<u8>;
|
||||
fn executing_move_get_user(
|
||||
r: ExternRef<ExecutingMoveImpl>,
|
||||
) -> WasmResult<ExternRef<PokemonImpl>>;
|
||||
fn executing_move_get_chosen_move(
|
||||
r: ExternRef<ExecutingMoveImpl>,
|
||||
) -> ExternRef<LearnedMoveImpl>;
|
||||
fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveDataImpl>;
|
||||
) -> WasmResult<ExternRef<LearnedMoveImpl>>;
|
||||
fn executing_move_get_use_move(
|
||||
r: ExternRef<ExecutingMoveImpl>,
|
||||
) -> WasmResult<ExternRef<MoveDataImpl>>;
|
||||
#[allow(improper_ctypes)]
|
||||
fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script;
|
||||
fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> WasmResult<u32>;
|
||||
|
||||
fn executing_move_is_pokemon_target(
|
||||
r: ExternRef<ExecutingMoveImpl>,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
) -> bool;
|
||||
) -> WasmResult<bool>;
|
||||
fn executing_move_get_hit_data(
|
||||
r: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
) -> ExternRef<HitDataImpl>;
|
||||
) -> WasmResult<ExternRef<HitDataImpl>>;
|
||||
|
||||
fn hit_data_is_critical(r: ExternRef<HitDataImpl>) -> bool;
|
||||
fn hit_data_get_base_power(r: ExternRef<HitDataImpl>) -> u8;
|
||||
fn hit_data_get_effectiveness(r: ExternRef<HitDataImpl>) -> f32;
|
||||
fn hit_data_get_damage(r: ExternRef<HitDataImpl>) -> u32;
|
||||
fn hit_data_get_move_type(r: ExternRef<HitDataImpl>) -> u8;
|
||||
fn hit_data_has_failed(r: ExternRef<HitDataImpl>) -> bool;
|
||||
fn hit_data_is_critical(r: ExternRef<HitDataImpl>) -> WasmResult<bool>;
|
||||
fn hit_data_get_base_power(r: ExternRef<HitDataImpl>) -> WasmResult<u8>;
|
||||
fn hit_data_get_effectiveness(r: ExternRef<HitDataImpl>) -> WasmResult<f32>;
|
||||
fn hit_data_get_damage(r: ExternRef<HitDataImpl>) -> WasmResult<u32>;
|
||||
fn hit_data_get_move_type(r: ExternRef<HitDataImpl>) -> WasmResult<u8>;
|
||||
fn hit_data_has_failed(r: ExternRef<HitDataImpl>) -> WasmResult<bool>;
|
||||
|
||||
fn hit_data_set_critical(r: ExternRef<HitDataImpl>, critical: bool);
|
||||
fn hit_data_set_base_power(r: ExternRef<HitDataImpl>, power: u8);
|
||||
fn hit_data_set_effectiveness(r: ExternRef<HitDataImpl>, effectiveness: f32);
|
||||
fn hit_data_set_damage(r: ExternRef<HitDataImpl>, damage: u32);
|
||||
fn hit_data_set_move_type(r: ExternRef<HitDataImpl>, move_type: u8);
|
||||
fn hit_data_fail(r: ExternRef<HitDataImpl>);
|
||||
fn hit_data_set_critical(r: ExternRef<HitDataImpl>, critical: bool) -> WasmResult<()>;
|
||||
fn hit_data_set_base_power(r: ExternRef<HitDataImpl>, power: u8) -> WasmResult<()>;
|
||||
fn hit_data_set_effectiveness(
|
||||
r: ExternRef<HitDataImpl>,
|
||||
effectiveness: f32,
|
||||
) -> WasmResult<()>;
|
||||
fn hit_data_set_damage(r: ExternRef<HitDataImpl>, damage: u32) -> WasmResult<()>;
|
||||
fn hit_data_set_move_type(r: ExternRef<HitDataImpl>, move_type: u8) -> WasmResult<()>;
|
||||
fn hit_data_fail(r: ExternRef<HitDataImpl>) -> WasmResult<()>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ mod implementation {
|
||||
use crate::app_interface::MoveDataImpl;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters, wasm_value_getters};
|
||||
use alloc::rc::Rc;
|
||||
@@ -58,9 +59,16 @@ mod implementation {
|
||||
inner: Rc::new(LearnedMoveInner {
|
||||
reference,
|
||||
move_data: cached_value!({
|
||||
Rc::new(learned_move_get_move_data(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
learned_move_get_move_data(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
learn_method: cached_value!({
|
||||
learned_move_get_learn_method(reference).unwrap()
|
||||
}),
|
||||
learn_method: cached_value!({ learned_move_get_learn_method(reference) }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
@@ -92,10 +100,14 @@ mod implementation {
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn learned_move_get_move_data(r: ExternRef<LearnedMoveImpl>) -> ExternRef<MoveDataImpl>;
|
||||
fn learned_move_get_learn_method(r: ExternRef<LearnedMoveImpl>) -> MoveLearnMethod;
|
||||
fn learned_move_restore_uses(r: ExternRef<LearnedMoveImpl>, uses: u8);
|
||||
fn learned_move_restore_all_uses(r: ExternRef<LearnedMoveImpl>);
|
||||
fn learned_move_get_move_data(
|
||||
r: ExternRef<LearnedMoveImpl>,
|
||||
) -> WasmResult<ExternRef<MoveDataImpl>>;
|
||||
fn learned_move_get_learn_method(
|
||||
r: ExternRef<LearnedMoveImpl>,
|
||||
) -> WasmResult<MoveLearnMethod>;
|
||||
fn learned_move_restore_uses(r: ExternRef<LearnedMoveImpl>, uses: u8) -> WasmResult<()>;
|
||||
fn learned_move_restore_all_uses(r: ExternRef<LearnedMoveImpl>) -> WasmResult<()>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ use core::iter::IntoIterator;
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait PartyTrait {
|
||||
fn get_pokemon(&self, index: usize) -> Option<Pokemon>;
|
||||
fn length(&self) -> usize;
|
||||
fn get_pokemon(&self, index: usize) -> PkmnResult<Option<Pokemon>>;
|
||||
fn length(&self) -> PkmnResult<usize>;
|
||||
}
|
||||
|
||||
pub type Party = Rc<dyn PartyTrait>;
|
||||
@@ -16,7 +16,10 @@ impl<'a> IntoIterator for &'a dyn PartyTrait {
|
||||
type IntoIter = ExternIterator<'a, Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
ExternIterator::new(self.length(), Box::new(move |i| self.get_pokemon(i)))
|
||||
ExternIterator::new(
|
||||
self.length().unwrap(),
|
||||
Box::new(move |i| self.get_pokemon(i).unwrap()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +31,8 @@ mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::PokemonImpl;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::PkmnResult;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PartyImpl {
|
||||
@@ -41,19 +46,21 @@ mod implementation {
|
||||
}
|
||||
|
||||
impl PartyTrait for PartyImpl {
|
||||
fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
||||
fn get_pokemon(&self, index: usize) -> PkmnResult<Option<Pokemon>> {
|
||||
unsafe {
|
||||
let v = party_get_pokemon(self.reference, index).get_value();
|
||||
if let Some(v) = v {
|
||||
let v = party_get_pokemon(self.reference, index)
|
||||
.as_res()?
|
||||
.get_value();
|
||||
Ok(if let Some(v) = v {
|
||||
Some(Rc::new(v))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn length(&self) -> usize {
|
||||
unsafe { party_get_length(self.reference) }
|
||||
fn length(&self) -> PkmnResult<usize> {
|
||||
unsafe { party_get_length(self.reference).as_res() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,11 +71,15 @@ mod implementation {
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn party_get_pokemon(r: ExternRef<PartyImpl>, index: usize) -> ExternRef<PokemonImpl>;
|
||||
fn party_get_length(r: ExternRef<PartyImpl>) -> usize;
|
||||
fn party_get_pokemon(
|
||||
r: ExternRef<PartyImpl>,
|
||||
index: usize,
|
||||
) -> WasmResult<ExternRef<PokemonImpl>>;
|
||||
fn party_get_length(r: ExternRef<PartyImpl>) -> WasmResult<usize>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::utils::ExternIterator;
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -8,36 +8,37 @@ use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
use cstr_core::c_char;
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
pub trait PokemonTrait: WithVolatile {
|
||||
fn reference(&self) -> u32;
|
||||
|
||||
fn species(&self) -> Species;
|
||||
fn form(&self) -> Form;
|
||||
fn active_ability(&self) -> Ability;
|
||||
fn nature(&self) -> Nature;
|
||||
fn display_species(&self) -> Species;
|
||||
fn display_form(&self) -> Form;
|
||||
fn held_item(&self) -> Option<Item>;
|
||||
fn battle(&self) -> Option<Battle>;
|
||||
fn level(&self) -> LevelInt;
|
||||
fn experience(&self) -> u32;
|
||||
fn unique_identifier(&self) -> u32;
|
||||
fn gender(&self) -> Gender;
|
||||
fn coloring(&self) -> u8;
|
||||
fn current_health(&self) -> u32;
|
||||
fn weight(&self) -> f32;
|
||||
fn height(&self) -> f32;
|
||||
fn nickname(&self) -> *const c_char;
|
||||
fn real_ability(&self) -> AbilityIndex;
|
||||
fn types_length(&self) -> usize;
|
||||
fn battle_side_index(&self) -> u8;
|
||||
fn battle_index(&self) -> u8;
|
||||
fn is_ability_overriden(&self) -> u8;
|
||||
fn allowed_experience_gain(&self) -> bool;
|
||||
fn is_usable(&self) -> bool;
|
||||
fn species(&self) -> PkmnResult<Species>;
|
||||
fn form(&self) -> PkmnResult<Form>;
|
||||
fn active_ability(&self) -> PkmnResult<Ability>;
|
||||
fn nature(&self) -> PkmnResult<Nature>;
|
||||
fn display_species(&self) -> PkmnResult<Species>;
|
||||
fn display_form(&self) -> PkmnResult<Form>;
|
||||
fn held_item(&self) -> PkmnResult<Option<Item>>;
|
||||
fn battle(&self) -> PkmnResult<Option<Battle>>;
|
||||
fn level(&self) -> PkmnResult<LevelInt>;
|
||||
fn experience(&self) -> PkmnResult<u32>;
|
||||
fn unique_identifier(&self) -> PkmnResult<u32>;
|
||||
fn gender(&self) -> PkmnResult<Gender>;
|
||||
fn coloring(&self) -> PkmnResult<u8>;
|
||||
fn current_health(&self) -> PkmnResult<u32>;
|
||||
fn weight(&self) -> PkmnResult<f32>;
|
||||
fn height(&self) -> PkmnResult<f32>;
|
||||
fn nickname(&self) -> PkmnResult<*const c_char>;
|
||||
fn real_ability(&self) -> PkmnResult<AbilityIndex>;
|
||||
fn types_length(&self) -> PkmnResult<usize>;
|
||||
fn battle_side_index(&self) -> PkmnResult<u8>;
|
||||
fn battle_index(&self) -> PkmnResult<u8>;
|
||||
fn is_ability_overriden(&self) -> PkmnResult<u8>;
|
||||
fn allowed_experience_gain(&self) -> PkmnResult<bool>;
|
||||
fn is_usable(&self) -> PkmnResult<bool>;
|
||||
|
||||
fn library(&self) -> DynamicLibrary;
|
||||
fn flat_stats(&self) -> StatisticSet<u32>;
|
||||
@@ -45,25 +46,30 @@ pub trait PokemonTrait: WithVolatile {
|
||||
fn boosted_stats(&self) -> StatisticSet<u32>;
|
||||
fn individual_values(&self) -> ClampedStatisticSet<u8>;
|
||||
fn effort_values(&self) -> ClampedStatisticSet<u8>;
|
||||
fn has_held_item(&self, name: &str) -> bool;
|
||||
fn set_held_item(&self, item: &Item) -> Option<Item>;
|
||||
fn remove_held_item(&self) -> Option<Item>;
|
||||
fn consume_held_item(&self) -> bool;
|
||||
fn max_health(&self) -> u32;
|
||||
fn get_type(&self, index: usize) -> u8;
|
||||
fn has_type(&self, type_identifier: TypeIdentifier) -> bool;
|
||||
fn has_type_by_name(&self, type_name: &str) -> bool;
|
||||
fn get_learned_move(&self, index: usize) -> Option<LearnedMove>;
|
||||
fn change_stat_boost(&self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> bool;
|
||||
fn ability_script(&self) -> Option<&Box<dyn Script>>;
|
||||
fn has_held_item(&self, name: &str) -> PkmnResult<bool>;
|
||||
fn set_held_item(&self, item: &Item) -> PkmnResult<Option<Item>>;
|
||||
fn remove_held_item(&self) -> PkmnResult<Option<Item>>;
|
||||
fn consume_held_item(&self) -> PkmnResult<bool>;
|
||||
fn max_health(&self) -> PkmnResult<u32>;
|
||||
fn get_type(&self, index: usize) -> PkmnResult<u8>;
|
||||
fn has_type(&self, type_identifier: TypeIdentifier) -> PkmnResult<bool>;
|
||||
fn has_type_by_name(&self, type_name: &str) -> PkmnResult<bool>;
|
||||
fn get_learned_move(&self, index: usize) -> PkmnResult<Option<LearnedMove>>;
|
||||
fn change_stat_boost(
|
||||
&self,
|
||||
stat: Statistic,
|
||||
diff_amount: i8,
|
||||
self_inflicted: bool,
|
||||
) -> PkmnResult<bool>;
|
||||
fn ability_script(&self) -> PkmnResult<Option<&Box<dyn Script>>>;
|
||||
fn change_species(&self, species: Species, form: Form);
|
||||
fn change_form(&self, form: Form);
|
||||
fn is_fainted(&self) -> bool;
|
||||
fn damage(&self, damage: u32, source: DamageSource);
|
||||
fn heal(&self, amount: u32, allow_revive: bool) -> bool;
|
||||
fn is_fainted(&self) -> PkmnResult<bool>;
|
||||
fn damage(&self, damage: u32, source: DamageSource) -> PkmnResult<()>;
|
||||
fn heal(&self, amount: u32, allow_revive: bool) -> PkmnResult<bool>;
|
||||
fn set_weight(&self, weight: f32);
|
||||
fn clear_status(&self);
|
||||
fn battle_side(&self) -> BattleSide;
|
||||
fn battle_side(&self) -> PkmnResult<BattleSide>;
|
||||
fn equals(&self, other: &Pokemon) -> bool;
|
||||
}
|
||||
|
||||
@@ -84,6 +90,7 @@ pub enum DamageSource {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use core::mem::transmute;
|
||||
use cstr_core::CString;
|
||||
|
||||
use crate::app_interface::dynamic_data::dynamic_library::DynamicLibraryImpl;
|
||||
@@ -92,12 +99,13 @@ mod implementation {
|
||||
StatisticSetImpl,
|
||||
};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::implementation::ScriptPtr;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_optional_reference_getters_extern,
|
||||
wasm_reference_getters_extern, wasm_value_getters_extern, wasm_value_getters_funcs,
|
||||
ExternRef, ExternalReferenceType,
|
||||
ExternRef, ExternalReferenceType, PkmnResult,
|
||||
};
|
||||
|
||||
struct PokemonInner {
|
||||
@@ -134,90 +142,154 @@ mod implementation {
|
||||
fn effort_values(&self) -> ClampedStatisticSet<u8>;
|
||||
}
|
||||
|
||||
fn active_ability(&self) -> Ability {
|
||||
fn nickname(&self) -> PkmnResult<*const u8> {
|
||||
unsafe {
|
||||
let nickname = pokemon_get_nickname(self.inner.reference).as_res()?;
|
||||
Ok(nickname as *const u8)
|
||||
}
|
||||
}
|
||||
fn species(&self) -> PkmnResult<Species> {
|
||||
Ok(unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_species(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
fn form(&self) -> PkmnResult<Form> {
|
||||
Ok(unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_form(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
fn active_ability(&self) -> PkmnResult<Ability> {
|
||||
Ok(unsafe {
|
||||
let implementation = pokemon_get_active_ability(self.reference())
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap();
|
||||
Rc::new(implementation)
|
||||
}
|
||||
})
|
||||
}
|
||||
fn held_item(&self) -> Option<Item> {
|
||||
unsafe {
|
||||
let i = pokemon_get_held_item(self.inner.reference).get_value();
|
||||
if let Some(i) = i {
|
||||
Some(Rc::new(i))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn nature(&self) -> PkmnResult<Nature> {
|
||||
Ok(unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_nature(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
fn battle(&self) -> Option<Battle> {
|
||||
unsafe {
|
||||
let b = pokemon_get_battle(self.reference()).get_value();
|
||||
if let Some(b) = b {
|
||||
Some(Rc::new(b))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn display_species(&self) -> PkmnResult<Species> {
|
||||
Ok(unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_display_species(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
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()) }
|
||||
fn display_form(&self) -> PkmnResult<Form> {
|
||||
Ok(unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_display_form(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
fn set_held_item(&self, item: &Item) -> Option<Item> {
|
||||
unsafe {
|
||||
let i = pokemon_set_held_item(self.inner.reference, item.reference().into())
|
||||
fn held_item(&self) -> PkmnResult<Option<Item>> {
|
||||
Ok(unsafe {
|
||||
let i = pokemon_get_held_item(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value();
|
||||
if let Some(i) = i {
|
||||
Some(Rc::new(i))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
fn remove_held_item(&self) -> Option<Item> {
|
||||
unsafe {
|
||||
let i = pokemon_remove_held_item(self.inner.reference).get_value();
|
||||
if let Some(i) = i {
|
||||
Some(Rc::new(i))
|
||||
fn battle(&self) -> PkmnResult<Option<Battle>> {
|
||||
Ok(unsafe {
|
||||
let b = pokemon_get_battle(self.reference()).as_res()?.get_value();
|
||||
if let Some(b) = b {
|
||||
Some(Rc::new(b))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
fn has_held_item(&self, name: &str) -> PkmnResult<bool> {
|
||||
let cstr = CString::new(name).unwrap();
|
||||
unsafe { pokemon_has_held_item(self.inner.reference, cstr.as_ptr()).as_res() }
|
||||
}
|
||||
fn set_held_item(&self, item: &Item) -> PkmnResult<Option<Item>> {
|
||||
unsafe {
|
||||
let i = pokemon_set_held_item(self.inner.reference, item.reference().into())
|
||||
.as_res()?
|
||||
.get_value();
|
||||
Ok(if let Some(i) = i {
|
||||
Some(Rc::new(i))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
fn consume_held_item(&self) -> bool {
|
||||
unsafe { pokemon_consume_held_item(self.inner.reference) }
|
||||
fn remove_held_item(&self) -> PkmnResult<Option<Item>> {
|
||||
unsafe {
|
||||
let i = pokemon_remove_held_item(self.inner.reference)
|
||||
.as_res()?
|
||||
.get_value();
|
||||
Ok(if let Some(i) = i {
|
||||
Some(Rc::new(i))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
fn max_health(&self) -> u32 {
|
||||
fn consume_held_item(&self) -> PkmnResult<bool> {
|
||||
unsafe { pokemon_consume_held_item(self.inner.reference).as_res() }
|
||||
}
|
||||
fn max_health(&self) -> PkmnResult<u32> {
|
||||
self.boosted_stats().hp()
|
||||
}
|
||||
fn get_type(&self, index: usize) -> u8 {
|
||||
unsafe { pokemon_get_type(self.inner.reference, index) }
|
||||
fn get_type(&self, index: usize) -> PkmnResult<u8> {
|
||||
unsafe { pokemon_get_type(self.inner.reference, index).as_res() }
|
||||
}
|
||||
fn has_type(&self, type_identifier: TypeIdentifier) -> bool {
|
||||
unsafe { pokemon_has_type(self.inner.reference, type_identifier.into()) }
|
||||
fn has_type(&self, type_identifier: TypeIdentifier) -> PkmnResult<bool> {
|
||||
unsafe { pokemon_has_type(self.inner.reference, type_identifier.into()).as_res() }
|
||||
}
|
||||
fn has_type_by_name(&self, type_name: &str) -> bool {
|
||||
fn has_type_by_name(&self, type_name: &str) -> PkmnResult<bool> {
|
||||
let type_identifier = self
|
||||
.library()
|
||||
.data_library()
|
||||
.type_library()
|
||||
.get_type_from_name(type_name);
|
||||
.get_type_from_name(type_name)?;
|
||||
if let Some(type_identifier) = type_identifier {
|
||||
return self.has_type(type_identifier);
|
||||
}
|
||||
false
|
||||
Ok(false)
|
||||
}
|
||||
fn get_learned_move(&self, index: usize) -> Option<LearnedMove> {
|
||||
fn get_learned_move(&self, index: usize) -> PkmnResult<Option<LearnedMove>> {
|
||||
unsafe {
|
||||
let v = pokemon_get_learned_move(self.inner.reference, index).get_value();
|
||||
if let Some(v) = v {
|
||||
let v = pokemon_get_learned_move(self.inner.reference, index)
|
||||
.as_res()?
|
||||
.get_value();
|
||||
Ok(if let Some(v) = v {
|
||||
Some(Rc::new(v))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
fn change_stat_boost(
|
||||
@@ -225,13 +297,18 @@ mod implementation {
|
||||
stat: Statistic,
|
||||
diff_amount: i8,
|
||||
self_inflicted: bool,
|
||||
) -> bool {
|
||||
) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted)
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
fn ability_script(&self) -> Option<&Box<dyn Script>> {
|
||||
unsafe { pokemon_get_ability_script(self.inner.reference).as_ref() }
|
||||
fn ability_script(&self) -> PkmnResult<Option<&Box<dyn Script>>> {
|
||||
unsafe {
|
||||
Ok((pokemon_get_ability_script(self.inner.reference).as_res()?
|
||||
as *const Box<dyn Script>)
|
||||
.as_ref())
|
||||
}
|
||||
}
|
||||
fn change_species(&self, species: Species, form: Form) {
|
||||
unsafe {
|
||||
@@ -245,81 +322,44 @@ mod implementation {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn change_form(&self, form: Form) {
|
||||
unsafe {
|
||||
let form_impl = form.as_any().downcast_ref_unchecked::<FormImpl>();
|
||||
pokemon_change_form(self.inner.reference, form_impl.reference());
|
||||
}
|
||||
}
|
||||
fn is_fainted(&self) -> bool {
|
||||
self.current_health() == 0
|
||||
|
||||
fn is_fainted(&self) -> PkmnResult<bool> {
|
||||
Ok(self.current_health()? == 0)
|
||||
}
|
||||
fn damage(&self, damage: u32, source: DamageSource) {
|
||||
unsafe { pokemon_damage(self.inner.reference, damage, source) }
|
||||
fn damage(&self, damage: u32, source: DamageSource) -> PkmnResult<()> {
|
||||
unsafe { pokemon_damage(self.inner.reference, damage, source).as_res() }
|
||||
}
|
||||
fn heal(&self, amount: u32, allow_revive: bool) -> bool {
|
||||
unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) }
|
||||
|
||||
fn heal(&self, amount: u32, allow_revive: bool) -> PkmnResult<bool> {
|
||||
unsafe { pokemon_heal(self.inner.reference, amount, allow_revive).as_res() }
|
||||
}
|
||||
|
||||
fn set_weight(&self, weight: f32) {
|
||||
unsafe {
|
||||
pokemon_set_weight(self.reference(), weight);
|
||||
}
|
||||
}
|
||||
|
||||
fn nature(&self) -> Nature {
|
||||
unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_nature(self.inner.reference)
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn species(&self) -> Species {
|
||||
unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_species(self.inner.reference)
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
fn form(&self) -> Form {
|
||||
unsafe { Rc::new(pokemon_get_form(self.inner.reference).get_value().unwrap()) }
|
||||
}
|
||||
|
||||
fn clear_status(&self) {
|
||||
unsafe {
|
||||
pokemon_clear_status(self.reference());
|
||||
}
|
||||
}
|
||||
|
||||
fn display_species(&self) -> Species {
|
||||
unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_display_species(self.inner.reference)
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
fn display_form(&self) -> Form {
|
||||
unsafe {
|
||||
Rc::new(
|
||||
pokemon_get_display_form(self.inner.reference)
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn battle_side(&self) -> BattleSide {
|
||||
self.battle()
|
||||
fn battle_side(&self) -> PkmnResult<BattleSide> {
|
||||
Ok(self
|
||||
.battle()?
|
||||
.unwrap()
|
||||
.sides()
|
||||
.get(self.battle_side_index() as u32)
|
||||
.get(self.battle_side_index()? as usize)
|
||||
.unwrap()
|
||||
.clone())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
@@ -333,8 +373,6 @@ mod implementation {
|
||||
fn current_health(&self) -> u32;
|
||||
fn weight(&self) -> f32;
|
||||
fn height(&self) -> f32;
|
||||
fn nickname(&self) -> *const c_char;
|
||||
fn real_ability(&self) -> AbilityIndex;
|
||||
fn types_length(&self) -> usize;
|
||||
fn battle_side_index(&self) -> u8;
|
||||
fn battle_index(&self) -> u8;
|
||||
@@ -349,45 +387,66 @@ mod implementation {
|
||||
.get_internal_index()
|
||||
.eq(&other.reference())
|
||||
}
|
||||
|
||||
fn real_ability(&self) -> PkmnResult<AbilityIndex> {
|
||||
unsafe {
|
||||
let real_ability = pokemon_get_real_ability(self.reference()).as_res()?;
|
||||
let split: (u8, u8) = transmute(real_ability);
|
||||
Ok(AbilityIndex {
|
||||
index: split.0,
|
||||
hidden: split.1 == 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl WithVolatile for PokemonImpl {
|
||||
fn has_volatile(&self, script_name: &str) -> bool {
|
||||
fn has_volatile(&self, script_name: &str) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
let ptr = CString::new(script_name).unwrap();
|
||||
pokemon_has_volatile(self.inner.reference, ptr.as_ptr())
|
||||
pokemon_has_volatile(self.inner.reference, ptr.as_ptr()).as_res()
|
||||
}
|
||||
}
|
||||
|
||||
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
|
||||
fn add_volatile(&self, script: Box<dyn Script>) -> PkmnResult<&dyn Script> {
|
||||
unsafe {
|
||||
pokemon_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
||||
.val()
|
||||
.unwrap()
|
||||
Ok(
|
||||
pokemon_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
||||
.as_res()?
|
||||
.val()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
|
||||
fn add_volatile_by_name(&self, script_name: &str) -> PkmnResult<&dyn Script> {
|
||||
unsafe {
|
||||
let ptr = CString::new(script_name).unwrap();
|
||||
pokemon_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
|
||||
.val()
|
||||
.unwrap()
|
||||
Ok(
|
||||
pokemon_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
|
||||
.as_res()?
|
||||
.val()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_volatile(&self, script: &dyn Script) {
|
||||
fn remove_volatile(&self, script: &dyn Script) -> PkmnResult<()> {
|
||||
unsafe {
|
||||
let name = CString::new(script.get_name()).unwrap();
|
||||
pokemon_remove_volatile(self.inner.reference, name.as_ptr());
|
||||
pokemon_remove_volatile(self.inner.reference, name.as_ptr()).as_res()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script> {
|
||||
fn get_volatile_script(&self, script_name: &str) -> PkmnResult<Option<&dyn Script>> {
|
||||
unsafe {
|
||||
let script_name = CString::new(script_name).unwrap();
|
||||
pokemon_get_volatile(self.inner.reference, script_name.as_ptr()).val()
|
||||
Ok(
|
||||
pokemon_get_volatile(self.inner.reference, script_name.as_ptr())
|
||||
.as_res()?
|
||||
.val(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,24 +457,41 @@ mod implementation {
|
||||
inner: Rc::new(PokemonInner {
|
||||
reference,
|
||||
library: cached_value!({
|
||||
Rc::new(pokemon_get_library(reference).get_value().unwrap())
|
||||
Rc::new(pokemon_get_library(reference).unwrap().get_value().unwrap())
|
||||
}),
|
||||
flat_stats: cached_value!({
|
||||
Rc::new(pokemon_get_flat_stats(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
pokemon_get_flat_stats(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
stat_boosts: cached_value!({
|
||||
pokemon_get_stat_boosts(reference).get_value().unwrap()
|
||||
pokemon_get_stat_boosts(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
boosted_stats: cached_value!({
|
||||
Rc::new(pokemon_get_boosted_stats(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
pokemon_get_boosted_stats(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
individual_values: cached_value!({
|
||||
pokemon_get_individual_values(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
effort_values: cached_value!({
|
||||
pokemon_get_effort_values(reference).get_value().unwrap()
|
||||
pokemon_get_effort_values(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -430,14 +506,14 @@ mod implementation {
|
||||
PokemonImpl, Pokemon,
|
||||
pub fn species(&self) -> SpeciesImpl;
|
||||
pub fn form(&self) -> FormImpl;
|
||||
pub fn display_species(&self) -> SpeciesImpl;
|
||||
pub fn display_form(&self) -> FormImpl;
|
||||
pub fn active_ability(&self) -> AbilityImpl;
|
||||
pub fn nature(&self) -> NatureImpl;
|
||||
}
|
||||
|
||||
wasm_optional_reference_getters_extern! {
|
||||
PokemonImpl, Pokemon,
|
||||
pub fn display_species(&self) -> Option<SpeciesImpl>;
|
||||
pub fn display_form(&self) -> Option<FormImpl>;
|
||||
pub fn held_item(&self) -> Option<ItemImpl>;
|
||||
pub fn battle(&self) -> Option<BattleImpl>;
|
||||
}
|
||||
@@ -452,8 +528,7 @@ mod implementation {
|
||||
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 real_ability(&self) -> u16;
|
||||
pub fn types_length(&self) -> usize;
|
||||
pub fn battle_side_index(&self) -> u8;
|
||||
pub fn battle_index(&self) -> u8;
|
||||
@@ -477,58 +552,89 @@ mod implementation {
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn pokemon_get_library(r: ExternRef<PokemonImpl>) -> ExternRef<DynamicLibraryImpl>;
|
||||
fn pokemon_get_flat_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>;
|
||||
fn pokemon_get_stat_boosts(r: ExternRef<PokemonImpl>)
|
||||
-> ExternRef<ClampedStatisticSet<i8>>;
|
||||
fn pokemon_get_boosted_stats(r: ExternRef<PokemonImpl>)
|
||||
-> ExternRef<StatisticSetImpl<u32>>;
|
||||
fn pokemon_get_nickname(r: ExternRef<PokemonImpl>) -> WasmResult<u32>;
|
||||
fn pokemon_get_library(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
) -> WasmResult<ExternRef<DynamicLibraryImpl>>;
|
||||
fn pokemon_get_flat_stats(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
) -> WasmResult<ExternRef<StatisticSetImpl<u32>>>;
|
||||
fn pokemon_get_stat_boosts(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
) -> WasmResult<ExternRef<ClampedStatisticSet<i8>>>;
|
||||
fn pokemon_get_boosted_stats(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
) -> WasmResult<ExternRef<StatisticSetImpl<u32>>>;
|
||||
fn pokemon_get_individual_values(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
) -> ExternRef<ClampedStatisticSet<u8>>;
|
||||
) -> WasmResult<ExternRef<ClampedStatisticSet<u8>>>;
|
||||
fn pokemon_get_effort_values(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
) -> ExternRef<ClampedStatisticSet<u8>>;
|
||||
fn pokemon_has_held_item(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool;
|
||||
) -> WasmResult<ExternRef<ClampedStatisticSet<u8>>>;
|
||||
fn pokemon_has_held_item(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmResult<bool>;
|
||||
fn pokemon_set_held_item(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
item: ExternRef<ItemImpl>,
|
||||
) -> ExternRef<ItemImpl>;
|
||||
fn pokemon_remove_held_item(r: ExternRef<PokemonImpl>) -> ExternRef<ItemImpl>;
|
||||
fn pokemon_consume_held_item(r: ExternRef<PokemonImpl>) -> bool;
|
||||
fn pokemon_get_type(r: ExternRef<PokemonImpl>, index: usize) -> u8;
|
||||
fn pokemon_has_type(r: ExternRef<PokemonImpl>, identifier: u8) -> bool;
|
||||
) -> WasmResult<ExternRef<ItemImpl>>;
|
||||
fn pokemon_remove_held_item(r: ExternRef<PokemonImpl>) -> WasmResult<ExternRef<ItemImpl>>;
|
||||
fn pokemon_consume_held_item(r: ExternRef<PokemonImpl>) -> WasmResult<bool>;
|
||||
fn pokemon_get_type(r: ExternRef<PokemonImpl>, index: usize) -> WasmResult<u8>;
|
||||
fn pokemon_has_type(r: ExternRef<PokemonImpl>, identifier: u8) -> WasmResult<bool>;
|
||||
fn pokemon_get_learned_move(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
index: usize,
|
||||
) -> ExternRef<LearnedMoveImpl>;
|
||||
) -> WasmResult<ExternRef<LearnedMoveImpl>>;
|
||||
fn pokemon_change_stat_boost(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
tat: Statistic,
|
||||
diff_amount: i8,
|
||||
self_inflicted: bool,
|
||||
) -> bool;
|
||||
) -> WasmResult<bool>;
|
||||
#[allow(improper_ctypes)]
|
||||
fn pokemon_get_ability_script(r: ExternRef<PokemonImpl>) -> *const Box<dyn Script>;
|
||||
fn pokemon_get_ability_script(r: ExternRef<PokemonImpl>) -> WasmResult<u32>;
|
||||
fn pokemon_change_species(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
species: ExternRef<SpeciesImpl>,
|
||||
form: ExternRef<FormImpl>,
|
||||
);
|
||||
fn pokemon_change_form(r: ExternRef<PokemonImpl>, form: ExternRef<FormImpl>);
|
||||
fn pokemon_damage(r: ExternRef<PokemonImpl>, damage: u32, source: DamageSource);
|
||||
fn pokemon_heal(r: ExternRef<PokemonImpl>, amount: u32, allow_revive: bool) -> bool;
|
||||
fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32);
|
||||
fn pokemon_clear_status(r: ExternRef<PokemonImpl>);
|
||||
) -> WasmResult<()>;
|
||||
fn pokemon_change_form(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
form: ExternRef<FormImpl>,
|
||||
) -> WasmResult<()>;
|
||||
fn pokemon_damage(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
damage: u32,
|
||||
source: DamageSource,
|
||||
) -> WasmResult<()>;
|
||||
fn pokemon_heal(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
amount: u32,
|
||||
allow_revive: bool,
|
||||
) -> WasmResult<bool>;
|
||||
fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32) -> WasmResult<()>;
|
||||
fn pokemon_clear_status(r: ExternRef<PokemonImpl>) -> WasmResult<()>;
|
||||
|
||||
fn pokemon_add_volatile_by_name(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
name: *const c_char,
|
||||
) -> ScriptPtr;
|
||||
fn pokemon_add_volatile(r: ExternRef<PokemonImpl>, script: ScriptPtr) -> ScriptPtr;
|
||||
fn pokemon_has_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool;
|
||||
fn pokemon_remove_volatile(r: ExternRef<PokemonImpl>, name: *const c_char);
|
||||
fn pokemon_get_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> ScriptPtr;
|
||||
) -> WasmResult<ScriptPtr>;
|
||||
fn pokemon_add_volatile(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
script: ScriptPtr,
|
||||
) -> WasmResult<ScriptPtr>;
|
||||
fn pokemon_has_volatile(r: ExternRef<PokemonImpl>, name: *const c_char)
|
||||
-> WasmResult<bool>;
|
||||
fn pokemon_remove_volatile(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmResult<()>;
|
||||
fn pokemon_get_volatile(
|
||||
r: ExternRef<PokemonImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmResult<ScriptPtr>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,30 +643,30 @@ mockall::mock!(
|
||||
pub Pokemon {}
|
||||
impl PokemonTrait for Pokemon {
|
||||
fn reference(&self) -> u32;
|
||||
fn species(&self) -> Species;
|
||||
fn form(&self) -> Form;
|
||||
fn active_ability(&self) -> Ability;
|
||||
fn nature(&self) -> Nature;
|
||||
fn display_species(&self) -> Species;
|
||||
fn display_form(&self) -> Form;
|
||||
fn held_item(&self) -> Option<Item>;
|
||||
fn battle(&self) -> Option<Battle>;
|
||||
fn level(&self) -> LevelInt;
|
||||
fn experience(&self) -> u32;
|
||||
fn unique_identifier(&self) -> u32;
|
||||
fn gender(&self) -> Gender;
|
||||
fn coloring(&self) -> u8;
|
||||
fn current_health(&self) -> u32;
|
||||
fn weight(&self) -> f32;
|
||||
fn height(&self) -> f32;
|
||||
fn nickname(&self) -> *const c_char;
|
||||
fn real_ability(&self) -> AbilityIndex;
|
||||
fn types_length(&self) -> usize;
|
||||
fn battle_side_index(&self) -> u8;
|
||||
fn battle_index(&self) -> u8;
|
||||
fn is_ability_overriden(&self) -> u8;
|
||||
fn allowed_experience_gain(&self) -> bool;
|
||||
fn is_usable(&self) -> bool;
|
||||
fn species(&self) -> PkmnResult<Species>;
|
||||
fn form(&self) -> PkmnResult<Form>;
|
||||
fn active_ability(&self) -> PkmnResult<Ability>;
|
||||
fn nature(&self) -> PkmnResult<Nature>;
|
||||
fn display_species(&self) -> PkmnResult<Species>;
|
||||
fn display_form(&self) -> PkmnResult<Form>;
|
||||
fn held_item(&self) -> PkmnResult<Option<Item>>;
|
||||
fn battle(&self) -> PkmnResult<Option<Battle>>;
|
||||
fn level(&self) -> PkmnResult<LevelInt>;
|
||||
fn experience(&self) -> PkmnResult<u32>;
|
||||
fn unique_identifier(&self) -> PkmnResult<u32>;
|
||||
fn gender(&self) -> PkmnResult<Gender>;
|
||||
fn coloring(&self) -> PkmnResult<u8>;
|
||||
fn current_health(&self) -> PkmnResult<u32>;
|
||||
fn weight(&self) -> PkmnResult<f32>;
|
||||
fn height(&self) -> PkmnResult<f32>;
|
||||
fn nickname(&self) -> PkmnResult<*const c_char>;
|
||||
fn real_ability(&self) -> PkmnResult<AbilityIndex>;
|
||||
fn types_length(&self) -> PkmnResult<usize>;
|
||||
fn battle_side_index(&self) -> PkmnResult<u8>;
|
||||
fn battle_index(&self) -> PkmnResult<u8>;
|
||||
fn is_ability_overriden(&self) -> PkmnResult<u8>;
|
||||
fn allowed_experience_gain(&self) -> PkmnResult<bool>;
|
||||
fn is_usable(&self) -> PkmnResult<bool>;
|
||||
|
||||
fn library(&self) -> DynamicLibrary;
|
||||
fn flat_stats(&self) -> StatisticSet<u32>;
|
||||
@@ -568,44 +674,44 @@ mockall::mock!(
|
||||
fn boosted_stats(&self) -> StatisticSet<u32>;
|
||||
fn individual_values(&self) -> ClampedStatisticSet<u8>;
|
||||
fn effort_values(&self) -> ClampedStatisticSet<u8>;
|
||||
fn has_held_item(&self, name: &str) -> bool;
|
||||
fn set_held_item(&self, item: &Item) -> Option<Item>;
|
||||
fn remove_held_item(&self) -> Option<Item>;
|
||||
fn consume_held_item(&self) -> bool;
|
||||
fn max_health(&self) -> u32;
|
||||
fn get_type(&self, index: usize) -> u8;
|
||||
fn has_type(&self, type_identifier: TypeIdentifier) -> bool;
|
||||
fn has_type_by_name(&self, type_name: &str) -> bool;
|
||||
fn get_learned_move(&self, index: usize) -> Option<LearnedMove>;
|
||||
fn change_stat_boost(&self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> bool;
|
||||
fn ability_script<'a>(&'a self) -> Option<&'a Box<dyn Script>>;
|
||||
fn has_held_item(&self, name: &str) -> PkmnResult<bool>;
|
||||
fn set_held_item(&self, item: &Item) -> PkmnResult<Option<Item>>;
|
||||
fn remove_held_item(&self) -> PkmnResult<Option<Item>>;
|
||||
fn consume_held_item(&self) -> PkmnResult<bool>;
|
||||
fn max_health(&self) -> PkmnResult<u32>;
|
||||
fn get_type(&self, index: usize) -> PkmnResult<u8>;
|
||||
fn has_type(&self, type_identifier: TypeIdentifier) -> PkmnResult<bool>;
|
||||
fn has_type_by_name(&self, type_name: &str) -> PkmnResult<bool>;
|
||||
fn get_learned_move(&self, index: usize) -> PkmnResult<Option<LearnedMove>>;
|
||||
fn change_stat_boost(&self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> PkmnResult<bool>;
|
||||
fn ability_script<'a>(&'a self) -> PkmnResult<Option<&'a Box<dyn Script>>>;
|
||||
fn change_species(&self, species: Species, form: Form);
|
||||
fn change_form(&self, form: Form);
|
||||
fn is_fainted(&self) -> bool;
|
||||
fn damage(&self, damage: u32, source: DamageSource);
|
||||
fn heal(&self, amount: u32, allow_revive: bool) -> bool;
|
||||
fn is_fainted(&self) -> PkmnResult<bool>;
|
||||
fn damage(&self, damage: u32, source: DamageSource) -> PkmnResult<()>;
|
||||
fn heal(&self, amount: u32, allow_revive: bool) -> PkmnResult<bool>;
|
||||
fn set_weight(&self, weight: f32);
|
||||
fn clear_status(&self);
|
||||
fn battle_side(&self) -> BattleSide;
|
||||
fn battle_side(&self) -> PkmnResult<BattleSide>;
|
||||
fn equals(&self, other: &Pokemon) -> bool;
|
||||
}
|
||||
);
|
||||
|
||||
#[cfg(feature = "mock_data")]
|
||||
impl WithVolatile for MockPokemon {
|
||||
fn has_volatile(&self, _script_name: &str) -> bool {
|
||||
fn has_volatile(&self, _script_name: &str) -> PkmnResult<bool> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn add_volatile(&self, _script: Box<dyn Script>) -> &dyn Script {
|
||||
fn add_volatile(&self, _script: Box<dyn Script>) -> PkmnResult<&dyn Script> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn add_volatile_by_name(&self, _script_name: &str) -> &dyn Script {
|
||||
fn add_volatile_by_name(&self, _script_name: &str) -> PkmnResult<&dyn Script> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn remove_volatile(&self, _script: &dyn Script) {
|
||||
fn remove_volatile(&self, _script: &dyn Script) -> PkmnResult<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn get_volatile_script<'a>(&'a self, _script_name: &str) -> Option<&'a dyn Script> {
|
||||
fn get_volatile_script<'a>(&'a self, _script_name: &str) -> PkmnResult<Option<&'a dyn Script>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::app_interface::Statistic;
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::{ExternRef, ExternalReferenceType, PkmnResult};
|
||||
use alloc::rc::Rc;
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
use core::fmt::Debug;
|
||||
@@ -12,28 +14,28 @@ where
|
||||
<T as TryFrom<i64>>::Error: Debug,
|
||||
<T as TryInto<i64>>::Error: Debug,
|
||||
{
|
||||
fn hp(&self) -> T {
|
||||
fn hp(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Attack)
|
||||
}
|
||||
fn attack(&self) -> T {
|
||||
fn attack(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Attack)
|
||||
}
|
||||
fn defense(&self) -> T {
|
||||
fn defense(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Defense)
|
||||
}
|
||||
fn special_attack(&self) -> T {
|
||||
fn special_attack(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::SpecialAttack)
|
||||
}
|
||||
fn special_defense(&self) -> T {
|
||||
fn special_defense(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::SpecialDefense)
|
||||
}
|
||||
fn speed(&self) -> T {
|
||||
fn speed(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Speed)
|
||||
}
|
||||
fn get_stat(&self, stat: Statistic) -> T;
|
||||
fn set_stat(&self, stat: Statistic, value: T);
|
||||
fn increase_stat(&self, stat: Statistic, value: T);
|
||||
fn decrease_stat(&self, stat: Statistic, value: T);
|
||||
fn get_stat(&self, stat: Statistic) -> PkmnResult<T>;
|
||||
fn set_stat(&self, stat: Statistic, value: T) -> PkmnResult<()>;
|
||||
fn increase_stat(&self, stat: Statistic, value: T) -> PkmnResult<()>;
|
||||
fn decrease_stat(&self, stat: Statistic, value: T) -> PkmnResult<()>;
|
||||
}
|
||||
|
||||
pub type StatisticSet<T> = Rc<dyn StatisticSetTrait<T>>;
|
||||
@@ -74,24 +76,29 @@ where
|
||||
<T as TryFrom<i64>>::Error: Debug,
|
||||
<T as TryInto<i64>>::Error: Debug,
|
||||
{
|
||||
fn get_stat(&self, stat: Statistic) -> T {
|
||||
fn get_stat(&self, stat: Statistic) -> PkmnResult<T> {
|
||||
unsafe {
|
||||
statistic_set_get(self.reference.cast(), stat)
|
||||
Ok(statistic_set_get(self.reference.cast(), stat)
|
||||
.as_res()?
|
||||
.try_into()
|
||||
.unwrap()
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
fn set_stat(&self, stat: Statistic, value: T) {
|
||||
unsafe { statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) }
|
||||
fn set_stat(&self, stat: Statistic, value: T) -> PkmnResult<()> {
|
||||
unsafe {
|
||||
statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()).as_res()
|
||||
}
|
||||
}
|
||||
fn increase_stat(&self, stat: Statistic, value: T) {
|
||||
fn increase_stat(&self, stat: Statistic, value: T) -> PkmnResult<()> {
|
||||
unsafe {
|
||||
statistic_set_increase_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
fn decrease_stat(&self, stat: Statistic, value: T) {
|
||||
fn decrease_stat(&self, stat: Statistic, value: T) -> PkmnResult<()> {
|
||||
unsafe {
|
||||
statistic_set_decrease_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,62 +143,68 @@ where
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn hp(&self) -> T {
|
||||
pub fn hp(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::HP)
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn attack(&self) -> T {
|
||||
pub fn attack(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Attack)
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn defense(&self) -> T {
|
||||
pub fn defense(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Defense)
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn special_attack(&self) -> T {
|
||||
pub fn special_attack(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::SpecialAttack)
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn special_defense(&self) -> T {
|
||||
pub fn special_defense(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::SpecialDefense)
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn speed(&self) -> T {
|
||||
pub fn speed(&self) -> PkmnResult<T> {
|
||||
self.get_stat(Statistic::Speed)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn get_stat(&self, stat: Statistic) -> T {
|
||||
pub fn get_stat(&self, stat: Statistic) -> PkmnResult<T> {
|
||||
unsafe {
|
||||
clamped_statistic_set_get(self.reference.cast(), stat)
|
||||
Ok(clamped_statistic_set_get(self.reference.cast(), stat)
|
||||
.as_res()?
|
||||
.try_into()
|
||||
.unwrap()
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn set_stat(&self, stat: Statistic, value: T) {
|
||||
unsafe { clamped_statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) }
|
||||
pub fn set_stat(&self, stat: Statistic, value: T) -> PkmnResult<()> {
|
||||
unsafe {
|
||||
clamped_statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap())
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn increase_stat(&self, stat: Statistic, value: T) -> bool {
|
||||
pub fn increase_stat(&self, stat: Statistic, value: T) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
clamped_statistic_set_increase_stat(
|
||||
self.reference.cast(),
|
||||
stat,
|
||||
value.try_into().unwrap(),
|
||||
)
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn decrease_stat(&self, stat: Statistic, value: T) -> bool {
|
||||
pub fn decrease_stat(&self, stat: Statistic, value: T) -> PkmnResult<bool> {
|
||||
unsafe {
|
||||
clamped_statistic_set_decrease_stat(
|
||||
self.reference.cast(),
|
||||
stat,
|
||||
value.try_into().unwrap(),
|
||||
)
|
||||
.as_res()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,33 +223,40 @@ where
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn statistic_set_get(r: ExternRef<StatisticSetImpl<i64>>, stat: Statistic) -> i64;
|
||||
fn statistic_set_set(r: ExternRef<StatisticSetImpl<i64>>, stat: Statistic, value: i64);
|
||||
fn statistic_set_get(r: ExternRef<StatisticSetImpl<i64>>, stat: Statistic) -> WasmResult<i64>;
|
||||
fn statistic_set_set(
|
||||
r: ExternRef<StatisticSetImpl<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
) -> WasmResult<()>;
|
||||
fn statistic_set_increase_stat(
|
||||
r: ExternRef<StatisticSetImpl<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
);
|
||||
) -> WasmResult<()>;
|
||||
fn statistic_set_decrease_stat(
|
||||
r: ExternRef<StatisticSetImpl<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
);
|
||||
) -> WasmResult<()>;
|
||||
|
||||
fn clamped_statistic_set_get(r: ExternRef<ClampedStatisticSet<i64>>, stat: Statistic) -> i64;
|
||||
fn clamped_statistic_set_get(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
) -> WasmResult<i64>;
|
||||
fn clamped_statistic_set_set(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
);
|
||||
) -> WasmResult<()>;
|
||||
fn clamped_statistic_set_increase_stat(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
) -> bool;
|
||||
) -> WasmResult<bool>;
|
||||
fn clamped_statistic_set_decrease_stat(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
) -> bool;
|
||||
) -> WasmResult<bool>;
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ impl TurnChoice {
|
||||
pub fn user(&self) -> Pokemon {
|
||||
self.base().user()
|
||||
}
|
||||
pub fn speed(&self) -> u32 {
|
||||
pub fn speed(&self) -> PkmnResult<u32> {
|
||||
self.base().speed()
|
||||
}
|
||||
pub fn has_failed(&self) -> bool {
|
||||
pub fn has_failed(&self) -> PkmnResult<bool> {
|
||||
self.base().has_failed()
|
||||
}
|
||||
pub fn fail(&self) {
|
||||
pub fn fail(&self) -> PkmnResult<()> {
|
||||
self.base().fail()
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,9 @@ impl TurnChoice {
|
||||
pub trait BaseTurnChoiceDataTrait {
|
||||
fn reference(&self) -> u32;
|
||||
fn user(&self) -> Pokemon;
|
||||
fn speed(&self) -> u32;
|
||||
fn has_failed(&self) -> bool;
|
||||
fn fail(&self);
|
||||
fn speed(&self) -> PkmnResult<u32>;
|
||||
fn has_failed(&self) -> PkmnResult<bool>;
|
||||
fn fail(&self) -> PkmnResult<()>;
|
||||
}
|
||||
|
||||
pub type BaseTurnChoiceData = Rc<dyn BaseTurnChoiceDataTrait>;
|
||||
@@ -55,8 +55,8 @@ pub trait MoveTurnChoiceDataTrait {
|
||||
fn used_move(&self) -> LearnedMove;
|
||||
fn target_side(&self) -> u8;
|
||||
fn target_index(&self) -> u8;
|
||||
fn priority(&self) -> i8;
|
||||
fn move_script<'a>(&self) -> Option<&'a Box<dyn Script>>;
|
||||
fn priority(&self) -> PkmnResult<i8>;
|
||||
fn move_script<'a>(&self) -> PkmnResult<Option<&'a Box<dyn Script>>>;
|
||||
}
|
||||
#[cfg(feature = "mock_data")]
|
||||
pub type MockMoveTurnChoiceData = MockMoveTurnChoiceDataTrait;
|
||||
@@ -65,10 +65,11 @@ pub type MockMoveTurnChoiceData = MockMoveTurnChoiceDataTrait;
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::{LearnedMoveImpl, PokemonImpl};
|
||||
use crate::cached_value;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::temporary::Temporary;
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::{cached_value, PkmnResult};
|
||||
|
||||
struct BaseTurnChoiceDataImpl {
|
||||
reference: ExternRef<TurnChoice>,
|
||||
@@ -83,14 +84,14 @@ mod implementation {
|
||||
fn user(&self) -> Pokemon {
|
||||
self.user.value()
|
||||
}
|
||||
fn speed(&self) -> u32 {
|
||||
unsafe { turn_choice_get_speed(self.reference) }
|
||||
fn speed(&self) -> PkmnResult<u32> {
|
||||
unsafe { turn_choice_get_speed(self.reference).as_res() }
|
||||
}
|
||||
fn has_failed(&self) -> bool {
|
||||
unsafe { turn_choice_has_failed(self.reference) }
|
||||
fn has_failed(&self) -> PkmnResult<bool> {
|
||||
unsafe { turn_choice_has_failed(self.reference).as_res() }
|
||||
}
|
||||
fn fail(&self) {
|
||||
unsafe { turn_choice_fail(self.reference) }
|
||||
fn fail(&self) -> PkmnResult<()> {
|
||||
unsafe { turn_choice_fail(self.reference).as_res() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,18 +122,24 @@ mod implementation {
|
||||
fn target_index(&self) -> u8 {
|
||||
self.inner.value().target_index.value()
|
||||
}
|
||||
fn priority(&self) -> i8 {
|
||||
unsafe { turn_choice_move_priority(self.base().reference().into()) }
|
||||
fn priority(&self) -> PkmnResult<i8> {
|
||||
unsafe { turn_choice_move_priority(self.base().reference().into()).as_res() }
|
||||
}
|
||||
fn move_script<'a>(&self) -> Option<&'a Box<dyn Script>> {
|
||||
unsafe { turn_choice_move_script(self.base().reference().into()).as_ref() }
|
||||
fn move_script<'a>(&self) -> PkmnResult<Option<&'a Box<dyn Script>>> {
|
||||
unsafe {
|
||||
Ok(
|
||||
(turn_choice_move_script(self.base().reference().into()).as_res()?
|
||||
as *const Box<dyn Script>)
|
||||
.as_ref(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl ExternalReferenceType for TurnChoice {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
let kind = unsafe { turn_choice_get_kind(reference) };
|
||||
let kind = unsafe { turn_choice_get_kind(reference).unwrap() };
|
||||
match kind {
|
||||
0 => TurnChoice::Move(Box::new(MoveTurnChoiceDataImpl {
|
||||
inner: Temporary::new(
|
||||
@@ -152,39 +159,50 @@ mod implementation {
|
||||
base: Rc::new(BaseTurnChoiceDataImpl {
|
||||
reference: reference.cast(),
|
||||
user: cached_value!({
|
||||
Rc::new(turn_choice_get_user(reference.cast()).get_value().unwrap())
|
||||
Rc::new(
|
||||
turn_choice_get_user(reference.cast())
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
}),
|
||||
used_move: cached_value!({
|
||||
Rc::new(
|
||||
turn_choice_move_used_move(reference.cast())
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
target_side: cached_value!({ turn_choice_move_target_side(reference.cast()) }),
|
||||
target_index: cached_value!({ turn_choice_move_target_index(reference.cast()) }),
|
||||
target_side: cached_value!({
|
||||
turn_choice_move_target_side(reference.cast()).unwrap()
|
||||
}),
|
||||
target_index: cached_value!({
|
||||
turn_choice_move_target_index(reference.cast()).unwrap()
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8;
|
||||
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<PokemonImpl>;
|
||||
fn turn_choice_get_speed(r: ExternRef<TurnChoice>) -> u32;
|
||||
fn turn_choice_has_failed(r: ExternRef<TurnChoice>) -> bool;
|
||||
fn turn_choice_fail(r: ExternRef<TurnChoice>);
|
||||
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> WasmResult<u8>;
|
||||
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> WasmResult<ExternRef<PokemonImpl>>;
|
||||
fn turn_choice_get_speed(r: ExternRef<TurnChoice>) -> WasmResult<u32>;
|
||||
fn turn_choice_has_failed(r: ExternRef<TurnChoice>) -> WasmResult<bool>;
|
||||
fn turn_choice_fail(r: ExternRef<TurnChoice>) -> WasmResult<()>;
|
||||
|
||||
fn turn_choice_move_used_move(
|
||||
r: ExternRef<MoveTurnChoiceDataImpl>,
|
||||
) -> ExternRef<LearnedMoveImpl>;
|
||||
fn turn_choice_move_target_side(r: ExternRef<MoveTurnChoiceDataImpl>) -> u8;
|
||||
fn turn_choice_move_target_index(r: ExternRef<MoveTurnChoiceDataImpl>) -> u8;
|
||||
fn turn_choice_move_priority(r: ExternRef<MoveTurnChoiceDataImpl>) -> i8;
|
||||
) -> WasmResult<ExternRef<LearnedMoveImpl>>;
|
||||
fn turn_choice_move_target_side(r: ExternRef<MoveTurnChoiceDataImpl>) -> WasmResult<u8>;
|
||||
fn turn_choice_move_target_index(r: ExternRef<MoveTurnChoiceDataImpl>) -> WasmResult<u8>;
|
||||
fn turn_choice_move_priority(r: ExternRef<MoveTurnChoiceDataImpl>) -> WasmResult<i8>;
|
||||
#[allow(improper_ctypes)]
|
||||
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceDataImpl>) -> *const Box<dyn Script>;
|
||||
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceDataImpl>) -> WasmResult<u32>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
use crate::handling::Script;
|
||||
use crate::PkmnResult;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
pub trait WithVolatile {
|
||||
fn has_volatile(&self, script_name: &str) -> bool;
|
||||
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script;
|
||||
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script;
|
||||
fn remove_volatile(&self, script: &dyn Script);
|
||||
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script>;
|
||||
fn has_volatile(&self, script_name: &str) -> PkmnResult<bool>;
|
||||
fn add_volatile(&self, script: Box<dyn Script>) -> PkmnResult<&dyn Script>;
|
||||
fn add_volatile_by_name(&self, script_name: &str) -> PkmnResult<&dyn Script>;
|
||||
fn remove_volatile(&self, script: &dyn Script) -> PkmnResult<()>;
|
||||
fn get_volatile_script(&self, script_name: &str) -> PkmnResult<Option<&dyn Script>>;
|
||||
}
|
||||
|
||||
pub fn get_volatile_as<'a, T>(v: &'a dyn WithVolatile, script_name: &str) -> Option<&'a T>
|
||||
pub fn get_volatile_as<'a, T>(
|
||||
v: &'a dyn WithVolatile,
|
||||
script_name: &str,
|
||||
) -> PkmnResult<Option<&'a T>>
|
||||
where
|
||||
T: Script + 'static,
|
||||
{
|
||||
let s = v.get_volatile_script(script_name);
|
||||
let s = v.get_volatile_script(script_name)?;
|
||||
if let Some(s) = s {
|
||||
Some(s.as_any().downcast_ref::<T>().unwrap())
|
||||
Ok(Some(s.as_any().downcast_ref::<T>().unwrap()))
|
||||
} else {
|
||||
None
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
use alloc::rc::Rc;
|
||||
|
||||
pub trait ImmutableListTrait<T> {
|
||||
fn get(&self, index: u32) -> Option<T>;
|
||||
}
|
||||
|
||||
pub type ImmutableList<T> = Rc<dyn ImmutableListTrait<T>>;
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::{
|
||||
BattleParty, BattlePartyImpl, BattleSide, BattleSideImpl, EffectParameter, StringKey,
|
||||
};
|
||||
use crate::handling::extern_ref::{ExternalReferenceType, VecExternRef};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
pub(crate) struct ImmutableListInner<T: Clone> {
|
||||
extern_ref: VecExternRef<T>,
|
||||
resource_type: PhantomData<T>,
|
||||
values: spin::RwLock<Vec<Option<Option<Rc<T>>>>>,
|
||||
}
|
||||
|
||||
pub(crate) trait ImmutableListWasm<T: Clone + ExternalReferenceType> {
|
||||
fn initialize(inner: *const ImmutableListInner<T>) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn new(extern_ref: VecExternRef<T>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let mut values = Vec::new();
|
||||
values.resize(extern_ref.len() as usize, None);
|
||||
let inner = Box::new(ImmutableListInner {
|
||||
extern_ref,
|
||||
resource_type: Default::default(),
|
||||
values: spin::RwLock::new(values),
|
||||
});
|
||||
let inner_ptr = Box::into_raw(inner);
|
||||
Self::initialize(inner_ptr)
|
||||
}
|
||||
|
||||
fn from_ref(extern_ref: VecExternRef<T>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
unsafe {
|
||||
if let None = CACHE {
|
||||
CACHE = Some(hashbrown::HashMap::new());
|
||||
}
|
||||
let existing = CACHE
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(&extern_ref.get_internal_index());
|
||||
if let Some(v) = existing {
|
||||
let inner = *v as *const ImmutableListInner<T>;
|
||||
Self::initialize(inner)
|
||||
} else {
|
||||
let v = Self::new(extern_ref);
|
||||
CACHE.as_mut().unwrap().insert(
|
||||
extern_ref.get_internal_index(),
|
||||
v.get_inner_ptr() as *const u8,
|
||||
);
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_inner(&self) -> &ImmutableListInner<T> {
|
||||
unsafe { self.get_inner_ptr().as_ref().unwrap() }
|
||||
}
|
||||
fn get_inner_ptr(&self) -> *const ImmutableListInner<T>;
|
||||
|
||||
fn get_cached(&self, index: u32) -> Option<Rc<T>> {
|
||||
let inner = self.get_inner();
|
||||
let rg = inner.values.read();
|
||||
let v = rg.get(index as usize).unwrap();
|
||||
if let Some(v) = v {
|
||||
return v.clone();
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
fn get_value(&self, index: u32) -> Option<Rc<T>> {
|
||||
if let Some(cached) = self.get_cached(index) {
|
||||
return Some(cached);
|
||||
}
|
||||
let inner = self.get_inner();
|
||||
let r = inner.extern_ref.at(index);
|
||||
let value = r.get_value();
|
||||
let value = if let Some(value) = value {
|
||||
Some(Rc::new(value))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut wg = inner.values.write();
|
||||
wg[index as usize] = Some(value);
|
||||
let v = wg[index as usize].as_ref().unwrap().clone();
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! immutable_list_type {
|
||||
($type_name:ident, $underlying:ident) => {
|
||||
paste::paste! {
|
||||
pub struct [<$type_name ImmutableList>] {
|
||||
inner: *const ImmutableListInner<$underlying>,
|
||||
}
|
||||
|
||||
impl ImmutableListWasm<$underlying> for [<$type_name ImmutableList>] {
|
||||
fn initialize(inner: *const ImmutableListInner<$underlying>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
fn get_inner_ptr(&self) -> *const ImmutableListInner<$underlying> {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl ImmutableListTrait<$type_name> for [<$type_name ImmutableList>] {
|
||||
fn get(&self, index: u32) -> Option<$type_name> {
|
||||
let v = self.get_value(index);
|
||||
if let Some(v) = v {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
immutable_list_type!(BattleSide, BattleSideImpl);
|
||||
immutable_list_type!(BattleParty, BattlePartyImpl);
|
||||
|
||||
pub struct EffectParameterImmutableList {
|
||||
inner: *const ImmutableListInner<EffectParameter>,
|
||||
}
|
||||
|
||||
impl ImmutableListWasm<EffectParameter> for EffectParameterImmutableList {
|
||||
fn initialize(inner: *const ImmutableListInner<EffectParameter>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
fn get_inner_ptr(&self) -> *const ImmutableListInner<EffectParameter> {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl ImmutableListTrait<Rc<EffectParameter>> for EffectParameterImmutableList {
|
||||
fn get(&self, index: u32) -> Option<Rc<EffectParameter>> {
|
||||
let v = self.get_value(index);
|
||||
if let Some(v) = v {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StringKeyImmutableList {
|
||||
inner: *const ImmutableListInner<StringKey>,
|
||||
}
|
||||
|
||||
impl ImmutableListWasm<StringKey> for StringKeyImmutableList {
|
||||
fn initialize(inner: *const ImmutableListInner<StringKey>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
fn get_inner_ptr(&self) -> *const ImmutableListInner<StringKey> {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl ImmutableListTrait<Rc<StringKey>> for StringKeyImmutableList {
|
||||
fn get(&self, index: u32) -> Option<Rc<StringKey>> {
|
||||
let v = self.get_value(index);
|
||||
if let Some(v) = v {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mut CACHE: Option<hashbrown::HashMap<u32, *const u8>> = None;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
@@ -1,5 +1,4 @@
|
||||
pub mod dynamic_data;
|
||||
pub mod list;
|
||||
pub mod static_data;
|
||||
pub mod string_key;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ pub trait AbilityTrait {
|
||||
|
||||
pub type Ability = Rc<dyn AbilityTrait>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[repr(C)]
|
||||
pub struct AbilityIndex {
|
||||
pub hidden: bool,
|
||||
@@ -19,21 +19,20 @@ pub struct AbilityIndex {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::list::{
|
||||
EffectParameterImmutableList, ImmutableList, ImmutableListWasm,
|
||||
};
|
||||
use crate::app_interface::{EffectParameter, StringKey};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType, VecExternRef};
|
||||
use crate::handling::Cacheable;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::ffi_array::FFIArray;
|
||||
use crate::handling::{Cacheable, WasmResult};
|
||||
use crate::{cached_value, cached_value_getters};
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
struct AbilityInner {
|
||||
reference: ExternRef<AbilityImpl>,
|
||||
name: CachedValue<StringKey>,
|
||||
effect: CachedValue<StringKey>,
|
||||
parameters: CachedValue<ImmutableList<Rc<EffectParameter>>>,
|
||||
parameters: CachedValue<Vec<Rc<EffectParameter>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -47,12 +46,21 @@ mod implementation {
|
||||
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() }),
|
||||
name: cached_value!({
|
||||
ability_get_name(reference).unwrap().get_value().unwrap()
|
||||
}),
|
||||
effect: cached_value!({
|
||||
ability_get_effect(reference).unwrap().get_value().unwrap()
|
||||
}),
|
||||
parameters: cached_value!({
|
||||
Rc::new(EffectParameterImmutableList::from_ref(
|
||||
ability_get_parameters(reference),
|
||||
))
|
||||
let pars: FFIArray<ExternRef<EffectParameter>> =
|
||||
FFIArray::from_u64(ability_get_parameters(reference).unwrap());
|
||||
let pars = Vec::from_raw_parts(pars.ptr(), pars.len(), pars.len());
|
||||
let pars = pars
|
||||
.into_iter()
|
||||
.map(|r| Rc::new(EffectParameter::new(r).unwrap()))
|
||||
.collect::<Vec<_>>();
|
||||
pars
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -77,9 +85,9 @@ mod implementation {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn ability_get_name(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
||||
fn ability_get_effect(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
||||
fn ability_get_parameters(r: ExternRef<AbilityImpl>) -> VecExternRef<EffectParameter>;
|
||||
fn ability_get_name(r: ExternRef<AbilityImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn ability_get_effect(r: ExternRef<AbilityImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn ability_get_parameters(r: ExternRef<AbilityImpl>) -> WasmResult<u64>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ mod implementation {
|
||||
use crate::app_interface::{get_hash, StringKey};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::Cacheable;
|
||||
use crate::handling::{Cacheable, WasmResult};
|
||||
use crate::{cached_value, cached_value_getters};
|
||||
use spin::RwLock;
|
||||
|
||||
@@ -60,24 +60,41 @@ mod implementation {
|
||||
inner: Rc::new(StaticDataInner {
|
||||
reference,
|
||||
move_library: cached_value!({
|
||||
Rc::new(static_data_get_move_library(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
static_data_get_move_library(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
item_library: cached_value!({
|
||||
Rc::new(static_data_get_item_library(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
static_data_get_item_library(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
species_library: cached_value!({
|
||||
Rc::new(
|
||||
static_data_get_species_library(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
type_library: cached_value!({
|
||||
Rc::new(static_data_get_type_library(reference).get_value().unwrap())
|
||||
Rc::new(
|
||||
static_data_get_type_library(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
settings: cached_value!({
|
||||
Rc::new(
|
||||
static_data_get_library_settings(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -119,7 +136,9 @@ mod implementation {
|
||||
pub(crate) fn new(ptr: ExternRef<LibrarySettingsImpl>) -> Self {
|
||||
Self {
|
||||
inner: Rc::new(LibrarySettingsInner {
|
||||
maximum_level: cached_value!({ library_settings_get_maximum_level(ptr) }),
|
||||
maximum_level: cached_value!({
|
||||
library_settings_get_maximum_level(ptr).unwrap()
|
||||
}),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -142,21 +161,23 @@ mod implementation {
|
||||
extern "wasm" {
|
||||
fn static_data_get_move_library(
|
||||
ptr: ExternRef<StaticDataImpl>,
|
||||
) -> ExternRef<MoveLibraryImpl>;
|
||||
) -> WasmResult<ExternRef<MoveLibraryImpl>>;
|
||||
fn static_data_get_item_library(
|
||||
ptr: ExternRef<StaticDataImpl>,
|
||||
) -> ExternRef<ItemLibraryImpl>;
|
||||
) -> WasmResult<ExternRef<ItemLibraryImpl>>;
|
||||
fn static_data_get_species_library(
|
||||
ptr: ExternRef<StaticDataImpl>,
|
||||
) -> ExternRef<SpeciesLibraryImpl>;
|
||||
) -> WasmResult<ExternRef<SpeciesLibraryImpl>>;
|
||||
fn static_data_get_type_library(
|
||||
ptr: ExternRef<StaticDataImpl>,
|
||||
) -> ExternRef<TypeLibraryImpl>;
|
||||
) -> WasmResult<ExternRef<TypeLibraryImpl>>;
|
||||
fn static_data_get_library_settings(
|
||||
ptr: ExternRef<StaticDataImpl>,
|
||||
) -> ExternRef<LibrarySettingsImpl>;
|
||||
) -> WasmResult<ExternRef<LibrarySettingsImpl>>;
|
||||
|
||||
fn library_settings_get_maximum_level(ptr: ExternRef<LibrarySettingsImpl>) -> LevelInt;
|
||||
fn library_settings_get_maximum_level(
|
||||
ptr: ExternRef<LibrarySettingsImpl>,
|
||||
) -> WasmResult<LevelInt>;
|
||||
}
|
||||
|
||||
pub trait DataLibrary<T>: Cacheable
|
||||
@@ -182,14 +203,16 @@ mod implementation {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if let Some(v) = self.get_cache().read().get(&name.hash()) {
|
||||
if let Some(v) = self.get_cache().read().get(&name.hash().unwrap()) {
|
||||
return Some(v.clone());
|
||||
}
|
||||
|
||||
let index = Self::_get_ref_by_name(self.get_self_ref(), name.ptr());
|
||||
let v = Self::_from_external_ref_index(index);
|
||||
if let Some(v) = &v {
|
||||
self.get_cache().write().insert(name.hash(), v.clone());
|
||||
self.get_cache()
|
||||
.write()
|
||||
.insert(name.hash().unwrap(), v.clone());
|
||||
}
|
||||
v
|
||||
}
|
||||
@@ -242,7 +265,7 @@ mod mocked {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.get_cache().read().get(&name.hash()).cloned()
|
||||
self.get_cache().read().get(&name.hash().unwrap()).cloned()
|
||||
}
|
||||
|
||||
fn get_by_hash(&self, hash: u32) -> Option<T>
|
||||
|
||||
@@ -2,17 +2,17 @@ use crate::app_interface::TypeIdentifier;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
pub trait TypeLibraryTrait {
|
||||
fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier>;
|
||||
fn get_type_from_name(&self, name: &str) -> PkmnResult<Option<TypeIdentifier>>;
|
||||
fn get_single_effectiveness(
|
||||
&self,
|
||||
attacking_type: TypeIdentifier,
|
||||
defending_type: TypeIdentifier,
|
||||
) -> f32;
|
||||
) -> PkmnResult<f32>;
|
||||
fn get_effectiveness(
|
||||
&self,
|
||||
attacking_type: TypeIdentifier,
|
||||
defending_types: &[TypeIdentifier],
|
||||
) -> f32;
|
||||
) -> PkmnResult<f32>;
|
||||
}
|
||||
|
||||
pub type Typelibrary = Rc<dyn TypeLibraryTrait>;
|
||||
@@ -21,6 +21,8 @@ pub type Typelibrary = Rc<dyn TypeLibraryTrait>;
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::WasmResult;
|
||||
use crate::PkmnResult;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::string::{String, ToString};
|
||||
use cstr_core::{c_char, CString};
|
||||
@@ -51,35 +53,37 @@ mod implementation {
|
||||
}
|
||||
|
||||
impl TypeLibraryTrait for TypeLibraryImpl {
|
||||
fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier> {
|
||||
fn get_type_from_name(&self, name: &str) -> PkmnResult<Option<TypeIdentifier>> {
|
||||
if let Some(cached) = self.inner.name_to_type_cache.read().get(name) {
|
||||
return Some(*cached);
|
||||
return Ok(Some(*cached));
|
||||
}
|
||||
let cstr = CString::new(name).unwrap();
|
||||
let v = unsafe { type_library_get_type_by_name(self.inner.reference, cstr.as_ptr()) };
|
||||
let v = unsafe {
|
||||
type_library_get_type_by_name(self.inner.reference, cstr.as_ptr()).as_res()?
|
||||
};
|
||||
if v == 255 {
|
||||
return None;
|
||||
return Ok(None);
|
||||
}
|
||||
let v = v.into();
|
||||
self.inner
|
||||
.name_to_type_cache
|
||||
.write()
|
||||
.insert(name.to_string(), v);
|
||||
Some(v)
|
||||
Ok(Some(v))
|
||||
}
|
||||
|
||||
fn get_single_effectiveness(
|
||||
&self,
|
||||
attacking_type: TypeIdentifier,
|
||||
defending_type: TypeIdentifier,
|
||||
) -> f32 {
|
||||
) -> PkmnResult<f32> {
|
||||
if let Some(cached) = self
|
||||
.inner
|
||||
.effectiveness_cache
|
||||
.read()
|
||||
.get(&(attacking_type, defending_type))
|
||||
{
|
||||
return *cached;
|
||||
return Ok(*cached);
|
||||
}
|
||||
let effectiveness = unsafe {
|
||||
type_library_get_single_effectiveness(
|
||||
@@ -87,24 +91,25 @@ mod implementation {
|
||||
attacking_type.into(),
|
||||
defending_type.into(),
|
||||
)
|
||||
};
|
||||
}
|
||||
.as_res()?;
|
||||
self.inner
|
||||
.effectiveness_cache
|
||||
.write()
|
||||
.insert((attacking_type, defending_type), effectiveness);
|
||||
effectiveness
|
||||
Ok(effectiveness)
|
||||
}
|
||||
|
||||
fn get_effectiveness(
|
||||
&self,
|
||||
attacking_type: TypeIdentifier,
|
||||
defending_types: &[TypeIdentifier],
|
||||
) -> f32 {
|
||||
) -> PkmnResult<f32> {
|
||||
let mut f = 1.0;
|
||||
for defending_type in defending_types {
|
||||
f *= self.get_single_effectiveness(attacking_type, *defending_type);
|
||||
f *= self.get_single_effectiveness(attacking_type, *defending_type)?;
|
||||
}
|
||||
f
|
||||
Ok(f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,10 +128,14 @@ mod implementation {
|
||||
r: ExternRef<TypeLibraryImpl>,
|
||||
attacking_type: u8,
|
||||
defending_type: u8,
|
||||
) -> f32;
|
||||
fn type_library_get_type_by_name(r: ExternRef<TypeLibraryImpl>, name: *const c_char) -> u8;
|
||||
) -> WasmResult<f32>;
|
||||
fn type_library_get_type_by_name(
|
||||
r: ExternRef<TypeLibraryImpl>,
|
||||
name: *const c_char,
|
||||
) -> WasmResult<u8>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use crate::app_interface::StringKey;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
use crate::{handling::WasmResult, ExternRef, ExternalReferenceType, PkmnResult};
|
||||
use core::fmt::{Display, Formatter};
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone)]
|
||||
enum EffectParameterType {
|
||||
None,
|
||||
Bool,
|
||||
@@ -12,6 +13,12 @@ enum EffectParameterType {
|
||||
String,
|
||||
}
|
||||
|
||||
impl Default for EffectParameterType {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum EffectParameter {
|
||||
None,
|
||||
@@ -23,18 +30,18 @@ pub enum EffectParameter {
|
||||
|
||||
impl EffectParameter {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
||||
unsafe {
|
||||
match effect_parameter_get_type(ptr) {
|
||||
pub(crate) fn new(ptr: ExternRef<Self>) -> PkmnResult<Self> {
|
||||
Ok(unsafe {
|
||||
match effect_parameter_get_type(ptr).as_res()? {
|
||||
EffectParameterType::None => Self::None,
|
||||
EffectParameterType::Bool => Self::Bool(effect_parameter_as_bool(ptr)),
|
||||
EffectParameterType::Int => Self::Int(effect_parameter_as_int(ptr)),
|
||||
EffectParameterType::Float => Self::Float(effect_parameter_as_float(ptr)),
|
||||
EffectParameterType::Bool => Self::Bool(effect_parameter_as_bool(ptr).as_res()?),
|
||||
EffectParameterType::Int => Self::Int(effect_parameter_as_int(ptr).as_res()?),
|
||||
EffectParameterType::Float => Self::Float(effect_parameter_as_float(ptr).as_res()?),
|
||||
EffectParameterType::String => {
|
||||
Self::String(StringKey::new(effect_parameter_as_string(ptr)))
|
||||
Self::String(StringKey::new(effect_parameter_as_string(ptr).as_res()?))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_bool(&self) -> bool {
|
||||
@@ -72,7 +79,7 @@ impl ExternalReferenceType for EffectParameter {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
EffectParameter::new(reference)
|
||||
EffectParameter::new(reference).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,9 +99,13 @@ impl Display for EffectParameter {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn effect_parameter_get_type(ptr: ExternRef<EffectParameter>) -> EffectParameterType;
|
||||
fn effect_parameter_as_bool(ptr: ExternRef<EffectParameter>) -> bool;
|
||||
fn effect_parameter_as_int(ptr: ExternRef<EffectParameter>) -> i64;
|
||||
fn effect_parameter_as_float(ptr: ExternRef<EffectParameter>) -> f32;
|
||||
fn effect_parameter_as_string(ptr: ExternRef<EffectParameter>) -> ExternRef<StringKey>;
|
||||
fn effect_parameter_get_type(
|
||||
ptr: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<EffectParameterType>;
|
||||
fn effect_parameter_as_bool(ptr: ExternRef<EffectParameter>) -> WasmResult<bool>;
|
||||
fn effect_parameter_as_int(ptr: ExternRef<EffectParameter>) -> WasmResult<i64>;
|
||||
fn effect_parameter_as_float(ptr: ExternRef<EffectParameter>) -> WasmResult<f32>;
|
||||
fn effect_parameter_as_string(
|
||||
ptr: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<ExternRef<StringKey>>;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,12 @@ pub enum ItemCategory {
|
||||
Mail,
|
||||
}
|
||||
|
||||
impl Default for ItemCategory {
|
||||
fn default() -> Self {
|
||||
Self::MiscItem
|
||||
}
|
||||
}
|
||||
|
||||
/// A battle item category defines how the item is categorized when in battle.
|
||||
#[repr(u8)]
|
||||
#[derive(Clone)]
|
||||
@@ -39,6 +45,12 @@ pub enum BattleItemCategory {
|
||||
MiscBattleItem,
|
||||
}
|
||||
|
||||
impl Default for BattleItemCategory {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait ItemTrait {
|
||||
fn reference(&self) -> u32;
|
||||
@@ -50,7 +62,7 @@ pub trait ItemTrait {
|
||||
fn battle_category(&self) -> BattleItemCategory;
|
||||
/// The buying value of the item.
|
||||
fn price(&self) -> i32;
|
||||
fn has_flag(&self, flag: &StringKey) -> bool;
|
||||
fn has_flag(&self, flag: &StringKey) -> PkmnResult<bool>;
|
||||
}
|
||||
|
||||
pub type Item = Rc<dyn ItemTrait>;
|
||||
@@ -62,8 +74,8 @@ mod implementation {
|
||||
use crate::app_interface::{BattleItemCategory, ItemCategory, ItemTrait, StringKey};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters};
|
||||
use crate::handling::{Cacheable, WasmResult};
|
||||
use crate::{cached_value, cached_value_getters, PkmnResult};
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct ItemInner {
|
||||
@@ -86,10 +98,12 @@ mod implementation {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(ItemInner {
|
||||
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) }),
|
||||
name: cached_value!({ StringKey::new(item_get_name(reference).unwrap()) }),
|
||||
category: cached_value!({ item_get_category(reference).unwrap() }),
|
||||
battle_category: cached_value!({
|
||||
item_get_battle_category(reference).unwrap()
|
||||
}),
|
||||
price: cached_value!({ item_get_price(reference).unwrap() }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
@@ -116,8 +130,8 @@ mod implementation {
|
||||
fn price(&self) -> i32;
|
||||
}
|
||||
|
||||
fn has_flag(&self, flag: &StringKey) -> bool {
|
||||
unsafe { item_has_flag(self.inner.reference, flag.ptr()) }
|
||||
fn has_flag(&self, flag: &StringKey) -> PkmnResult<bool> {
|
||||
unsafe { item_has_flag(self.inner.reference, flag.ptr()).as_res() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,13 +145,14 @@ mod implementation {
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn item_get_name(ptr: ExternRef<ItemImpl>) -> ExternRef<StringKey>;
|
||||
fn item_get_category(ptr: ExternRef<ItemImpl>) -> ItemCategory;
|
||||
fn item_get_battle_category(ptr: ExternRef<ItemImpl>) -> BattleItemCategory;
|
||||
fn item_get_price(ptr: ExternRef<ItemImpl>) -> i32;
|
||||
fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> bool;
|
||||
fn item_get_name(ptr: ExternRef<ItemImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn item_get_category(ptr: ExternRef<ItemImpl>) -> WasmResult<ItemCategory>;
|
||||
fn item_get_battle_category(ptr: ExternRef<ItemImpl>) -> WasmResult<BattleItemCategory>;
|
||||
fn item_get_price(ptr: ExternRef<ItemImpl>) -> WasmResult<i32>;
|
||||
fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> WasmResult<bool>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -9,6 +9,12 @@ pub enum MoveCategory {
|
||||
Status = 2,
|
||||
}
|
||||
|
||||
impl Default for MoveCategory {
|
||||
fn default() -> Self {
|
||||
Self::Physical
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub enum MoveTarget {
|
||||
@@ -29,6 +35,12 @@ pub enum MoveTarget {
|
||||
OnSelf,
|
||||
}
|
||||
|
||||
impl Default for MoveTarget {
|
||||
fn default() -> Self {
|
||||
Self::Adjacent
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||
pub trait MoveDataTrait {
|
||||
fn name(&self) -> StringKey;
|
||||
@@ -39,7 +51,7 @@ pub trait MoveDataTrait {
|
||||
fn base_usages(&self) -> u8;
|
||||
fn target(&self) -> MoveTarget;
|
||||
fn priority(&self) -> i8;
|
||||
fn has_flag(&self, flag: &str) -> bool;
|
||||
fn has_flag(&self, flag: &str) -> PkmnResult<bool>;
|
||||
}
|
||||
|
||||
pub type MoveData = Rc<dyn MoveDataTrait>;
|
||||
@@ -52,8 +64,8 @@ mod implementation {
|
||||
use crate::app_interface::get_hash;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters};
|
||||
use crate::handling::{Cacheable, WasmResult};
|
||||
use crate::{cached_value, cached_value_getters, PkmnResult};
|
||||
|
||||
struct MoveDataInner {
|
||||
ptr: ExternRef<MoveDataImpl>,
|
||||
@@ -77,14 +89,14 @@ mod implementation {
|
||||
MoveDataImpl::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) }),
|
||||
name: cached_value!({ StringKey::new(move_data_get_name(ptr).unwrap()) }),
|
||||
move_type: cached_value!({ move_data_get_type(ptr).unwrap() }),
|
||||
category: cached_value!({ move_data_get_category(ptr).unwrap() }),
|
||||
base_power: cached_value!({ move_data_get_base_power(ptr).unwrap() }),
|
||||
accuracy: cached_value!({ move_data_get_accuracy(ptr).unwrap() }),
|
||||
base_usages: cached_value!({ move_data_get_base_power(ptr).unwrap() }),
|
||||
target: cached_value!({ move_data_get_target(ptr).unwrap() }),
|
||||
priority: cached_value!({ move_data_get_priority(ptr).unwrap() }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
@@ -102,9 +114,9 @@ mod implementation {
|
||||
fn priority(&self) -> i8;
|
||||
}
|
||||
|
||||
fn has_flag(&self, flag: &str) -> bool {
|
||||
fn has_flag(&self, flag: &str) -> PkmnResult<bool> {
|
||||
let hash = get_hash(flag);
|
||||
unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) }
|
||||
unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash).as_res() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,17 +129,21 @@ mod implementation {
|
||||
crate::handling::cacheable::cacheable!(MoveDataImpl);
|
||||
|
||||
extern "wasm" {
|
||||
fn move_data_get_name(ptr: ExternRef<MoveDataImpl>) -> ExternRef<StringKey>;
|
||||
fn move_data_get_type(ptr: ExternRef<MoveDataImpl>) -> u8;
|
||||
fn move_data_get_category(ptr: ExternRef<MoveDataImpl>) -> MoveCategory;
|
||||
fn move_data_get_base_power(ptr: ExternRef<MoveDataImpl>) -> u8;
|
||||
fn move_data_get_accuracy(ptr: ExternRef<MoveDataImpl>) -> u8;
|
||||
fn move_data_get_base_usages(ptr: ExternRef<MoveDataImpl>) -> u8;
|
||||
fn move_data_get_target(ptr: ExternRef<MoveDataImpl>) -> MoveTarget;
|
||||
fn move_data_get_priority(ptr: ExternRef<MoveDataImpl>) -> i8;
|
||||
fn move_data_has_flag_by_hash(ptr: ExternRef<MoveDataImpl>, flag_hash: u32) -> bool;
|
||||
fn move_data_get_name(ptr: ExternRef<MoveDataImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn move_data_get_type(ptr: ExternRef<MoveDataImpl>) -> WasmResult<u8>;
|
||||
fn move_data_get_category(ptr: ExternRef<MoveDataImpl>) -> WasmResult<MoveCategory>;
|
||||
fn move_data_get_base_power(ptr: ExternRef<MoveDataImpl>) -> WasmResult<u8>;
|
||||
fn move_data_get_accuracy(ptr: ExternRef<MoveDataImpl>) -> WasmResult<u8>;
|
||||
fn move_data_get_base_usages(ptr: ExternRef<MoveDataImpl>) -> WasmResult<u8>;
|
||||
fn move_data_get_target(ptr: ExternRef<MoveDataImpl>) -> WasmResult<MoveTarget>;
|
||||
fn move_data_get_priority(ptr: ExternRef<MoveDataImpl>) -> WasmResult<i8>;
|
||||
fn move_data_has_flag_by_hash(
|
||||
ptr: ExternRef<MoveDataImpl>,
|
||||
flag_hash: u32,
|
||||
) -> WasmResult<bool>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -14,7 +14,7 @@ pub type Nature = Rc<dyn NatureTrait>;
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::Cacheable;
|
||||
use crate::handling::{Cacheable, WasmResult};
|
||||
|
||||
struct NatureInner {
|
||||
reference: ExternRef<NatureImpl>,
|
||||
@@ -41,10 +41,10 @@ mod implementation {
|
||||
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),
|
||||
increase_stat: nature_get_increase_stat(reference).unwrap(),
|
||||
decrease_stat: nature_get_decrease_stat(reference).unwrap(),
|
||||
increase_modifier: nature_get_increase_modifier(reference).unwrap(),
|
||||
decrease_modifier: nature_get_decrease_modifier(reference).unwrap(),
|
||||
}),
|
||||
}
|
||||
})
|
||||
@@ -76,10 +76,10 @@ mod implementation {
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn nature_get_increase_stat(r: ExternRef<NatureImpl>) -> Statistic;
|
||||
fn nature_get_decrease_stat(r: ExternRef<NatureImpl>) -> Statistic;
|
||||
fn nature_get_increase_modifier(r: ExternRef<NatureImpl>) -> f32;
|
||||
fn nature_get_decrease_modifier(r: ExternRef<NatureImpl>) -> f32;
|
||||
fn nature_get_increase_stat(r: ExternRef<NatureImpl>) -> WasmResult<Statistic>;
|
||||
fn nature_get_decrease_stat(r: ExternRef<NatureImpl>) -> WasmResult<Statistic>;
|
||||
fn nature_get_increase_modifier(r: ExternRef<NatureImpl>) -> WasmResult<f32>;
|
||||
fn nature_get_decrease_modifier(r: ExternRef<NatureImpl>) -> WasmResult<f32>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
use crate::app_interface::list::ImmutableList;
|
||||
use crate::app_interface::{ImmutableStatisticSet, StringKey};
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::any::Any;
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
||||
pub enum Gender {
|
||||
Male = 0,
|
||||
Female = 1,
|
||||
Genderless = 2,
|
||||
}
|
||||
|
||||
impl Default for Gender {
|
||||
fn default() -> Self {
|
||||
Self::Genderless
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FormTrait {
|
||||
fn name(&self) -> StringKey;
|
||||
fn height(&self) -> f32;
|
||||
fn weight(&self) -> f32;
|
||||
fn base_experience(&self) -> u32;
|
||||
fn base_stats(&self) -> ImmutableStatisticSet;
|
||||
fn abilities(&self) -> ImmutableList<Rc<StringKey>>;
|
||||
fn hidden_abilities(&self) -> ImmutableList<Rc<StringKey>>;
|
||||
fn abilities(&self) -> Vec<Rc<StringKey>>;
|
||||
fn hidden_abilities(&self) -> Vec<Rc<StringKey>>;
|
||||
fn types(&self) -> &Vec<u8>;
|
||||
fn has_flag(&self, flag: &str) -> bool;
|
||||
fn has_flag(&self, flag: &str) -> PkmnResult<bool>;
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
@@ -39,7 +44,7 @@ pub trait SpeciesTrait {
|
||||
/// uncatchable.
|
||||
fn capture_rate(&self) -> u8;
|
||||
fn get_form(&self, form_name: &str) -> Option<Form>;
|
||||
fn has_flag(&self, flag: &str) -> bool;
|
||||
fn has_flag(&self, flag: &str) -> PkmnResult<bool>;
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
@@ -50,13 +55,13 @@ pub type Species = Rc<dyn SpeciesTrait>;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::*;
|
||||
use crate::app_interface::list::ImmutableListWasm;
|
||||
use crate::app_interface::{get_hash, ImmutableStatisticSetImpl};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType, VecExternRef};
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::ffi_array::FFIArray;
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters};
|
||||
use crate::{cached_value, cached_value_getters, PkmnResult};
|
||||
use spin::RwLock;
|
||||
|
||||
struct FormInner {
|
||||
@@ -67,8 +72,8 @@ mod implementation {
|
||||
types: CachedValue<Vec<u8>>,
|
||||
base_experience: CachedValue<u32>,
|
||||
base_stats: CachedValue<ImmutableStatisticSet>,
|
||||
abilities: CachedValue<ImmutableList<Rc<StringKey>>>,
|
||||
hidden_abilities: CachedValue<ImmutableList<Rc<StringKey>>>,
|
||||
abilities: CachedValue<Vec<Rc<StringKey>>>,
|
||||
hidden_abilities: CachedValue<Vec<Rc<StringKey>>>,
|
||||
// moves: CachedValue<LearnableMoves>,
|
||||
}
|
||||
|
||||
@@ -82,30 +87,38 @@ mod implementation {
|
||||
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) }),
|
||||
name: cached_value!({ form_get_name(reference).unwrap().get_value().unwrap() }),
|
||||
height: cached_value!({ form_get_height(reference).unwrap() }),
|
||||
weight: cached_value!({ form_get_weight(reference).unwrap() }),
|
||||
types: cached_value!({
|
||||
let raw = form_get_types(reference);
|
||||
let raw = FFIArray::from_u64(form_get_types(reference).unwrap());
|
||||
Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len())
|
||||
}),
|
||||
base_experience: cached_value!({ form_get_base_experience(reference) }),
|
||||
base_experience: cached_value!({
|
||||
form_get_base_experience(reference).unwrap()
|
||||
}),
|
||||
base_stats: cached_value!({
|
||||
Rc::new(form_get_base_stats(reference).get_value().unwrap())
|
||||
Rc::new(form_get_base_stats(reference).unwrap().get_value().unwrap())
|
||||
}),
|
||||
abilities: cached_value!({
|
||||
Rc::new(
|
||||
crate::app_interface::list::StringKeyImmutableList::from_ref(
|
||||
form_get_abilities(reference),
|
||||
),
|
||||
)
|
||||
let abilities: FFIArray<ExternRef<StringKey>> =
|
||||
FFIArray::from_u64(form_get_abilities(reference).unwrap());
|
||||
let abilities =
|
||||
Vec::from_raw_parts(abilities.ptr(), abilities.len(), abilities.len());
|
||||
abilities
|
||||
.into_iter()
|
||||
.map::<Rc<StringKey>, _>(|r| Rc::new(StringKey::new(r)))
|
||||
.collect()
|
||||
}),
|
||||
hidden_abilities: cached_value!({
|
||||
Rc::new(
|
||||
crate::app_interface::list::StringKeyImmutableList::from_ref(
|
||||
form_get_hidden_abilities(reference),
|
||||
),
|
||||
)
|
||||
let abilities: FFIArray<ExternRef<StringKey>> =
|
||||
FFIArray::from_u64(form_get_hidden_abilities(reference).unwrap());
|
||||
let abilities =
|
||||
Vec::from_raw_parts(abilities.ptr(), abilities.len(), abilities.len());
|
||||
abilities
|
||||
.into_iter()
|
||||
.map::<Rc<StringKey>, _>(|r| Rc::new(StringKey::new(r)))
|
||||
.collect()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -123,16 +136,16 @@ mod implementation {
|
||||
fn weight(&self) -> f32;
|
||||
fn base_experience(&self) -> u32;
|
||||
fn base_stats(&self) -> ImmutableStatisticSet;
|
||||
fn abilities(&self) -> ImmutableList<Rc<StringKey>>;
|
||||
fn hidden_abilities(&self) -> ImmutableList<Rc<StringKey>>;
|
||||
fn abilities(&self) -> Vec<Rc<StringKey>>;
|
||||
fn hidden_abilities(&self) -> Vec<Rc<StringKey>>;
|
||||
}
|
||||
fn types(&self) -> &Vec<u8> {
|
||||
self.inner.types.value_ref()
|
||||
}
|
||||
|
||||
fn has_flag(&self, flag: &str) -> bool {
|
||||
fn has_flag(&self, flag: &str) -> PkmnResult<bool> {
|
||||
let hash = get_hash(flag);
|
||||
unsafe { form_has_flag_by_hash(self.inner.reference, hash) }
|
||||
unsafe { form_has_flag_by_hash(self.inner.reference, hash).as_res() }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
@@ -160,13 +173,18 @@ mod implementation {
|
||||
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()
|
||||
id: cached_value!({ species_get_id(reference).unwrap() }),
|
||||
name: cached_value!({
|
||||
species_get_name(reference).unwrap().get_value().unwrap()
|
||||
}),
|
||||
capture_rate: cached_value!({ species_get_capture_rate(reference) }),
|
||||
gender_rate: cached_value!({ species_get_gender_rate(reference).unwrap() }),
|
||||
growth_rate: cached_value!({
|
||||
species_get_growth_rate(reference)
|
||||
.unwrap()
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
capture_rate: cached_value!({ species_get_capture_rate(reference).unwrap() }),
|
||||
forms: Default::default(),
|
||||
}),
|
||||
}
|
||||
@@ -198,7 +216,7 @@ mod implementation {
|
||||
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 r = species_get_form_by_hash(self.inner.reference, hash).unwrap();
|
||||
let value = r.get_value();
|
||||
let value: Option<Form> = if let Some(value) = value {
|
||||
Some(Rc::new(value))
|
||||
@@ -211,9 +229,9 @@ mod implementation {
|
||||
}
|
||||
}
|
||||
|
||||
fn has_flag(&self, flag: &str) -> bool {
|
||||
fn has_flag(&self, flag: &str) -> PkmnResult<bool> {
|
||||
let hash = get_hash(flag);
|
||||
unsafe { species_has_flag_by_hash(self.inner.reference, hash) }
|
||||
unsafe { species_has_flag_by_hash(self.inner.reference, hash).as_res() }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
@@ -237,25 +255,31 @@ mod implementation {
|
||||
crate::handling::cacheable::cacheable!(SpeciesImpl);
|
||||
|
||||
extern "wasm" {
|
||||
fn form_get_name(r: ExternRef<FormImpl>) -> ExternRef<StringKey>;
|
||||
fn form_get_height(r: ExternRef<FormImpl>) -> f32;
|
||||
fn form_get_weight(r: ExternRef<FormImpl>) -> f32;
|
||||
fn form_get_types(r: ExternRef<FormImpl>) -> FFIArray<u8>;
|
||||
fn form_get_base_experience(r: ExternRef<FormImpl>) -> u32;
|
||||
fn form_get_base_stats(r: ExternRef<FormImpl>) -> ExternRef<ImmutableStatisticSetImpl>;
|
||||
fn form_get_abilities(r: ExternRef<FormImpl>) -> VecExternRef<StringKey>;
|
||||
fn form_get_hidden_abilities(r: ExternRef<FormImpl>) -> VecExternRef<StringKey>;
|
||||
fn form_has_flag_by_hash(r: ExternRef<FormImpl>, hash: u32) -> bool;
|
||||
fn form_get_name(r: ExternRef<FormImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn form_get_height(r: ExternRef<FormImpl>) -> WasmResult<f32>;
|
||||
fn form_get_weight(r: ExternRef<FormImpl>) -> WasmResult<f32>;
|
||||
fn form_get_types(r: ExternRef<FormImpl>) -> WasmResult<u64>;
|
||||
fn form_get_base_experience(r: ExternRef<FormImpl>) -> WasmResult<u32>;
|
||||
fn form_get_base_stats(
|
||||
r: ExternRef<FormImpl>,
|
||||
) -> WasmResult<ExternRef<ImmutableStatisticSetImpl>>;
|
||||
fn form_get_abilities(r: ExternRef<FormImpl>) -> WasmResult<u64>;
|
||||
fn form_get_hidden_abilities(r: ExternRef<FormImpl>) -> WasmResult<u64>;
|
||||
fn form_has_flag_by_hash(r: ExternRef<FormImpl>, hash: u32) -> WasmResult<bool>;
|
||||
|
||||
fn species_get_id(r: ExternRef<SpeciesImpl>) -> u16;
|
||||
fn species_get_name(r: ExternRef<SpeciesImpl>) -> ExternRef<StringKey>;
|
||||
fn species_get_gender_rate(r: ExternRef<SpeciesImpl>) -> f32;
|
||||
fn species_get_growth_rate(r: ExternRef<SpeciesImpl>) -> ExternRef<StringKey>;
|
||||
fn species_get_capture_rate(r: ExternRef<SpeciesImpl>) -> u8;
|
||||
fn species_get_form_by_hash(r: ExternRef<SpeciesImpl>, hash: u32) -> ExternRef<FormImpl>;
|
||||
fn species_has_flag_by_hash(r: ExternRef<SpeciesImpl>, flag_hash: u32) -> bool;
|
||||
fn species_get_id(r: ExternRef<SpeciesImpl>) -> WasmResult<u16>;
|
||||
fn species_get_name(r: ExternRef<SpeciesImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn species_get_gender_rate(r: ExternRef<SpeciesImpl>) -> WasmResult<f32>;
|
||||
fn species_get_growth_rate(r: ExternRef<SpeciesImpl>) -> WasmResult<ExternRef<StringKey>>;
|
||||
fn species_get_capture_rate(r: ExternRef<SpeciesImpl>) -> WasmResult<u8>;
|
||||
fn species_get_form_by_hash(
|
||||
r: ExternRef<SpeciesImpl>,
|
||||
hash: u32,
|
||||
) -> WasmResult<ExternRef<FormImpl>>;
|
||||
fn species_has_flag_by_hash(r: ExternRef<SpeciesImpl>, flag_hash: u32) -> WasmResult<bool>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
||||
@@ -11,6 +11,12 @@ pub enum Statistic {
|
||||
Speed = 5,
|
||||
}
|
||||
|
||||
impl Default for Statistic {
|
||||
fn default() -> Self {
|
||||
Self::HP
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ImmutableStatisticSetTrait {
|
||||
fn hp(&self) -> u16;
|
||||
fn attack(&self) -> u16;
|
||||
@@ -28,7 +34,7 @@ mod implementation {
|
||||
use crate::cached_value;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||
use crate::handling::Cacheable;
|
||||
use crate::handling::{Cacheable, WasmResult};
|
||||
|
||||
pub struct ImmutableStatisticSetInner {
|
||||
reference: ExternRef<ImmutableStatisticSetImpl>,
|
||||
@@ -56,21 +62,24 @@ mod implementation {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(ImmutableStatisticSetInner {
|
||||
reference,
|
||||
hp: cached_value!({ static_statistics_set_get_stat(reference, Statistic::HP) }),
|
||||
hp: cached_value!({
|
||||
static_statistics_set_get_stat(reference, Statistic::HP).unwrap()
|
||||
}),
|
||||
attack: cached_value!({
|
||||
static_statistics_set_get_stat(reference, Statistic::Attack)
|
||||
static_statistics_set_get_stat(reference, Statistic::Attack).unwrap()
|
||||
}),
|
||||
defense: cached_value!({
|
||||
static_statistics_set_get_stat(reference, Statistic::Defense)
|
||||
static_statistics_set_get_stat(reference, Statistic::Defense).unwrap()
|
||||
}),
|
||||
special_attack: cached_value!({
|
||||
static_statistics_set_get_stat(reference, Statistic::SpecialAttack)
|
||||
static_statistics_set_get_stat(reference, Statistic::SpecialAttack).unwrap()
|
||||
}),
|
||||
special_defense: cached_value!({
|
||||
static_statistics_set_get_stat(reference, Statistic::SpecialDefense)
|
||||
.unwrap()
|
||||
}),
|
||||
speed: cached_value!({
|
||||
static_statistics_set_get_stat(reference, Statistic::Speed)
|
||||
static_statistics_set_get_stat(reference, Statistic::Speed).unwrap()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -110,7 +119,7 @@ mod implementation {
|
||||
fn static_statistics_set_get_stat(
|
||||
r: ExternRef<ImmutableStatisticSetImpl>,
|
||||
stat: Statistic,
|
||||
) -> u16;
|
||||
) -> WasmResult<u16>;
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::alloc::string::ToString;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::handling::wasm_result::WasmResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::handling::Cacheable;
|
||||
use crate::PkmnResult;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
use crate::{pkmn_err, ExternRef, ExternalReferenceType, PkmnErr};
|
||||
use alloc::rc::Rc;
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
@@ -21,7 +26,10 @@ pub struct StringKey {
|
||||
|
||||
impl Debug for StringKey {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "\"{}\"", self.str().to_str().unwrap())
|
||||
match self.str() {
|
||||
Ok(s) => write!(f, "\"{}\"", s.to_str().unwrap()),
|
||||
Err(e) => write!(f, "Error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,41 +53,44 @@ impl StringKey {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn str(&self) -> &CString {
|
||||
pub fn str(&self) -> PkmnResult<&CString> {
|
||||
if self.data.str.borrow().is_none() {
|
||||
unsafe {
|
||||
self.data
|
||||
.str
|
||||
.replace(Some(CString::from_raw(string_key_get_str(self.ptr()))));
|
||||
let ptr = string_key_get_str(self.ptr()).as_res()?;
|
||||
let ptr = ptr as *mut cstr_core::c_char;
|
||||
self.data.str.replace(Some(CString::from_raw(ptr)));
|
||||
}
|
||||
}
|
||||
unsafe { (*self.data.str.as_ptr()).as_ref().unwrap() }
|
||||
Ok(unsafe {
|
||||
(*self.data.str.as_ptr())
|
||||
.as_ref()
|
||||
.ok_or(pkmn_err!("Stringkey was null"))?
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "mock_data")]
|
||||
pub fn str(&self) -> &CString {
|
||||
unsafe { (*self.data.str.as_ptr()).as_ref().unwrap() }
|
||||
pub fn str(&self) -> PkmnResult<&CString> {
|
||||
Ok(unsafe { (*self.data.str.as_ptr()).as_ref().unwrap() })
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn hash(&self) -> u32 {
|
||||
pub fn hash(&self) -> PkmnResult<u32> {
|
||||
if self.data.hash.borrow().is_none() {
|
||||
unsafe {
|
||||
self.data
|
||||
.hash
|
||||
.replace(Some(string_key_get_hash(self.ptr())));
|
||||
let hash = string_key_get_hash(self.ptr()).as_res()?;
|
||||
self.data.hash.replace(Some(hash));
|
||||
}
|
||||
}
|
||||
self.data.hash.borrow().unwrap()
|
||||
Ok(self.data.hash.borrow().unwrap())
|
||||
}
|
||||
|
||||
#[cfg(feature = "mock_data")]
|
||||
pub fn hash(&self) -> u32 {
|
||||
self.data.hash.borrow().unwrap()
|
||||
pub fn hash(&self) -> PkmnResult<u32> {
|
||||
Ok(self.data.hash.borrow().unwrap())
|
||||
}
|
||||
|
||||
pub fn equals_str(&self, other: &str) -> bool {
|
||||
self.hash() == get_hash(other)
|
||||
self.hash().unwrap() == get_hash(other)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,15 +118,15 @@ impl ExternalReferenceType for StringKey {
|
||||
|
||||
impl Display for StringKey {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||
let s = self.str();
|
||||
let s = self.str().unwrap();
|
||||
f.write_str(s.to_str().as_ref().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn string_key_get_str(ptr: ExternRef<StringKey>) -> *mut cstr_core::c_char;
|
||||
fn string_key_get_hash(ptr: ExternRef<StringKey>) -> u32;
|
||||
fn string_key_get_str(ptr: ExternRef<StringKey>) -> WasmResult<u32>;
|
||||
fn string_key_get_hash(ptr: ExternRef<StringKey>) -> WasmResult<u32>;
|
||||
}
|
||||
|
||||
const CRC_TABLE: &[u32] = &[
|
||||
|
||||
@@ -7,7 +7,7 @@ pub struct CachedValue<T> {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl<T> CachedValue<T> {
|
||||
impl<T: Clone> CachedValue<T> {
|
||||
pub fn new(init_fn: Box<dyn Fn() -> T>) -> Self {
|
||||
Self {
|
||||
init_fn,
|
||||
@@ -15,13 +15,15 @@ impl<T> CachedValue<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn init_if_empty(&self) {
|
||||
if self.value.is_none() {
|
||||
unsafe {
|
||||
let s = self as *const Self as *mut Self;
|
||||
s.as_mut().unwrap().value.replace((self.init_fn)());
|
||||
}
|
||||
fn init_if_empty(&self) -> T
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
unsafe {
|
||||
let s = self as *const Self as *mut Self;
|
||||
let v = (self.init_fn)();
|
||||
s.as_mut().unwrap().value.replace(v.clone());
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +32,10 @@ impl<T> CachedValue<T> {
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
self.init_if_empty();
|
||||
self.value.as_ref().unwrap().clone()
|
||||
match self.value {
|
||||
Some(ref v) => v.clone(),
|
||||
None => self.init_if_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use alloc::rc::Rc;
|
||||
use core::cmp::Ordering;
|
||||
use core::hash::{Hash, Hasher};
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use core::intrinsics::transmute;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[repr(C)]
|
||||
@@ -82,6 +80,15 @@ impl<T> Clone for ExternRef<T> {
|
||||
|
||||
impl<T> Copy for ExternRef<T> {}
|
||||
|
||||
impl<T> Default for ExternRef<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
p: 0,
|
||||
resource_type: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for ExternRef<T> {}
|
||||
|
||||
impl<T> PartialEq<Self> for ExternRef<T> {
|
||||
@@ -117,70 +124,6 @@ impl<T> From<u32> for ExternRef<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct VecExternRef<T> {
|
||||
v: u64,
|
||||
resource_type: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> VecExternRef<T> {
|
||||
pub fn is_null(&self) -> bool {
|
||||
self.v == 0
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) fn get_internal_index(&self) -> u32 {
|
||||
let v: (u32, u32) = unsafe { transmute(self.v) };
|
||||
v.0
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) fn len(&self) -> u32 {
|
||||
let v: (u32, u32) = unsafe { transmute(self.v) };
|
||||
v.1
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) fn at(&self, index: u32) -> ExternRef<T> {
|
||||
let p = unsafe { _vec_extern_ref_get_value(self.get_internal_index(), index) };
|
||||
ExternRef {
|
||||
p,
|
||||
resource_type: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for VecExternRef<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
v: self.v,
|
||||
resource_type: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for VecExternRef<T> {}
|
||||
|
||||
impl<T> Eq for VecExternRef<T> {}
|
||||
|
||||
impl<T> PartialEq<Self> for VecExternRef<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
u64::eq(&self.v, &other.v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialOrd<Self> for VecExternRef<T> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
u64::partial_cmp(&self.v, &other.v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ord for VecExternRef<T> {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
u64::cmp(&self.v, &other.v)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ExternalReferenceType {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self
|
||||
where
|
||||
@@ -222,8 +165,3 @@ macro_rules! impl_extern_ctor {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn _vec_extern_ref_get_value(extern_ref: u32, index: u32) -> u32;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,24 @@ impl<T> FFIArray<T> {
|
||||
mem::forget(boxed_slice);
|
||||
r
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) fn from_u64(v: u64) -> Self {
|
||||
let v: (u32, u32) = unsafe { core::mem::transmute(v) };
|
||||
Self {
|
||||
ptr: v.0 as *mut T,
|
||||
len: v.1 as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for FFIArray<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ptr: core::ptr::null_mut(),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod ffi_array;
|
||||
pub mod script;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) mod temporary;
|
||||
pub(crate) mod wasm_result;
|
||||
|
||||
pub use capabilities::*;
|
||||
|
||||
@@ -15,6 +16,7 @@ pub use capabilities::*;
|
||||
pub(crate) use cacheable::Cacheable;
|
||||
pub use script::Script;
|
||||
pub use script::ScriptOwner;
|
||||
pub use wasm_result::*;
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum ScriptCategory {
|
||||
@@ -41,7 +43,7 @@ macro_rules! wasm_reference_getters_extern {
|
||||
extern "wasm" {
|
||||
$(
|
||||
paste::paste!{
|
||||
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> ExternRef<$type>;
|
||||
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> WasmResult<ExternRef<$type>>;
|
||||
}
|
||||
)*
|
||||
}
|
||||
@@ -151,7 +153,7 @@ macro_rules! wasm_optional_reference_getters_extern {
|
||||
extern "wasm" {
|
||||
$(
|
||||
paste::paste!{
|
||||
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> ExternRef<$type>;
|
||||
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> WasmResult<ExternRef<$type>>;
|
||||
}
|
||||
)*
|
||||
}
|
||||
@@ -228,7 +230,7 @@ macro_rules! wasm_value_getters_extern {
|
||||
extern "wasm" {
|
||||
$(
|
||||
paste::paste!{
|
||||
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> $type;
|
||||
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> WasmResult<$type>;
|
||||
}
|
||||
)*
|
||||
}
|
||||
@@ -246,10 +248,10 @@ macro_rules! wasm_value_getters_funcs {
|
||||
) => {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
$v fn $name(&self) -> $type {
|
||||
$v fn $name(&self) -> PkmnResult<$type> {
|
||||
paste::paste!{
|
||||
unsafe{
|
||||
[<$base_type:snake _get_ $name>](self.inner.reference)
|
||||
[<$base_type:snake _get_ $name>](self.inner.reference).as_res()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app_interface::list::ImmutableList;
|
||||
use crate::app_interface::{
|
||||
Battle, BattleSide, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item,
|
||||
Pokemon, Statistic, TurnChoice, TypeIdentifier,
|
||||
@@ -6,8 +5,10 @@ use crate::app_interface::{
|
||||
use crate::handling::ScriptCapabilities;
|
||||
use crate::StringKey;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::any::Any;
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
type Result<T> = crate::result::PkmnResult<T>;
|
||||
|
||||
pub trait Script {
|
||||
fn new() -> Self
|
||||
@@ -18,58 +19,97 @@ pub trait Script {
|
||||
|
||||
/// This function is ran when a volatile effect is added while that volatile effect already is
|
||||
/// in place. Instead of adding the volatile effect twice, it will execute this function instead.
|
||||
fn stack(&self) {}
|
||||
fn stack(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is ran when this script stops being in effect, and is removed from its owner.
|
||||
fn on_remove(&self) {}
|
||||
fn on_remove(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function is ran when this script starts being in effect.
|
||||
fn on_initialize(
|
||||
&self,
|
||||
_library: DynamicLibrary,
|
||||
_parameters: Option<ImmutableList<Rc<EffectParameter>>>,
|
||||
) {
|
||||
_parameters: Option<Vec<Rc<EffectParameter>>>,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function is ran just before the start of the turn. Everyone has made its choices here,
|
||||
/// and the turn is about to start. This is a great place to initialize data if you need to know
|
||||
/// something has happened during a turn.
|
||||
fn on_before_turn(&self, _choice: TurnChoice) {}
|
||||
fn on_before_turn(&self, _choice: TurnChoice) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function allows you to modify the effective speed of the Pokemon. This is ran before
|
||||
/// turn ordering, so overriding here will allow you to put certain Pokemon before others.
|
||||
fn change_speed(&self, _choice: TurnChoice, _speed: &mut u32) {}
|
||||
fn change_speed(&self, _choice: TurnChoice, _speed: &mut u32) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows you to modify the effective priority of the Pokemon. This is ran before
|
||||
/// turn ordering, so overriding here will allow you to put certain Pokemon before others. Note
|
||||
/// that this is only relevant on move choices, as other turn choice types do not have a priority.
|
||||
fn change_priority(&self, _choice: TurnChoice, _priority: &mut i8) {}
|
||||
fn change_priority(&self, _choice: TurnChoice, _priority: &mut i8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function allows you to change the move that is used during execution. This is useful for
|
||||
/// moves such as metronome, where the move chosen actually differs from the move used.
|
||||
fn change_move(&self, _choice: TurnChoice, _move_name: &mut StringKey) {}
|
||||
fn change_move(&self, _choice: TurnChoice, _move_name: &mut StringKey) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows you to change a move into a multi-hit move. The number of hits set here
|
||||
/// gets used as the number of hits. If set to 0, this will behave as if the move missed on its
|
||||
/// first hit.
|
||||
fn change_number_of_hits(&self, _choice: TurnChoice, _number_of_hits: &mut u8) {}
|
||||
fn change_number_of_hits(&self, _choice: TurnChoice, _number_of_hits: &mut u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function allows you to prevent a move from running. If this gets set to true, the move
|
||||
/// ends execution here. No PP will be decreased in this case.
|
||||
fn prevent_move(&self, _move: ExecutingMove, _prevent: &mut bool) {}
|
||||
fn prevent_move(&self, _move: ExecutingMove, _prevent: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function makes the move fail. If the fail field gets set to true, the move ends execution,
|
||||
/// and fail events get triggered.
|
||||
fn fail_move(&self, _move: ExecutingMove, _fail: &mut bool) {}
|
||||
fn fail_move(&self, _move: ExecutingMove, _fail: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// Similar to [`Self::prevent_move`]. This function will also stop execution, but PP will be
|
||||
/// decreased.
|
||||
fn stop_before_move(&self, _move: ExecutingMove, _stop: &mut bool) {}
|
||||
fn stop_before_move(&self, _move: ExecutingMove, _stop: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function runs just before the move starts its execution.
|
||||
fn on_before_move(&self, _move: ExecutingMove) {}
|
||||
fn on_before_move(&self, _move: ExecutingMove) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to prevent a move that is targeted at its owner. If set to true
|
||||
/// the move fails, and fail events get triggered.
|
||||
fn fail_incoming_move(&self, _move: ExecutingMove, _target: Pokemon, _fail: &mut bool) {}
|
||||
fn fail_incoming_move(
|
||||
&self,
|
||||
_move: ExecutingMove,
|
||||
_target: Pokemon,
|
||||
_fail: &mut bool,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to make its owner invulnerable to an incoming move.
|
||||
fn is_invulnerable(&self, _move: ExecutingMove, _target: Pokemon, _invulnerable: &mut bool) {}
|
||||
fn is_invulnerable(
|
||||
&self,
|
||||
_move: ExecutingMove,
|
||||
_target: Pokemon,
|
||||
_invulnerable: &mut bool,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function occurs when a move gets missed. This runs on the scripts belonging to the executing
|
||||
/// move, which include the scripts that are attached to the owner of the script.
|
||||
fn on_move_miss(&self, _move: ExecutingMove, _target: Pokemon) {}
|
||||
fn on_move_miss(&self, _move: ExecutingMove, _target: Pokemon) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows the script to change the actual type that is used for the move on a target.
|
||||
fn change_move_type(
|
||||
&self,
|
||||
@@ -77,7 +117,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_move_type: &mut TypeIdentifier,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows the script to change how effective a move is on a target.
|
||||
fn change_effectiveness(
|
||||
@@ -86,7 +127,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_effectiveness: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to block an outgoing move from being critical.
|
||||
fn block_critical(
|
||||
@@ -95,7 +137,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_block_critical: &mut bool,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to block an incoming move from being critical.
|
||||
fn block_incoming_critical(
|
||||
@@ -104,7 +147,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_block_critical: &mut bool,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to modify the accuracy of a move used. This value represents
|
||||
/// the percentage accuracy, so anything above 100% will make it always hit.
|
||||
@@ -114,7 +158,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_accuracy: &mut u8,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function allows a script to change the critical stage of the move used.
|
||||
@@ -124,7 +169,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_stage: &mut u8,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to change the damage modifier of a critical hit. This will only
|
||||
/// run when a hit is critical.
|
||||
@@ -134,7 +180,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_modifier: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to change the damage modifier of a Same Type Attack Bonus, which
|
||||
/// occurs when the user has the move type as one of its own types.
|
||||
@@ -144,7 +191,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_modifier: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function allows a script to change the effective base power of a move hit.
|
||||
@@ -154,7 +202,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_base_power: &mut u8,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to bypass defensive stat boosts for a move hit.
|
||||
fn bypass_defensive_stat_boost(
|
||||
@@ -163,7 +212,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_bypass: &mut bool,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to bypass offensive stat boosts for a move hit.
|
||||
fn bypass_offensive_stat_boost(
|
||||
@@ -172,7 +222,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_bypass: &mut bool,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to change the actual offensive stat values used when calculating damage
|
||||
fn change_offensive_stat_value(
|
||||
@@ -181,7 +232,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_amount: &mut u32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to change the actual defensive stat values used when calculating damage.
|
||||
fn change_defensive_stat_value(
|
||||
@@ -190,7 +242,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_amount: &mut u32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function allows a script to change the raw modifier we retrieved from the stats of the
|
||||
@@ -201,7 +254,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_modifier: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to apply a raw multiplier to the damage done by a move.
|
||||
fn change_damage_modifier(
|
||||
@@ -210,10 +264,19 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_modifier: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to modify the outgoing damage done by a move.
|
||||
fn change_damage(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _damage: &mut u32) {}
|
||||
fn change_damage(
|
||||
&self,
|
||||
_move: ExecutingMove,
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_damage: &mut u32,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script to modify the incoming damage done by a move.
|
||||
fn change_incoming_damage(
|
||||
&self,
|
||||
@@ -221,13 +284,18 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_damage: &mut u32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function triggers when an incoming hit happens. This triggers after the damage is done,
|
||||
/// but before the secondary effect of the move happens.
|
||||
fn on_incoming_hit(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) {}
|
||||
fn on_incoming_hit(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function triggers when an opponent on the field faints.
|
||||
fn on_opponent_faints(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) {}
|
||||
fn on_opponent_faints(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script attached to a Pokemon or its parents to prevent stat boost
|
||||
/// changes on that Pokemon.
|
||||
fn prevent_stat_boost_change(
|
||||
@@ -237,7 +305,8 @@ pub trait Script {
|
||||
_amount: i8,
|
||||
_self_inflicted: bool,
|
||||
_prevent: &mut bool,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script attached to a Pokemon or its parents to modify the amount by
|
||||
/// which the stat boost will change. If the stat boost is done by the user itself, self
|
||||
@@ -248,7 +317,8 @@ pub trait Script {
|
||||
_stat: Statistic,
|
||||
_self_inflicted: bool,
|
||||
_amount: &mut i8,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script attached to a Pokemon or its parents to prevent an incoming
|
||||
/// secondary effect. This means the move will still hit and do damage, but not trigger its
|
||||
@@ -259,7 +329,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_prevent: &mut bool,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script attached to a move or its parents to change the chance the
|
||||
/// secondary effect of a move will trigger. The chance is depicted in percentage here, so
|
||||
@@ -271,7 +342,8 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_chance: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows a script attached to a Pokemon or its parents to change the chance the
|
||||
/// secondary effect of an incoming move will trigger. The chance is depicted in percentage here,
|
||||
@@ -283,30 +355,49 @@ pub trait Script {
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
_chance: &mut f32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function triggers when the move uses its secondary effect. Moves should implement their
|
||||
/// secondary effects here. Status moves should implement their actual functionality in this
|
||||
/// function as well, as status moves effects are defined as secondary effects for simplicity.
|
||||
fn on_secondary_effect(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) {}
|
||||
fn on_secondary_effect(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function triggers on a move or its parents when all hits on a target are finished.
|
||||
fn on_after_hits(&self, _move: ExecutingMove, _target: Pokemon) {}
|
||||
fn on_after_hits(&self, _move: ExecutingMove, _target: Pokemon) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function prevents the Pokemon it is attached to from being able to switch out.
|
||||
fn prevent_self_switch(&self, _choice: TurnChoice, _prevent: &mut bool) {}
|
||||
fn prevent_self_switch(&self, _choice: TurnChoice, _prevent: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows the prevention of switching for any opponent.
|
||||
fn prevent_opponent_switch(&self, _choice: TurnChoice, _prevent: &mut bool) {}
|
||||
fn prevent_opponent_switch(&self, _choice: TurnChoice, _prevent: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is called on a move and its parents when the move fails.
|
||||
fn on_fail(&self, _target: Pokemon) {}
|
||||
fn on_fail(&self, _target: Pokemon) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is called on a script when an opponent fails.
|
||||
fn on_opponent_fail(&self, _target: Pokemon) {}
|
||||
fn on_opponent_fail(&self, _target: Pokemon) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function allows preventing the running away of the Pokemon its attached to
|
||||
fn prevent_self_run_away(&self, _choice: TurnChoice, _prevent: &mut bool) {}
|
||||
fn prevent_self_run_away(&self, _choice: TurnChoice, _prevent: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function prevents a Pokemon on another side than where its attached to from running away.
|
||||
fn prevent_opponent_run_away(&self, _choice: TurnChoice, _prevent: &mut bool) {}
|
||||
fn prevent_opponent_run_away(&self, _choice: TurnChoice, _prevent: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function id triggered on all scripts active in the battle after all choices have finished
|
||||
/// running. Note that choices are not active anymore here, so their scripts do not call this
|
||||
/// function.
|
||||
fn on_end_turn(&self) {}
|
||||
fn on_end_turn(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon takes damage.
|
||||
fn on_damage(
|
||||
&self,
|
||||
@@ -314,16 +405,23 @@ pub trait Script {
|
||||
_source: DamageSource,
|
||||
_old_health: u32,
|
||||
_new_health: u32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon faints.
|
||||
fn on_faint(&self, _pokemon: Pokemon, _source: DamageSource) {}
|
||||
fn on_faint(&self, _pokemon: Pokemon, _source: DamageSource) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon is switched into
|
||||
/// the battlefield.
|
||||
fn on_switch_in(&self, _pokemon: Pokemon) {}
|
||||
fn on_switch_in(&self, _pokemon: Pokemon) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the
|
||||
/// held item it had.
|
||||
fn on_after_held_item_consume(&self, _pokemon: Pokemon, _item: Item) {}
|
||||
fn on_after_held_item_consume(&self, _pokemon: Pokemon, _item: Item) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||
/// and allows for changing this amount of experience.
|
||||
fn change_experience_gained(
|
||||
@@ -331,18 +429,35 @@ pub trait Script {
|
||||
_fainted_mon: Pokemon,
|
||||
_winning_mon: Pokemon,
|
||||
_amount: &mut u32,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||
/// and allows for making the experience be shared across multiple Pokemon.
|
||||
fn share_experience(&self, _fainted_mon: Pokemon, _winning_mon: Pokemon, _shares: &mut bool) {}
|
||||
fn share_experience(
|
||||
&self,
|
||||
_fainted_mon: Pokemon,
|
||||
_winning_mon: Pokemon,
|
||||
_shares: &mut bool,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is triggered on a battle and its parents when something attempts to change the
|
||||
/// weather, and allows for blocking the weather change.
|
||||
fn block_weather(&self, _battle: Battle, _blocked: &mut bool) {}
|
||||
fn block_weather(&self, _battle: Battle, _blocked: &mut bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// This function is called when a Pokeball is thrown at a Pokemon, and allows modifying the catch
|
||||
/// rate of this attempt. Pokeball modifier effects should be implemented here, as well as for
|
||||
/// example status effects that change capture rates.
|
||||
fn change_capture_rate_bonus(&self, _target: Pokemon, _pokeball: Item, _modifier: &mut u8) {}
|
||||
fn change_capture_rate_bonus(
|
||||
&self,
|
||||
_target: Pokemon,
|
||||
_pokeball: Item,
|
||||
_modifier: &mut u8,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
|
||||
90
pkmn_lib_interface/src/handling/wasm_result.rs
Normal file
90
pkmn_lib_interface/src/handling/wasm_result.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use crate::{pkmn_err, PkmnErr, PkmnResult};
|
||||
use alloc::string::ToString;
|
||||
use cstr_core::{c_char, CString};
|
||||
|
||||
#[repr(C)]
|
||||
#[repr(packed)]
|
||||
#[derive(Debug)]
|
||||
pub struct WasmResult<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
err_ptr: u32,
|
||||
value: T,
|
||||
}
|
||||
|
||||
pub type WasmVoidResult = WasmResult<()>;
|
||||
|
||||
impl<T> WasmResult<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
pub fn unwrap(self) -> T {
|
||||
unsafe {
|
||||
if self.err_ptr == 0 {
|
||||
self.value
|
||||
} else {
|
||||
let ptr = self.err_ptr as *mut c_char;
|
||||
let s = CString::from_raw(ptr).to_string_lossy().to_string();
|
||||
panic!("{}", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_res(self) -> PkmnResult<T> {
|
||||
PkmnResult::from(self)
|
||||
}
|
||||
|
||||
pub fn ok(value: T) -> Self {
|
||||
WasmResult { err_ptr: 0, value }
|
||||
}
|
||||
|
||||
pub fn err(err: PkmnErr) -> Self {
|
||||
let s: CString = err.into();
|
||||
let ptr = s.into_raw();
|
||||
WasmResult {
|
||||
err_ptr: ptr as u32,
|
||||
value: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_res(res: PkmnResult<T>) -> Self {
|
||||
WasmResult::from(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<WasmResult<T>> for crate::PkmnResult<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
fn from(value: WasmResult<T>) -> Self {
|
||||
unsafe {
|
||||
if value.err_ptr == 0 {
|
||||
Ok(value.value)
|
||||
} else {
|
||||
let ptr = value.err_ptr as *mut c_char;
|
||||
let s = CString::from_raw(ptr).to_string_lossy().to_string();
|
||||
Err(pkmn_err!(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<crate::PkmnResult<T>> for WasmResult<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
fn from(value: PkmnResult<T>) -> Self {
|
||||
match value {
|
||||
Ok(value) => WasmResult { err_ptr: 0, value },
|
||||
Err(e) => {
|
||||
let s: CString = e.into();
|
||||
let ptr = s.into_raw();
|
||||
WasmResult {
|
||||
err_ptr: ptr as u32,
|
||||
value: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,13 @@
|
||||
#![feature(thread_local)]
|
||||
#![feature(build_hasher_simple_hash_one)]
|
||||
#![feature(adt_const_params)]
|
||||
#![feature(try_trait_v2)]
|
||||
#![cfg_attr(not(feature = "mock_data"), no_std)]
|
||||
#![allow(incomplete_features)]
|
||||
// These give false positives too often
|
||||
#![allow(clippy::borrowed_box)]
|
||||
#![allow(clippy::needless_lifetimes)]
|
||||
#![allow(stable_features)]
|
||||
|
||||
extern crate alloc;
|
||||
extern crate core;
|
||||
@@ -33,25 +35,28 @@ use alloc::boxed::Box;
|
||||
#[allow(dead_code)]
|
||||
pub mod app_interface;
|
||||
pub mod handling;
|
||||
mod result;
|
||||
pub mod utils;
|
||||
|
||||
pub use result::*;
|
||||
|
||||
pub type LoadScriptFnType = Box<dyn Fn(ScriptCategory, &StringKey) -> Option<Box<dyn Script>>>;
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::LoadScriptFnType;
|
||||
|
||||
use crate::app_interface::list::{EffectParameterImmutableList, ImmutableListWasm};
|
||||
use crate::app_interface::{
|
||||
BattleImpl, DamageSource, DynamicLibraryImpl, EffectParameter, ExecutingMoveImpl, ItemImpl,
|
||||
PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier,
|
||||
};
|
||||
use crate::handling::extern_ref::ExternRef;
|
||||
use crate::handling::extern_ref::VecExternRef;
|
||||
use crate::handling::ffi_array::FFIArray;
|
||||
use crate::handling::wasm_result::WasmVoidResult;
|
||||
use crate::handling::{Script, ScriptCapabilities, ScriptCategory};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use cstr_core::{c_char, CString};
|
||||
use hashbrown::HashMap;
|
||||
@@ -86,7 +91,7 @@ mod implementation {
|
||||
static mut SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct ScriptPtr {
|
||||
index: u32,
|
||||
}
|
||||
@@ -183,56 +188,64 @@ mod implementation {
|
||||
FFIArray::new(c)
|
||||
}
|
||||
|
||||
fn script_stack(script: ScriptPtr) {
|
||||
script.val().unwrap().stack();
|
||||
fn script_stack(script: ScriptPtr) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().stack())
|
||||
}
|
||||
|
||||
fn script_on_remove(script: ScriptPtr) {
|
||||
script.val().unwrap().on_remove();
|
||||
fn script_on_remove(script: ScriptPtr) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_remove())
|
||||
}
|
||||
|
||||
fn script_on_initialize(
|
||||
script: ScriptPtr,
|
||||
library: ExternRef<DynamicLibraryImpl>,
|
||||
parameters: VecExternRef<EffectParameter>,
|
||||
) {
|
||||
let parameters = Rc::new(EffectParameterImmutableList::from_ref(parameters));
|
||||
script.val().unwrap().on_initialize(library.not_null_rc(), Some(parameters));
|
||||
parameters: u64,
|
||||
) -> WasmVoidResult {
|
||||
let parameters : FFIArray<ExternRef<EffectParameter>> = FFIArray::from_u64(parameters);
|
||||
let parameters = Vec::from_raw_parts(parameters.ptr(), parameters.len(), parameters.len());
|
||||
let parameters = parameters.into_iter().map(|p| Rc::new(EffectParameter::new(p).unwrap())).collect::<Vec<_>>();
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_initialize(library.not_null_rc(), Some(parameters)))
|
||||
}
|
||||
|
||||
fn script_on_before_turn(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
) {
|
||||
script.val().unwrap().on_before_turn(choice.not_null())
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_before_turn(choice.not_null()))
|
||||
}
|
||||
|
||||
fn script_change_speed(
|
||||
script:ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
speed: *mut u32,
|
||||
) {
|
||||
script.val().unwrap().change_speed(choice.not_null(), speed.as_mut().unwrap())
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_speed(choice.not_null(), speed.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_priority(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
priority: *mut i8,
|
||||
) {
|
||||
script.val().unwrap().change_priority(choice.not_null(), priority.as_mut().unwrap())
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_priority(choice.not_null(), priority.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_move(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
mv: *mut ExternRef<StringKey>,
|
||||
) {
|
||||
) -> WasmVoidResult {
|
||||
let old = mv.as_ref().unwrap().not_null();
|
||||
let mut new = old.clone();
|
||||
script.val().unwrap().change_move(choice.not_null(), &mut new);
|
||||
if old != new {
|
||||
*mv = new.ptr();
|
||||
let res = script.val().unwrap().change_move(choice.not_null(), &mut new);
|
||||
match res {
|
||||
Ok(_) => {
|
||||
if old != new {
|
||||
*mv = new.ptr();
|
||||
}
|
||||
WasmVoidResult::ok(())
|
||||
}
|
||||
Err(e) => WasmVoidResult::err(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,39 +253,39 @@ mod implementation {
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
out: *mut u8,
|
||||
) {
|
||||
script.val().unwrap().change_number_of_hits(choice.not_null(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_number_of_hits(choice.not_null(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_prevent_move(
|
||||
script: ScriptPtr,
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_move(mv.not_null_rc(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_fail_move(
|
||||
script: ScriptPtr,
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().fail_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().fail_move(mv.not_null_rc(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_stop_before_move(
|
||||
script: ScriptPtr,
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().stop_before_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().stop_before_move(mv.not_null_rc(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_on_before_move(
|
||||
script: ScriptPtr,
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
) {
|
||||
script.val().unwrap().on_before_move(mv.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_before_move(mv.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_fail_incoming_move(
|
||||
@@ -280,8 +293,8 @@ mod implementation {
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().fail_incoming_move(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().fail_incoming_move(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_is_invulnerable(
|
||||
@@ -289,16 +302,16 @@ mod implementation {
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().is_invulnerable(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().is_invulnerable(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_on_move_miss(
|
||||
script: ScriptPtr,
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
) {
|
||||
script.val().unwrap().on_move_miss(mv.not_null_rc(), target.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_move_miss(mv.not_null_rc(), target.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_change_move_type(
|
||||
@@ -307,8 +320,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut TypeIdentifier,
|
||||
) {
|
||||
script.val().unwrap().change_move_type(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_move_type(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_effectiveness(
|
||||
@@ -317,8 +330,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_effectiveness(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_effectiveness(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_block_critical(
|
||||
@@ -327,8 +340,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().block_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().block_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_block_incoming_critical(
|
||||
@@ -337,8 +350,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().block_incoming_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().block_incoming_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_accuracy(
|
||||
@@ -347,8 +360,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u8,
|
||||
) {
|
||||
script.val().unwrap().change_accuracy(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_accuracy(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_critical_stage(
|
||||
@@ -357,8 +370,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u8,
|
||||
) {
|
||||
script.val().unwrap().change_critical_stage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_critical_stage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_critical_modifier(
|
||||
@@ -367,8 +380,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_critical_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_critical_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_stab_modifier(
|
||||
@@ -377,8 +390,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_stab_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_stab_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_base_power(
|
||||
@@ -387,8 +400,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u8,
|
||||
) {
|
||||
script.val().unwrap().change_base_power(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_base_power(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_bypass_defensive_stat_boost(
|
||||
@@ -397,8 +410,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().bypass_defensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().bypass_defensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_bypass_offensive_stat_boost(
|
||||
@@ -407,8 +420,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().bypass_offensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().bypass_offensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_defensive_stat_value(
|
||||
@@ -417,8 +430,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u32,
|
||||
) {
|
||||
script.val().unwrap().change_defensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_defensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_offensive_stat_value(
|
||||
@@ -427,8 +440,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u32,
|
||||
) {
|
||||
script.val().unwrap().change_offensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_offensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_damage_stat_modifier(
|
||||
@@ -437,8 +450,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_damage_stat_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_damage_stat_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_damage_modifier(
|
||||
@@ -447,8 +460,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_damage_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_damage_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_damage(
|
||||
@@ -457,8 +470,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u32,
|
||||
) {
|
||||
script.val().unwrap().change_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_incoming_damage(
|
||||
@@ -467,8 +480,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut u32,
|
||||
) {
|
||||
script.val().unwrap().change_incoming_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_incoming_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_on_incoming_hit(
|
||||
@@ -476,8 +489,8 @@ mod implementation {
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
) {
|
||||
script.val().unwrap().on_incoming_hit(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_incoming_hit(mv.not_null_rc(), target.not_null_rc(), hit))
|
||||
}
|
||||
|
||||
fn script_on_opponent_faints(
|
||||
@@ -485,8 +498,8 @@ mod implementation {
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
) {
|
||||
script.val().unwrap().on_opponent_faints(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_opponent_faints(mv.not_null_rc(), target.not_null_rc(), hit))
|
||||
}
|
||||
|
||||
fn script_prevent_stat_boost_change(
|
||||
@@ -496,8 +509,8 @@ mod implementation {
|
||||
amount: i8,
|
||||
self_inflicted: u8,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_stat_boost_change(target.not_null_rc(), stat, amount, self_inflicted == 1, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_stat_boost_change(target.not_null_rc(), stat, amount, self_inflicted == 1, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_prevent_secondary_effect(
|
||||
@@ -506,8 +519,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_effect_chance(
|
||||
@@ -516,8 +529,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_incoming_effect_chance(
|
||||
@@ -526,8 +539,8 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
out: *mut f32,
|
||||
) {
|
||||
script.val().unwrap().change_incoming_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_incoming_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_on_secondary_effect(
|
||||
@@ -535,68 +548,68 @@ mod implementation {
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
hit: u8,
|
||||
) {
|
||||
script.val().unwrap().on_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit))
|
||||
}
|
||||
|
||||
fn script_on_after_hits(
|
||||
script: ScriptPtr,
|
||||
mv: ExternRef<ExecutingMoveImpl>,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
) {
|
||||
script.val().unwrap().on_after_hits(mv.not_null_rc(), target.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_after_hits(mv.not_null_rc(), target.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_prevent_self_switch(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_self_switch(choice.not_null(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_self_switch(choice.not_null(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_prevent_opponent_switch(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_opponent_switch(choice.not_null(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_opponent_switch(choice.not_null(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_on_fail(
|
||||
script: ScriptPtr,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
) {
|
||||
script.val().unwrap().on_fail(pokemon.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_fail(pokemon.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_on_opponent_fail(
|
||||
script: ScriptPtr,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
) {
|
||||
script.val().unwrap().on_opponent_fail(pokemon.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_opponent_fail(pokemon.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_prevent_self_run_away(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_self_run_away(choice.not_null(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_self_run_away(choice.not_null(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_prevent_opponent_run_away(
|
||||
script: ScriptPtr,
|
||||
choice: ExternRef<TurnChoice>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().prevent_opponent_run_away(choice.not_null(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().prevent_opponent_run_away(choice.not_null(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_on_end_turn(
|
||||
script: ScriptPtr,
|
||||
) {
|
||||
script.val().unwrap().on_end_turn();
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_end_turn())
|
||||
}
|
||||
|
||||
fn script_on_damage(
|
||||
@@ -605,31 +618,31 @@ mod implementation {
|
||||
source: DamageSource,
|
||||
old_health: u32,
|
||||
new_health: u32,
|
||||
) {
|
||||
script.val().unwrap().on_damage(pokemon.not_null_rc(), source, old_health, new_health);
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_damage(pokemon.not_null_rc(), source, old_health, new_health))
|
||||
}
|
||||
|
||||
fn script_on_faint(
|
||||
script: ScriptPtr,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
source: DamageSource,
|
||||
) {
|
||||
script.val().unwrap().on_faint(pokemon.not_null_rc(), source);
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_faint(pokemon.not_null_rc(), source))
|
||||
}
|
||||
|
||||
fn script_on_switch_in(
|
||||
script: ScriptPtr,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
) {
|
||||
script.val().unwrap().on_switch_in(pokemon.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_switch_in(pokemon.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_on_after_held_item_consume(
|
||||
script: ScriptPtr,
|
||||
pokemon: ExternRef<PokemonImpl>,
|
||||
item: ExternRef<ItemImpl>
|
||||
) {
|
||||
script.val().unwrap().on_after_held_item_consume(pokemon.not_null_rc(), item.not_null_rc());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_after_held_item_consume(pokemon.not_null_rc(), item.not_null_rc()))
|
||||
}
|
||||
|
||||
fn script_change_experience_gained(
|
||||
@@ -637,8 +650,12 @@ mod implementation {
|
||||
fainted_pokemon: ExternRef<PokemonImpl>,
|
||||
winning_pokemon: ExternRef<PokemonImpl>,
|
||||
out: *mut u32
|
||||
) {
|
||||
script.val().unwrap().change_experience_gained(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_experience_gained(
|
||||
fainted_pokemon.not_null_rc(),
|
||||
winning_pokemon.not_null_rc(),
|
||||
out.as_mut().unwrap()
|
||||
))
|
||||
}
|
||||
|
||||
fn script_share_experience(
|
||||
@@ -646,16 +663,20 @@ mod implementation {
|
||||
fainted_pokemon: ExternRef<PokemonImpl>,
|
||||
winning_pokemon: ExternRef<PokemonImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().share_experience(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().share_experience(
|
||||
fainted_pokemon.not_null_rc(),
|
||||
winning_pokemon.not_null_rc(),
|
||||
out.as_mut().unwrap()
|
||||
))
|
||||
}
|
||||
|
||||
fn script_block_weather(
|
||||
script: ScriptPtr,
|
||||
battle: ExternRef<BattleImpl>,
|
||||
out: *mut bool,
|
||||
) {
|
||||
script.val().unwrap().block_weather(battle.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().block_weather(battle.not_null_rc(), out.as_mut().unwrap()))
|
||||
}
|
||||
|
||||
fn script_change_capture_rate_bonus(
|
||||
@@ -663,8 +684,12 @@ mod implementation {
|
||||
target: ExternRef<PokemonImpl>,
|
||||
pokeball: ExternRef<ItemImpl>,
|
||||
out: *mut u8,
|
||||
) {
|
||||
script.val().unwrap().change_capture_rate_bonus(target.not_null_rc(), pokeball.not_null_rc(), out.as_mut().unwrap());
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().change_capture_rate_bonus(
|
||||
target.not_null_rc(),
|
||||
pokeball.not_null_rc(),
|
||||
out.as_mut().unwrap()
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
49
pkmn_lib_interface/src/result.rs
Normal file
49
pkmn_lib_interface/src/result.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use alloc::string::{String, ToString};
|
||||
use core::fmt;
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
use cstr_core::CString;
|
||||
|
||||
pub type PkmnResult<T> = Result<T, PkmnErr>;
|
||||
|
||||
pub struct PkmnErr {
|
||||
pub file: &'static str,
|
||||
pub line: u32,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl PkmnErr {
|
||||
pub fn new(file: &'static str, line: u32, message: String) -> Self {
|
||||
Self {
|
||||
file,
|
||||
line,
|
||||
message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for PkmnErr {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "PkmnErr: {}:{}: {}", self.file, self.line, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PkmnErr {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "PkmnErr: {}:{}: {}", self.file, self.line, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PkmnErr> for CString {
|
||||
fn from(val: PkmnErr) -> Self {
|
||||
CString::new(val.to_string()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! pkmn_err {
|
||||
($message: expr) => {
|
||||
PkmnErr::new(file!(), line!(), $message.to_string())
|
||||
};
|
||||
}
|
||||
|
||||
pub use pkmn_err;
|
||||
@@ -1,8 +1,23 @@
|
||||
use alloc::boxed::Box;
|
||||
|
||||
#[macro_export]
|
||||
#[cfg(feature = "mock_data")]
|
||||
macro_rules! println {
|
||||
($($args:tt)*) => {};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
macro_rules! println { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
|
||||
macro_rules! println { ($($args:tt)*) => { pkmn_lib_interface::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! println_crate { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
#[allow(unused_macros)]
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use println_crate;
|
||||
|
||||
#[macro_export]
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
@@ -18,13 +33,14 @@ macro_rules! dbg {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use alloc::alloc::alloc;
|
||||
use alloc::string::ToString;
|
||||
use core::alloc::Layout;
|
||||
use core::panic::PanicInfo;
|
||||
use cstr_core::{c_char, CString};
|
||||
|
||||
extern "wasm" {
|
||||
fn _print(s: *const u8);
|
||||
fn _error(message: *const u8, file: *const u8, line: u32, position: u32);
|
||||
fn _error(message: *const u8);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
@@ -40,18 +56,11 @@ mod implementation {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
#[cfg(not(test))]
|
||||
pub fn begin_panic_handler(panic_info: &PanicInfo<'_>) -> ! {
|
||||
let msg = CString::new(panic_info.message().unwrap().as_str().unwrap()).unwrap();
|
||||
let mut line = 0;
|
||||
let mut position = 0;
|
||||
let mut file = CString::default();
|
||||
if let Some(s) = panic_info.location() {
|
||||
line = s.line();
|
||||
position = s.column();
|
||||
file = CString::new(s.file()).unwrap();
|
||||
}
|
||||
let payload = panic_info.to_string();
|
||||
let msg = CString::new(payload.as_bytes()).unwrap();
|
||||
|
||||
unsafe {
|
||||
_error(msg.as_ptr(), file.as_ptr(), line, position);
|
||||
_error(msg.as_ptr());
|
||||
}
|
||||
loop {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user