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