Support for item use scripts
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
48ff2c4536
commit
e44ddf18a2
|
@ -10,6 +10,7 @@ fn main() {
|
|||
use alloc::boxed::Box;
|
||||
use pkmn_lib_interface::app_interface::{{get_hash, StringKey}};
|
||||
use pkmn_lib_interface::handling::{{Script, ScriptCategory}};
|
||||
use pkmn_lib_interface::handling::item_script::ItemScript;
|
||||
|
||||
macro_rules! resolve_match {{
|
||||
(
|
||||
|
@ -56,6 +57,8 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn
|
|||
"#
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
write_item_scripts(&mut output_file);
|
||||
}
|
||||
|
||||
fn write_category(path: &str, category: &str, output_file: &mut std::fs::File) {
|
||||
|
@ -122,3 +125,59 @@ fn write_scripts(path: &str, output_file: &mut std::fs::File) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_item_scripts(output_file: &mut std::fs::File) {
|
||||
writeln!(
|
||||
output_file,
|
||||
r"
|
||||
pub fn get_item_script(name: &StringKey) -> Option<Box<dyn ItemScript>> {{
|
||||
resolve_match! {{
|
||||
name.hash().unwrap(),"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let item_files = std::fs::read_dir("src/items")
|
||||
.unwrap()
|
||||
.map(|f| f.unwrap().path())
|
||||
.filter(|f| f.extension().unwrap() == "rs")
|
||||
.map(|f| f.file_stem().unwrap().to_str().unwrap().to_string())
|
||||
.collect::<Vec<_>>();
|
||||
for file in item_files {
|
||||
println!("cargo:rerun-if-changed=src/items/{}.rs", file);
|
||||
let parsed =
|
||||
syn::parse_file(&std::fs::read_to_string(format!("src/items/{}.rs", file)).unwrap())
|
||||
.unwrap();
|
||||
// Now we need to find every impl ItemScript for X { ... } block inside parsed
|
||||
let script_impls = parsed
|
||||
.items
|
||||
.iter()
|
||||
.filter_map(|item| match item {
|
||||
syn::Item::Impl(impl_block) => match impl_block.trait_ {
|
||||
Some((_, ref path, _)) => {
|
||||
if path.segments[0].ident == "ItemScript" {
|
||||
Some(impl_block)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
},
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
for script_impl in script_impls {
|
||||
if let syn::Type::Path(p) = script_impl.self_ty.as_ref() {
|
||||
let ident = p.path.segments[0].ident.to_string();
|
||||
writeln!(output_file, " crate::items::{}::{},", file, ident).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(
|
||||
output_file,
|
||||
r" }}
|
||||
None
|
||||
}}"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
use crate::common_usings::*;
|
||||
use pkmn_lib_interface::handling::item_script::ItemScript;
|
||||
|
||||
script!(
|
||||
HealingItem,
|
||||
"healing_item",
|
||||
amount: AtomicU32
|
||||
);
|
||||
|
||||
impl ItemScript for HealingItem {
|
||||
fn new() -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self {
|
||||
amount: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &'static str {
|
||||
Self::get_const_name()
|
||||
}
|
||||
|
||||
fn is_item_usable(&self) -> PkmnResult<bool> {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn requires_target(&self) -> PkmnResult<bool> {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn is_target_valid(&self, target: &Pokemon) -> PkmnResult<bool> {
|
||||
Ok(!target.is_fainted()?)
|
||||
}
|
||||
|
||||
fn on_use_with_target(&self, target: &Pokemon) -> PkmnResult<()> {
|
||||
target.heal(self.amount.load(Ordering::Relaxed), false)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod healing_item;
|
|
@ -27,6 +27,7 @@ pub mod status;
|
|||
pub mod util_scripts;
|
||||
pub(crate) mod utils;
|
||||
pub mod weather;
|
||||
pub mod items;
|
||||
|
||||
#[no_mangle]
|
||||
#[cfg(not(test))]
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use alloc::boxed::Box;
|
||||
use pkmn_lib_interface::app_interface::{get_hash, StringKey};
|
||||
use pkmn_lib_interface::handling::{Script, ScriptCategory};
|
||||
use pkmn_lib_interface::handling::item_script::ItemScript;
|
||||
|
||||
macro_rules! resolve_match {
|
||||
(
|
||||
|
@ -94,4 +95,11 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
pub fn get_item_script(name: &StringKey) -> Option<Box<dyn ItemScript>> {
|
||||
resolve_match! {
|
||||
name.hash().unwrap(),
|
||||
crate::items::healing_item::HealingItem,
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
/// The time of day. These values are the 4 different groups of time of day in Pokemon games since
|
||||
/// gen 5. The exact times these correspond to differ between games.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
|
||||
#[repr(u8)]
|
||||
pub enum TimeOfDay {
|
||||
/// The morning.
|
||||
Morning = 0,
|
||||
/// The day.
|
||||
#[default]
|
||||
Day = 1,
|
||||
/// The evening.
|
||||
Evening = 2,
|
||||
/// The night.
|
||||
Night = 3,
|
||||
}
|
||||
|
||||
impl Default for TimeOfDay {
|
||||
fn default() -> Self {
|
||||
TimeOfDay::Day
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
use crate::app_interface::{EffectParameter, Pokemon};
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
type Result<T> = crate::result::PkmnResult<T>;
|
||||
|
||||
pub trait ItemScript {
|
||||
fn new() -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
fn get_name(&self) -> &'static str;
|
||||
|
||||
/// Initializes the script with the given parameters for a specific item
|
||||
fn on_initialize(&self, _pars: Option<Vec<Rc<EffectParameter>>>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns whether the item is usable in the current context.
|
||||
/// Note that the host caches this value, so it will not be called again
|
||||
fn is_item_usable(&self) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Returns whether the item requires a target to be used.
|
||||
/// Note that the host caches this value, so it will not be called again
|
||||
fn requires_target(&self) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Returns whether the item can be held.
|
||||
/// Note that the host caches this value, so it will not be called again
|
||||
fn is_holdable(&self) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Returns whether the item is usable on the given target.
|
||||
fn is_target_valid(&self, _target: &Pokemon) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Returns whether the item can be held by the given target.
|
||||
fn can_target_hold(&self, _target: &Pokemon) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Handles the use of the item.
|
||||
fn on_use(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handles the use of the item on the given target.
|
||||
fn on_use_with_target(&self, _target: &Pokemon) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ pub(crate) mod cached_value;
|
|||
pub mod capabilities;
|
||||
pub mod extern_ref;
|
||||
pub mod ffi_array;
|
||||
pub mod item_script;
|
||||
pub mod script;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(crate) mod temporary;
|
||||
|
|
|
@ -496,7 +496,7 @@ pub enum ScriptOwner {
|
|||
|
||||
impl ScriptOwner {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
fn from_script(script: &dyn Script) -> Option<ScriptOwner> {
|
||||
fn from_script<'a>(script: &'a dyn Script) -> Option<ScriptOwner> {
|
||||
let script_ptr = crate::implementation::ScriptPtr::from_existing(script);
|
||||
unsafe {
|
||||
let kind = script_get_owner_kind(script_ptr);
|
||||
|
|
|
@ -42,17 +42,19 @@ pub mod utils;
|
|||
pub use result::*;
|
||||
|
||||
pub type LoadScriptFnType = Box<dyn Fn(ScriptCategory, &StringKey) -> Option<Box<dyn Script>>>;
|
||||
pub type LoadItemScriptFnType = Box<dyn Fn(&StringKey) -> Option<Box<dyn ItemScript>>>;
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
mod implementation {
|
||||
use super::LoadScriptFnType;
|
||||
use super::{LoadItemScriptFnType, LoadScriptFnType};
|
||||
|
||||
use crate::app_interface::{
|
||||
BattleImpl, DamageSource, DynamicLibraryImpl, EffectParameter, ExecutingMoveImpl, ItemImpl,
|
||||
PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier,
|
||||
Pokemon, PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier,
|
||||
};
|
||||
use crate::handling::extern_ref::ExternRef;
|
||||
use crate::handling::ffi_array::FFIArray;
|
||||
use crate::handling::item_script::ItemScript;
|
||||
use crate::handling::wasm_result::WasmVoidResult;
|
||||
use crate::handling::{Script, ScriptCapabilities, ScriptCategory};
|
||||
use alloc::boxed::Box;
|
||||
|
@ -63,6 +65,7 @@ mod implementation {
|
|||
use hashbrown::HashMap;
|
||||
|
||||
static mut LOAD_SCRIPT_FN: Option<LoadScriptFnType> = None;
|
||||
static mut LOAD_ITEM_SCRIPT_FN: Option<LoadItemScriptFnType> = None;
|
||||
|
||||
pub fn set_load_script_fn(f: LoadScriptFnType) {
|
||||
unsafe {
|
||||
|
@ -70,6 +73,12 @@ mod implementation {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_load_item_script_fn(f: LoadItemScriptFnType) {
|
||||
unsafe {
|
||||
LOAD_ITEM_SCRIPT_FN = Some(f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! exported_functions {
|
||||
(
|
||||
$(
|
||||
|
@ -91,74 +100,104 @@ mod implementation {
|
|||
static mut SCRIPT_PTR_REVERSE_CACHE: Option<HashMap<u32, Box<dyn Script>>> = None;
|
||||
static mut SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
||||
|
||||
#[repr(C)]
|
||||
static mut ITEM_SCRIPT_PTR_CACHE: Option<HashMap<*const dyn ItemScript, u32>> = None;
|
||||
static mut ITEM_SCRIPT_PTR_REVERSE_CACHE: Option<HashMap<u32, Box<dyn ItemScript>>> = None;
|
||||
static mut ITEM_SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
||||
|
||||
macro_rules! script_ptr_impl {
|
||||
($name:ident, $script:ident, $cache:ident, $reverse_cache:ident, $counter:ident) => {
|
||||
impl $name {
|
||||
fn get_cache<'a>() -> &'a mut HashMap<*const dyn $script, u32> {
|
||||
unsafe {
|
||||
if let None = $cache {
|
||||
$cache = Some(HashMap::new());
|
||||
}
|
||||
let cache = $cache.as_mut().unwrap();
|
||||
cache
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reverse_cache<'a>() -> &'a mut HashMap<u32, Box<dyn $script>> {
|
||||
unsafe {
|
||||
if let None = $reverse_cache {
|
||||
$reverse_cache = Some(HashMap::new());
|
||||
}
|
||||
let cache = $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($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
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Default)]
|
||||
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(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(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
|
||||
}
|
||||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct ItemScriptPtr {
|
||||
index: u32,
|
||||
}
|
||||
|
||||
script_ptr_impl!(
|
||||
ScriptPtr,
|
||||
Script,
|
||||
SCRIPT_PTR_CACHE,
|
||||
SCRIPT_PTR_REVERSE_CACHE,
|
||||
SCRIPT_INDEX_COUNTER
|
||||
);
|
||||
|
||||
script_ptr_impl!(
|
||||
ItemScriptPtr,
|
||||
ItemScript,
|
||||
ITEM_SCRIPT_PTR_CACHE,
|
||||
ITEM_SCRIPT_PTR_REVERSE_CACHE,
|
||||
ITEM_SCRIPT_INDEX_COUNTER
|
||||
);
|
||||
|
||||
exported_functions! {
|
||||
|
||||
fn load_script(category: ScriptCategory, name: ExternRef<StringKey>) -> ScriptPtr {
|
||||
|
@ -171,6 +210,16 @@ mod implementation {
|
|||
ScriptPtr::new(b)
|
||||
}
|
||||
|
||||
fn load_item_script(name: ExternRef<StringKey>) -> ItemScriptPtr {
|
||||
let name_c = StringKey::new(name);
|
||||
let boxed_script = unsafe { &LOAD_ITEM_SCRIPT_FN }.as_ref().unwrap()(&name_c);
|
||||
if boxed_script.is_none() {
|
||||
return ItemScriptPtr::null();
|
||||
}
|
||||
let b = boxed_script.unwrap();
|
||||
ItemScriptPtr::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.
|
||||
|
@ -178,6 +227,13 @@ mod implementation {
|
|||
drop(boxed_script);
|
||||
}
|
||||
|
||||
fn destroy_item_script(script: *mut Box<dyn ItemScript>) {
|
||||
// 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()
|
||||
|
@ -737,9 +793,109 @@ mod implementation {
|
|||
*out = out_saturating.0;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Item script functions
|
||||
|
||||
fn item_script_item_on_initialize(script: ItemScriptPtr, parameters: u64) -> WasmVoidResult {
|
||||
let parameters : FFIArray<ExternRef<EffectParameter>> = FFIArray::from_u64(parameters);
|
||||
let parameters = Vec::from_raw_parts(parameters.ptr(), parameters.len(), parameters.len());
|
||||
let parameters = parameters.into_iter().map(|p| Rc::new(EffectParameter::new(p).unwrap())).collect::<Vec<_>>();
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_initialize(Some(parameters)))
|
||||
}
|
||||
|
||||
fn item_script_item_is_usable(script: ItemScriptPtr, out: *mut bool) -> WasmVoidResult {
|
||||
let res = script.val().unwrap().is_item_usable();
|
||||
match res {
|
||||
Ok(r) => {
|
||||
unsafe {
|
||||
*out = r;
|
||||
}
|
||||
WasmVoidResult::ok(())
|
||||
}
|
||||
Err(e) => WasmVoidResult::err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_script_item_requires_target(script: ItemScriptPtr, out: *mut bool) -> WasmVoidResult {
|
||||
let res = script.val().unwrap().requires_target();
|
||||
match res {
|
||||
Ok(r) => {
|
||||
unsafe {
|
||||
*out = r;
|
||||
}
|
||||
WasmVoidResult::ok(())
|
||||
}
|
||||
Err(e) => WasmVoidResult::err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_script_item_is_holdable(script: ItemScriptPtr, out: *mut bool) -> WasmVoidResult {
|
||||
let res = script.val().unwrap().is_holdable();
|
||||
match res {
|
||||
Ok(r) => {
|
||||
unsafe {
|
||||
*out = r;
|
||||
}
|
||||
WasmVoidResult::ok(())
|
||||
}
|
||||
Err(e) => WasmVoidResult::err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_script_item_is_target_valid(
|
||||
script: ItemScriptPtr,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
out: *mut bool
|
||||
) -> WasmVoidResult {
|
||||
let target : Pokemon = target.not_null_rc();
|
||||
let res = script.val().unwrap().is_target_valid(&target);
|
||||
match res {
|
||||
Ok(r) => {
|
||||
unsafe {
|
||||
*out = r;
|
||||
}
|
||||
WasmVoidResult::ok(())
|
||||
}
|
||||
Err(e) => WasmVoidResult::err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_script_item_can_target_hold(
|
||||
script: ItemScriptPtr,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
out: *mut bool
|
||||
) -> WasmVoidResult {
|
||||
let target : Pokemon = target.not_null_rc();
|
||||
let res = script.val().unwrap().can_target_hold(&target);
|
||||
match res {
|
||||
Ok(r) => {
|
||||
unsafe {
|
||||
*out = r;
|
||||
}
|
||||
WasmVoidResult::ok(())
|
||||
}
|
||||
Err(e) => WasmVoidResult::err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_script_item_on_use(
|
||||
script: ItemScriptPtr,
|
||||
) -> WasmVoidResult {
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_use())
|
||||
}
|
||||
|
||||
fn item_script_item_on_use_with_target(
|
||||
script: ItemScriptPtr,
|
||||
target: ExternRef<PokemonImpl>,
|
||||
) -> WasmVoidResult {
|
||||
let target : Pokemon = target.not_null_rc();
|
||||
WasmVoidResult::from_res(script.val().unwrap().on_use_with_target(&target))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
use crate::handling::item_script::ItemScript;
|
||||
use crate::handling::{Script, ScriptCategory};
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub use implementation::*;
|
||||
|
|
Loading…
Reference in New Issue