594 lines
20 KiB
Rust
Executable File
594 lines
20 KiB
Rust
Executable File
use std::mem::transmute;
|
|
|
|
use crate::defines::LevelInt;
|
|
use crate::dynamic_data::{Battle, DynamicLibrary, EventBatchId, LearnedMove, Pokemon, VolatileScriptsOwner};
|
|
use crate::script_implementations::wasm::export_registry::{
|
|
get_value, get_value_arc, get_value_arc_void, get_value_call_getter, get_value_void, register, try_wasm, wasm_err,
|
|
wasm_ok, WasmResult, WasmVoidResult, WasmVoidResultExtension,
|
|
};
|
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
|
use crate::static_data::{Ability, ClampedStatisticSet, Form, Nature, Species};
|
|
use crate::static_data::{Item, StatisticSet};
|
|
use crate::{ScriptCategory, VecExt};
|
|
use anyhow::anyhow;
|
|
use std::ffi::{c_char, CStr, CString};
|
|
use wasmer::FunctionEnvMut;
|
|
|
|
register! {
|
|
fn pokemon_get_library(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let lib = pokemon.library();
|
|
wasm_ok(ExternRef::<dyn DynamicLibrary>::func_new(&env, lib.into()))
|
|
}
|
|
|
|
fn pokemon_get_boosted_stats(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let statistic_set = pokemon.boosted_stats();
|
|
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set.into()))
|
|
}
|
|
|
|
fn pokemon_get_flat_stats(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let statistic_set = pokemon.flat_stats();
|
|
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set.into()))
|
|
}
|
|
|
|
fn pokemon_get_stat_boosts(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<ClampedStatisticSet<i8, -6, 6>>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let statistic_set = pokemon.stat_boosts();
|
|
wasm_ok(ExternRef::<ClampedStatisticSet<i8, -6, 6>>::func_new(&env, statistic_set.into()))
|
|
}
|
|
|
|
fn pokemon_get_individual_values(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 31>>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let statistic_set = pokemon.individual_values();
|
|
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 31>>::func_new(&env, statistic_set.into()))
|
|
}
|
|
|
|
fn pokemon_get_effort_values(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 252>>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let statistic_set = pokemon.effort_values();
|
|
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 252>>::func_new(&env, statistic_set.into()))
|
|
}
|
|
|
|
fn pokemon_get_species(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Species>> {
|
|
let species = get_value_call_getter!(pokemon.species(), env);
|
|
wasm_ok(ExternRef::<dyn Species>::func_new(&env, (&species).into()))
|
|
}
|
|
|
|
fn pokemon_get_weight(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<f32> {
|
|
wasm_ok(get_value_call_getter!(pokemon.weight(), env))
|
|
}
|
|
|
|
fn pokemon_set_weight(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
weight: f32,
|
|
) -> WasmVoidResult {
|
|
let pokemon = match pokemon.value_func(&env) {
|
|
Ok(pokemon) => pokemon,
|
|
Err(e) => return WasmVoidResult::err(e, &env),
|
|
};
|
|
pokemon.set_weight(weight);
|
|
WasmVoidResult::ok()
|
|
}
|
|
|
|
|
|
fn pokemon_get_height(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<f32> {
|
|
wasm_ok(get_value_call_getter!(pokemon.height(), env))
|
|
}
|
|
|
|
fn pokemon_get_gender(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
unsafe {
|
|
wasm_ok(transmute(get_value_call_getter!(pokemon.gender(), env)))
|
|
}
|
|
}
|
|
|
|
fn pokemon_damage(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
damage: u32,
|
|
source: u8,
|
|
event_batch_id_1: u64,
|
|
event_batch_id_2: u64,
|
|
) -> WasmVoidResult {
|
|
unsafe {
|
|
let pokemon = match pokemon.value_func(&env) {
|
|
Ok(pokemon) => pokemon,
|
|
Err(e) => return WasmVoidResult::err(e, &env),
|
|
};
|
|
match pokemon.damage(damage, transmute(source), EventBatchId::from_u64_pair(event_batch_id_1, event_batch_id_2)) {
|
|
Ok(()) => WasmVoidResult::ok(),
|
|
Err(e) => WasmVoidResult::err(e, &env),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn pokemon_get_learned_move(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
index: u32
|
|
) -> WasmResult<ExternRef<LearnedMove>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let read_lock = pokemon.learned_moves().read();
|
|
let mv = read_lock.get(index as usize);
|
|
wasm_ok(if let Some(Some(mv)) = mv {
|
|
ExternRef::<LearnedMove>::func_new(&env, mv.into())
|
|
}
|
|
else{
|
|
ExternRef::<LearnedMove>::null()
|
|
})
|
|
}
|
|
|
|
fn pokemon_change_stat_boost(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
stat: u8,
|
|
amount: i8,
|
|
self_inflicted: u8
|
|
) -> WasmResult<u8> {
|
|
unsafe{
|
|
let pokemon = get_value!(pokemon, env);
|
|
let res = try_wasm!(pokemon.change_stat_boost(transmute(stat), amount, self_inflicted == 1), env);
|
|
wasm_ok(u8::from(res))
|
|
}
|
|
}
|
|
|
|
fn pokemon_get_battle(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<Battle>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if let Some(battle) = pokemon.get_battle() {
|
|
ExternRef::func_new(&env, (&battle).into())
|
|
} else {
|
|
ExternRef::null()
|
|
})
|
|
}
|
|
|
|
fn pokemon_get_battle_index(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if let Some(i) = pokemon.get_battle_index() {
|
|
i
|
|
} else {
|
|
255
|
|
})
|
|
}
|
|
|
|
fn pokemon_get_battle_side_index(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if let Some(i) = pokemon.get_battle_side_index() {
|
|
i
|
|
} else {
|
|
255
|
|
})
|
|
}
|
|
|
|
fn pokemon_get_held_item(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Item>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let read_lock = pokemon.held_item().read();
|
|
wasm_ok(if let Some(item) = read_lock.as_ref() {
|
|
ExternRef::<dyn Item>::func_new(&env, item.into())
|
|
} else {
|
|
ExternRef::<dyn Item>::null()
|
|
})
|
|
}
|
|
|
|
fn pokemon_has_held_item(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
name: u32
|
|
) -> WasmResult<u8> {
|
|
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
|
let name = unsafe { CStr::from_ptr(name) };
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(u8::from(pokemon.has_held_item(&name.into())))
|
|
}
|
|
|
|
fn pokemon_heal(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
amount: u32,
|
|
allow_revive: u8
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(u8::from(pokemon.heal(amount, allow_revive == 1)))
|
|
}
|
|
|
|
fn pokemon_clear_status(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmVoidResult {
|
|
let pokemon = match pokemon.value_func(&env) {
|
|
Ok(pokemon) => pokemon,
|
|
Err(e) => return WasmVoidResult::err(e, &env),
|
|
};
|
|
pokemon.clear_status();
|
|
WasmVoidResult::ok()
|
|
}
|
|
|
|
fn pokemon_get_active_ability(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Ability>> {
|
|
let active_ability = get_value_call_getter!(pokemon.active_ability(), env);
|
|
let active_ability = try_wasm!(active_ability, env);
|
|
wasm_ok(ExternRef::<dyn Ability>::func_new(&env, (&active_ability).into()))
|
|
}
|
|
|
|
fn pokemon_get_real_ability(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u16> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let index = pokemon.real_ability();
|
|
let t: (u8, u8) = (if index.hidden { 1 } else { 0 }, index.index);
|
|
let r: u16 = unsafe { transmute(t) };
|
|
wasm_ok(r)
|
|
}
|
|
|
|
fn pokemon_get_is_ability_overriden(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if pokemon.is_ability_overriden() { 1 } else { 0 })
|
|
}
|
|
|
|
fn pokemon_get_allowed_experience_gain(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if pokemon.allowed_experience_gain() { 1 } else { 0 })
|
|
}
|
|
|
|
fn pokemon_get_is_usable(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if pokemon.is_usable() { 1 } else { 0 })
|
|
}
|
|
|
|
|
|
fn pokemon_set_held_item(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
item: ExternRef<dyn Item>
|
|
) -> WasmResult<ExternRef<dyn Item>> {
|
|
let item = get_value_arc!(item, env);
|
|
let pokemon = get_value!(pokemon, env);
|
|
let old_item = pokemon.set_held_item(&item);
|
|
wasm_ok(if let Some(old_item) = old_item {
|
|
ExternRef::<dyn Item>::func_new(&env, (&old_item).into())
|
|
} else {
|
|
ExternRef::null()
|
|
})
|
|
}
|
|
|
|
fn pokemon_remove_held_item(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Item>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let old_item = pokemon.remove_held_item();
|
|
wasm_ok(if let Some(old_item) = old_item {
|
|
ExternRef::<dyn Item>::func_new(&env, (&old_item).into())
|
|
} else {
|
|
ExternRef::<dyn Item>::null()
|
|
})
|
|
}
|
|
|
|
fn pokemon_consume_held_item(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let res = try_wasm!(pokemon.consume_held_item(), env);
|
|
wasm_ok(if res { 1 } else { 0 })
|
|
}
|
|
|
|
fn pokemon_get_types_length(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>
|
|
) -> WasmResult<u32> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let len = pokemon.types().len();
|
|
wasm_ok(len as u32)
|
|
}
|
|
|
|
fn pokemon_get_type(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
index: u32
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let types = pokemon.types();
|
|
let type_v = types.get_res(index as usize);
|
|
match type_v {
|
|
Ok(t) => wasm_ok(u8::from(*t)),
|
|
Err(e) => wasm_err::<u8>(e, &env),
|
|
}
|
|
}
|
|
|
|
fn pokemon_has_type(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
t: u8
|
|
) -> WasmResult<u8> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(if pokemon.types().contains(&t.into()) { 1 } else { 0 })
|
|
}
|
|
|
|
fn pokemon_change_species(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
species: ExternRef<dyn Species>,
|
|
form: ExternRef<dyn Form>,
|
|
) -> WasmVoidResult {
|
|
let pokemon = get_value_void!(pokemon, env);
|
|
let species = get_value_arc_void!(species, env);
|
|
let form = get_value_arc_void!(form, env);
|
|
|
|
match pokemon.change_species(
|
|
species,
|
|
form,
|
|
) {
|
|
Ok(_) => WasmVoidResult::ok(),
|
|
Err(e) => WasmVoidResult::err(e, &env),
|
|
}
|
|
}
|
|
|
|
fn pokemon_change_form(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
form: ExternRef<dyn Form>,
|
|
) -> WasmVoidResult {
|
|
let pokemon = get_value_void!(pokemon, env);
|
|
let form = get_value_arc_void!(form, env);
|
|
match pokemon.change_form(&form) {
|
|
Ok(_) => WasmVoidResult::ok(),
|
|
Err(e) => WasmVoidResult::err(e, &env),
|
|
}
|
|
}
|
|
|
|
fn pokemon_get_current_health(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u32> {
|
|
wasm_ok(get_value_call_getter!(pokemon.current_health(), env))
|
|
}
|
|
|
|
fn pokemon_get_nature(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Nature>> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let nature = pokemon.nature();
|
|
wasm_ok(ExternRef::<dyn Nature>::func_new(&env, nature.into()))
|
|
}
|
|
|
|
fn pokemon_get_form(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Form>> {
|
|
let form = get_value_call_getter!(pokemon.form(), env);
|
|
wasm_ok(ExternRef::<dyn Form>::func_new(&env, (&form).into()))
|
|
}
|
|
|
|
fn pokemon_get_display_species(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Species>> {
|
|
let display_species = get_value_call_getter!(pokemon.display_species(), env);
|
|
wasm_ok(ExternRef::<dyn Species>::func_new(&env, (&display_species).into()))
|
|
}
|
|
|
|
fn pokemon_get_display_form(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<ExternRef<dyn Form>> {
|
|
let display_form = get_value_call_getter!(pokemon.display_form(), env);
|
|
wasm_ok(ExternRef::<dyn Form>::func_new(&env, (&display_form).into()))
|
|
}
|
|
|
|
fn pokemon_get_level(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<LevelInt> {
|
|
wasm_ok(get_value_call_getter!(pokemon.level(), env))
|
|
}
|
|
|
|
fn pokemon_get_experience(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u32> {
|
|
wasm_ok(get_value_call_getter!(pokemon.experience(), env))
|
|
}
|
|
|
|
fn pokemon_get_unique_identifier(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u32> {
|
|
wasm_ok(get_value_call_getter!(pokemon.unique_identifier(), env))
|
|
}
|
|
|
|
fn pokemon_get_coloring(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u8> {
|
|
wasm_ok(get_value_call_getter!(pokemon.coloring(), env))
|
|
}
|
|
|
|
fn pokemon_get_nickname(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u32> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let nickname = pokemon.nickname();
|
|
if let Some(nickname) = nickname {
|
|
let nickname: CString = match CString::new(nickname.as_str()) {
|
|
Ok(nickname) => nickname,
|
|
Err(e) => return wasm_err::<u32>(e.into(), &env),
|
|
};
|
|
match env.data().data().copy_value_vec_to_wasm(nickname.as_bytes()) {
|
|
Ok(ptr) => wasm_ok(ptr),
|
|
Err(e) => wasm_err::<u32>(e, &env),
|
|
}
|
|
} else {
|
|
wasm_ok(0)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fn pokemon_add_volatile_by_name(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
name_ptr: u32
|
|
) -> WasmResult<u32> {
|
|
unsafe {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
|
let script = try_wasm!(pokemon.add_volatile_script(&c_name.as_ref().into()), env);
|
|
if let Some(script) = script {
|
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
|
wasm_ok(script.get_wasm_pointer())
|
|
} else {
|
|
wasm_ok(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn pokemon_add_volatile(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
script_ptr: u32
|
|
) -> WasmResult<u32> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
unsafe{
|
|
let env_data = env.data().data();
|
|
let name_ptr = match try_wasm!(env_data.script_function_cache().script_get_name(&env_data), env).call(&mut env_data.store_mut(), script_ptr){
|
|
Ok(name_ptr) => name_ptr,
|
|
Err(e) => return wasm_err::<u32>(e.into(), &env)
|
|
};
|
|
let c_name: &CStr = CStr::from_ptr(env_data.get_raw_pointer(name_ptr));
|
|
let script = try_wasm!(env_data.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), (&pokemon).into()), env);
|
|
try_wasm!(env_data.script_function_cache().dealloc_cstring(&env_data, name_ptr), env);
|
|
|
|
if let Some(script) = script {
|
|
let script = try_wasm!(pokemon.add_volatile_script_with_script(script), env);
|
|
let s = match script.as_ref() {
|
|
Some(s) => s,
|
|
None => return wasm_err::<u32>(anyhow!("Unable to get script"), &env)
|
|
};
|
|
let s = try_wasm!(s.get_as::<WebAssemblyScript>(), env);
|
|
wasm_ok(s.get_wasm_pointer())
|
|
} else {
|
|
wasm_ok(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn pokemon_has_volatile(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
name_ptr: u32
|
|
) -> WasmResult<u8> {
|
|
unsafe {
|
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
|
let pokemon = get_value!(pokemon, env);
|
|
wasm_ok(u8::from(pokemon.has_volatile_script(&c_name.as_ref().into())))
|
|
}
|
|
}
|
|
|
|
fn pokemon_get_volatile(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
name_ptr: u32
|
|
) -> WasmResult<u32> {
|
|
unsafe {
|
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
|
let pokemon = get_value!(pokemon, env);
|
|
let script = pokemon.get_volatile_script(&c_name.as_ref().into());
|
|
wasm_ok(if let Some(script) = script {
|
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
|
script.get_wasm_pointer()
|
|
} else {
|
|
0
|
|
})
|
|
}
|
|
}
|
|
|
|
fn pokemon_remove_volatile(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
name_ptr: u32
|
|
) -> WasmVoidResult {
|
|
unsafe {
|
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
|
let pokemon = get_value_void!(pokemon, env);
|
|
match pokemon.remove_volatile_script(&c_name.as_ref().into()) {
|
|
Ok(_) => WasmVoidResult::ok(),
|
|
Err(e) => WasmVoidResult::err(e, &env)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn pokemon_get_ability_script(
|
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
|
pokemon: ExternRef<Pokemon>,
|
|
) -> WasmResult<u32> {
|
|
let pokemon = get_value!(pokemon, env);
|
|
let script = pokemon.ability_script();
|
|
if script.is_any() {
|
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
|
return wasm_ok(script.get_wasm_pointer());
|
|
}
|
|
wasm_ok(0)
|
|
}
|
|
|
|
}
|