678 lines
20 KiB
Rust
Executable File
678 lines
20 KiB
Rust
Executable File
#![feature(core_panic)]
|
|
#![feature(alloc_error_handler)]
|
|
#![feature(fn_traits)]
|
|
#![feature(const_for)]
|
|
#![feature(const_mut_refs)]
|
|
#![feature(inline_const)]
|
|
#![feature(inline_const_pat)]
|
|
#![feature(repr128)]
|
|
#![feature(downcast_unchecked)]
|
|
#![feature(panic_info_message)]
|
|
#![feature(wasm_abi)]
|
|
#![feature(thread_local)]
|
|
#![feature(build_hasher_simple_hash_one)]
|
|
#![feature(adt_const_params)]
|
|
#![cfg_attr(not(feature = "mock_data"), no_std)]
|
|
#![allow(incomplete_features)]
|
|
// These give false positives too often
|
|
#![allow(clippy::borrowed_box)]
|
|
#![allow(clippy::needless_lifetimes)]
|
|
|
|
extern crate alloc;
|
|
extern crate core;
|
|
extern crate dlmalloc;
|
|
|
|
#[global_allocator]
|
|
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {};
|
|
|
|
pub(crate) use crate::app_interface::StringKey;
|
|
pub(crate) use crate::handling::extern_ref::*;
|
|
use alloc::boxed::Box;
|
|
|
|
#[macro_use]
|
|
#[allow(dead_code)]
|
|
pub mod app_interface;
|
|
pub mod handling;
|
|
pub mod utils;
|
|
|
|
pub type LoadScriptFnType = Box<dyn Fn(ScriptCategory, &StringKey) -> Option<Box<dyn Script>>>;
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
mod implementation {
|
|
use super::LoadScriptFnType;
|
|
|
|
use crate::app_interface::list::{EffectParameterImmutableList, ImmutableListWasm};
|
|
use crate::app_interface::{
|
|
BattleImpl, DamageSource, DynamicLibraryImpl, EffectParameter, ExecutingMoveImpl, ItemImpl,
|
|
PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier,
|
|
};
|
|
use crate::handling::extern_ref::ExternRef;
|
|
use crate::handling::extern_ref::VecExternRef;
|
|
use crate::handling::ffi_array::FFIArray;
|
|
use crate::handling::{Script, ScriptCapabilities, ScriptCategory};
|
|
use alloc::boxed::Box;
|
|
use alloc::rc::Rc;
|
|
use core::sync::atomic::{AtomicU32, Ordering};
|
|
use cstr_core::{c_char, CString};
|
|
use hashbrown::HashMap;
|
|
|
|
static mut LOAD_SCRIPT_FN: Option<LoadScriptFnType> = None;
|
|
|
|
pub fn set_load_script_fn(f: LoadScriptFnType) {
|
|
unsafe {
|
|
LOAD_SCRIPT_FN = Some(f);
|
|
}
|
|
}
|
|
|
|
macro_rules! exported_functions {
|
|
(
|
|
$(
|
|
fn $func_name:ident($($par_name:ident: $par_type:ty),*$(,)?) $(-> $return_type:ty)? $func_body:block
|
|
)*
|
|
) => {
|
|
$(
|
|
#[no_mangle]
|
|
unsafe extern "wasm" fn $func_name(
|
|
$(
|
|
$par_name: $par_type,
|
|
)*
|
|
) $(-> $return_type)* $func_body
|
|
)*
|
|
};
|
|
}
|
|
|
|
static mut SCRIPT_PTR_CACHE: Option<hashbrown::HashMap<*const dyn Script, u32>> = None;
|
|
static mut SCRIPT_PTR_REVERSE_CACHE: Option<hashbrown::HashMap<u32, Box<dyn Script>>> = None;
|
|
static mut SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
|
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct ScriptPtr {
|
|
index: u32,
|
|
}
|
|
|
|
impl ScriptPtr {
|
|
fn get_cache<'a>() -> &'a mut HashMap<*const dyn Script, u32> {
|
|
unsafe {
|
|
if let None = SCRIPT_PTR_CACHE {
|
|
SCRIPT_PTR_CACHE = Some(hashbrown::HashMap::new());
|
|
}
|
|
let cache = SCRIPT_PTR_CACHE.as_mut().unwrap();
|
|
cache
|
|
}
|
|
}
|
|
|
|
fn get_reverse_cache<'a>() -> &'a mut HashMap<u32, Box<dyn Script>> {
|
|
unsafe {
|
|
if let None = SCRIPT_PTR_REVERSE_CACHE {
|
|
SCRIPT_PTR_REVERSE_CACHE = Some(hashbrown::HashMap::new());
|
|
}
|
|
let cache = SCRIPT_PTR_REVERSE_CACHE.as_mut().unwrap();
|
|
cache
|
|
}
|
|
}
|
|
|
|
pub fn from_existing(ptr: &dyn Script) -> Self {
|
|
let cache = Self::get_cache();
|
|
let index = *cache.get(&(ptr as *const dyn Script)).unwrap();
|
|
Self { index }
|
|
}
|
|
|
|
pub fn new(ptr: Box<dyn Script>) -> Self {
|
|
unsafe {
|
|
let cache = Self::get_cache();
|
|
let mut index = cache.get(&(ptr.as_ref() as *const dyn Script)).cloned();
|
|
if index.is_none() {
|
|
index = Some(SCRIPT_INDEX_COUNTER.fetch_add(1, Ordering::SeqCst));
|
|
let reverse_cache = Self::get_reverse_cache();
|
|
reverse_cache.insert(index.unwrap(), ptr);
|
|
|
|
let v = reverse_cache.get(&index.unwrap()).unwrap();
|
|
cache.insert(v.as_ref(), index.unwrap());
|
|
}
|
|
Self {
|
|
index: index.unwrap(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn null() -> Self {
|
|
Self { index: 0 }
|
|
}
|
|
|
|
pub fn val<'a, 'b>(&'a self) -> Option<&'b dyn Script> {
|
|
if self.index == 0 {
|
|
return None;
|
|
}
|
|
let cache = Self::get_reverse_cache();
|
|
if let Some(c) = cache.get(&self.index) {
|
|
Some(c.as_ref())
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
exported_functions! {
|
|
|
|
fn load_script(category: ScriptCategory, name: ExternRef<StringKey>) -> ScriptPtr {
|
|
let name_c = StringKey::new(name);
|
|
let boxed_script = unsafe { &LOAD_SCRIPT_FN }.as_ref().unwrap()(category, &name_c);
|
|
if boxed_script.is_none() {
|
|
return ScriptPtr::null();
|
|
}
|
|
let b = boxed_script.unwrap();
|
|
ScriptPtr::new(b)
|
|
}
|
|
|
|
fn destroy_script(script: *mut Box<dyn Script>) {
|
|
// By turning it from a raw pointer back into a Box with from_raw, we give ownership back to rust.
|
|
// This lets Rust do the cleanup.
|
|
let boxed_script = Box::from_raw(script);
|
|
drop(boxed_script);
|
|
}
|
|
|
|
fn script_get_name(script: ScriptPtr) -> *mut c_char {
|
|
let c = script.val().unwrap().get_name();
|
|
CString::new(c).unwrap().into_raw()
|
|
}
|
|
|
|
|
|
fn get_script_capabilities(script: ScriptPtr) -> FFIArray<ScriptCapabilities> {
|
|
let c = script.val().unwrap().get_capabilities();
|
|
FFIArray::new(c)
|
|
}
|
|
|
|
fn script_stack(script: ScriptPtr) {
|
|
script.val().unwrap().stack();
|
|
}
|
|
|
|
fn script_on_remove(script: ScriptPtr) {
|
|
script.val().unwrap().on_remove();
|
|
}
|
|
|
|
fn script_on_initialize(
|
|
script: ScriptPtr,
|
|
library: ExternRef<DynamicLibraryImpl>,
|
|
parameters: VecExternRef<EffectParameter>,
|
|
) {
|
|
let parameters = Rc::new(EffectParameterImmutableList::from_ref(parameters));
|
|
script.val().unwrap().on_initialize(library.not_null_rc(), Some(parameters));
|
|
}
|
|
|
|
fn script_on_before_turn(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
) {
|
|
script.val().unwrap().on_before_turn(choice.not_null())
|
|
}
|
|
|
|
fn script_change_speed(
|
|
script:ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
speed: *mut u32,
|
|
) {
|
|
script.val().unwrap().change_speed(choice.not_null(), speed.as_mut().unwrap())
|
|
}
|
|
|
|
fn script_change_priority(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
priority: *mut i8,
|
|
) {
|
|
script.val().unwrap().change_priority(choice.not_null(), priority.as_mut().unwrap())
|
|
}
|
|
|
|
fn script_change_move(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
mv: *mut ExternRef<StringKey>,
|
|
) {
|
|
let old = mv.as_ref().unwrap().not_null();
|
|
let mut new = old.clone();
|
|
script.val().unwrap().change_move(choice.not_null(), &mut new);
|
|
if old != new {
|
|
*mv = new.ptr();
|
|
}
|
|
}
|
|
|
|
fn script_change_number_of_hits(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
out: *mut u8,
|
|
) {
|
|
script.val().unwrap().change_number_of_hits(choice.not_null(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_prevent_move(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_move(mv.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_fail_move(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().fail_move(mv.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_stop_before_move(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().stop_before_move(mv.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_on_before_move(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
) {
|
|
script.val().unwrap().on_before_move(mv.not_null_rc());
|
|
}
|
|
|
|
fn script_fail_incoming_move(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().fail_incoming_move(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_is_invulnerable(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().is_invulnerable(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_on_move_miss(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
) {
|
|
script.val().unwrap().on_move_miss(mv.not_null_rc(), target.not_null_rc());
|
|
}
|
|
|
|
fn script_change_move_type(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut TypeIdentifier,
|
|
) {
|
|
script.val().unwrap().change_move_type(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_effectiveness(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_effectiveness(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_block_critical(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().block_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_block_incoming_critical(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().block_incoming_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_accuracy(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u8,
|
|
) {
|
|
script.val().unwrap().change_accuracy(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_critical_stage(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u8,
|
|
) {
|
|
script.val().unwrap().change_critical_stage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_critical_modifier(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_critical_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_stab_modifier(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_stab_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_base_power(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u8,
|
|
) {
|
|
script.val().unwrap().change_base_power(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_bypass_defensive_stat_boost(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().bypass_defensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_bypass_offensive_stat_boost(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().bypass_offensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_defensive_stat_value(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u32,
|
|
) {
|
|
script.val().unwrap().change_defensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_offensive_stat_value(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u32,
|
|
) {
|
|
script.val().unwrap().change_offensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_damage_stat_modifier(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_damage_stat_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_damage_modifier(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_damage_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_damage(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u32,
|
|
) {
|
|
script.val().unwrap().change_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_incoming_damage(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut u32,
|
|
) {
|
|
script.val().unwrap().change_incoming_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_on_incoming_hit(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
) {
|
|
script.val().unwrap().on_incoming_hit(mv.not_null_rc(), target.not_null_rc(), hit);
|
|
}
|
|
|
|
fn script_on_opponent_faints(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
) {
|
|
script.val().unwrap().on_opponent_faints(mv.not_null_rc(), target.not_null_rc(), hit);
|
|
}
|
|
|
|
fn script_prevent_stat_boost_change(
|
|
script: ScriptPtr,
|
|
target: ExternRef<PokemonImpl>,
|
|
stat: Statistic,
|
|
amount: i8,
|
|
self_inflicted: u8,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_stat_boost_change(target.not_null_rc(), stat, amount, self_inflicted == 1, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_prevent_secondary_effect(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_effect_chance(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_incoming_effect_chance(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
out: *mut f32,
|
|
) {
|
|
script.val().unwrap().change_incoming_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_on_secondary_effect(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
hit: u8,
|
|
) {
|
|
script.val().unwrap().on_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit);
|
|
}
|
|
|
|
fn script_on_after_hits(
|
|
script: ScriptPtr,
|
|
mv: ExternRef<ExecutingMoveImpl>,
|
|
target: ExternRef<PokemonImpl>,
|
|
) {
|
|
script.val().unwrap().on_after_hits(mv.not_null_rc(), target.not_null_rc());
|
|
}
|
|
|
|
fn script_prevent_self_switch(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_self_switch(choice.not_null(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_prevent_opponent_switch(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_opponent_switch(choice.not_null(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_on_fail(
|
|
script: ScriptPtr,
|
|
pokemon: ExternRef<PokemonImpl>,
|
|
) {
|
|
script.val().unwrap().on_fail(pokemon.not_null_rc());
|
|
}
|
|
|
|
fn script_on_opponent_fail(
|
|
script: ScriptPtr,
|
|
pokemon: ExternRef<PokemonImpl>,
|
|
) {
|
|
script.val().unwrap().on_opponent_fail(pokemon.not_null_rc());
|
|
}
|
|
|
|
fn script_prevent_self_run_away(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_self_run_away(choice.not_null(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_prevent_opponent_run_away(
|
|
script: ScriptPtr,
|
|
choice: ExternRef<TurnChoice>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().prevent_opponent_run_away(choice.not_null(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_on_end_turn(
|
|
script: ScriptPtr,
|
|
) {
|
|
script.val().unwrap().on_end_turn();
|
|
}
|
|
|
|
fn script_on_damage(
|
|
script: ScriptPtr,
|
|
pokemon: ExternRef<PokemonImpl>,
|
|
source: DamageSource,
|
|
old_health: u32,
|
|
new_health: u32,
|
|
) {
|
|
script.val().unwrap().on_damage(pokemon.not_null_rc(), source, old_health, new_health);
|
|
}
|
|
|
|
fn script_on_faint(
|
|
script: ScriptPtr,
|
|
pokemon: ExternRef<PokemonImpl>,
|
|
source: DamageSource,
|
|
) {
|
|
script.val().unwrap().on_faint(pokemon.not_null_rc(), source);
|
|
}
|
|
|
|
fn script_on_switch_in(
|
|
script: ScriptPtr,
|
|
pokemon: ExternRef<PokemonImpl>,
|
|
) {
|
|
script.val().unwrap().on_switch_in(pokemon.not_null_rc());
|
|
}
|
|
|
|
fn script_on_after_held_item_consume(
|
|
script: ScriptPtr,
|
|
pokemon: ExternRef<PokemonImpl>,
|
|
item: ExternRef<ItemImpl>
|
|
) {
|
|
script.val().unwrap().on_after_held_item_consume(pokemon.not_null_rc(), item.not_null_rc());
|
|
}
|
|
|
|
fn script_change_experience_gained(
|
|
script: ScriptPtr,
|
|
fainted_pokemon: ExternRef<PokemonImpl>,
|
|
winning_pokemon: ExternRef<PokemonImpl>,
|
|
out: *mut u32
|
|
) {
|
|
script.val().unwrap().change_experience_gained(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_share_experience(
|
|
script: ScriptPtr,
|
|
fainted_pokemon: ExternRef<PokemonImpl>,
|
|
winning_pokemon: ExternRef<PokemonImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().share_experience(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_block_weather(
|
|
script: ScriptPtr,
|
|
battle: ExternRef<BattleImpl>,
|
|
out: *mut bool,
|
|
) {
|
|
script.val().unwrap().block_weather(battle.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
|
|
fn script_change_capture_rate_bonus(
|
|
script: ScriptPtr,
|
|
target: ExternRef<PokemonImpl>,
|
|
pokeball: ExternRef<ItemImpl>,
|
|
out: *mut u8,
|
|
) {
|
|
script.val().unwrap().change_capture_rate_bonus(target.not_null_rc(), pokeball.not_null_rc(), out.as_mut().unwrap());
|
|
}
|
|
}
|
|
}
|
|
|
|
use crate::handling::{Script, ScriptCategory};
|
|
#[cfg(not(feature = "mock_data"))]
|
|
pub use implementation::*;
|
|
|
|
#[cfg(feature = "mock_data")]
|
|
pub fn set_load_script_fn(_f: LoadScriptFnType) {}
|