Support for item use scripts
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-07-22 21:16:19 +02:00
parent 48ff2c4536
commit e44ddf18a2
10 changed files with 388 additions and 72 deletions

View File

@@ -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();
}

View File

@@ -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(())
}
}

View File

@@ -0,0 +1 @@
pub mod healing_item;

View File

@@ -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))]

View File

@@ -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
}