PkmnLib_rs/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs

297 lines
9.4 KiB
Rust
Executable File

use std::mem::transmute;
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::{ClampedStatisticSet, Species};
use crate::static_data::{Item, StatisticSet};
use crate::{ScriptCategory, StringKey};
use std::ffi::{c_char, CStr};
use wasmer::FunctionEnvMut;
register! {
fn pokemon_get_library(
env: FunctionEnvMut<WebAssemblyEnv>,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<DynamicLibrary> {
let lib = pokemon.value_func(&env).unwrap().library();
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<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{
if pokemon.value_func(&env).unwrap().change_stat_boost(transmute(stat), amount, self_inflicted == 1) {
1
} else {
0
}
}
}
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<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) };
let key = StringKey::new(name.to_str().unwrap().into());
if pokemon.value_func(&env).unwrap().has_held_item(&key) { 1 } else { 0 }
}
fn pokemon_heal(
env: FunctionEnvMut<WebAssemblyEnv>,
pokemon: ExternRef<Pokemon>,
amount: u32,
allow_revive: u8
) -> u8 {
if pokemon.value_func(&env).unwrap().heal(amount, allow_revive == 1) { 1 } else { 0 }
}
fn pokemon_clear_status(
env: FunctionEnvMut<WebAssemblyEnv>,
pokemon: ExternRef<Pokemon>,
) {
pokemon.value_func(&env).unwrap().clear_status()
}
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.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));
if pokemon.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()) { 1 } else { 0 }
}
}
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());
}
}
}