A lot of work on mocking to set up unit testing
This commit is contained in:
parent
3c6aecb0e9
commit
a1e13af793
|
@ -14,3 +14,4 @@ atomic_float = "0.1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] }
|
pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] }
|
||||||
|
mockall = "0.11.2"
|
|
@ -1,6 +1,7 @@
|
||||||
#![feature(inline_const)]
|
#![feature(inline_const)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
#![feature(wasm_abi)]
|
#![feature(wasm_abi)]
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
#![cfg_attr(not(test), no_std)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::script;
|
use crate::script;
|
||||||
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
|
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
|
||||||
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
||||||
|
@ -38,3 +39,56 @@ impl Script for Acrobatics {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
use pkmn_lib_interface::app_interface::{Item, MockExecutingMove, MockItem, MockPokemon};
|
||||||
|
|
||||||
|
fn mock_executing_move(has_held_item: bool) -> ExecutingMove {
|
||||||
|
let mut mv = MockExecutingMove::new();
|
||||||
|
mv.expect_user().returning(move || {
|
||||||
|
let mut user = MockPokemon::new();
|
||||||
|
user.expect_held_item().returning(move || {
|
||||||
|
if has_held_item {
|
||||||
|
Some(Rc::new(MockItem::new()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Rc::new(user)
|
||||||
|
});
|
||||||
|
Rc::new(mv)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn without_held_item_doubles_power() {
|
||||||
|
let mv = mock_executing_move(false);
|
||||||
|
|
||||||
|
let script = Acrobatics::new();
|
||||||
|
let mut base_power = 50u8;
|
||||||
|
script.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power);
|
||||||
|
assert_eq!(100, base_power);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn without_held_item_does_not_overflow() {
|
||||||
|
let mv = mock_executing_move(false);
|
||||||
|
|
||||||
|
let script = Acrobatics::new();
|
||||||
|
let mut base_power = 200u8;
|
||||||
|
script.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power);
|
||||||
|
assert_eq!(255, base_power);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_held_item_does_nothing() {
|
||||||
|
let mv = mock_executing_move(true);
|
||||||
|
|
||||||
|
let script = Acrobatics::new();
|
||||||
|
let mut base_power = 50u8;
|
||||||
|
script.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power);
|
||||||
|
assert_eq!(50, base_power);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::mem::transmute;
|
use core::mem::transmute;
|
||||||
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic};
|
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic};
|
||||||
|
@ -25,7 +26,7 @@ impl Script for Acupressure {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, hit: u8) {
|
fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, hit: u8) {
|
||||||
if target == mv.user() {
|
if target.equals(&mv.user()) {
|
||||||
mv.get_hit_data(&target, hit).fail();
|
mv.get_hit_data(&target, hit).fail();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
|
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
|
||||||
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
||||||
|
|
|
@ -14,7 +14,7 @@ impl Assist {
|
||||||
let mon = party.get_pokemon(mon_index);
|
let mon = party.get_pokemon(mon_index);
|
||||||
if let Some(mon) = mon {
|
if let Some(mon) = mon {
|
||||||
// Ignore moves from the user
|
// Ignore moves from the user
|
||||||
if mon == *user {
|
if mon.equals(user) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Iterate over all moves. We make the assumption of 4 moves.
|
// Iterate over all moves. We make the assumption of 4 moves.
|
||||||
|
|
|
@ -3,7 +3,8 @@ use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use pkmn_lib_interface::app_interface::{
|
use pkmn_lib_interface::app_interface::{
|
||||||
BattleSide, DamageSource, DataLibrary, ExecutingMove, Pokemon, TurnChoice,
|
BattleSide, BattleSideImpl, DamageSource, DataLibrary, ExecutingMove, Pokemon, TurnChoice,
|
||||||
|
WithVolatile,
|
||||||
};
|
};
|
||||||
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
||||||
|
|
||||||
|
@ -25,9 +26,10 @@ impl Script for Assurance {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
fn on_before_turn(&self, choice: TurnChoice) {
|
fn on_before_turn(&self, choice: TurnChoice) {
|
||||||
if let TurnChoice::Move(data) = &choice {
|
if let TurnChoice::Move(data) = &choice {
|
||||||
let side: BattleSide = choice
|
let side: BattleSideImpl = choice
|
||||||
.user()
|
.user()
|
||||||
.battle()
|
.battle()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -48,10 +50,10 @@ impl Script for Assurance {
|
||||||
_hit: u8,
|
_hit: u8,
|
||||||
base_power: &mut u8,
|
base_power: &mut u8,
|
||||||
) {
|
) {
|
||||||
if let Some(s) = target
|
if let Some(s) = pkmn_lib_interface::app_interface::get_volatile_as::<AssuranceData>(
|
||||||
.battle_side()
|
target.battle_side().as_ref(),
|
||||||
.get_volatile::<AssuranceData>(AssuranceData::get_const_name())
|
AssuranceData::get_const_name(),
|
||||||
{
|
) {
|
||||||
if s.has_hit.load(Ordering::Relaxed) {
|
if s.has_hit.load(Ordering::Relaxed) {
|
||||||
*base_power *= 2;
|
*base_power *= 2;
|
||||||
}
|
}
|
||||||
|
@ -86,8 +88,9 @@ impl Script for AssuranceData {
|
||||||
&[ScriptCapabilities::OnEndTurn, ScriptCapabilities::OnDamage]
|
&[ScriptCapabilities::OnEndTurn, ScriptCapabilities::OnDamage]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
fn on_end_turn(&self) {
|
fn on_end_turn(&self) {
|
||||||
let side: BattleSide = self.get_owner().unwrap();
|
let side: BattleSideImpl = self.get_owner().unwrap();
|
||||||
side.remove_volatile(self);
|
side.remove_volatile(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@ use crate::weather::hail::Hail;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
use pkmn_lib_interface::app_interface::{BattleSide, ExecutingMove, MoveCategory, Pokemon};
|
use pkmn_lib_interface::app_interface::{
|
||||||
|
BattleSide, BattleSideImpl, ExecutingMove, MoveCategory, Pokemon, WithVolatile,
|
||||||
|
};
|
||||||
use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn;
|
use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn;
|
||||||
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
|
||||||
|
|
||||||
|
@ -63,6 +65,7 @@ impl Script for AuroraVeilEffect {
|
||||||
&[ScriptCapabilities::ChangeIncomingDamage, OnEndTurn]
|
&[ScriptCapabilities::ChangeIncomingDamage, OnEndTurn]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
fn change_incoming_damage(
|
fn change_incoming_damage(
|
||||||
&self,
|
&self,
|
||||||
mv: ExecutingMove,
|
mv: ExecutingMove,
|
||||||
|
@ -73,7 +76,7 @@ impl Script for AuroraVeilEffect {
|
||||||
if mv.get_hit_data(&target, hit).is_critical() {
|
if mv.get_hit_data(&target, hit).is_critical() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let side: BattleSide = self.get_owner().unwrap();
|
let side: BattleSideImpl = self.get_owner().unwrap();
|
||||||
if side.has_volatile(ReflectEffect::get_const_name())
|
if side.has_volatile(ReflectEffect::get_const_name())
|
||||||
&& mv.use_move().category() == MoveCategory::Physical
|
&& mv.use_move().category() == MoveCategory::Physical
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,11 +45,11 @@ impl Script for ChangeAllTargetStats {
|
||||||
fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, _hit: u8) {
|
fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, _hit: u8) {
|
||||||
let user = mv.user();
|
let user = mv.user();
|
||||||
let amount = self.amount.load(Ordering::SeqCst);
|
let amount = self.amount.load(Ordering::SeqCst);
|
||||||
target.change_stat_boost(Statistic::Attack, amount, user == target);
|
target.change_stat_boost(Statistic::Attack, amount, user.equals(&target));
|
||||||
target.change_stat_boost(Statistic::Defense, amount, user == target);
|
target.change_stat_boost(Statistic::Defense, amount, user.equals(&target));
|
||||||
target.change_stat_boost(Statistic::SpecialAttack, amount, user == target);
|
target.change_stat_boost(Statistic::SpecialAttack, amount, user.equals(&target));
|
||||||
target.change_stat_boost(Statistic::SpecialDefense, amount, user == target);
|
target.change_stat_boost(Statistic::SpecialDefense, amount, user.equals(&target));
|
||||||
target.change_stat_boost(Statistic::Speed, amount, user == target);
|
target.change_stat_boost(Statistic::Speed, amount, user.equals(&target));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
|
|
@ -54,7 +54,7 @@ macro_rules! change_stat_effect {
|
||||||
target.change_stat_boost(
|
target.change_stat_boost(
|
||||||
Statistic::$stat,
|
Statistic::$stat,
|
||||||
self.amount.load(Ordering::SeqCst),
|
self.amount.load(Ordering::SeqCst),
|
||||||
mv.user() == target,
|
mv.user().equals(&target),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Script for CurePartyStatus {
|
||||||
for index in 0..p.length() {
|
for index in 0..p.length() {
|
||||||
let mon = p.get_pokemon(index);
|
let mon = p.get_pokemon(index);
|
||||||
if let Some(mon) = mon {
|
if let Some(mon) = mon {
|
||||||
if mon != user {
|
if !mon.equals(&user) {
|
||||||
mon.clear_status();
|
mon.clear_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ authors = ["Deukhoofd <Deukhoofd@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
mock_data = []
|
mock_data = ["mockall"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cstr_core = { version = "0.2.6", features = ["nightly"]}
|
cstr_core = { version = "0.2.6", features = ["nightly"]}
|
||||||
|
@ -14,7 +14,6 @@ spin = { version = "0.9.4", default-features = false, features = ["rwlock"] }
|
||||||
paste = { version = "1.0.7" }
|
paste = { version = "1.0.7" }
|
||||||
hashbrown = { version = "0.12.3" }
|
hashbrown = { version = "0.12.3" }
|
||||||
dlmalloc = { version = "0.2.4", features = ["global"] }
|
dlmalloc = { version = "0.2.4", features = ["global"] }
|
||||||
|
mockall = { version = "0.11.2", optional = true }
|
||||||
[dev-dependencies]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,74 +1,108 @@
|
||||||
use crate::app_interface::{BattleParty, BattleRandom, BattleSide, ChoiceQueue, Pokemon};
|
use crate::app_interface::{
|
||||||
|
BattleParty, BattlePartyImpl, BattleRandom, BattleRandomImpl, BattleSide, BattleSideImpl,
|
||||||
|
ChoiceQueue, ChoiceQueueImpl, Pokemon, PokemonImpl,
|
||||||
|
};
|
||||||
use crate::handling::cached_value::CachedValue;
|
use crate::handling::cached_value::CachedValue;
|
||||||
use crate::handling::Cacheable;
|
use crate::handling::Cacheable;
|
||||||
use crate::{
|
use crate::{
|
||||||
cached_value, cached_value_getters, wasm_value_getters, DynamicLibrary, ExternRef,
|
cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern,
|
||||||
ExternalReferenceType, ImmutableList, StringKey, VecExternRef,
|
wasm_value_getters_funcs, DynamicLibrary, ExternRef, ExternalReferenceType, ImmutableList,
|
||||||
|
StringKey, VecExternRef,
|
||||||
};
|
};
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
|
pub trait BattleTrait {
|
||||||
|
fn library(&self) -> DynamicLibrary;
|
||||||
|
fn parties(&self) -> ImmutableList<BattlePartyImpl>;
|
||||||
|
fn sides(&self) -> ImmutableList<BattleSideImpl>;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Battle = Rc<dyn BattleTrait>;
|
||||||
|
|
||||||
struct BattleInner {
|
struct BattleInner {
|
||||||
reference: ExternRef<Battle>,
|
reference: ExternRef<BattleImpl>,
|
||||||
library: CachedValue<DynamicLibrary>,
|
library: CachedValue<DynamicLibrary>,
|
||||||
parties: CachedValue<ImmutableList<BattleParty>>,
|
parties: CachedValue<ImmutableList<BattlePartyImpl>>,
|
||||||
sides: CachedValue<ImmutableList<BattleSide>>,
|
sides: CachedValue<ImmutableList<BattleSideImpl>>,
|
||||||
random: CachedValue<BattleRandom>,
|
random: CachedValue<Rc<BattleRandomImpl>>,
|
||||||
choice_queue: CachedValue<ChoiceQueue>,
|
choice_queue: CachedValue<Rc<ChoiceQueueImpl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Battle {
|
pub struct BattleImpl {
|
||||||
inner: Rc<BattleInner>,
|
inner: Rc<BattleInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Battle {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl BattleImpl {
|
||||||
pub fn new(reference: ExternRef<Battle>) -> Self {
|
pub fn new(reference: ExternRef<BattleImpl>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
inner: Rc::new(BattleInner {
|
inner: Rc::new(BattleInner {
|
||||||
reference,
|
reference,
|
||||||
library: cached_value!({ battle_get_library(reference).get_value().unwrap() }),
|
library: cached_value!({ battle_get_library(reference).get_value().unwrap() }),
|
||||||
parties: cached_value!({ battle_get_parties(reference).get_immutable_list() }),
|
parties: cached_value!({ battle_get_parties(reference).get_immutable_list() }),
|
||||||
sides: cached_value!({ battle_get_sides(reference).get_immutable_list() }),
|
sides: cached_value!({ battle_get_sides(reference).get_immutable_list() }),
|
||||||
random: cached_value!({ battle_get_random(reference).get_value().unwrap() }),
|
random: cached_value!({
|
||||||
|
Rc::new(battle_get_random(reference).get_value().unwrap())
|
||||||
|
}),
|
||||||
choice_queue: cached_value!({
|
choice_queue: cached_value!({
|
||||||
battle_get_choice_queue(reference).get_value().unwrap()
|
Rc::new(battle_get_choice_queue(reference).get_value().unwrap())
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl BattleTrait for BattleImpl {
|
||||||
cached_value_getters! {
|
cached_value_getters! {
|
||||||
pub fn library(&self) -> DynamicLibrary;
|
fn library(&self) -> DynamicLibrary;
|
||||||
pub fn parties(&self) -> ImmutableList<BattleParty>;
|
fn parties(&self) -> ImmutableList<BattlePartyImpl>;
|
||||||
pub fn sides(&self) -> ImmutableList<BattleSide>;
|
fn sides(&self) -> ImmutableList<BattleSideImpl>;
|
||||||
pub fn random(&self) -> BattleRandom;
|
fn random(&self) -> BattleRandom;
|
||||||
pub fn choice_queue(&self) -> ChoiceQueue;
|
fn choice_queue(&self) -> ChoiceQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon> {
|
||||||
pub fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon> {
|
|
||||||
unsafe { battle_get_pokemon(self.inner.reference, side, index).get_value() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> Option<BattleParty> {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
battle_find_party_for_pokemon(self.inner.reference, pokemon.reference()).get_value()
|
let v = battle_get_pokemon(self.inner.reference, side, index).get_value();
|
||||||
}
|
if let Some(v) = v {
|
||||||
}
|
Some(Rc::new(v))
|
||||||
|
} else {
|
||||||
#[cfg(feature = "mock_data")]
|
|
||||||
pub fn weather_name(&self) -> Option<StringKey> {
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn weather_name(&self) -> Option<StringKey> {
|
|
||||||
unsafe { battle_get_weather_name(self.inner.reference).get_value() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_weather(&self, name: &str) -> bool {
|
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> Option<BattleParty> {
|
||||||
|
unsafe {
|
||||||
|
let b = battle_find_party_for_pokemon(self.inner.reference, pokemon.reference().into())
|
||||||
|
.get_value();
|
||||||
|
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 has_weather(&self, name: &str) -> bool {
|
||||||
if let Some(weather) = self.weather_name() {
|
if let Some(weather) = self.weather_name() {
|
||||||
if weather.eq(name) {
|
if weather.eq(name) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -76,10 +110,21 @@ impl Battle {
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasm_value_getters_funcs! {
|
||||||
|
Battle,
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_value_getters! {
|
wasm_value_getters_extern! {
|
||||||
Battle,
|
BattleImpl, Battle,
|
||||||
pub fn can_flee(&self) -> bool;
|
pub fn can_flee(&self) -> bool;
|
||||||
pub fn number_of_sides(&self) -> u8;
|
pub fn number_of_sides(&self) -> u8;
|
||||||
pub fn pokemon_per_side(&self) -> u8;
|
pub fn pokemon_per_side(&self) -> u8;
|
||||||
|
@ -89,10 +134,10 @@ wasm_value_getters! {
|
||||||
pub fn current_turn(&self) -> u32;
|
pub fn current_turn(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(Battle);
|
crate::handling::cacheable::cacheable!(BattleImpl);
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for Battle {
|
impl ExternalReferenceType for BattleImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
|
@ -100,16 +145,16 @@ impl ExternalReferenceType for Battle {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn battle_get_library(r: ExternRef<Battle>) -> ExternRef<DynamicLibrary>;
|
fn battle_get_library(r: ExternRef<BattleImpl>) -> ExternRef<DynamicLibrary>;
|
||||||
fn battle_get_parties(r: ExternRef<Battle>) -> VecExternRef<BattleParty>;
|
fn battle_get_parties(r: ExternRef<BattleImpl>) -> VecExternRef<BattlePartyImpl>;
|
||||||
fn battle_get_sides(r: ExternRef<Battle>) -> VecExternRef<BattleSide>;
|
fn battle_get_sides(r: ExternRef<BattleImpl>) -> VecExternRef<BattleSideImpl>;
|
||||||
fn battle_get_random(r: ExternRef<Battle>) -> ExternRef<BattleRandom>;
|
fn battle_get_random(r: ExternRef<BattleImpl>) -> ExternRef<BattleRandomImpl>;
|
||||||
fn battle_get_choice_queue(r: ExternRef<Battle>) -> ExternRef<ChoiceQueue>;
|
fn battle_get_choice_queue(r: ExternRef<BattleImpl>) -> ExternRef<ChoiceQueueImpl>;
|
||||||
fn battle_get_pokemon(r: ExternRef<Battle>, side: u8, index: u8) -> ExternRef<Pokemon>;
|
fn battle_get_pokemon(r: ExternRef<BattleImpl>, side: u8, index: u8) -> ExternRef<PokemonImpl>;
|
||||||
fn battle_find_party_for_pokemon(
|
fn battle_find_party_for_pokemon(
|
||||||
r: ExternRef<Battle>,
|
r: ExternRef<BattleImpl>,
|
||||||
mon: ExternRef<Pokemon>,
|
mon: ExternRef<PokemonImpl>,
|
||||||
) -> ExternRef<BattleParty>;
|
) -> ExternRef<BattlePartyImpl>;
|
||||||
|
|
||||||
fn battle_get_weather_name(r: ExternRef<Battle>) -> ExternRef<StringKey>;
|
fn battle_get_weather_name(r: ExternRef<BattleImpl>) -> ExternRef<StringKey>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,50 @@
|
||||||
use crate::app_interface::Party;
|
use crate::app_interface::{Party, PartyImpl};
|
||||||
use crate::handling::cached_value::CachedValue;
|
use crate::handling::cached_value::CachedValue;
|
||||||
use crate::handling::Cacheable;
|
use crate::handling::Cacheable;
|
||||||
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType};
|
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType};
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
|
pub trait BattlePartyTrait {
|
||||||
|
fn party(&self) -> Party;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BattleParty = Rc<dyn BattlePartyTrait>;
|
||||||
|
|
||||||
struct BattlePartyInner {
|
struct BattlePartyInner {
|
||||||
reference: ExternRef<BattleParty>,
|
reference: ExternRef<BattlePartyImpl>,
|
||||||
party: CachedValue<Party>,
|
party: CachedValue<Rc<PartyImpl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BattleParty {
|
pub struct BattlePartyImpl {
|
||||||
inner: Rc<BattlePartyInner>,
|
inner: Rc<BattlePartyInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BattleParty {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl BattlePartyImpl {
|
||||||
pub fn new(reference: ExternRef<BattleParty>) -> Self {
|
pub fn new(reference: ExternRef<BattlePartyImpl>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
inner: Rc::new(BattlePartyInner {
|
inner: Rc::new(BattlePartyInner {
|
||||||
reference,
|
reference,
|
||||||
party: cached_value!({ battle_party_get_party(reference).get_value().unwrap() }),
|
party: cached_value!({
|
||||||
|
Rc::new(battle_party_get_party(reference).get_value().unwrap())
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl BattlePartyTrait for BattlePartyImpl {
|
||||||
cached_value_getters! {
|
cached_value_getters! {
|
||||||
pub fn party(&self) -> Party;
|
fn party(&self) -> Party;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(BattleParty);
|
crate::handling::cacheable::cacheable!(BattlePartyImpl);
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for BattleParty {
|
impl ExternalReferenceType for BattlePartyImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
|
@ -41,5 +52,5 @@ impl ExternalReferenceType for BattleParty {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn battle_party_get_party(r: ExternRef<BattleParty>) -> ExternRef<Party>;
|
fn battle_party_get_party(r: ExternRef<BattlePartyImpl>) -> ExternRef<PartyImpl>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,37 @@
|
||||||
use crate::{ExternRef, ExternalReferenceType};
|
use crate::{ExternRef, ExternalReferenceType};
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
|
pub trait BattleRandomTrait {
|
||||||
|
fn get(&self) -> i32;
|
||||||
|
fn get_max(&self, max: i32) -> i32;
|
||||||
|
fn get_between(&self, min: i32, max: i32) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BattleRandom = Rc<dyn BattleRandomTrait>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BattleRandom {
|
pub struct BattleRandomImpl {
|
||||||
reference: ExternRef<Self>,
|
reference: ExternRef<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BattleRandom {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl BattleRandomTrait for BattleRandomImpl {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn get(&self) -> i32 {
|
fn get(&self) -> i32 {
|
||||||
unsafe { battle_random_get(self.reference) }
|
unsafe { battle_random_get(self.reference) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn get_max(&self, max: i32) -> i32 {
|
fn get_max(&self, max: i32) -> i32 {
|
||||||
unsafe { battle_random_get_max(self.reference, max) }
|
unsafe { battle_random_get_max(self.reference, max) }
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn get_between(&self, min: i32, max: i32) -> i32 {
|
fn get_between(&self, min: i32, max: i32) -> i32 {
|
||||||
unsafe { battle_random_get_between(self.reference, min, max) }
|
unsafe { battle_random_get_between(self.reference, min, max) }
|
||||||
}
|
}
|
||||||
// TODO: effect_chance()
|
// TODO: effect_chance()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalReferenceType for BattleRandom {
|
impl ExternalReferenceType for BattleRandomImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self { reference }
|
Self { reference }
|
||||||
}
|
}
|
||||||
|
@ -29,8 +39,8 @@ impl ExternalReferenceType for BattleRandom {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn battle_random_get(r: ExternRef<BattleRandom>) -> i32;
|
fn battle_random_get(r: ExternRef<BattleRandomImpl>) -> i32;
|
||||||
fn battle_random_get_max(r: ExternRef<BattleRandom>, max: i32) -> i32;
|
fn battle_random_get_max(r: ExternRef<BattleRandomImpl>, max: i32) -> i32;
|
||||||
fn battle_random_get_between(r: ExternRef<BattleRandom>, min: i32, max: i32) -> i32;
|
fn battle_random_get_between(r: ExternRef<BattleRandomImpl>, min: i32, max: i32) -> i32;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,102 +1,117 @@
|
||||||
use crate::app_interface::{Battle, Pokemon};
|
use crate::app_interface::{Battle, BattleImpl, Pokemon, PokemonImpl, WithVolatile};
|
||||||
use crate::handling::cacheable::Cacheable;
|
use crate::handling::cacheable::Cacheable;
|
||||||
use crate::handling::cached_value::CachedValue;
|
use crate::handling::cached_value::CachedValue;
|
||||||
use crate::{
|
use crate::{
|
||||||
cached_value, cached_value_getters, wasm_value_getters, ExternRef, ExternalReferenceType,
|
cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern,
|
||||||
Script, ScriptPtr,
|
wasm_value_getters_funcs, ExternRef, ExternalReferenceType, Script, ScriptPtr,
|
||||||
};
|
};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use cstr_core::{c_char, CString};
|
use cstr_core::{c_char, CString};
|
||||||
|
|
||||||
|
pub trait BattleSideTrait: WithVolatile {
|
||||||
|
fn side_index(&self) -> u8;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BattleSide = Rc<dyn BattleSideTrait>;
|
||||||
|
|
||||||
struct BattleSideInner {
|
struct BattleSideInner {
|
||||||
reference: ExternRef<BattleSide>,
|
reference: ExternRef<BattleSideImpl>,
|
||||||
side_index: CachedValue<u8>,
|
side_index: CachedValue<u8>,
|
||||||
pokemon_per_side: CachedValue<u8>,
|
pokemon_per_side: CachedValue<u8>,
|
||||||
battle: CachedValue<Battle>,
|
battle: CachedValue<Rc<BattleImpl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BattleSide {
|
pub struct BattleSideImpl {
|
||||||
inner: Rc<BattleSideInner>,
|
inner: Rc<BattleSideInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BattleSide {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl BattleSideImpl {
|
||||||
pub fn new(reference: ExternRef<Self>) -> Self {
|
pub fn new(reference: ExternRef<Self>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
inner: Rc::new(BattleSideInner {
|
inner: Rc::new(BattleSideInner {
|
||||||
reference,
|
reference,
|
||||||
side_index: cached_value!({ battleside_get_side_index(reference) }),
|
side_index: cached_value!({ battleside_get_side_index(reference) }),
|
||||||
pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }),
|
pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }),
|
||||||
battle: cached_value!({ battleside_get_battle(reference).get_value().unwrap() }),
|
battle: cached_value!({
|
||||||
|
Rc::new(battleside_get_battle(reference).get_value().unwrap())
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl BattleSideTrait for BattleSideImpl {
|
||||||
cached_value_getters! {
|
cached_value_getters! {
|
||||||
pub fn side_index(&self) -> u8;
|
fn side_index(&self) -> u8;
|
||||||
pub fn pokemon_per_side(&self) -> u8;
|
fn pokemon_per_side(&self) -> u8;
|
||||||
pub fn battle(&self) -> Battle;
|
fn battle(&self) -> Battle;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
||||||
pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
unsafe {
|
||||||
unsafe { battleside_get_pokemon(self.inner.reference, index).get_value() }
|
let p = battleside_get_pokemon(self.inner.reference, index).get_value();
|
||||||
|
if let Some(p) = p {
|
||||||
|
Some(Rc::new(p))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
wasm_value_getters_funcs! {
|
||||||
pub fn has_volatile(&self, script_name: &str) -> bool {
|
BattleSide,
|
||||||
|
fn has_fled_battle(&self) -> bool;
|
||||||
|
fn is_defeated(&self) -> bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl WithVolatile for BattleSideImpl {
|
||||||
|
fn has_volatile(&self, script_name: &str) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
let script_name = CString::new(script_name).unwrap();
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn add_volatile<'a, 'b>(&'a self, script: Box<dyn Script>) -> &'b dyn Script {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn add_volatile<'a, 'b>(&'a self, script: Box<dyn Script>) -> &'b dyn Script {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
||||||
.val()
|
.val()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn remove_volatile(&self, script: &dyn Script) {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn remove_volatile(&self, script: &dyn Script) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let name = CString::new(script.get_name()).unwrap();
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script> {
|
||||||
pub fn get_volatile<T>(&self, script_name: &str) -> Option<&T>
|
|
||||||
where
|
|
||||||
T: Script + 'static,
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
let script_name = CString::new(script_name).unwrap();
|
let script_name = CString::new(script_name).unwrap();
|
||||||
let s = battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val();
|
unsafe { battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val() }
|
||||||
if let Some(s) = s {
|
|
||||||
Some(s.as_any().downcast_ref().unwrap())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_value_getters! {
|
wasm_value_getters_extern! {
|
||||||
BattleSide,
|
BattleSideImpl, BattleSide,
|
||||||
pub fn has_fled_battle(&self) -> bool;
|
pub fn has_fled_battle(&self) -> bool;
|
||||||
pub fn is_defeated(&self) -> bool;
|
pub fn is_defeated(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(BattleSide);
|
crate::handling::cacheable::cacheable!(BattleSideImpl);
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for BattleSide {
|
impl ExternalReferenceType for BattleSideImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
|
@ -104,14 +119,18 @@ impl ExternalReferenceType for BattleSide {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn battleside_get_side_index(r: ExternRef<BattleSide>) -> u8;
|
fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> u8;
|
||||||
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSide>) -> u8;
|
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSideImpl>) -> u8;
|
||||||
fn battleside_get_battle(r: ExternRef<BattleSide>) -> ExternRef<Battle>;
|
fn battleside_get_battle(r: ExternRef<BattleSideImpl>) -> ExternRef<BattleImpl>;
|
||||||
fn battleside_get_pokemon(r: ExternRef<BattleSide>, index: usize) -> ExternRef<Pokemon>;
|
fn battleside_get_pokemon(r: ExternRef<BattleSideImpl>, index: usize)
|
||||||
|
-> ExternRef<PokemonImpl>;
|
||||||
|
|
||||||
fn battleside_add_volatile_by_name(r: ExternRef<BattleSide>, name: *const c_char) -> ScriptPtr;
|
fn battleside_add_volatile_by_name(
|
||||||
fn battleside_add_volatile(r: ExternRef<BattleSide>, script: ScriptPtr) -> ScriptPtr;
|
r: ExternRef<BattleSideImpl>,
|
||||||
fn battleside_has_volatile(r: ExternRef<BattleSide>, name: *const c_char) -> bool;
|
name: *const c_char,
|
||||||
fn battleside_remove_volatile(r: ExternRef<BattleSide>, name: *const c_char);
|
) -> ScriptPtr;
|
||||||
fn battleside_get_volatile(r: ExternRef<BattleSide>, 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
|
use crate::app_interface::PokemonImpl;
|
||||||
use crate::{ExternRef, ExternalReferenceType, Pokemon};
|
use crate::{ExternRef, ExternalReferenceType, Pokemon};
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub trait ChoiceQueueTrait {
|
||||||
pub struct ChoiceQueue {
|
fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool;
|
||||||
reference: ExternRef<ChoiceQueue>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChoiceQueue {
|
pub type ChoiceQueue = Rc<dyn ChoiceQueueTrait>;
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn new(reference: ExternRef<ChoiceQueue>) -> Self {
|
|
||||||
Self { reference }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool {
|
#[derive(Clone)]
|
||||||
unsafe { choice_queue_move_pokemon_choice_next(self.reference, pokemon.reference()) }
|
pub struct ChoiceQueueImpl {
|
||||||
|
reference: ExternRef<ChoiceQueueImpl>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ChoiceQueueImpl {
|
||||||
|
pub fn new(reference: ExternRef<ChoiceQueueImpl>) -> Self {
|
||||||
|
Self { reference }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for ChoiceQueue {
|
impl ChoiceQueueTrait for ChoiceQueueImpl {
|
||||||
|
fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool {
|
||||||
|
unsafe { choice_queue_move_pokemon_choice_next(self.reference, pokemon.reference().into()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ExternalReferenceType for ChoiceQueueImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
|
@ -26,7 +37,7 @@ impl ExternalReferenceType for ChoiceQueue {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn choice_queue_move_pokemon_choice_next(
|
fn choice_queue_move_pokemon_choice_next(
|
||||||
r: ExternRef<ChoiceQueue>,
|
r: ExternRef<ChoiceQueueImpl>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,42 @@
|
||||||
use crate::app_interface::{LearnedMove, MoveData, Pokemon};
|
use crate::app_interface::{LearnedMove, MoveData, Pokemon, PokemonImpl};
|
||||||
use crate::handling::cached_value::CachedValue;
|
use crate::handling::cached_value::CachedValue;
|
||||||
use crate::handling::temporary::Temporary;
|
use crate::handling::temporary::Temporary;
|
||||||
use crate::{cached_value, ExternRef, ExternalReferenceType, Script};
|
use crate::{cached_value, ExternRef, ExternalReferenceType, Script};
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
struct ExecutingMoveInner {
|
struct ExecutingMoveInner {
|
||||||
reference: ExternRef<ExecutingMove>,
|
reference: ExternRef<ExecutingMoveImpl>,
|
||||||
number_of_hits: CachedValue<u8>,
|
number_of_hits: CachedValue<u8>,
|
||||||
user: CachedValue<Pokemon>,
|
user: CachedValue<PokemonImpl>,
|
||||||
chosen_move: CachedValue<LearnedMove>,
|
chosen_move: CachedValue<LearnedMove>,
|
||||||
use_move: CachedValue<MoveData>,
|
use_move: CachedValue<MoveData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||||
|
pub trait ExecutingMoveTrait {
|
||||||
|
fn number_of_hits(&self) -> u8;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ExecutingMove = Rc<dyn ExecutingMoveTrait>;
|
||||||
|
#[cfg(feature = "mock_data")]
|
||||||
|
pub type MockExecutingMove = MockExecutingMoveTrait;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ExecutingMove {
|
pub struct ExecutingMoveImpl {
|
||||||
inner: Temporary<ExecutingMoveInner>,
|
inner: Temporary<ExecutingMoveInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExecutingMove {
|
impl ExecutingMoveImpl {
|
||||||
pub(crate) fn new(reference: ExternRef<ExecutingMove>) -> Self {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Temporary::new(
|
inner: Temporary::new(
|
||||||
reference.get_internal_index(),
|
reference.get_internal_index(),
|
||||||
|
@ -39,88 +58,119 @@ impl ExecutingMove {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn number_of_hits(&self) -> u8 {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ExecutingMoveTrait for ExecutingMoveImpl {
|
||||||
|
fn number_of_hits(&self) -> u8 {
|
||||||
self.inner.value().number_of_hits.value()
|
self.inner.value().number_of_hits.value()
|
||||||
}
|
}
|
||||||
pub fn user(&self) -> Pokemon {
|
fn user(&self) -> Pokemon {
|
||||||
self.inner.value().user.value()
|
Rc::new(self.inner.value().user.value())
|
||||||
}
|
}
|
||||||
pub fn chosen_move(&self) -> LearnedMove {
|
fn chosen_move(&self) -> LearnedMove {
|
||||||
self.inner.value().chosen_move.value()
|
self.inner.value().chosen_move.value()
|
||||||
}
|
}
|
||||||
pub fn use_move(&self) -> MoveData {
|
fn use_move(&self) -> MoveData {
|
||||||
self.inner.value().use_move.value()
|
self.inner.value().use_move.value()
|
||||||
}
|
}
|
||||||
pub fn move_script(&self) -> Option<&dyn Script> {
|
fn move_script(&self) -> Option<&dyn Script> {
|
||||||
unsafe { executing_move_get_script(self.inner.value().reference).as_ref() }
|
unsafe { executing_move_get_script(self.inner.value().reference).as_ref() }
|
||||||
}
|
}
|
||||||
pub fn number_of_targets(&self) -> usize {
|
fn number_of_targets(&self) -> usize {
|
||||||
unsafe { executing_move_get_number_of_targets(self.inner.value().reference) }
|
unsafe { executing_move_get_number_of_targets(self.inner.value().reference) }
|
||||||
}
|
}
|
||||||
pub fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool {
|
fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
executing_move_is_pokemon_target(self.inner.value().reference, pokemon.reference())
|
executing_move_is_pokemon_target(
|
||||||
|
self.inner.value().reference,
|
||||||
|
pokemon.reference().into(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData {
|
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData {
|
||||||
unsafe {
|
unsafe {
|
||||||
executing_move_get_hit_data(self.inner.value().reference, pokemon.reference(), hit)
|
Rc::new(
|
||||||
|
executing_move_get_hit_data(
|
||||||
|
self.inner.value().reference,
|
||||||
|
pokemon.reference().into(),
|
||||||
|
hit,
|
||||||
|
)
|
||||||
.get_value()
|
.get_value()
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type HitData = Rc<dyn HitDataTrait>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct HitData {
|
pub struct HitDataImpl {
|
||||||
reference: ExternRef<HitData>,
|
reference: ExternRef<HitDataImpl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HitData {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn is_critical(&self) -> bool {
|
impl HitDataTrait for HitDataImpl {
|
||||||
|
fn is_critical(&self) -> bool {
|
||||||
unsafe { hit_data_is_critical(self.reference) }
|
unsafe { hit_data_is_critical(self.reference) }
|
||||||
}
|
}
|
||||||
pub fn base_power(&self) -> u8 {
|
fn base_power(&self) -> u8 {
|
||||||
unsafe { hit_data_get_base_power(self.reference) }
|
unsafe { hit_data_get_base_power(self.reference) }
|
||||||
}
|
}
|
||||||
pub fn effectiveness(&self) -> f32 {
|
fn effectiveness(&self) -> f32 {
|
||||||
unsafe { hit_data_get_effectiveness(self.reference) }
|
unsafe { hit_data_get_effectiveness(self.reference) }
|
||||||
}
|
}
|
||||||
pub fn damage(&self) -> u32 {
|
fn damage(&self) -> u32 {
|
||||||
unsafe { hit_data_get_damage(self.reference) }
|
unsafe { hit_data_get_damage(self.reference) }
|
||||||
}
|
}
|
||||||
pub fn move_type(&self) -> u8 {
|
fn move_type(&self) -> u8 {
|
||||||
unsafe { hit_data_get_move_type(self.reference) }
|
unsafe { hit_data_get_move_type(self.reference) }
|
||||||
}
|
}
|
||||||
pub fn has_failed(&self) -> bool {
|
fn has_failed(&self) -> bool {
|
||||||
unsafe { hit_data_is_critical(self.reference) }
|
unsafe { hit_data_is_critical(self.reference) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_critical(&self, critical: bool) {
|
fn set_critical(&self, critical: bool) {
|
||||||
unsafe { hit_data_set_critical(self.reference, critical) }
|
unsafe { hit_data_set_critical(self.reference, critical) }
|
||||||
}
|
}
|
||||||
pub fn set_effectiveness(&self, effectiveness: f32) {
|
fn set_effectiveness(&self, effectiveness: f32) {
|
||||||
unsafe { hit_data_set_effectiveness(self.reference, effectiveness) }
|
unsafe { hit_data_set_effectiveness(self.reference, effectiveness) }
|
||||||
}
|
}
|
||||||
pub fn set_damage(&self, damage: u32) {
|
fn set_damage(&self, damage: u32) {
|
||||||
unsafe { hit_data_set_damage(self.reference, damage) }
|
unsafe { hit_data_set_damage(self.reference, damage) }
|
||||||
}
|
}
|
||||||
pub fn set_move_type(&self, move_type: u8) {
|
fn set_move_type(&self, move_type: u8) {
|
||||||
unsafe { hit_data_set_move_type(self.reference, move_type) }
|
unsafe { hit_data_set_move_type(self.reference, move_type) }
|
||||||
}
|
}
|
||||||
pub fn fail(&self) {
|
fn fail(&self) {
|
||||||
unsafe { hit_data_fail(self.reference) }
|
unsafe { hit_data_fail(self.reference) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalReferenceType for ExecutingMove {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ExternalReferenceType for ExecutingMoveImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalReferenceType for HitData {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ExternalReferenceType for HitDataImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self { reference }
|
Self { reference }
|
||||||
}
|
}
|
||||||
|
@ -128,35 +178,35 @@ impl ExternalReferenceType for HitData {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn executing_move_get_number_of_targets(r: ExternRef<ExecutingMove>) -> usize;
|
fn executing_move_get_number_of_targets(r: ExternRef<ExecutingMoveImpl>) -> usize;
|
||||||
fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMove>) -> u8;
|
fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMoveImpl>) -> u8;
|
||||||
fn executing_move_get_user(r: ExternRef<ExecutingMove>) -> ExternRef<Pokemon>;
|
fn executing_move_get_user(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<PokemonImpl>;
|
||||||
fn executing_move_get_chosen_move(r: ExternRef<ExecutingMove>) -> ExternRef<LearnedMove>;
|
fn executing_move_get_chosen_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<LearnedMove>;
|
||||||
fn executing_move_get_use_move(r: ExternRef<ExecutingMove>) -> ExternRef<MoveData>;
|
fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveData>;
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn executing_move_get_script(r: ExternRef<ExecutingMove>) -> *const dyn Script;
|
fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script;
|
||||||
|
|
||||||
fn executing_move_is_pokemon_target(
|
fn executing_move_is_pokemon_target(
|
||||||
r: ExternRef<ExecutingMove>,
|
r: ExternRef<ExecutingMoveImpl>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
fn executing_move_get_hit_data(
|
fn executing_move_get_hit_data(
|
||||||
r: ExternRef<ExecutingMove>,
|
r: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) -> ExternRef<HitData>;
|
) -> ExternRef<HitDataImpl>;
|
||||||
|
|
||||||
fn hit_data_is_critical(r: ExternRef<HitData>) -> bool;
|
fn hit_data_is_critical(r: ExternRef<HitDataImpl>) -> bool;
|
||||||
fn hit_data_get_base_power(r: ExternRef<HitData>) -> u8;
|
fn hit_data_get_base_power(r: ExternRef<HitDataImpl>) -> u8;
|
||||||
fn hit_data_get_effectiveness(r: ExternRef<HitData>) -> f32;
|
fn hit_data_get_effectiveness(r: ExternRef<HitDataImpl>) -> f32;
|
||||||
fn hit_data_get_damage(r: ExternRef<HitData>) -> u32;
|
fn hit_data_get_damage(r: ExternRef<HitDataImpl>) -> u32;
|
||||||
fn hit_data_get_move_type(r: ExternRef<HitData>) -> u8;
|
fn hit_data_get_move_type(r: ExternRef<HitDataImpl>) -> u8;
|
||||||
fn hit_data_has_failed(r: ExternRef<HitData>) -> bool;
|
fn hit_data_has_failed(r: ExternRef<HitDataImpl>) -> bool;
|
||||||
|
|
||||||
fn hit_data_set_critical(r: ExternRef<HitData>, critical: bool);
|
fn hit_data_set_critical(r: ExternRef<HitDataImpl>, critical: bool);
|
||||||
fn hit_data_set_base_power(r: ExternRef<HitData>, power: u8);
|
fn hit_data_set_base_power(r: ExternRef<HitDataImpl>, power: u8);
|
||||||
fn hit_data_set_effectiveness(r: ExternRef<HitData>, effectiveness: f32);
|
fn hit_data_set_effectiveness(r: ExternRef<HitDataImpl>, effectiveness: f32);
|
||||||
fn hit_data_set_damage(r: ExternRef<HitData>, damage: u32);
|
fn hit_data_set_damage(r: ExternRef<HitDataImpl>, damage: u32);
|
||||||
fn hit_data_set_move_type(r: ExternRef<HitData>, move_type: u8);
|
fn hit_data_set_move_type(r: ExternRef<HitDataImpl>, move_type: u8);
|
||||||
fn hit_data_fail(r: ExternRef<HitData>);
|
fn hit_data_fail(r: ExternRef<HitDataImpl>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ mod party;
|
||||||
mod pokemon;
|
mod pokemon;
|
||||||
mod statistic_set;
|
mod statistic_set;
|
||||||
mod turn_choices;
|
mod turn_choices;
|
||||||
|
mod with_volatile;
|
||||||
|
|
||||||
pub use battle::*;
|
pub use battle::*;
|
||||||
pub use battle_party::*;
|
pub use battle_party::*;
|
||||||
|
@ -23,3 +24,4 @@ pub use party::*;
|
||||||
pub use pokemon::*;
|
pub use pokemon::*;
|
||||||
pub use statistic_set::*;
|
pub use statistic_set::*;
|
||||||
pub use turn_choices::*;
|
pub use turn_choices::*;
|
||||||
|
pub use with_volatile::*;
|
||||||
|
|
|
@ -1,27 +1,46 @@
|
||||||
use crate::app_interface::Pokemon;
|
use crate::app_interface::{Pokemon, PokemonImpl};
|
||||||
use crate::{ExternRef, ExternalReferenceType};
|
use crate::{ExternRef, ExternalReferenceType};
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub trait PartyTrait {
|
||||||
pub struct Party {
|
fn get_pokemon(&self, index: usize) -> Option<Pokemon>;
|
||||||
reference: ExternRef<Party>,
|
fn length(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Party {
|
pub type Party = Rc<dyn PartyTrait>;
|
||||||
pub fn new(reference: ExternRef<Party>) -> Self {
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct PartyImpl {
|
||||||
|
reference: ExternRef<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl PartyImpl {
|
||||||
|
pub fn new(reference: ExternRef<PartyImpl>) -> Self {
|
||||||
Self { reference }
|
Self { reference }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
impl PartyTrait for PartyImpl {
|
||||||
unsafe { party_get_pokemon(self.reference, index).get_value() }
|
fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
||||||
|
unsafe {
|
||||||
|
let v = party_get_pokemon(self.reference, index).get_value();
|
||||||
|
if let Some(v) = v {
|
||||||
|
Some(Rc::new(v))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize {
|
fn length(&self) -> usize {
|
||||||
unsafe { party_get_length(self.reference) }
|
unsafe { party_get_length(self.reference) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalReferenceType for Party {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ExternalReferenceType for PartyImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +48,6 @@ impl ExternalReferenceType for Party {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn party_get_pokemon(r: ExternRef<Party>, index: usize) -> ExternRef<Pokemon>;
|
fn party_get_pokemon(r: ExternRef<PartyImpl>, index: usize) -> ExternRef<PokemonImpl>;
|
||||||
fn party_get_length(r: ExternRef<Party>) -> usize;
|
fn party_get_length(r: ExternRef<PartyImpl>) -> usize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,324 @@
|
||||||
use crate::app_interface::ability::{Ability, AbilityIndex};
|
use crate::app_interface::ability::{Ability, AbilityIndex};
|
||||||
use crate::app_interface::{
|
use crate::app_interface::{
|
||||||
Battle, BattleSide, ClampedStatisticSet, Form, Gender, Item, LearnedMove, LevelInt, Nature,
|
AbilityImpl, Battle, BattleImpl, BattleSide, ClampedStatisticSet, Form, Gender, Item, ItemImpl,
|
||||||
Species, Statistic, StatisticSet,
|
LearnedMove, LevelInt, Nature, Species, Statistic, StatisticSet, StatisticSetImpl,
|
||||||
};
|
};
|
||||||
use crate::handling::cached_value::CachedValue;
|
use crate::handling::cached_value::CachedValue;
|
||||||
use crate::handling::Cacheable;
|
use crate::handling::Cacheable;
|
||||||
use crate::{
|
use crate::{
|
||||||
cached_value, cached_value_getters, wasm_optional_reference_getters, wasm_reference_getters,
|
cached_value, cached_value_getters, wasm_optional_reference_getters,
|
||||||
wasm_value_getters, DynamicLibrary, ExternRef, ExternalReferenceType, Script, ScriptPtr,
|
wasm_optional_reference_getters_extern, wasm_optional_reference_getters_funcs,
|
||||||
TypeIdentifier,
|
wasm_reference_getters, wasm_reference_getters_extern, wasm_reference_getters_funcs,
|
||||||
|
wasm_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs, DynamicLibrary,
|
||||||
|
ExternRef, ExternalReferenceType, Script, ScriptPtr, TypeIdentifier,
|
||||||
};
|
};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
|
use core::any::Any;
|
||||||
use cstr_core::{c_char, CString};
|
use cstr_core::{c_char, CString};
|
||||||
|
|
||||||
struct PokemonInner {
|
struct PokemonInner {
|
||||||
reference: ExternRef<Pokemon>,
|
reference: ExternRef<PokemonImpl>,
|
||||||
library: CachedValue<DynamicLibrary>,
|
library: CachedValue<DynamicLibrary>,
|
||||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||||
flat_stats: CachedValue<StatisticSet<u32>>,
|
flat_stats: CachedValue<Rc<StatisticSetImpl<u32>>>,
|
||||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||||
stat_boosts: CachedValue<ClampedStatisticSet<i8>>,
|
stat_boosts: CachedValue<ClampedStatisticSet<i8>>,
|
||||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||||
boosted_stats: CachedValue<StatisticSet<u32>>,
|
boosted_stats: CachedValue<Rc<StatisticSetImpl<u32>>>,
|
||||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||||
individual_values: CachedValue<ClampedStatisticSet<u8>>,
|
individual_values: CachedValue<ClampedStatisticSet<u8>>,
|
||||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||||
effort_values: CachedValue<ClampedStatisticSet<u8>>,
|
effort_values: CachedValue<ClampedStatisticSet<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type Pokemon = Rc<dyn PokemonTrait>;
|
||||||
|
#[cfg(feature = "mock_data")]
|
||||||
|
pub type MockPokemon = MockPokemonTrait;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Pokemon {
|
pub struct PokemonImpl {
|
||||||
inner: Rc<PokemonInner>,
|
inner: Rc<PokemonInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pokemon {
|
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||||
|
pub trait PokemonTrait {
|
||||||
|
fn reference(&self) -> u32;
|
||||||
|
|
||||||
|
fn species(&self) -> Species;
|
||||||
|
fn form(&self) -> Form;
|
||||||
|
fn active_ability(&self) -> AbilityImpl;
|
||||||
|
fn nature(&self) -> Nature;
|
||||||
|
fn display_species(&self) -> Option<Species>;
|
||||||
|
fn display_form(&self) -> Option<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 library(&self) -> DynamicLibrary;
|
||||||
|
fn flat_stats(&self) -> StatisticSet<u32>;
|
||||||
|
fn stat_boosts(&self) -> ClampedStatisticSet<i8>;
|
||||||
|
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 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 set_weight(&self, weight: f32);
|
||||||
|
fn clear_status(&self);
|
||||||
|
fn battle_side(&self) -> BattleSide;
|
||||||
|
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<T: Script>(&self, script_name: &str) -> Option<&'static T>
|
||||||
|
// where
|
||||||
|
// T: Script + 'static;
|
||||||
|
|
||||||
|
fn equals(&self, other: &Pokemon) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl PokemonTrait for PokemonImpl {
|
||||||
|
fn reference(&self) -> u32 {
|
||||||
|
self.reference().get_internal_index()
|
||||||
|
}
|
||||||
|
|
||||||
|
cached_value_getters! {
|
||||||
|
fn library(&self) -> DynamicLibrary;
|
||||||
|
fn flat_stats(&self) -> StatisticSet<u32>;
|
||||||
|
fn stat_boosts(&self) -> ClampedStatisticSet<i8>;
|
||||||
|
fn boosted_stats(&self) -> StatisticSet<u32>;
|
||||||
|
fn individual_values(&self) -> ClampedStatisticSet<u8>;
|
||||||
|
fn effort_values(&self) -> ClampedStatisticSet<u8>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 set_held_item(&self, item: &Item) -> Option<Item> {
|
||||||
|
unsafe {
|
||||||
|
let i =
|
||||||
|
pokemon_set_held_item(self.inner.reference, item.reference().into()).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))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn consume_held_item(&self) -> bool {
|
||||||
|
unsafe { pokemon_consume_held_item(self.inner.reference) }
|
||||||
|
}
|
||||||
|
fn max_health(&self) -> u32 {
|
||||||
|
self.boosted_stats().hp()
|
||||||
|
}
|
||||||
|
fn get_type(&self, index: usize) -> u8 {
|
||||||
|
unsafe { pokemon_get_type(self.inner.reference, index) }
|
||||||
|
}
|
||||||
|
fn has_type(&self, type_identifier: TypeIdentifier) -> bool {
|
||||||
|
unsafe { pokemon_has_type(self.inner.reference, type_identifier.into()) }
|
||||||
|
}
|
||||||
|
fn has_type_by_name(&self, type_name: &str) -> bool {
|
||||||
|
let type_identifier = self
|
||||||
|
.library()
|
||||||
|
.data_library()
|
||||||
|
.type_library()
|
||||||
|
.get_type_from_name(type_name);
|
||||||
|
if let Some(type_identifier) = type_identifier {
|
||||||
|
return self.has_type(type_identifier);
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn get_learned_move(&self, index: usize) -> Option<LearnedMove> {
|
||||||
|
unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() }
|
||||||
|
}
|
||||||
|
fn change_stat_boost(&self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> bool {
|
||||||
|
unsafe {
|
||||||
|
pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn ability_script(&self) -> Option<&Box<dyn Script>> {
|
||||||
|
unsafe { pokemon_get_ability_script(self.inner.reference).as_ref() }
|
||||||
|
}
|
||||||
|
fn change_species(&self, species: Species, form: Form) {
|
||||||
|
unsafe {
|
||||||
|
pokemon_change_species(self.inner.reference, species.reference(), form.reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn change_form(&self, form: Form) {
|
||||||
|
unsafe {
|
||||||
|
pokemon_change_form(self.inner.reference, form.reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn is_fainted(&self) -> bool {
|
||||||
|
self.current_health() == 0
|
||||||
|
}
|
||||||
|
fn damage(&self, damage: u32, source: DamageSource) {
|
||||||
|
unsafe { pokemon_damage(self.inner.reference, damage, source) }
|
||||||
|
}
|
||||||
|
fn heal(&self, amount: u32, allow_revive: bool) -> bool {
|
||||||
|
unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) }
|
||||||
|
}
|
||||||
|
fn set_weight(&self, weight: f32) {
|
||||||
|
unsafe {
|
||||||
|
pokemon_set_weight(self.reference(), weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn clear_status(&self) {
|
||||||
|
unsafe {
|
||||||
|
pokemon_clear_status(self.reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn battle_side(&self) -> BattleSide {
|
||||||
|
Rc::new(
|
||||||
|
self.battle()
|
||||||
|
.unwrap()
|
||||||
|
.sides()
|
||||||
|
.get(self.battle_side_index() as u32)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
|
||||||
|
unsafe {
|
||||||
|
pokemon_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
||||||
|
.val()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
|
||||||
|
unsafe {
|
||||||
|
let ptr = CString::new(script_name).unwrap();
|
||||||
|
pokemon_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
|
||||||
|
.val()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_reference_getters_funcs! {
|
||||||
|
Pokemon,
|
||||||
|
fn species(&self) -> Species;
|
||||||
|
fn form(&self) -> Form;
|
||||||
|
fn active_ability(&self) -> AbilityImpl;
|
||||||
|
fn nature(&self) -> Nature;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_optional_reference_getters_funcs! {
|
||||||
|
Pokemon,
|
||||||
|
fn display_species(&self) -> Option<Species>;
|
||||||
|
fn display_form(&self) -> Option<Form>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 remove_volatile(&self, script: &dyn Script) {
|
||||||
|
unsafe {
|
||||||
|
let name = CString::new(script.get_name()).unwrap();
|
||||||
|
pokemon_remove_volatile(self.inner.reference, name.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
wasm_value_getters_funcs! {
|
||||||
|
Pokemon,
|
||||||
|
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 equals(&self, other: &Pokemon) -> bool {
|
||||||
|
self.inner
|
||||||
|
.reference
|
||||||
|
.get_internal_index()
|
||||||
|
.eq(&other.reference())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl PokemonImpl {
|
||||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
inner: Rc::new(PokemonInner {
|
inner: Rc::new(PokemonInner {
|
||||||
reference,
|
reference,
|
||||||
library: cached_value!({ pokemon_get_library(reference).get_value().unwrap() }),
|
library: cached_value!({ pokemon_get_library(reference).get_value().unwrap() }),
|
||||||
flat_stats: cached_value!({
|
flat_stats: cached_value!({
|
||||||
pokemon_get_flat_stats(reference).get_value().unwrap()
|
Rc::new(pokemon_get_flat_stats(reference).get_value().unwrap())
|
||||||
}),
|
}),
|
||||||
stat_boosts: cached_value!({
|
stat_boosts: cached_value!({
|
||||||
pokemon_get_stat_boosts(reference).get_value().unwrap()
|
pokemon_get_stat_boosts(reference).get_value().unwrap()
|
||||||
}),
|
}),
|
||||||
boosted_stats: cached_value!({
|
boosted_stats: cached_value!({
|
||||||
pokemon_get_boosted_stats(reference).get_value().unwrap()
|
Rc::new(pokemon_get_boosted_stats(reference).get_value().unwrap())
|
||||||
}),
|
}),
|
||||||
individual_values: cached_value!({
|
individual_values: cached_value!({
|
||||||
pokemon_get_individual_values(reference)
|
pokemon_get_individual_values(reference)
|
||||||
|
@ -66,163 +336,7 @@ impl Pokemon {
|
||||||
self.inner.reference
|
self.inner.reference
|
||||||
}
|
}
|
||||||
|
|
||||||
cached_value_getters! {
|
fn get_volatile<T>(&self, script_name: &str) -> Option<&T>
|
||||||
pub fn library(&self) -> DynamicLibrary;
|
|
||||||
pub fn flat_stats(&self) -> StatisticSet<u32>;
|
|
||||||
pub fn stat_boosts(&self) -> ClampedStatisticSet<i8>;
|
|
||||||
pub fn boosted_stats(&self) -> StatisticSet<u32>;
|
|
||||||
pub fn individual_values(&self) -> ClampedStatisticSet<u8>;
|
|
||||||
pub fn effort_values(&self) -> ClampedStatisticSet<u8>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn has_held_item(&self, name: &str) -> bool {
|
|
||||||
let cstr = CString::new(name).unwrap();
|
|
||||||
unsafe { pokemon_has_held_item(self.inner.reference, cstr.as_ptr()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn set_held_item(&self, item: &Item) -> Option<Item> {
|
|
||||||
unsafe { pokemon_set_held_item(self.inner.reference, item.reference()).get_value() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn remove_held_item(&self) -> Option<Item> {
|
|
||||||
unsafe { pokemon_remove_held_item(self.inner.reference).get_value() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn consume_held_item(&self) -> bool {
|
|
||||||
unsafe { pokemon_consume_held_item(self.inner.reference) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn max_health(&self) -> u32 {
|
|
||||||
self.boosted_stats().hp()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn get_type(&self, index: usize) -> u8 {
|
|
||||||
unsafe { pokemon_get_type(self.inner.reference, index) }
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn has_type(&self, type_identifier: TypeIdentifier) -> bool {
|
|
||||||
unsafe { pokemon_has_type(self.inner.reference, type_identifier.into()) }
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn has_type_by_name(&self, type_name: &str) -> bool {
|
|
||||||
let type_identifier = self
|
|
||||||
.library()
|
|
||||||
.data_library()
|
|
||||||
.type_library()
|
|
||||||
.get_type_from_name(type_name);
|
|
||||||
if let Some(type_identifier) = type_identifier {
|
|
||||||
return self.has_type(type_identifier);
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn get_learned_move(&self, index: usize) -> Option<LearnedMove> {
|
|
||||||
unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() }
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn change_stat_boost(
|
|
||||||
&self,
|
|
||||||
stat: Statistic,
|
|
||||||
diff_amount: i8,
|
|
||||||
self_inflicted: bool,
|
|
||||||
) -> bool {
|
|
||||||
unsafe {
|
|
||||||
pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn ability_script(&self) -> Option<&Box<dyn Script>> {
|
|
||||||
unsafe { pokemon_get_ability_script(self.inner.reference).as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn change_species(&self, species: Species, form: Form) {
|
|
||||||
unsafe {
|
|
||||||
pokemon_change_species(self.inner.reference, species.reference(), form.reference());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn change_form(&self, form: Form) {
|
|
||||||
unsafe {
|
|
||||||
pokemon_change_form(self.inner.reference, form.reference());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_fainted(&self) -> bool {
|
|
||||||
self.current_health() == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn damage(&self, damage: u32, source: DamageSource) {
|
|
||||||
unsafe { pokemon_damage(self.inner.reference, damage, source) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn heal(&self, amount: u32, allow_revive: bool) -> bool {
|
|
||||||
unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn set_weight(&self, weight: f32) {
|
|
||||||
unsafe {
|
|
||||||
pokemon_set_weight(self.reference(), weight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn clear_status(&self) {
|
|
||||||
unsafe {
|
|
||||||
pokemon_clear_status(self.reference());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn battle_side(&self) -> BattleSide {
|
|
||||||
self.battle()
|
|
||||||
.unwrap()
|
|
||||||
.sides()
|
|
||||||
.get(self.battle_side_index() as u32)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
|
|
||||||
unsafe {
|
|
||||||
pokemon_add_volatile(self.inner.reference, ScriptPtr::new(script))
|
|
||||||
.val()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
|
|
||||||
unsafe {
|
|
||||||
let ptr = CString::new(script_name).unwrap();
|
|
||||||
pokemon_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
|
|
||||||
.val()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn remove_volatile(&self, script: &dyn Script) {
|
|
||||||
unsafe {
|
|
||||||
let name = CString::new(script.get_name()).unwrap();
|
|
||||||
pokemon_remove_volatile(self.inner.reference, name.as_ptr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn get_volatile<T>(&self, script_name: &str) -> Option<&T>
|
|
||||||
where
|
where
|
||||||
T: Script + 'static,
|
T: Script + 'static,
|
||||||
{
|
{
|
||||||
|
@ -239,26 +353,26 @@ impl Pokemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
wasm_reference_getters! {
|
wasm_reference_getters_extern! {
|
||||||
Pokemon,
|
PokemonImpl, Pokemon,
|
||||||
pub fn species(&self) -> Species;
|
pub fn species(&self) -> Species;
|
||||||
pub fn form(&self) -> Form;
|
pub fn form(&self) -> Form;
|
||||||
pub fn active_ability(&self) -> Ability;
|
pub fn active_ability(&self) -> AbilityImpl;
|
||||||
pub fn nature(&self) -> Nature;
|
pub fn nature(&self) -> Nature;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
wasm_optional_reference_getters! {
|
wasm_optional_reference_getters_extern! {
|
||||||
Pokemon,
|
PokemonImpl, Pokemon,
|
||||||
pub fn display_species(&self) -> Option<Species>;
|
pub fn display_species(&self) -> Option<Species>;
|
||||||
pub fn display_form(&self) -> Option<Form>;
|
pub fn display_form(&self) -> Option<Form>;
|
||||||
pub fn held_item(&self) -> Option<Item>;
|
pub fn held_item(&self) -> Option<ItemImpl>;
|
||||||
pub fn battle(&self) -> Option<Battle>;
|
pub fn battle(&self) -> Option<BattleImpl>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
wasm_value_getters! {
|
wasm_value_getters_extern! {
|
||||||
Pokemon,
|
PokemonImpl, Pokemon,
|
||||||
pub fn level(&self) -> LevelInt;
|
pub fn level(&self) -> LevelInt;
|
||||||
pub fn experience(&self) -> u32;
|
pub fn experience(&self) -> u32;
|
||||||
pub fn unique_identifier(&self) -> u32;
|
pub fn unique_identifier(&self) -> u32;
|
||||||
|
@ -277,7 +391,7 @@ wasm_value_getters! {
|
||||||
pub fn is_usable(&self) -> bool;
|
pub fn is_usable(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Pokemon {
|
impl PartialEq for PokemonImpl {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner.reference == other.inner.reference
|
self.inner.reference == other.inner.reference
|
||||||
}
|
}
|
||||||
|
@ -295,10 +409,10 @@ pub enum DamageSource {
|
||||||
Struggle = 2,
|
Struggle = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(Pokemon);
|
crate::handling::cacheable::cacheable!(PokemonImpl);
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for Pokemon {
|
impl ExternalReferenceType for PokemonImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
|
@ -306,51 +420,46 @@ impl ExternalReferenceType for Pokemon {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn pokemon_get_library(r: ExternRef<Pokemon>) -> ExternRef<DynamicLibrary>;
|
fn pokemon_get_library(r: ExternRef<PokemonImpl>) -> ExternRef<DynamicLibrary>;
|
||||||
fn pokemon_get_flat_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>;
|
fn pokemon_get_flat_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>;
|
||||||
fn pokemon_get_stat_boosts(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<i8>>;
|
fn pokemon_get_stat_boosts(r: ExternRef<PokemonImpl>) -> ExternRef<ClampedStatisticSet<i8>>;
|
||||||
fn pokemon_get_boosted_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>;
|
fn pokemon_get_boosted_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>;
|
||||||
fn pokemon_get_individual_values(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<u8>>;
|
fn pokemon_get_individual_values(
|
||||||
fn pokemon_get_effort_values(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<u8>>;
|
r: ExternRef<PokemonImpl>,
|
||||||
fn pokemon_has_held_item(r: ExternRef<Pokemon>, name: *const c_char) -> bool;
|
) -> ExternRef<ClampedStatisticSet<u8>>;
|
||||||
fn pokemon_set_held_item(r: ExternRef<Pokemon>, item: ExternRef<Item>) -> ExternRef<Item>;
|
fn pokemon_get_effort_values(r: ExternRef<PokemonImpl>) -> ExternRef<ClampedStatisticSet<u8>>;
|
||||||
fn pokemon_remove_held_item(r: ExternRef<Pokemon>) -> ExternRef<Item>;
|
fn pokemon_has_held_item(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool;
|
||||||
fn pokemon_consume_held_item(r: ExternRef<Pokemon>) -> bool;
|
fn pokemon_set_held_item(
|
||||||
fn pokemon_get_type(r: ExternRef<Pokemon>, index: usize) -> u8;
|
r: ExternRef<PokemonImpl>,
|
||||||
fn pokemon_has_type(r: ExternRef<Pokemon>, identifier: u8) -> bool;
|
item: ExternRef<ItemImpl>,
|
||||||
fn pokemon_get_learned_move(r: ExternRef<Pokemon>, index: usize) -> ExternRef<LearnedMove>;
|
) -> 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;
|
||||||
|
fn pokemon_get_learned_move(r: ExternRef<PokemonImpl>, index: usize) -> ExternRef<LearnedMove>;
|
||||||
fn pokemon_change_stat_boost(
|
fn pokemon_change_stat_boost(
|
||||||
r: ExternRef<Pokemon>,
|
r: ExternRef<PokemonImpl>,
|
||||||
tat: Statistic,
|
tat: Statistic,
|
||||||
diff_amount: i8,
|
diff_amount: i8,
|
||||||
self_inflicted: bool,
|
self_inflicted: bool,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn pokemon_get_ability_script(r: ExternRef<Pokemon>) -> *const Box<dyn Script>;
|
fn pokemon_get_ability_script(r: ExternRef<PokemonImpl>) -> *const Box<dyn Script>;
|
||||||
fn pokemon_change_species(
|
fn pokemon_change_species(
|
||||||
r: ExternRef<Pokemon>,
|
r: ExternRef<PokemonImpl>,
|
||||||
species: ExternRef<Species>,
|
species: ExternRef<Species>,
|
||||||
form: ExternRef<Form>,
|
form: ExternRef<Form>,
|
||||||
);
|
);
|
||||||
fn pokemon_change_form(r: ExternRef<Pokemon>, form: ExternRef<Form>);
|
fn pokemon_change_form(r: ExternRef<PokemonImpl>, form: ExternRef<Form>);
|
||||||
fn pokemon_damage(r: ExternRef<Pokemon>, damage: u32, source: DamageSource);
|
fn pokemon_damage(r: ExternRef<PokemonImpl>, damage: u32, source: DamageSource);
|
||||||
fn pokemon_heal(r: ExternRef<Pokemon>, amount: u32, allow_revive: bool) -> bool;
|
fn pokemon_heal(r: ExternRef<PokemonImpl>, amount: u32, allow_revive: bool) -> bool;
|
||||||
fn pokemon_set_weight(r: ExternRef<Pokemon>, weight: f32);
|
fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32);
|
||||||
fn pokemon_clear_status(r: ExternRef<Pokemon>);
|
fn pokemon_clear_status(r: ExternRef<PokemonImpl>);
|
||||||
|
|
||||||
fn pokemon_add_volatile_by_name(r: ExternRef<Pokemon>, name: *const c_char) -> ScriptPtr;
|
fn pokemon_add_volatile_by_name(r: ExternRef<PokemonImpl>, name: *const c_char) -> ScriptPtr;
|
||||||
fn pokemon_add_volatile(r: ExternRef<Pokemon>, script: ScriptPtr) -> ScriptPtr;
|
fn pokemon_add_volatile(r: ExternRef<PokemonImpl>, script: ScriptPtr) -> ScriptPtr;
|
||||||
fn pokemon_has_volatile(r: ExternRef<Pokemon>, name: *const c_char) -> bool;
|
fn pokemon_has_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool;
|
||||||
fn pokemon_remove_volatile(r: ExternRef<Pokemon>, name: *const c_char);
|
fn pokemon_remove_volatile(r: ExternRef<PokemonImpl>, name: *const c_char);
|
||||||
fn pokemon_get_volatile(r: ExternRef<Pokemon>, name: *const c_char) -> ScriptPtr;
|
fn pokemon_get_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> ScriptPtr;
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "mock_data")]
|
|
||||||
impl Pokemon {
|
|
||||||
pub fn current_health(&self) -> u32 {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
pub fn species(&self) -> Species {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,57 @@
|
||||||
use crate::app_interface::Statistic;
|
use crate::app_interface::Statistic;
|
||||||
use crate::{ExternRef, ExternalReferenceType};
|
use crate::{ExternRef, ExternalReferenceType};
|
||||||
|
use alloc::rc::Rc;
|
||||||
use core::convert::{TryFrom, TryInto};
|
use core::convert::{TryFrom, TryInto};
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub trait StatisticSetTrait<T>
|
||||||
pub struct StatisticSet<T>
|
|
||||||
where
|
where
|
||||||
T: TryFrom<i64>,
|
T: TryFrom<i64>,
|
||||||
T: TryInto<i64>,
|
T: TryInto<i64>,
|
||||||
|
<T as TryFrom<i64>>::Error: Debug,
|
||||||
|
<T as TryInto<i64>>::Error: Debug,
|
||||||
|
{
|
||||||
|
fn hp(&self) -> T {
|
||||||
|
self.get_stat(Statistic::Attack)
|
||||||
|
}
|
||||||
|
fn attack(&self) -> T {
|
||||||
|
self.get_stat(Statistic::Attack)
|
||||||
|
}
|
||||||
|
fn defense(&self) -> T {
|
||||||
|
self.get_stat(Statistic::Defense)
|
||||||
|
}
|
||||||
|
fn special_attack(&self) -> T {
|
||||||
|
self.get_stat(Statistic::SpecialAttack)
|
||||||
|
}
|
||||||
|
fn special_defense(&self) -> T {
|
||||||
|
self.get_stat(Statistic::SpecialDefense)
|
||||||
|
}
|
||||||
|
fn speed(&self) -> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type StatisticSet<T> = Rc<dyn StatisticSetTrait<T>>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct StatisticSetImpl<T>
|
||||||
|
where
|
||||||
|
T: TryFrom<i64>,
|
||||||
|
T: TryInto<i64>,
|
||||||
|
<T as TryFrom<i64>>::Error: Debug,
|
||||||
|
<T as TryInto<i64>>::Error: Debug,
|
||||||
{
|
{
|
||||||
reference: ExternRef<Self>,
|
reference: ExternRef<Self>,
|
||||||
_p: PhantomData<T>,
|
_p: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> StatisticSet<T>
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl<T> StatisticSetImpl<T>
|
||||||
where
|
where
|
||||||
T: TryFrom<i64>,
|
T: TryFrom<i64>,
|
||||||
T: TryInto<i64>,
|
T: TryInto<i64>,
|
||||||
|
@ -27,61 +64,40 @@ where
|
||||||
_p: Default::default(),
|
_p: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn hp(&self) -> T {
|
impl<T> StatisticSetTrait<T> for StatisticSetImpl<T>
|
||||||
self.get_stat(Statistic::HP)
|
where
|
||||||
}
|
T: TryFrom<i64>,
|
||||||
#[cfg(not(feature = "mock_data"))]
|
T: TryInto<i64>,
|
||||||
pub fn attack(&self) -> T {
|
<T as TryFrom<i64>>::Error: Debug,
|
||||||
self.get_stat(Statistic::Attack)
|
<T as TryInto<i64>>::Error: Debug,
|
||||||
}
|
{
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn get_stat(&self, stat: Statistic) -> T {
|
||||||
pub fn defense(&self) -> T {
|
|
||||||
self.get_stat(Statistic::Defense)
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn special_attack(&self) -> T {
|
|
||||||
self.get_stat(Statistic::SpecialAttack)
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn special_defense(&self) -> T {
|
|
||||||
self.get_stat(Statistic::SpecialDefense)
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn speed(&self) -> T {
|
|
||||||
self.get_stat(Statistic::Speed)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn get_stat(&self, stat: Statistic) -> T {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
statistic_set_get(self.reference.cast(), stat)
|
statistic_set_get(self.reference.cast(), stat)
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn set_stat(&self, stat: Statistic, value: T) {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn set_stat(&self, stat: Statistic, value: T) {
|
|
||||||
unsafe { statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) }
|
unsafe { statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) }
|
||||||
}
|
}
|
||||||
|
fn increase_stat(&self, stat: Statistic, value: T) {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn increase_stat(&self, stat: Statistic, value: T) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
statistic_set_increase_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
statistic_set_increase_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn decrease_stat(&self, stat: Statistic, value: T) {
|
||||||
pub fn decrease_stat(&self, stat: Statistic, value: T) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
statistic_set_decrease_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
statistic_set_decrease_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ExternalReferenceType for StatisticSet<T>
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl<T> ExternalReferenceType for StatisticSetImpl<T>
|
||||||
where
|
where
|
||||||
T: TryFrom<i64>,
|
T: TryFrom<i64>,
|
||||||
T: TryInto<i64>,
|
T: TryInto<i64>,
|
||||||
|
@ -89,7 +105,7 @@ where
|
||||||
<T as TryInto<i64>>::Error: Debug,
|
<T as TryInto<i64>>::Error: Debug,
|
||||||
{
|
{
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
StatisticSet::<T>::new(reference)
|
StatisticSetImpl::<T>::new(reference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +114,8 @@ pub struct ClampedStatisticSet<T>
|
||||||
where
|
where
|
||||||
T: TryFrom<i64>,
|
T: TryFrom<i64>,
|
||||||
T: TryInto<i64>,
|
T: TryInto<i64>,
|
||||||
|
<T as TryFrom<i64>>::Error: Debug,
|
||||||
|
<T as TryInto<i64>>::Error: Debug,
|
||||||
{
|
{
|
||||||
reference: ExternRef<Self>,
|
reference: ExternRef<Self>,
|
||||||
_p: PhantomData<T>,
|
_p: PhantomData<T>,
|
||||||
|
@ -192,10 +210,18 @@ where
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn statistic_set_get(r: ExternRef<StatisticSet<i64>>, stat: Statistic) -> i64;
|
fn statistic_set_get(r: ExternRef<StatisticSetImpl<i64>>, stat: Statistic) -> i64;
|
||||||
fn statistic_set_set(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);
|
fn statistic_set_set(r: ExternRef<StatisticSetImpl<i64>>, stat: Statistic, value: i64);
|
||||||
fn statistic_set_increase_stat(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);
|
fn statistic_set_increase_stat(
|
||||||
fn statistic_set_decrease_stat(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);
|
r: ExternRef<StatisticSetImpl<i64>>,
|
||||||
|
stat: Statistic,
|
||||||
|
value: i64,
|
||||||
|
);
|
||||||
|
fn statistic_set_decrease_stat(
|
||||||
|
r: ExternRef<StatisticSetImpl<i64>>,
|
||||||
|
stat: Statistic,
|
||||||
|
value: i64,
|
||||||
|
);
|
||||||
|
|
||||||
fn clamped_statistic_set_get(r: ExternRef<ClampedStatisticSet<i64>>, stat: Statistic) -> i64;
|
fn clamped_statistic_set_get(r: ExternRef<ClampedStatisticSet<i64>>, stat: Statistic) -> i64;
|
||||||
fn clamped_statistic_set_set(
|
fn clamped_statistic_set_set(
|
||||||
|
|
|
@ -1,17 +1,46 @@
|
||||||
use crate::app_interface::{LearnedMove, Pokemon};
|
use crate::app_interface::{LearnedMove, Pokemon, PokemonImpl};
|
||||||
use crate::handling::cached_value::CachedValue;
|
use crate::handling::cached_value::CachedValue;
|
||||||
use crate::handling::temporary::Temporary;
|
use crate::handling::temporary::Temporary;
|
||||||
use crate::ExternRef;
|
use crate::ExternRef;
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
use crate::{cached_value, ExternalReferenceType, Script};
|
use crate::{cached_value, ExternalReferenceType, Script};
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
struct BaseTurnChoiceData {
|
pub trait BaseTurnChoiceDataTrait {
|
||||||
reference: ExternRef<TurnChoice>,
|
fn reference(&self) -> u32;
|
||||||
user: CachedValue<Pokemon>,
|
fn user(&self) -> Pokemon;
|
||||||
|
fn speed(&self) -> u32;
|
||||||
|
fn has_failed(&self) -> bool;
|
||||||
|
fn fail(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BaseTurnChoiceDataImpl {
|
||||||
|
reference: ExternRef<TurnChoice>,
|
||||||
|
user: CachedValue<Rc<PokemonImpl>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl BaseTurnChoiceDataTrait for BaseTurnChoiceDataImpl {
|
||||||
|
fn reference(&self) -> u32 {
|
||||||
|
self.reference.get_internal_index()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user(&self) -> Pokemon {
|
||||||
|
self.user.value()
|
||||||
|
}
|
||||||
|
fn speed(&self) -> u32 {
|
||||||
|
unsafe { turn_choice_get_speed(self.reference) }
|
||||||
|
}
|
||||||
|
fn has_failed(&self) -> bool {
|
||||||
|
unsafe { turn_choice_has_failed(self.reference) }
|
||||||
|
}
|
||||||
|
fn fail(&self) {
|
||||||
|
unsafe { turn_choice_fail(self.reference) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BaseTurnChoiceData = Rc<dyn BaseTurnChoiceDataTrait>;
|
||||||
|
|
||||||
struct MoveTurnChoiceDataInner {
|
struct MoveTurnChoiceDataInner {
|
||||||
base: BaseTurnChoiceData,
|
base: BaseTurnChoiceData,
|
||||||
used_move: CachedValue<LearnedMove>,
|
used_move: CachedValue<LearnedMove>,
|
||||||
|
@ -19,13 +48,22 @@ struct MoveTurnChoiceDataInner {
|
||||||
target_index: CachedValue<u8>,
|
target_index: CachedValue<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait MoveTurnChoiceDataTrait {
|
||||||
|
fn base(&self) -> BaseTurnChoiceData;
|
||||||
|
fn used_move(&self) -> LearnedMove;
|
||||||
|
fn target_side(&self) -> u8;
|
||||||
|
fn target_index(&self) -> u8;
|
||||||
|
fn priority(&self) -> i8;
|
||||||
|
fn move_script(&self) -> Option<&Box<dyn Script>>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MoveTurnChoiceData {
|
pub struct MoveTurnChoiceDataImpl {
|
||||||
inner: Temporary<MoveTurnChoiceDataInner>,
|
inner: Temporary<MoveTurnChoiceDataInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TurnChoice {
|
pub enum TurnChoice {
|
||||||
Move(MoveTurnChoiceData),
|
Move(Box<dyn MoveTurnChoiceDataTrait>),
|
||||||
Item(),
|
Item(),
|
||||||
Switch(),
|
Switch(),
|
||||||
Flee,
|
Flee,
|
||||||
|
@ -33,9 +71,9 @@ pub enum TurnChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TurnChoice {
|
impl TurnChoice {
|
||||||
fn base(&self) -> &BaseTurnChoiceData {
|
fn base(&self) -> BaseTurnChoiceData {
|
||||||
match self {
|
match self {
|
||||||
TurnChoice::Move(d) => &d.inner.value_ref().base,
|
TurnChoice::Move(m) => m.base(),
|
||||||
TurnChoice::Item() => unimplemented!(),
|
TurnChoice::Item() => unimplemented!(),
|
||||||
TurnChoice::Switch() => unimplemented!(),
|
TurnChoice::Switch() => unimplemented!(),
|
||||||
TurnChoice::Flee => unimplemented!(),
|
TurnChoice::Flee => unimplemented!(),
|
||||||
|
@ -44,43 +82,39 @@ impl TurnChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user(&self) -> Pokemon {
|
pub fn user(&self) -> Pokemon {
|
||||||
self.base().user.value()
|
self.base().user()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn speed(&self) -> u32 {
|
pub fn speed(&self) -> u32 {
|
||||||
unsafe { turn_choice_get_speed(self.base().reference) }
|
self.base().speed()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn has_failed(&self) -> bool {
|
pub fn has_failed(&self) -> bool {
|
||||||
unsafe { turn_choice_has_failed(self.base().reference) }
|
self.base().has_failed()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn fail(&self) {
|
pub fn fail(&self) {
|
||||||
unsafe { turn_choice_fail(self.base().reference) }
|
self.base().fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MoveTurnChoiceData {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn used_move(&self) -> LearnedMove {
|
impl MoveTurnChoiceDataTrait for MoveTurnChoiceDataImpl {
|
||||||
self.inner.value().used_move.value()
|
fn base(&self) -> BaseTurnChoiceData {
|
||||||
}
|
self.inner.value().base.clone()
|
||||||
pub fn target_side(&self) -> u8 {
|
|
||||||
self.inner.value().target_side.value()
|
|
||||||
}
|
|
||||||
pub fn target_index(&self) -> u8 {
|
|
||||||
self.inner.value().target_index.value()
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn priority(&self) -> i8 {
|
|
||||||
unsafe { turn_choice_move_priority(self.inner.value().base.reference.cast()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn used_move(&self) -> LearnedMove {
|
||||||
pub fn move_script(&self) -> Option<&Box<dyn Script>> {
|
self.inner.value().used_move.value()
|
||||||
unsafe { turn_choice_move_script(self.inner.value().base.reference.cast()).as_ref() }
|
}
|
||||||
|
fn target_side(&self) -> u8 {
|
||||||
|
self.inner.value().target_side.value()
|
||||||
|
}
|
||||||
|
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 move_script(&self) -> Option<&Box<dyn Script>> {
|
||||||
|
unsafe { turn_choice_move_script(self.base().reference().into()).as_ref() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +123,12 @@ impl ExternalReferenceType for TurnChoice {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
let kind = unsafe { turn_choice_get_kind(reference) };
|
let kind = unsafe { turn_choice_get_kind(reference) };
|
||||||
match kind {
|
match kind {
|
||||||
0 => TurnChoice::Move(MoveTurnChoiceData {
|
0 => TurnChoice::Move(Box::new(MoveTurnChoiceDataImpl {
|
||||||
inner: Temporary::new(
|
inner: Temporary::new(
|
||||||
reference.get_internal_index(),
|
reference.get_internal_index(),
|
||||||
MoveTurnChoiceDataInner::from_reference(reference.cast()),
|
MoveTurnChoiceDataInner::from_reference(reference.cast()),
|
||||||
),
|
),
|
||||||
}),
|
})),
|
||||||
_ => panic!("Unknown turn choice type"),
|
_ => panic!("Unknown turn choice type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,14 +136,14 @@ impl ExternalReferenceType for TurnChoice {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl MoveTurnChoiceDataInner {
|
impl MoveTurnChoiceDataInner {
|
||||||
fn from_reference(reference: ExternRef<MoveTurnChoiceData>) -> Self {
|
fn from_reference(reference: ExternRef<MoveTurnChoiceDataImpl>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base: BaseTurnChoiceData {
|
base: Rc::new(BaseTurnChoiceDataImpl {
|
||||||
reference: reference.cast(),
|
reference: reference.cast(),
|
||||||
user: cached_value!({
|
user: cached_value!({
|
||||||
turn_choice_get_user(reference.cast()).get_value().unwrap()
|
Rc::new(turn_choice_get_user(reference.cast()).get_value().unwrap())
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
},
|
|
||||||
used_move: cached_value!({
|
used_move: cached_value!({
|
||||||
turn_choice_move_used_move(reference.cast())
|
turn_choice_move_used_move(reference.cast())
|
||||||
.get_value()
|
.get_value()
|
||||||
|
@ -124,15 +158,15 @@ impl MoveTurnChoiceDataInner {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8;
|
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8;
|
||||||
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<Pokemon>;
|
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<PokemonImpl>;
|
||||||
fn turn_choice_get_speed(r: ExternRef<TurnChoice>) -> u32;
|
fn turn_choice_get_speed(r: ExternRef<TurnChoice>) -> u32;
|
||||||
fn turn_choice_has_failed(r: ExternRef<TurnChoice>) -> bool;
|
fn turn_choice_has_failed(r: ExternRef<TurnChoice>) -> bool;
|
||||||
fn turn_choice_fail(r: ExternRef<TurnChoice>);
|
fn turn_choice_fail(r: ExternRef<TurnChoice>);
|
||||||
|
|
||||||
fn turn_choice_move_used_move(r: ExternRef<MoveTurnChoiceData>) -> ExternRef<LearnedMove>;
|
fn turn_choice_move_used_move(r: ExternRef<MoveTurnChoiceDataImpl>) -> ExternRef<LearnedMove>;
|
||||||
fn turn_choice_move_target_side(r: ExternRef<MoveTurnChoiceData>) -> u8;
|
fn turn_choice_move_target_side(r: ExternRef<MoveTurnChoiceDataImpl>) -> u8;
|
||||||
fn turn_choice_move_target_index(r: ExternRef<MoveTurnChoiceData>) -> u8;
|
fn turn_choice_move_target_index(r: ExternRef<MoveTurnChoiceDataImpl>) -> u8;
|
||||||
fn turn_choice_move_priority(r: ExternRef<MoveTurnChoiceData>) -> i8;
|
fn turn_choice_move_priority(r: ExternRef<MoveTurnChoiceDataImpl>) -> i8;
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceData>) -> *const Box<dyn Script>;
|
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceDataImpl>) -> *const Box<dyn Script>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
use crate::handling::Script;
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
|
pub trait WithVolatile {
|
||||||
|
fn has_volatile(&self, script_name: &str) -> bool;
|
||||||
|
fn add_volatile<'a, 'b>(&'a self, script: Box<dyn Script>) -> &'b dyn Script;
|
||||||
|
fn remove_volatile(&self, script: &dyn Script);
|
||||||
|
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_volatile_as<'a, T>(v: &'a dyn WithVolatile, script_name: &str) -> Option<&'a T>
|
||||||
|
where
|
||||||
|
T: Script + 'static,
|
||||||
|
{
|
||||||
|
let s = v.get_volatile_script(script_name);
|
||||||
|
if let Some(s) = s {
|
||||||
|
Some(s.as_any().downcast_ref::<T>().unwrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,18 +7,24 @@ use crate::{
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
|
|
||||||
struct AbilityInner {
|
struct AbilityInner {
|
||||||
reference: ExternRef<Ability>,
|
reference: ExternRef<AbilityImpl>,
|
||||||
name: CachedValue<StringKey>,
|
name: CachedValue<StringKey>,
|
||||||
effect: CachedValue<StringKey>,
|
effect: CachedValue<StringKey>,
|
||||||
parameters: CachedValue<ImmutableList<EffectParameter>>,
|
parameters: CachedValue<ImmutableList<EffectParameter>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(test, mockall::automock)]
|
||||||
|
pub trait Ability {
|
||||||
|
fn name(&self) -> StringKey;
|
||||||
|
fn effect(&self) -> StringKey;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Ability {
|
pub struct AbilityImpl {
|
||||||
inner: Rc<AbilityInner>,
|
inner: Rc<AbilityInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ability {
|
impl AbilityImpl {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub fn new(reference: ExternRef<Self>) -> Self {
|
pub fn new(reference: ExternRef<Self>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
|
@ -32,21 +38,23 @@ impl Ability {
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ability for AbilityImpl {
|
||||||
cached_value_getters! {
|
cached_value_getters! {
|
||||||
pub fn name(&self) -> StringKey;
|
fn name(&self) -> StringKey;
|
||||||
pub fn effect(&self) -> StringKey;
|
fn effect(&self) -> StringKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for Ability {
|
impl ExternalReferenceType for AbilityImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(Ability);
|
crate::handling::cacheable::cacheable!(AbilityImpl);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -57,7 +65,7 @@ pub struct AbilityIndex {
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn ability_get_name(r: ExternRef<Ability>) -> ExternRef<StringKey>;
|
fn ability_get_name(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
||||||
fn ability_get_effect(r: ExternRef<Ability>) -> ExternRef<StringKey>;
|
fn ability_get_effect(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
||||||
fn ability_get_parameters(r: ExternRef<Ability>) -> VecExternRef<EffectParameter>;
|
fn ability_get_parameters(r: ExternRef<AbilityImpl>) -> VecExternRef<EffectParameter>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::app_interface::{DataLibrary, Item};
|
use crate::app_interface::{DataLibrary, Item, ItemImpl};
|
||||||
use crate::{ExternRef, ExternalReferenceType, StringKey};
|
use crate::{ExternRef, ExternalReferenceType, StringKey};
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use spin::rwlock::RwLock;
|
use spin::rwlock::RwLock;
|
||||||
|
|
||||||
struct ItemLibraryInner {
|
struct ItemLibraryInner {
|
||||||
ptr: ExternRef<ItemLibrary>,
|
ptr: ExternRef<ItemLibrary>,
|
||||||
cache: RwLock<hashbrown::HashMap<u32, Item>>,
|
cache: RwLock<hashbrown::HashMap<u32, ItemImpl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -25,8 +25,8 @@ impl ItemLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<Item> for ItemLibrary {
|
impl DataLibrary<ItemImpl> for ItemLibrary {
|
||||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Item>> {
|
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, ItemImpl>> {
|
||||||
&self.inner.cache
|
&self.inner.cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,12 +35,12 @@ impl DataLibrary<Item> for ItemLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<Item> {
|
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<ItemImpl> {
|
||||||
unsafe { item_library_get_item(ptr, name) }
|
unsafe { item_library_get_item(ptr, name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<Item> {
|
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<ItemImpl> {
|
||||||
unsafe { item_library_get_item_by_hash(ptr, hash) }
|
unsafe { item_library_get_item_by_hash(ptr, hash) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,9 @@ extern "wasm" {
|
||||||
fn item_library_get_item(
|
fn item_library_get_item(
|
||||||
ptr: ExternRef<ItemLibrary>,
|
ptr: ExternRef<ItemLibrary>,
|
||||||
name: ExternRef<StringKey>,
|
name: ExternRef<StringKey>,
|
||||||
) -> ExternRef<Item>;
|
) -> ExternRef<ItemImpl>;
|
||||||
fn item_library_get_item_by_hash(ptr: ExternRef<ItemLibrary>, hash: u32) -> ExternRef<Item>;
|
fn item_library_get_item_by_hash(ptr: ExternRef<ItemLibrary>, hash: u32)
|
||||||
|
-> ExternRef<ItemImpl>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mock_data")]
|
#[cfg(feature = "mock_data")]
|
||||||
|
|
|
@ -41,8 +41,26 @@ pub enum BattleItemCategory {
|
||||||
MiscBattleItem,
|
MiscBattleItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
||||||
|
pub trait ItemTrait {
|
||||||
|
fn reference(&self) -> u32;
|
||||||
|
/// The name of the item.
|
||||||
|
fn name(&self) -> StringKey;
|
||||||
|
/// Which bag slot items are stored in.
|
||||||
|
fn category(&self) -> ItemCategory;
|
||||||
|
/// How the item is categorized when in battle.
|
||||||
|
fn battle_category(&self) -> BattleItemCategory;
|
||||||
|
/// The buying value of the item.
|
||||||
|
fn price(&self) -> i32;
|
||||||
|
fn has_flag(&self, flag: &StringKey) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Item = Rc<dyn ItemTrait>;
|
||||||
|
#[cfg(feature = "mock_data")]
|
||||||
|
pub type MockItem = MockItemTrait;
|
||||||
|
|
||||||
struct ItemInner {
|
struct ItemInner {
|
||||||
reference: ExternRef<Item>,
|
reference: ExternRef<ItemImpl>,
|
||||||
name: CachedValue<StringKey>,
|
name: CachedValue<StringKey>,
|
||||||
category: CachedValue<ItemCategory>,
|
category: CachedValue<ItemCategory>,
|
||||||
battle_category: CachedValue<BattleItemCategory>,
|
battle_category: CachedValue<BattleItemCategory>,
|
||||||
|
@ -51,12 +69,12 @@ struct ItemInner {
|
||||||
|
|
||||||
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Item {
|
pub struct ItemImpl {
|
||||||
inner: Rc<ItemInner>,
|
inner: Rc<ItemInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl ItemImpl {
|
||||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
inner: Rc::new(ItemInner {
|
inner: Rc::new(ItemInner {
|
||||||
|
@ -69,69 +87,47 @@ impl Item {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub(crate) fn reference(&self) -> ExternRef<Self> {
|
pub(crate) fn reference(&self) -> ExternRef<Self> {
|
||||||
self.inner.reference
|
self.inner.reference
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ItemTrait for ItemImpl {
|
||||||
|
fn reference(&self) -> u32 {
|
||||||
|
self.inner.reference.get_internal_index()
|
||||||
|
}
|
||||||
|
|
||||||
cached_value_getters! {
|
cached_value_getters! {
|
||||||
/// The name of the item.
|
/// The name of the item.
|
||||||
pub fn name(&self) -> StringKey;
|
fn name(&self) -> StringKey;
|
||||||
/// Which bag slot items are stored in.
|
/// Which bag slot items are stored in.
|
||||||
pub fn category(&self) -> ItemCategory;
|
fn category(&self) -> ItemCategory;
|
||||||
/// How the item is categorized when in battle.
|
/// How the item is categorized when in battle.
|
||||||
pub fn battle_category(&self) -> BattleItemCategory;
|
fn battle_category(&self) -> BattleItemCategory;
|
||||||
/// The buying value of the item.
|
/// The buying value of the item.
|
||||||
pub fn price(&self) -> i32;
|
fn price(&self) -> i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn has_flag(&self, flag: &StringKey) -> bool {
|
||||||
pub fn has_flag(&self, flag: &StringKey) -> bool {
|
|
||||||
unsafe { item_has_flag(self.inner.reference, flag.ptr()) }
|
unsafe { item_has_flag(self.inner.reference, flag.ptr()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(Item);
|
crate::handling::cacheable::cacheable!(ItemImpl);
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for Item {
|
impl ExternalReferenceType for ItemImpl {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Item::new(reference)
|
ItemImpl::new(reference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
extern "wasm" {
|
||||||
fn item_get_name(ptr: ExternRef<Item>) -> ExternRef<StringKey>;
|
fn item_get_name(ptr: ExternRef<ItemImpl>) -> ExternRef<StringKey>;
|
||||||
fn item_get_category(ptr: ExternRef<Item>) -> ItemCategory;
|
fn item_get_category(ptr: ExternRef<ItemImpl>) -> ItemCategory;
|
||||||
fn item_get_battle_category(ptr: ExternRef<Item>) -> BattleItemCategory;
|
fn item_get_battle_category(ptr: ExternRef<ItemImpl>) -> BattleItemCategory;
|
||||||
fn item_get_price(ptr: ExternRef<Item>) -> i32;
|
fn item_get_price(ptr: ExternRef<ItemImpl>) -> i32;
|
||||||
fn item_has_flag(ptr: ExternRef<Item>, flag: ExternRef<StringKey>) -> bool;
|
fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> bool;
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "mock_data")]
|
|
||||||
mod test {
|
|
||||||
use super::Item;
|
|
||||||
use super::ItemInner;
|
|
||||||
use crate::app_interface::{BattleItemCategory, ItemCategory};
|
|
||||||
use crate::{cached_value, ExternRef, StringKey};
|
|
||||||
use alloc::rc::Rc;
|
|
||||||
|
|
||||||
impl Item {
|
|
||||||
pub fn mock() -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Rc::new(ItemInner {
|
|
||||||
reference: ExternRef::mock(),
|
|
||||||
name: StringKey::new("test").into(),
|
|
||||||
category: ItemCategory::MiscItem.into(),
|
|
||||||
battle_category: BattleItemCategory::None.into(),
|
|
||||||
price: 0.into(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_flag(&self) -> bool {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub mod move_data;
|
||||||
mod nature;
|
mod nature;
|
||||||
pub mod species;
|
pub mod species;
|
||||||
|
|
||||||
|
pub use ability::*;
|
||||||
pub use data_libraries::*;
|
pub use data_libraries::*;
|
||||||
pub use effect_parameter::EffectParameter;
|
pub use effect_parameter::EffectParameter;
|
||||||
pub use item::*;
|
pub use item::*;
|
||||||
|
|
|
@ -166,7 +166,7 @@ mod test {
|
||||||
|
|
||||||
impl StringKey {
|
impl StringKey {
|
||||||
pub fn new(s: &str) -> Self {
|
pub fn new(s: &str) -> Self {
|
||||||
let hash = get_hash(s.as_bytes());
|
let hash = get_hash(s);
|
||||||
Self {
|
Self {
|
||||||
data: Rc::new(StringKeyInner {
|
data: Rc::new(StringKeyInner {
|
||||||
ptr: ExternRef::mock(),
|
ptr: ExternRef::mock(),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::ImmutableList;
|
use crate::app_interface::list::ImmutableList;
|
||||||
|
use alloc::rc::Rc;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
use core::intrinsics::transmute;
|
use core::intrinsics::transmute;
|
||||||
|
@ -29,6 +30,16 @@ impl<T> ExternRef<T> {
|
||||||
T::instantiate_from_extern_value(*self)
|
T::instantiate_from_extern_value(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn get_value_rc(&self) -> Option<Rc<T>>
|
||||||
|
where
|
||||||
|
T: ExternalReferenceType,
|
||||||
|
T: Sized,
|
||||||
|
T:,
|
||||||
|
{
|
||||||
|
T::instantiate_from_extern_value_rc(*self)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn not_null(&self) -> T
|
pub fn not_null(&self) -> T
|
||||||
where
|
where
|
||||||
|
@ -39,6 +50,16 @@ impl<T> ExternRef<T> {
|
||||||
T::instantiate_from_extern_value(*self).unwrap()
|
T::instantiate_from_extern_value(*self).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn not_null_rc(&self) -> Rc<T>
|
||||||
|
where
|
||||||
|
T: ExternalReferenceType,
|
||||||
|
T: Sized,
|
||||||
|
T:,
|
||||||
|
{
|
||||||
|
Rc::new(T::instantiate_from_extern_value(*self).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn cast<TCast>(&self) -> ExternRef<TCast> {
|
pub(crate) fn cast<TCast>(&self) -> ExternRef<TCast> {
|
||||||
ExternRef::<TCast> {
|
ExternRef::<TCast> {
|
||||||
|
@ -93,6 +114,15 @@ impl<T> Hash for ExternRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> From<u32> for ExternRef<T> {
|
||||||
|
fn from(value: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
p: value,
|
||||||
|
resource_type: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct VecExternRef<T> {
|
pub struct VecExternRef<T> {
|
||||||
v: u64,
|
v: u64,
|
||||||
|
@ -179,6 +209,17 @@ pub trait ExternalReferenceType {
|
||||||
Some(Self::from_extern_value(reference))
|
Some(Self::from_extern_value(reference))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn instantiate_from_extern_value_rc(reference: ExternRef<Self>) -> Option<Rc<Self>>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
if reference.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Rc::new(Self::from_extern_value(reference)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
|
@ -23,6 +23,48 @@ pub enum ScriptCategory {
|
||||||
ItemBattleTrigger,
|
ItemBattleTrigger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wasm_reference_getters_extern {
|
||||||
|
(
|
||||||
|
$base_type:ty, $type_name:ident,
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$v:vis fn $name:ident(&self) -> $type:ty;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
extern "wasm" {
|
||||||
|
$(
|
||||||
|
paste::paste!{
|
||||||
|
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> ExternRef<$type>;
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wasm_reference_getters_funcs {
|
||||||
|
(
|
||||||
|
$base_type:ty,
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$v:vis fn $name:ident(&self) -> $type:ty;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
$v fn $name(&self) -> $type {
|
||||||
|
paste::paste!{
|
||||||
|
unsafe{
|
||||||
|
[<$base_type:snake _get_ $name>](self.inner.reference).get_value().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! wasm_reference_getters {
|
macro_rules! wasm_reference_getters {
|
||||||
(
|
(
|
||||||
|
@ -91,6 +133,48 @@ extern "wasm" {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wasm_optional_reference_getters_extern {
|
||||||
|
(
|
||||||
|
$base_type:ty, $type_name:ident,
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$v:vis fn $name:ident(&self) -> Option<$type:ty>;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
extern "wasm" {
|
||||||
|
$(
|
||||||
|
paste::paste!{
|
||||||
|
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> ExternRef<$type>;
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wasm_optional_reference_getters_funcs {
|
||||||
|
(
|
||||||
|
$base_type:ty,
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$v:vis fn $name:ident(&self) -> Option<$type:ty>;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
$v fn $name(&self) -> Option<$type> {
|
||||||
|
paste::paste!{
|
||||||
|
unsafe{
|
||||||
|
[<$base_type:snake _get_ $name>](self.inner.reference).get_value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! wasm_value_getters {
|
macro_rules! wasm_value_getters {
|
||||||
(
|
(
|
||||||
|
@ -125,3 +209,45 @@ extern "wasm" {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wasm_value_getters_extern {
|
||||||
|
(
|
||||||
|
$base_type:ty, $type_name:ident,
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$v:vis fn $name:ident(&self) -> $type:ty;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
extern "wasm" {
|
||||||
|
$(
|
||||||
|
paste::paste!{
|
||||||
|
fn [<$type_name:snake _get_ $name>](r: ExternRef<$base_type>) -> $type;
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! wasm_value_getters_funcs {
|
||||||
|
(
|
||||||
|
$base_type:ty,
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$v:vis fn $name:ident(&self) -> $type:ty;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
$v fn $name(&self) -> $type {
|
||||||
|
paste::paste!{
|
||||||
|
unsafe{
|
||||||
|
[<$base_type:snake _get_ $name>](self.inner.reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::app_interface::list::ImmutableList;
|
use crate::app_interface::list::ImmutableList;
|
||||||
use crate::app_interface::{
|
use crate::app_interface::{
|
||||||
Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Pokemon, Statistic,
|
Battle, BattleImpl, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item,
|
||||||
|
Pokemon, Statistic,
|
||||||
};
|
};
|
||||||
use crate::handling::ScriptCapabilities;
|
use crate::handling::ScriptCapabilities;
|
||||||
use crate::{ExternRef, ExternalReferenceType, ScriptPtr, StringKey, TurnChoice, TypeIdentifier};
|
use crate::{ExternRef, ExternalReferenceType, ScriptPtr, StringKey, TurnChoice, TypeIdentifier};
|
||||||
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
@ -321,7 +323,7 @@ pub trait Script {
|
||||||
fn on_switch_in(&self, _pokemon: Pokemon) {}
|
fn on_switch_in(&self, _pokemon: Pokemon) {}
|
||||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the
|
/// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the
|
||||||
/// held item it had.
|
/// 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) {}
|
||||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||||
/// and allows for changing this amount of experience.
|
/// and allows for changing this amount of experience.
|
||||||
fn change_experience_gained(
|
fn change_experience_gained(
|
||||||
|
@ -356,6 +358,14 @@ pub trait Script {
|
||||||
.get_value()
|
.get_value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mock_data")]
|
||||||
|
fn get_owner<T>(&self) -> Option<T>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for dyn Script {
|
impl Debug for dyn Script {
|
||||||
|
|
|
@ -23,12 +23,10 @@ extern crate dlmalloc;
|
||||||
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {};
|
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {};
|
||||||
|
|
||||||
use crate::app_interface::list::ImmutableList;
|
use crate::app_interface::list::ImmutableList;
|
||||||
use crate::app_interface::Statistic;
|
|
||||||
use crate::app_interface::{
|
use crate::app_interface::{
|
||||||
Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, StringKey,
|
BattleImpl, DamageSource, DynamicLibrary, EffectParameter, ExecutingMoveImpl, Item, ItemImpl,
|
||||||
TurnChoice,
|
Pokemon, PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier,
|
||||||
};
|
};
|
||||||
use crate::app_interface::{Pokemon, TypeIdentifier};
|
|
||||||
pub(crate) use crate::handling::extern_ref::*;
|
pub(crate) use crate::handling::extern_ref::*;
|
||||||
use crate::handling::ffi_array::FFIArray;
|
use crate::handling::ffi_array::FFIArray;
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
@ -237,305 +235,305 @@ fn script_change_number_of_hits(
|
||||||
|
|
||||||
fn script_prevent_move(
|
fn script_prevent_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_move(mv.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().prevent_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_fail_move(
|
fn script_fail_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().fail_move(mv.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().fail_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_stop_before_move(
|
fn script_stop_before_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().stop_before_move(mv.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().stop_before_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_before_move(
|
fn script_on_before_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_before_move(mv.not_null());
|
script.val().unwrap().on_before_move(mv.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_fail_incoming_move(
|
fn script_fail_incoming_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().fail_incoming_move(mv.not_null(), target.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().fail_incoming_move(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_is_invulnerable(
|
fn script_is_invulnerable(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().is_invulnerable(mv.not_null(), target.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().is_invulnerable(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_move_miss(
|
fn script_on_move_miss(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_move_miss(mv.not_null(), target.not_null());
|
script.val().unwrap().on_move_miss(mv.not_null_rc(), target.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_move_type(
|
fn script_change_move_type(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut TypeIdentifier,
|
out: *mut TypeIdentifier,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_move_type(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_move_type(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_effectiveness(
|
fn script_change_effectiveness(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_effectiveness(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_effectiveness(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_block_critical(
|
fn script_block_critical(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().block_critical(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().block_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_block_incoming_critical(
|
fn script_block_incoming_critical(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().block_incoming_critical(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().block_incoming_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_accuracy(
|
fn script_change_accuracy(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_accuracy(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_accuracy(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_critical_stage(
|
fn script_change_critical_stage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_critical_stage(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_critical_stage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_critical_modifier(
|
fn script_change_critical_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_critical_modifier(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_critical_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_stab_modifier(
|
fn script_change_stab_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_stab_modifier(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_stab_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_base_power(
|
fn script_change_base_power(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_base_power(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_bypass_defensive_stat_boost(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().bypass_defensive_stat_boost(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_bypass_offensive_stat_boost(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().bypass_offensive_stat_boost(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_change_defensive_stat_value(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_defensive_stat_value(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_change_offensive_stat_value(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_offensive_stat_value(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_change_damage_stat_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_damage_stat_modifier(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_change_damage_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_damage_modifier(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_damage_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_damage(
|
fn script_change_damage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_damage(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_incoming_damage(
|
fn script_change_incoming_damage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_incoming_damage(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_incoming_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_incoming_hit(
|
fn script_on_incoming_hit(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_incoming_hit(mv.not_null(), target.not_null(), hit);
|
script.val().unwrap().on_incoming_hit(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_opponent_faints(
|
fn script_on_opponent_faints(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_opponent_faints(mv.not_null(), target.not_null(), hit);
|
script.val().unwrap().on_opponent_faints(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_stat_boost_change(
|
fn script_prevent_stat_boost_change(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
stat: Statistic,
|
stat: Statistic,
|
||||||
amount: i8,
|
amount: i8,
|
||||||
self_inflicted: u8,
|
self_inflicted: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_stat_boost_change(target.not_null(), stat, amount, self_inflicted == 1, out.as_mut().unwrap());
|
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(
|
fn script_prevent_secondary_effect(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_secondary_effect(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
script.val().unwrap().prevent_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_effect_chance(
|
fn script_change_effect_chance(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_effect_chance(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_change_incoming_effect_chance(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_incoming_effect_chance(mv.not_null(), target.not_null(), hit, out.as_mut().unwrap());
|
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(
|
fn script_on_secondary_effect(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_secondary_effect(mv.not_null(), target.not_null(), hit);
|
script.val().unwrap().on_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_after_hits(
|
fn script_on_after_hits(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMove>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_after_hits(mv.not_null(), target.not_null());
|
script.val().unwrap().on_after_hits(mv.not_null_rc(), target.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_self_switch(
|
fn script_prevent_self_switch(
|
||||||
|
@ -556,16 +554,16 @@ fn script_prevent_opponent_switch(
|
||||||
|
|
||||||
fn script_on_fail(
|
fn script_on_fail(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_fail(pokemon.not_null());
|
script.val().unwrap().on_fail(pokemon.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_opponent_fail(
|
fn script_on_opponent_fail(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_opponent_fail(pokemon.not_null());
|
script.val().unwrap().on_opponent_fail(pokemon.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_self_run_away(
|
fn script_prevent_self_run_away(
|
||||||
|
@ -592,70 +590,70 @@ fn script_on_end_turn(
|
||||||
|
|
||||||
fn script_on_damage(
|
fn script_on_damage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
source: DamageSource,
|
source: DamageSource,
|
||||||
old_health: u32,
|
old_health: u32,
|
||||||
new_health: u32,
|
new_health: u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_damage(pokemon.not_null(), source, old_health, new_health);
|
script.val().unwrap().on_damage(pokemon.not_null_rc(), source, old_health, new_health);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_faint(
|
fn script_on_faint(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
source: DamageSource,
|
source: DamageSource,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_faint(pokemon.not_null(), source);
|
script.val().unwrap().on_faint(pokemon.not_null_rc(), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_switch_in(
|
fn script_on_switch_in(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_switch_in(pokemon.not_null());
|
script.val().unwrap().on_switch_in(pokemon.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_after_held_item_consume(
|
fn script_on_after_held_item_consume(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
item: ExternRef<Item>
|
item: ExternRef<ItemImpl>
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_after_held_item_consume(pokemon.not_null(), &item.not_null());
|
script.val().unwrap().on_after_held_item_consume(pokemon.not_null_rc(), item.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_experience_gained(
|
fn script_change_experience_gained(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
fainted_pokemon: ExternRef<Pokemon>,
|
fainted_pokemon: ExternRef<PokemonImpl>,
|
||||||
winning_pokemon: ExternRef<Pokemon>,
|
winning_pokemon: ExternRef<PokemonImpl>,
|
||||||
out: *mut u32
|
out: *mut u32
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_experience_gained(fainted_pokemon.not_null(), winning_pokemon.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().change_experience_gained(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_share_experience(
|
fn script_share_experience(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
fainted_pokemon: ExternRef<Pokemon>,
|
fainted_pokemon: ExternRef<PokemonImpl>,
|
||||||
winning_pokemon: ExternRef<Pokemon>,
|
winning_pokemon: ExternRef<PokemonImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().share_experience(fainted_pokemon.not_null(), winning_pokemon.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().share_experience(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_block_weather(
|
fn script_block_weather(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<BattleImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().block_weather(battle.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().block_weather(battle.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_capture_rate_bonus(
|
fn script_change_capture_rate_bonus(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<PokemonImpl>,
|
||||||
pokeball: ExternRef<Item>,
|
pokeball: ExternRef<ItemImpl>,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_capture_rate_bonus(target.not_null(), pokeball.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().change_capture_rate_bonus(target.not_null_rc(), pokeball.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue