From 42bee5e37c49a027e7e2161f4c84a3cdffec1083 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 11 May 2024 16:01:04 +0200 Subject: [PATCH] Large amounts of work on Rune --- src/dynamic_data/choices.rs | 110 +++------ src/dynamic_data/models/learned_move.rs | 25 +- src/dynamic_data/models/pokemon.rs | 5 +- .../serialization/serialized_pokemon.rs | 7 +- src/dynamic_data/script_handling/mod.rs | 12 +- src/ffi/dynamic_data/models/pokemon.rs | 52 ++--- src/script_implementations/rune/script.rs | 20 +- .../rune/wrappers/dynamic_data/battle.rs | 65 ++++++ .../wrappers/dynamic_data/battle_party.rs | 14 ++ .../wrappers/dynamic_data/battle_random.rs | 43 ++++ .../rune/wrappers/dynamic_data/battle_side.rs | 16 ++ .../wrappers/dynamic_data/executing_move.rs | 8 +- .../wrappers/dynamic_data/learned_move.rs | 49 ++++ .../rune/wrappers/dynamic_data/libraries.rs | 70 ++++++ .../rune/wrappers/dynamic_data/mod.rs | 31 ++- .../rune/wrappers/dynamic_data/pokemon.rs | 216 +++++++++++++++++- .../rune/wrappers/dynamic_data/turn_choice.rs | 114 +++++++-- .../rune/wrappers/mod.rs | 6 +- .../rune/wrappers/static_data/form.rs | 2 +- .../rune/wrappers/static_data/item.rs | 2 +- .../wrappers/static_data/libraries/mod.rs | 2 +- .../static_data/libraries/static_data.rs | 2 +- .../rune/wrappers/static_data/mod.rs | 6 +- .../wrappers/static_data/statistic_set.rs | 24 +- src/static_data/mod.rs | 36 +-- src/static_data/species_data/mod.rs | 18 +- src/static_data/statistic_set.rs | 102 ++++----- 27 files changed, 751 insertions(+), 306 deletions(-) create mode 100644 src/script_implementations/rune/wrappers/dynamic_data/battle.rs create mode 100644 src/script_implementations/rune/wrappers/dynamic_data/battle_party.rs create mode 100644 src/script_implementations/rune/wrappers/dynamic_data/battle_random.rs create mode 100644 src/script_implementations/rune/wrappers/dynamic_data/battle_side.rs create mode 100644 src/script_implementations/rune/wrappers/dynamic_data/learned_move.rs create mode 100644 src/script_implementations/rune/wrappers/dynamic_data/libraries.rs diff --git a/src/dynamic_data/choices.rs b/src/dynamic_data/choices.rs index 8a4037c..38a4cce 100755 --- a/src/dynamic_data/choices.rs +++ b/src/dynamic_data/choices.rs @@ -56,47 +56,33 @@ impl TurnChoice { } /// Get the user of the given choice. - pub fn user(&self) -> &Pokemon { - &self.choice_data().user - } + pub fn user(&self) -> &Pokemon { &self.choice_data().user } /// Get the speed of the user for the choice. Note that this speed is the speed of the Pokemon /// at the start of the turn! - pub fn speed(&self) -> u32 { - self.choice_data().speed.load(Ordering::Relaxed) - } + pub fn speed(&self) -> u32 { self.choice_data().speed.load(Ordering::Relaxed) } /// Sets the speed of user for the choice. Note that this speed is the speed of the Pokemon at /// the start of the turn! - pub fn set_speed(&self, value: u32) { - self.choice_data().speed.store(value, Ordering::Relaxed); - } + pub fn set_speed(&self, value: u32) { self.choice_data().speed.store(value, Ordering::Relaxed); } /// Gets whether or not the choice has failed. If we notice this when we execute the choice, we /// will not execute it. - pub fn has_failed(&self) -> bool { - self.choice_data().has_failed.load(Ordering::SeqCst) - } + pub fn has_failed(&self) -> bool { self.choice_data().has_failed.load(Ordering::SeqCst) } /// Fails the choice. This will prevent it from executing and run a specific fail handling during /// execution. Note that this can not be undone. - pub fn fail(&self) { - self.choice_data().has_failed.store(true, Ordering::SeqCst) - } + pub fn fail(&self) { self.choice_data().has_failed.store(true, Ordering::SeqCst) } /// The random value of a turn choice gets set during the start of a choice, and is used for tie /// breaking of turn executions. This means that choices get executed with a predictable order, /// regardless of implementation details. - pub(crate) fn random_value(&self) -> u32 { - self.choice_data().random_value.load(Ordering::Relaxed) - } + pub(crate) fn random_value(&self) -> u32 { self.choice_data().random_value.load(Ordering::Relaxed) } /// This sets the above random value. - pub(crate) fn set_random_value(&self, val: u32) { - self.choice_data().random_value.store(val, Ordering::Relaxed) - } + pub(crate) fn set_random_value(&self, val: u32) { self.choice_data().random_value.store(val, Ordering::Relaxed) } - /// Helper function to get the move choice data from a turn. Note that this will panic if not + /// Helper function to get the move choice data from a turn. Note that this will error if not /// used on a move choice. pub(crate) fn get_move_turn_data(&self) -> Result<&MoveChoice> { if let TurnChoice::Move(data) = self { @@ -187,48 +173,28 @@ impl MoveChoice { } /// The actual learned move on the Pokemon we use for this choice. - pub fn used_move(&self) -> &Arc { - &self.used_move - } + pub fn used_move(&self) -> &Arc { &self.used_move } /// The target side the move is aimed at. - pub fn target_side(&self) -> u8 { - self.target_side - } + pub fn target_side(&self) -> u8 { self.target_side } /// The Pokemon index on the side we're aiming at. - pub fn target_index(&self) -> u8 { - self.target_index - } + pub fn target_index(&self) -> u8 { self.target_index } /// The priority of the move choice at the beginning of the turn. - pub fn priority(&self) -> i8 { - self.priority.load(Ordering::Relaxed) - } + pub fn priority(&self) -> i8 { self.priority.load(Ordering::Relaxed) } /// The priority of the move choice at the beginning of the turn. - pub fn set_priority(&self, value: i8) { - self.priority.store(value, Ordering::Relaxed) - } + pub fn set_priority(&self, value: i8) { self.priority.store(value, Ordering::Relaxed) } /// The user of the choice. - pub fn user(&self) -> &Pokemon { - &self.choice_data.user - } + pub fn user(&self) -> &Pokemon { &self.choice_data.user } /// The move script of the choice. - pub fn script(&self) -> &ScriptContainer { - &self.script - } + pub fn script(&self) -> &ScriptContainer { &self.script } } impl ScriptSource for MoveChoice { - fn get_script_count(&self) -> Result { - Ok(self.choice_data.user.get_script_count()? + 1) - } + fn get_script_count(&self) -> Result { Ok(self.choice_data.user.get_script_count()? + 1) } - fn get_script_source_data(&self) -> &RwLock { - &self.choice_data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.choice_data.script_source_data } - fn get_own_scripts(&self, scripts: &mut Vec) { - scripts.push((&self.script).into()); - } + fn get_own_scripts(&self, scripts: &mut Vec) { scripts.push((&self.script).into()); } fn collect_scripts(&self, scripts: &mut Vec) -> Result<()> { self.get_own_scripts(scripts); @@ -260,13 +226,9 @@ impl ItemChoice { } impl ScriptSource for ItemChoice { - fn get_script_count(&self) -> Result { - Ok(0) - } + fn get_script_count(&self) -> Result { Ok(0) } - fn get_script_source_data(&self) -> &RwLock { - &self.choice_data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.choice_data.script_source_data } fn get_own_scripts(&self, _scripts: &mut Vec) {} @@ -299,13 +261,9 @@ impl SwitchChoice { } impl ScriptSource for SwitchChoice { - fn get_script_count(&self) -> Result { - Ok(0) - } + fn get_script_count(&self) -> Result { Ok(0) } - fn get_script_source_data(&self) -> &RwLock { - &self.choice_data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.choice_data.script_source_data } fn get_own_scripts(&self, _scripts: &mut Vec) {} @@ -337,13 +295,9 @@ impl FleeChoice { } impl ScriptSource for FleeChoice { - fn get_script_count(&self) -> Result { - Ok(0) - } + fn get_script_count(&self) -> Result { Ok(0) } - fn get_script_source_data(&self) -> &RwLock { - &self.choice_data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.choice_data.script_source_data } fn get_own_scripts(&self, _scripts: &mut Vec) {} @@ -376,13 +330,9 @@ impl PassChoice { } impl ScriptSource for PassChoice { - fn get_script_count(&self) -> Result { - Ok(0) - } + fn get_script_count(&self) -> Result { Ok(0) } - fn get_script_source_data(&self) -> &RwLock { - &self.choice_data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.choice_data.script_source_data } fn get_own_scripts(&self, _scripts: &mut Vec) {} @@ -392,17 +342,13 @@ impl ScriptSource for PassChoice { } impl PartialEq for TurnChoice { - fn eq(&self, other: &Self) -> bool { - std::ptr::eq(self, other) - } + fn eq(&self, other: &Self) -> bool { std::ptr::eq(self, other) } } impl Eq for TurnChoice {} impl PartialOrd for TurnChoice { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for TurnChoice { diff --git a/src/dynamic_data/models/learned_move.rs b/src/dynamic_data/models/learned_move.rs index 3f3c165..0c03444 100755 --- a/src/dynamic_data/models/learned_move.rs +++ b/src/dynamic_data/models/learned_move.rs @@ -23,6 +23,7 @@ pub struct LearnedMove { #[derive(Copy, Clone, Debug, Default)] #[repr(u8)] #[cfg_attr(feature = "serde", derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr))] +#[cfg_attr(feature = "rune", derive(rune::Any))] pub enum MoveLearnMethod { /// We do not know the learn method. #[default] @@ -44,28 +45,18 @@ impl LearnedMove { } /// The immutable move information of the move. - pub fn move_data(&self) -> &Arc { - &self.move_data - } + pub fn move_data(&self) -> &Arc { &self.move_data } /// The maximal power points for this move. - pub fn max_pp(&self) -> u8 { - self.move_data.base_usages() + self.max_pp_modification - } + pub fn max_pp(&self) -> u8 { self.move_data.base_usages() + self.max_pp_modification } /// The amount by which the maximal power points have been modified for this move. /// This could for example be due to PP Ups. - pub fn max_pp_modification(&self) -> u8 { - self.max_pp_modification - } + pub fn max_pp_modification(&self) -> u8 { self.max_pp_modification } /// The amount of remaining power points. If this is 0, we can not use the move anymore. - pub fn remaining_pp(&self) -> u8 { - self.remaining_pp.load(Ordering::Relaxed) - } + pub fn remaining_pp(&self) -> u8 { self.remaining_pp.load(Ordering::Relaxed) } /// The way the move was learned. - pub fn learn_method(&self) -> MoveLearnMethod { - self.learn_method - } + pub fn learn_method(&self) -> MoveLearnMethod { self.learn_method } /// Try and reduce the PP by a certain amount. If the amount is higher than the current uses, /// return false. Otherwise, reduce the PP, and return true. @@ -81,9 +72,7 @@ impl LearnedMove { } /// Set the remaining PP to the max amount of PP. - pub fn restore_all_uses(&self) { - self.remaining_pp.store(self.max_pp(), Ordering::SeqCst); - } + pub fn restore_all_uses(&self) { self.remaining_pp.store(self.max_pp(), Ordering::SeqCst); } /// Restore the remaining PP by a certain amount. Will prevent it from going above max PP. pub fn restore_uses(&self, mut uses: u8) { diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index 6727379..e2ad91a 100755 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -256,7 +256,7 @@ impl Pokemon { /// currently not used, and can be used for other implementations. pub fn coloring(&self) -> u8 { self.data.coloring } /// Gets the held item of a Pokemon - pub fn held_item(&self) -> &RwLock>> { &self.data.held_item } + pub fn held_item(&self) -> Option> { self.data.held_item.read().clone().map(|v| v) } /// Checks whether the Pokemon is holding a specific item. pub fn has_held_item(&self, name: &StringKey) -> bool { // Only true if we have an item, and the item name is the same as the requested item. @@ -413,7 +413,7 @@ impl Pokemon { /// if the Pokemon is on the battlefield. pub fn get_battle_index(&self) -> Option { self.data.battle_data.read().as_ref().map(|data| data.index()) } /// Returns whether something overrides the ability. - pub fn is_ability_overriden(&self) -> bool { self.data.override_ability.is_some() } + pub fn is_ability_overridden(&self) -> bool { self.data.override_ability.is_some() } /// Returns the currently active ability. pub fn active_ability(&self) -> Result> { if let Some(v) = &self.data.override_ability { @@ -1021,6 +1021,7 @@ impl VolatileScriptsOwner for Pokemon { /// A source of damage. #[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "rune", derive(rune::Any))] #[repr(u8)] pub enum DamageSource { /// The damage is done by a move. diff --git a/src/dynamic_data/models/serialization/serialized_pokemon.rs b/src/dynamic_data/models/serialization/serialized_pokemon.rs index 44dc013..5d1fbaa 100644 --- a/src/dynamic_data/models/serialization/serialized_pokemon.rs +++ b/src/dynamic_data/models/serialization/serialized_pokemon.rs @@ -96,10 +96,7 @@ impl Into> for &Pokemon { personality_value: self.personality_value(), gender: self.gender(), coloring: self.coloring(), - held_item: { - let held_item = self.held_item().read(); - held_item.as_ref().map(|held_item| held_item.name().clone()) - }, + held_item: self.held_item().map(|held_item| held_item.name().clone()), current_health: self.current_health(), weight: self.weight(), height: self.height(), @@ -111,7 +108,7 @@ impl Into> for &Pokemon { nickname: self.nickname().clone(), ability_index: *self.real_ability(), override_ability: { - if self.is_ability_overriden() { + if self.is_ability_overridden() { Some(self.active_ability()?.name().clone()) } else { None diff --git a/src/dynamic_data/script_handling/mod.rs b/src/dynamic_data/script_handling/mod.rs index a1e4955..05ada21 100755 --- a/src/dynamic_data/script_handling/mod.rs +++ b/src/dynamic_data/script_handling/mod.rs @@ -4,14 +4,10 @@ use std::sync::{Arc, LazyLock, Weak}; use parking_lot::RwLock; use crate::VecExt; -#[doc(inline)] -pub use item_script::*; -#[doc(inline)] -pub use script::*; -#[doc(inline)] -pub use script_set::*; -#[doc(inline)] -pub use volatile_scripts_owner::*; +#[doc(inline)] pub use item_script::*; +#[doc(inline)] pub use script::*; +#[doc(inline)] pub use script_set::*; +#[doc(inline)] pub use volatile_scripts_owner::*; /// Scripts that are used for item usage mod item_script; diff --git a/src/ffi/dynamic_data/models/pokemon.rs b/src/ffi/dynamic_data/models/pokemon.rs index 69b2a5a..c05eb8f 100644 --- a/src/ffi/dynamic_data/models/pokemon.rs +++ b/src/ffi/dynamic_data/models/pokemon.rs @@ -78,16 +78,12 @@ extern "C" fn pokemon_display_form(handle: FFIHandle) -> FFIHandle) -> LevelInt { - handle.from_ffi_handle().level() -} +extern "C" fn pokemon_level(handle: FFIHandle) -> LevelInt { handle.from_ffi_handle().level() } /// The experience of the Pokemon. /// [See also](https://bulbapedia.bulbagarden.net/wiki/Experience) #[no_mangle] -extern "C" fn pokemon_experience(handle: FFIHandle) -> u32 { - handle.from_ffi_handle().experience() -} +extern "C" fn pokemon_experience(handle: FFIHandle) -> u32 { handle.from_ffi_handle().experience() } /// The personality value of the Pokemon. /// [See also](https://bulbapedia.bulbagarden.net/wiki/Personality_value) @@ -98,21 +94,17 @@ extern "C" fn pokemon_personality_value(handle: FFIHandle) -> u32 { /// The gender of the Pokemon. #[no_mangle] -extern "C" fn pokemon_gender(handle: FFIHandle) -> Gender { - handle.from_ffi_handle().gender() -} +extern "C" fn pokemon_gender(handle: FFIHandle) -> Gender { handle.from_ffi_handle().gender() } /// The coloring of the Pokemon. If this is 1, the Pokemon is shiny, otherwise it is not. This can /// also be used for other custom coloring schemes. #[no_mangle] -extern "C" fn pokemon_coloring(handle: FFIHandle) -> u8 { - handle.from_ffi_handle().coloring() -} +extern "C" fn pokemon_coloring(handle: FFIHandle) -> u8 { handle.from_ffi_handle().coloring() } /// Gets the held item of a Pokemon #[no_mangle] extern "C" fn pokemon_held_item(handle: FFIHandle) -> FFIHandle> { - if let Some(v) = handle.from_ffi_handle().held_item().read().as_ref() { + if let Some(v) = handle.from_ffi_handle().held_item() { FFIHandle::get_handle(v.clone().into()) } else { FFIHandle::none() @@ -160,27 +152,19 @@ extern "C" fn pokemon_consume_held_item(handle: FFIHandle) -> FFIResult /// The current health of the Pokemon. #[no_mangle] -extern "C" fn pokemon_current_health(handle: FFIHandle) -> u32 { - handle.from_ffi_handle().current_health() -} +extern "C" fn pokemon_current_health(handle: FFIHandle) -> u32 { handle.from_ffi_handle().current_health() } /// The max health of the Pokemon. #[no_mangle] -extern "C" fn pokemon_max_health(handle: FFIHandle) -> u32 { - handle.from_ffi_handle().max_health() -} +extern "C" fn pokemon_max_health(handle: FFIHandle) -> u32 { handle.from_ffi_handle().max_health() } /// The current weight of the Pokemon. #[no_mangle] -extern "C" fn pokemon_weight(handle: FFIHandle) -> f32 { - handle.from_ffi_handle().weight() -} +extern "C" fn pokemon_weight(handle: FFIHandle) -> f32 { handle.from_ffi_handle().weight() } /// The current height of the Pokemon. #[no_mangle] -extern "C" fn pokemon_height(handle: FFIHandle) -> f32 { - handle.from_ffi_handle().height() -} +extern "C" fn pokemon_height(handle: FFIHandle) -> f32 { handle.from_ffi_handle().height() } /// An optional nickname of the Pokemon. #[no_mangle] @@ -211,9 +195,7 @@ extern "C" fn pokemon_real_ability_index(handle: FFIHandle) -> u8 { /// The amount of types the Pokemon has. #[no_mangle] -extern "C" fn pokemon_types_length(ptr: FFIHandle) -> usize { - ptr.from_ffi_handle().types().len() -} +extern "C" fn pokemon_types_length(ptr: FFIHandle) -> usize { ptr.from_ffi_handle().types().len() } /// Gets a type of the Pokemon. #[no_mangle] @@ -328,7 +310,7 @@ extern "C" fn pokemon_get_battle_index(handle: FFIHandle) -> u8 { /// Returns whether something overrides the ability. #[no_mangle] extern "C" fn pokemon_is_ability_overriden(handle: FFIHandle) -> u8 { - u8::from(handle.from_ffi_handle().is_ability_overriden()) + u8::from(handle.from_ffi_handle().is_ability_overridden()) } /// Returns the currently active ability. @@ -388,15 +370,11 @@ extern "C" fn pokemon_change_form(handle: FFIHandle, form: FFIHandle) -> u8 { - u8::from(handle.from_ffi_handle().is_usable()) -} +extern "C" fn pokemon_is_usable(handle: FFIHandle) -> u8 { u8::from(handle.from_ffi_handle().is_usable()) } /// Returns whether the Pokemon is fainted. #[no_mangle] -extern "C" fn pokemon_is_fainted(handle: FFIHandle) -> u8 { - u8::from(handle.from_ffi_handle().is_fainted()) -} +extern "C" fn pokemon_is_fainted(handle: FFIHandle) -> u8 { u8::from(handle.from_ffi_handle().is_fainted()) } /// Whether or not the Pokemon is on the battlefield. #[no_mangle] @@ -447,9 +425,7 @@ extern "C" fn pokemon_learn_move( /// Removes the current non-volatile status from the Pokemon. #[no_mangle] -extern "C" fn pokemon_clear_status(handle: FFIHandle) { - handle.from_ffi_handle().clear_status() -} +extern "C" fn pokemon_clear_status(handle: FFIHandle) { handle.from_ffi_handle().clear_status() } /// Returns a serialized version of the Pokemon as xml. #[cfg(feature = "serde")] diff --git a/src/script_implementations/rune/script.rs b/src/script_implementations/rune/script.rs index da8dd5c..3058aa8 100644 --- a/src/script_implementations/rune/script.rs +++ b/src/script_implementations/rune/script.rs @@ -4,17 +4,15 @@ use crate::script_implementations::rune::RuneScriptType; use crate::static_data::Parameter; use crate::StringKey; use hashbrown::HashMap; -use parking_lot::RwLock; use rune::runtime::{Object, RuntimeContext, Shared, VmError, VmResult}; use rune::{Unit, Value}; use std::convert::TryFrom; -use std::ops::Deref; use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::Arc; pub struct RuneScript { name: StringKey, - state: RwLock>, + state: Shared, /// Returns an atomic bool for internal marking of deletion. This is currently only specifically /// used for deletion of a script while we are holding a reference to it (i.e. executing a script /// hook on it). @@ -43,7 +41,7 @@ impl RuneScript { ) -> Self { Self { name, - state: RwLock::new(object), + state: object, marked_for_deletion: Default::default(), suppressed_count: Default::default(), script_type, @@ -51,6 +49,8 @@ impl RuneScript { unit, } } + + pub(crate) fn get_state(&self) -> Shared { self.state.clone() } } impl Script for RuneScript { @@ -68,10 +68,10 @@ impl Script for RuneScript { if pars.is_empty() { return Ok(()); } - let write_lock = self.state.write(); + let state = self.state.clone(); for par in pars { let key = rune::alloc::string::String::try_from(par.0.str())?; - write_lock + state .borrow_mut()? .insert(key, parameter_to_rune_value(par.1.as_ref())?)?; } @@ -82,14 +82,12 @@ impl Script for RuneScript { if let Some(hash) = self.script_type.fn_change_speed { let mut vm = rune::runtime::Vm::new(self.runtime.clone(), self.unit.clone()); let speed_handle = wrap_int_reference(*speed as i64)?; - let read_lock = self.state.read(); - let state = read_lock.deref(); let res = vm .execute( hash, vec![ - Value::Object(state.clone()), + Value::Object(self.state.clone()), Value::from(choice.wrap()), speed_handle.clone(), ], @@ -114,13 +112,11 @@ impl Script for RuneScript { if let Some(hash) = self.script_type.fn_block_critical { let mut vm = rune::runtime::Vm::new(self.runtime.clone(), self.unit.clone()); let block_critical_handle = wrap_bool_reference(*block_critical)?; - let read_lock = self.state.read(); - let state = read_lock.deref(); vm.execute( hash, vec![ - Value::Object(state.clone()), + Value::Object(self.state.clone()), Value::from(move_data.wrap()), Value::from(target.wrap()), Value::from(hit), diff --git a/src/script_implementations/rune/wrappers/dynamic_data/battle.rs b/src/script_implementations/rune/wrappers/dynamic_data/battle.rs new file mode 100644 index 0000000..789ba62 --- /dev/null +++ b/src/script_implementations/rune/wrappers/dynamic_data/battle.rs @@ -0,0 +1,65 @@ +use crate::dynamic_data::Battle; +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use rune::runtime::{AnyObj, Shared}; +use rune::Any; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneBattle::library)?; + module.function_meta(RuneBattle::parties)?; + module.function_meta(RuneBattle::can_flee)?; + module.function_meta(RuneBattle::number_of_sides)?; + module.function_meta(RuneBattle::pokemon_per_side)?; + module.function_meta(RuneBattle::sides)?; + module.function_meta(RuneBattle::random)?; + module.function_meta(RuneBattle::has_ended)?; + module.function_meta(RuneBattle::current_turn)?; + module.function_meta(RuneBattle::get_pokemon)?; + module.function_meta(RuneBattle::set_weather)?; + + Ok(()) +} + +#[derive(Debug, Clone, Any)] +pub struct RuneBattle(Battle); + +impl_rune_wrapper!(&Battle, RuneBattle); + +impl RuneBattle { + #[rune::function] + fn library(&self) -> Shared { self.0.library().wrap() } + + #[rune::function] + fn parties(&self) -> Vec> { self.0.parties().iter().map(|p| p.wrap()).collect() } + + #[rune::function] + fn can_flee(&self) -> bool { self.0.can_flee() } + + #[rune::function] + fn number_of_sides(&self) -> u8 { self.0.number_of_sides() } + + #[rune::function] + fn pokemon_per_side(&self) -> u8 { self.0.pokemon_per_side() } + + #[rune::function] + fn sides(&self) -> Vec> { self.0.sides().iter().map(|s| s.wrap()).collect() } + + #[rune::function] + fn random(&self) -> Shared { self.0.random().wrap() } + + #[rune::function] + fn has_ended(&self) -> bool { self.0.has_ended() } + + #[rune::function] + fn current_turn(&self) -> u32 { self.0.current_turn() } + + #[rune::function] + fn get_pokemon(&self, side: u8, index: u8) -> Option> { + self.0.get_pokemon(side, index).map(|v| v.wrap()) + } + + #[rune::function] + fn set_weather(&self, weather: Option) -> anyhow::Result<()> { + self.0.set_weather(weather.map(|w| w.0)) + } +} diff --git a/src/script_implementations/rune/wrappers/dynamic_data/battle_party.rs b/src/script_implementations/rune/wrappers/dynamic_data/battle_party.rs new file mode 100644 index 0000000..a6747b3 --- /dev/null +++ b/src/script_implementations/rune/wrappers/dynamic_data/battle_party.rs @@ -0,0 +1,14 @@ +use crate::dynamic_data::BattleParty; +use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use rune::Any; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + Ok(()) +} + +#[derive(Debug, Clone, Any)] +pub struct RuneBattleParty(pub Arc); + +impl_rune_wrapper!(&Arc, RuneBattleParty); diff --git a/src/script_implementations/rune/wrappers/dynamic_data/battle_random.rs b/src/script_implementations/rune/wrappers/dynamic_data/battle_random.rs new file mode 100644 index 0000000..6950904 --- /dev/null +++ b/src/script_implementations/rune/wrappers/dynamic_data/battle_random.rs @@ -0,0 +1,43 @@ +use crate::dynamic_data::BattleRandom; +use crate::script_implementations::rune::wrappers::dynamic_data::executing_move::RuneExecutingMove; +use crate::script_implementations::rune::wrappers::dynamic_data::pokemon::RunePokemon; +use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use rune::Any; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneBattleRandom::get)?; + module.function_meta(RuneBattleRandom::get_max)?; + module.function_meta(RuneBattleRandom::get_between)?; + module.function_meta(RuneBattleRandom::effect_chance)?; + + Ok(()) +} + +#[derive(Debug, Clone, Any)] +pub struct RuneBattleRandom(pub(crate) Arc); + +impl_rune_wrapper!(&Arc, RuneBattleRandom); + +impl RuneBattleRandom { + #[rune::function] + fn get(&self) -> i32 { self.0.get().unwrap() } + + #[rune::function] + fn get_max(&self, max: i32) -> i32 { self.0.get_max(max).unwrap() } + + #[rune::function] + fn get_between(&self, min: i32, max: i32) -> i32 { self.0.get_between(min, max).unwrap() } + + #[rune::function] + fn effect_chance( + &self, + chance: f32, + executing_move: &RuneExecutingMove, + target: RunePokemon, + hit_number: u8, + ) -> anyhow::Result { + self.0.effect_chance(chance, &executing_move.0, &target.0, hit_number) + } +} diff --git a/src/script_implementations/rune/wrappers/dynamic_data/battle_side.rs b/src/script_implementations/rune/wrappers/dynamic_data/battle_side.rs new file mode 100644 index 0000000..6e75d95 --- /dev/null +++ b/src/script_implementations/rune/wrappers/dynamic_data/battle_side.rs @@ -0,0 +1,16 @@ +use crate::dynamic_data::BattleSide; +use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use rune::Any; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + + Ok(()) +} + +#[derive(Debug, Clone, Any)] +pub struct RuneBattleSide(pub BattleSide); + +impl_rune_wrapper!(&BattleSide, RuneBattleSide); + +impl RuneBattleSide {} diff --git a/src/script_implementations/rune/wrappers/dynamic_data/executing_move.rs b/src/script_implementations/rune/wrappers/dynamic_data/executing_move.rs index e412871..139c6d7 100644 --- a/src/script_implementations/rune/wrappers/dynamic_data/executing_move.rs +++ b/src/script_implementations/rune/wrappers/dynamic_data/executing_move.rs @@ -13,8 +13,10 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { Ok(()) } -#[derive(Debug, Any)] -pub struct RuneExecutingMove(Arc); +#[derive(Debug, Clone, Any)] +pub struct RuneExecutingMove(pub Arc); + +impl_rune_wrapper!(&Arc, RuneExecutingMove); impl RuneExecutingMove { #[rune::function] @@ -24,5 +26,3 @@ impl RuneExecutingMove { #[rune::function] fn user(&self) -> Shared { self.0.user().wrap() } } - -impl_rune_wrapper!(&Arc, RuneExecutingMove); diff --git a/src/script_implementations/rune/wrappers/dynamic_data/learned_move.rs b/src/script_implementations/rune/wrappers/dynamic_data/learned_move.rs new file mode 100644 index 0000000..a7f1c0f --- /dev/null +++ b/src/script_implementations/rune/wrappers/dynamic_data/learned_move.rs @@ -0,0 +1,49 @@ +use crate::dynamic_data::{LearnedMove, MoveLearnMethod}; +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper}; +use rune::runtime::{AnyObj, Shared}; +use rune::Any; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneLearnedMove::move_data)?; + module.function_meta(RuneLearnedMove::max_pp)?; + module.function_meta(RuneLearnedMove::max_pp_modification)?; + module.function_meta(RuneLearnedMove::remaining_pp)?; + module.function_meta(RuneLearnedMove::learn_method)?; + module.function_meta(RuneLearnedMove::try_use)?; + module.function_meta(RuneLearnedMove::restore_all_uses)?; + module.function_meta(RuneLearnedMove::restore_uses)?; + Ok(()) +} + +#[derive(Debug, Clone, Any)] +struct RuneLearnedMove(Arc); + +impl_rune_wrapper!(&Arc, RuneLearnedMove); + +impl RuneLearnedMove { + #[rune::function] + fn move_data(&self) -> Shared { self.0.move_data().wrap() } + + #[rune::function] + fn max_pp(&self) -> u8 { self.0.max_pp() } + + #[rune::function] + fn max_pp_modification(&self) -> u8 { self.0.max_pp_modification() } + + #[rune::function] + fn remaining_pp(&self) -> u8 { self.0.remaining_pp() } + + #[rune::function] + fn learn_method(&self) -> MoveLearnMethod { self.0.learn_method() } + + #[rune::function] + fn try_use(&self, amount: u8) -> bool { self.0.try_use(amount) } + + #[rune::function] + fn restore_all_uses(&self) { self.0.restore_all_uses() } + + #[rune::function] + fn restore_uses(&self, amount: u8) { self.0.restore_uses(amount) } +} diff --git a/src/script_implementations/rune/wrappers/dynamic_data/libraries.rs b/src/script_implementations/rune/wrappers/dynamic_data/libraries.rs new file mode 100644 index 0000000..5d44654 --- /dev/null +++ b/src/script_implementations/rune/wrappers/dynamic_data/libraries.rs @@ -0,0 +1,70 @@ +use crate::dynamic_data::{BattleStatCalculator, DynamicLibrary, MiscLibrary}; +use crate::script_implementations::rune::wrappers::dynamic_data::pokemon::RunePokemon; +use crate::script_implementations::rune::wrappers::dynamic_data::turn_choice::RuneTurnChoice; +use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use crate::script_implementations::rune::wrappers::static_data::libraries::static_data::RuneStaticData; +use crate::static_data::{Statistic, TimeOfDay}; +use rune::Any; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneBattleStatCalculator::calculate_flat_stat)?; + module.function_meta(RuneBattleStatCalculator::calculate_boosted_stat)?; + + module.ty::()?; + module.function_meta(RuneMiscLibrary::can_flee)?; + module.function_meta(RuneMiscLibrary::time_of_day)?; + + module.ty::()?; + module.function_meta(RuneDynamicLibrary::battle_stat_calculator)?; + module.function_meta(RuneDynamicLibrary::misc_library)?; + + Ok(()) +} + +#[derive(Debug, Clone, Any)] +pub struct RuneBattleStatCalculator(Arc); + +impl_rune_wrapper!(&Arc, RuneBattleStatCalculator); + +impl RuneBattleStatCalculator { + #[rune::function] + fn calculate_flat_stat(&self, pokemon: RunePokemon, stat: Statistic) -> anyhow::Result { + self.0.calculate_flat_stat(&pokemon.0, stat) + } + + #[rune::function] + fn calculate_boosted_stat(&self, pokemon: RunePokemon, stat: Statistic) -> anyhow::Result { + self.0.calculate_boosted_stat(&pokemon.0, stat) + } +} + +#[derive(Debug, Clone, Any)] +pub struct RuneMiscLibrary(Arc); +impl_rune_wrapper!(&Arc, RuneMiscLibrary); + +impl RuneMiscLibrary { + #[rune::function] + fn can_flee(&self, choice: RuneTurnChoice) -> bool { self.0.can_flee(choice.get_turn_choice()) } + + #[rune::function] + fn time_of_day(&self) -> TimeOfDay { self.0.time_of_day() } +} + +#[derive(Debug, Clone, Any)] +pub struct RuneDynamicLibrary(Arc); +impl_rune_wrapper!(&Arc, RuneDynamicLibrary); + +impl RuneDynamicLibrary { + #[rune::function] + fn battle_stat_calculator(&self) -> RuneBattleStatCalculator { + RuneBattleStatCalculator(self.0.stat_calculator().clone()) + } + + #[rune::function] + fn misc_library(&self) -> RuneMiscLibrary { RuneMiscLibrary(self.0.misc_library().clone()) } + + #[rune::function] + fn static_data(&self) -> RuneStaticData { RuneStaticData(self.0.static_data().clone()) } +} diff --git a/src/script_implementations/rune/wrappers/dynamic_data/mod.rs b/src/script_implementations/rune/wrappers/dynamic_data/mod.rs index 22c9196..76baf41 100644 --- a/src/script_implementations/rune/wrappers/dynamic_data/mod.rs +++ b/src/script_implementations/rune/wrappers/dynamic_data/mod.rs @@ -1,4 +1,14 @@ +use crate::dynamic_data::ScriptContainer; +use crate::script_implementations::rune::script::RuneScript; +use rune::runtime::{Object, Shared}; + +mod battle; +mod battle_party; +mod battle_random; +mod battle_side; mod executing_move; +mod learned_move; +mod libraries; mod pokemon; mod turn_choice; @@ -6,5 +16,24 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { executing_move::register(module)?; pokemon::register(module)?; turn_choice::register(module)?; + learned_move::register(module)?; + battle::register(module)?; + battle_random::register(module)?; + battle_party::register(module)?; + battle_side::register(module)?; + + libraries::register(module)?; Ok(()) -} \ No newline at end of file +} + +fn resolve_script_data(container: &ScriptContainer) -> Option> { + container + .get() + .map(|v| { + v.read() + .as_ref() + .map(|v| v.clone().as_any().downcast_ref::().map(|s| s.get_state())) + }) + .flatten() + .flatten() +} diff --git a/src/script_implementations/rune/wrappers/dynamic_data/pokemon.rs b/src/script_implementations/rune/wrappers/dynamic_data/pokemon.rs index 9f5a524..e071354 100644 --- a/src/script_implementations/rune/wrappers/dynamic_data/pokemon.rs +++ b/src/script_implementations/rune/wrappers/dynamic_data/pokemon.rs @@ -1,20 +1,228 @@ use crate::defines::LevelInt; -use crate::dynamic_data::Pokemon; -use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use crate::dynamic_data::{DamageSource, EventBatchId, Pokemon}; +use crate::script_implementations::rune::wrappers::dynamic_data::resolve_script_data; +use crate::script_implementations::rune::wrappers::static_data::form::RuneForm; +use crate::script_implementations::rune::wrappers::static_data::item::RuneItem; +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::{Gender, Statistic}; +use rune::runtime::{AnyObj, Object, Shared}; use rune::Any; pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.ty::()?; + module.function_meta(RunePokemon::library)?; + module.function_meta(RunePokemon::species)?; + module.function_meta(RunePokemon::form)?; + module.function_meta(RunePokemon::has_different_display_species)?; + module.function_meta(RunePokemon::display_species)?; + module.function_meta(RunePokemon::has_different_display_form)?; + module.function_meta(RunePokemon::display_form)?; module.function_meta(RunePokemon::level)?; + module.function_meta(RunePokemon::experience)?; + module.function_meta(RunePokemon::personality_value)?; + module.function_meta(RunePokemon::gender)?; + module.function_meta(RunePokemon::coloring)?; + module.function_meta(RunePokemon::held_item)?; + module.function_meta(RunePokemon::has_held_item)?; + module.function_meta(RunePokemon::set_held_item)?; + module.function_meta(RunePokemon::remove_held_item)?; + module.function_meta(RunePokemon::consume_held_item)?; + module.function_meta(RunePokemon::current_health)?; + module.function_meta(RunePokemon::max_health)?; + module.function_meta(RunePokemon::weight)?; + module.function_meta(RunePokemon::set_weight)?; + module.function_meta(RunePokemon::height)?; + module.function_meta(RunePokemon::happiness)?; + module.function_meta(RunePokemon::nickname)?; + module.function_meta(RunePokemon::real_ability)?; + module.function_meta(RunePokemon::types)?; + module.function_meta(RunePokemon::learned_moves)?; + module.function_meta(RunePokemon::flat_stats)?; + module.function_meta(RunePokemon::is_egg)?; + module.function_meta(RunePokemon::boosted_stats)?; + module.function_meta(RunePokemon::stat_boost)?; + module.function_meta(RunePokemon::change_stat_boost)?; + module.function_meta(RunePokemon::get_individual_value)?; + module.function_meta(RunePokemon::get_effort_value)?; + module.function_meta(RunePokemon::get_battle)?; + module.function_meta(RunePokemon::get_battle_side_index)?; + module.function_meta(RunePokemon::get_battle_index)?; + module.function_meta(RunePokemon::is_ability_overridden)?; + module.function_meta(RunePokemon::active_ability)?; + module.function_meta(RunePokemon::allowed_experience_gain)?; + module.function_meta(RunePokemon::nature)?; + module.function_meta(RunePokemon::change_form)?; + module.function_meta(RunePokemon::is_usable)?; + module.function_meta(RunePokemon::is_fainted)?; + module.function_meta(RunePokemon::damage)?; + module.function_meta(RunePokemon::heal)?; + module.function_meta(RunePokemon::status_script)?; + module.function_meta(RunePokemon::clear_status)?; + Ok(()) } -#[derive(Any)] -pub struct RunePokemon(Pokemon); +#[derive(Any, Clone, Debug)] +pub struct RunePokemon(pub Pokemon); impl RunePokemon { + #[rune::function] + fn library(&self) -> Shared { self.0.library().wrap() } + + #[rune::function] + fn species(&self) -> Shared { self.0.species().wrap() } + + #[rune::function] + fn form(&self) -> Shared { self.0.form().wrap() } + + #[rune::function] + fn has_different_display_species(&self) -> bool { self.0.has_different_display_species() } + + #[rune::function] + fn display_species(&self) -> Shared { self.0.display_species().wrap() } + + #[rune::function] + fn has_different_display_form(&self) -> bool { self.0.has_different_display_form() } + + #[rune::function] + fn display_form(&self) -> Shared { self.0.display_form().wrap() } + #[rune::function] fn level(&self) -> LevelInt { self.0.level() } + + #[rune::function] + fn experience(&self) -> u32 { self.0.experience() } + + #[rune::function] + fn personality_value(&self) -> u32 { self.0.personality_value() } + + #[rune::function] + fn gender(&self) -> Gender { self.0.gender() } + + #[rune::function] + fn coloring(&self) -> u8 { self.0.coloring() } + + #[rune::function] + fn held_item(&self) -> Option> { self.0.held_item().map(|v| v.wrap()) } + + #[rune::function] + fn has_held_item(&self, key: RuneStringKey) -> bool { self.0.has_held_item(&key.0) } + + #[rune::function] + fn set_held_item(&mut self, key: RuneItem) -> Option> { + self.0.set_held_item(&key.0).map(|v| v.wrap()) + } + + #[rune::function] + fn remove_held_item(&mut self) -> Option> { self.0.remove_held_item().map(|v| v.wrap()) } + + #[rune::function] + fn consume_held_item(&mut self) -> anyhow::Result { self.0.consume_held_item() } + + #[rune::function] + fn current_health(&self) -> u32 { self.0.current_health() } + + #[rune::function] + fn max_health(&self) -> u32 { self.0.max_health() } + + #[rune::function] + fn weight(&self) -> f32 { self.0.weight() } + + #[rune::function] + fn set_weight(&mut self, value: f32) { self.0.set_weight(value); } + + #[rune::function] + fn height(&self) -> f32 { self.0.height() } + + #[rune::function] + fn happiness(&self) -> u8 { self.0.happiness() } + + #[rune::function] + fn nickname(&self) -> Option { self.0.nickname().clone() } + + #[rune::function] + fn real_ability(&self) -> (bool, u8) { (self.0.real_ability().hidden, self.0.real_ability().index) } + + #[rune::function] + fn types(&self) -> Vec { self.0.types().iter().map(|v| u8::from(*v)).collect() } + + #[rune::function] + fn learned_moves(&self) -> Vec>> { + let l = self.0.learned_moves().read(); + l.iter().map(|v| v.as_ref().map(|l| l.wrap())).collect() + } + + #[rune::function] + fn flat_stats(&self) -> Shared { self.0.flat_stats().wrap() } + + #[rune::function] + fn is_egg(&self) -> bool { self.0.is_egg() } + + #[rune::function] + fn boosted_stats(&self) -> Shared { self.0.boosted_stats().wrap() } + + #[rune::function] + fn stat_boost(&self, stat: Statistic) -> i8 { self.0.stat_boost(stat) } + + #[rune::function] + fn change_stat_boost(&mut self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> anyhow::Result { + self.0.change_stat_boost(stat, diff_amount, self_inflicted) + } + + #[rune::function] + fn get_individual_value(&self, stat: Statistic) -> u8 { self.0.individual_values().get_stat(stat) } + + #[rune::function] + fn get_effort_value(&self, stat: Statistic) -> u8 { self.0.effort_values().get_stat(stat) } + + #[rune::function] + fn get_battle(&self) -> Option> { self.0.get_battle().map(|v| v.wrap()) } + + #[rune::function] + fn get_battle_side_index(&self) -> Option { self.0.get_battle_side_index() } + + #[rune::function] + fn get_battle_index(&self) -> Option { self.0.get_battle_index() } + + #[rune::function] + fn is_ability_overridden(&self) -> bool { self.0.is_ability_overridden() } + + #[rune::function] + fn active_ability(&self) -> anyhow::Result> { self.0.active_ability().map(|v| v.wrap()) } + + #[rune::function] + fn allowed_experience_gain(&self) -> bool { self.0.allowed_experience_gain() } + + #[rune::function] + fn nature(&self) -> Shared { self.0.nature().wrap() } + + #[rune::function] + fn change_form(&self, form: RuneForm) -> anyhow::Result<()> { self.0.change_form(&form.0) } + + #[rune::function] + fn is_usable(&self) -> bool { self.0.is_usable() } + + #[rune::function] + fn is_fainted(&self) -> bool { self.0.is_fainted() } + + #[rune::function] + fn damage(&self, amount: u32, source: DamageSource) -> anyhow::Result<()> { + self.0.damage(amount, source, EventBatchId::default()) + } + + #[rune::function] + fn heal(&self, amount: u32, allow_revive: bool) -> bool { self.0.heal(amount, allow_revive) } + + #[rune::function] + fn clear_status(&self) { self.0.clear_status() } + + #[rune::function] + fn status_script(&self) -> Option> { resolve_script_data(&self.0.status()) } + + #[rune::function] + fn ability_script(&self) -> Option> { resolve_script_data(&self.0.ability_script()) } } impl_rune_wrapper!(&Pokemon, RunePokemon); diff --git a/src/script_implementations/rune/wrappers/dynamic_data/turn_choice.rs b/src/script_implementations/rune/wrappers/dynamic_data/turn_choice.rs index 527fb86..a7a570d 100644 --- a/src/script_implementations/rune/wrappers/dynamic_data/turn_choice.rs +++ b/src/script_implementations/rune/wrappers/dynamic_data/turn_choice.rs @@ -1,24 +1,112 @@ use crate::dynamic_data::TurnChoice; -use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper}; -use rune::{Any, Value}; +use crate::script_implementations::rune::wrappers::RuneWrapper; +use rune::runtime::{AnyObj, Shared}; +use rune::Any; use std::sync::Arc; pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { module.ty::()?; - module.function_meta(RuneTurnChoice::speed)?; module.function_meta(RuneTurnChoice::user)?; + module.function_meta(RuneTurnChoice::speed)?; + module.function_meta(RuneTurnChoice::has_failed)?; + module.function_meta(RuneTurnChoice::fail)?; + + module.ty::()?; + module.function_meta(RuneMoveChoice::used_move)?; + module.function_meta(RuneMoveChoice::target_side)?; + module.function_meta(RuneMoveChoice::target_index)?; + module.function_meta(RuneMoveChoice::priority)?; + module.function_meta(RuneMoveChoice::user)?; + + module.ty::()?; + module.ty::()?; + module.ty::()?; + module.ty::()?; + Ok(()) } -#[derive(Any)] -pub struct RuneTurnChoice(Arc); - -impl RuneTurnChoice { - #[rune::function] - fn speed(&self) -> u32 { self.0.speed() } - - #[rune::function] - fn user(&self) -> Value { Value::from(self.0.user().wrap()) } +#[derive(Debug, Clone, Any)] +pub enum RuneTurnChoice { + Move(#[rune(get)] RuneMoveChoice), + Item(#[rune(get)] RuneItemChoice), + Switch(#[rune(get)] RuneSwitchChoice), + Flee(#[rune(get)] RuneFleeChoice), + Pass(#[rune(get)] RunePassChoice), } -impl_rune_wrapper!(&Arc, RuneTurnChoice); +#[derive(Debug, Clone, Any)] +pub struct RuneMoveChoice(Arc); + +#[derive(Debug, Clone, Any)] +pub struct RuneItemChoice(Arc); + +#[derive(Debug, Clone, Any)] +pub struct RuneSwitchChoice(Arc); + +#[derive(Debug, Clone, Any)] +pub struct RuneFleeChoice(Arc); + +#[derive(Debug, Clone, Any)] +pub struct RunePassChoice(Arc); + +impl RuneTurnChoice { + pub fn get_turn_choice(&self) -> &Arc { + match self { + RuneTurnChoice::Move(m) => &m.0, + RuneTurnChoice::Item(i) => &i.0, + RuneTurnChoice::Switch(s) => &s.0, + RuneTurnChoice::Flee(f) => &f.0, + RuneTurnChoice::Pass(p) => &p.0, + } + } + + #[rune::function] + fn user(&self) -> Shared { self.get_turn_choice().user().wrap() } + + #[rune::function] + fn speed(&self) -> u32 { self.get_turn_choice().speed() } + + #[rune::function] + fn has_failed(&self) -> bool { self.get_turn_choice().has_failed() } + + #[rune::function] + fn fail(&self) { self.get_turn_choice().fail() } +} + +impl RuneWrapper for &Arc { + fn wrap(self) -> Shared { + let o = match self.as_ref() { + TurnChoice::Move(_) => RuneTurnChoice::Move(RuneMoveChoice(self.clone())), + TurnChoice::Item(_) => RuneTurnChoice::Item(RuneItemChoice(self.clone())), + TurnChoice::Switch(_) => RuneTurnChoice::Switch(RuneSwitchChoice(self.clone())), + TurnChoice::Flee(_) => RuneTurnChoice::Flee(RuneFleeChoice(self.clone())), + TurnChoice::Pass(_) => RuneTurnChoice::Pass(RunePassChoice(self.clone())), + }; + Shared::new(AnyObj::new(o).unwrap()).unwrap() + } +} + +impl RuneMoveChoice { + fn move_choice(&self) -> &crate::dynamic_data::MoveChoice { + match self.0.as_ref() { + TurnChoice::Move(m) => m, + _ => unreachable!("RuneMoveChoice should only be created with a MoveChoice"), + } + } + + #[rune::function] + fn used_move(&self) -> Shared { self.move_choice().used_move().wrap() } + + #[rune::function] + fn target_side(&self) -> u8 { self.move_choice().target_side() } + + #[rune::function] + fn target_index(&self) -> u8 { self.move_choice().target_index() } + + #[rune::function] + fn priority(&self) -> i8 { self.move_choice().priority() } + + #[rune::function] + fn user(&self) -> Shared { self.move_choice().user().wrap() } +} diff --git a/src/script_implementations/rune/wrappers/mod.rs b/src/script_implementations/rune/wrappers/mod.rs index 5d4d525..c368f61 100644 --- a/src/script_implementations/rune/wrappers/mod.rs +++ b/src/script_implementations/rune/wrappers/mod.rs @@ -136,7 +136,7 @@ impl RuneValueBoolWrapper { } #[derive(Any, Clone, Debug)] -pub(super) struct RuneStringKey(StringKey); +pub(super) struct RuneStringKey(pub StringKey); impl RuneStringKey { pub fn new(value: StringKey) -> Self { Self(value) } @@ -145,7 +145,5 @@ impl RuneStringKey { } impl RuneWrapper for &StringKey { - fn wrap(self) -> Shared { - Shared::new(AnyObj::new(RuneStringKey(self.clone())).unwrap()).unwrap() - } + fn wrap(self) -> Shared { Shared::new(AnyObj::new(RuneStringKey(self.clone())).unwrap()).unwrap() } } diff --git a/src/script_implementations/rune/wrappers/static_data/form.rs b/src/script_implementations/rune/wrappers/static_data/form.rs index 56c9891..db0290a 100644 --- a/src/script_implementations/rune/wrappers/static_data/form.rs +++ b/src/script_implementations/rune/wrappers/static_data/form.rs @@ -22,7 +22,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { } #[derive(Debug, Any)] -pub struct RuneForm(Arc); +pub struct RuneForm(pub Arc); impl_rune_wrapper!(&Arc, RuneForm); diff --git a/src/script_implementations/rune/wrappers/static_data/item.rs b/src/script_implementations/rune/wrappers/static_data/item.rs index 76635c3..f17b23e 100644 --- a/src/script_implementations/rune/wrappers/static_data/item.rs +++ b/src/script_implementations/rune/wrappers/static_data/item.rs @@ -22,7 +22,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { } #[derive(Debug, Any)] -pub struct RuneItem(Arc); +pub struct RuneItem(pub Arc); impl_rune_wrapper!(&Arc, RuneItem); diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs b/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs index 76f0518..2a900fd 100644 --- a/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs +++ b/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs @@ -1,7 +1,7 @@ mod growth_rate_library; mod library_settings; mod nature_library; -mod static_data; +pub mod static_data; mod type_library; use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/static_data.rs b/src/script_implementations/rune/wrappers/static_data/libraries/static_data.rs index 0bd3cb0..fc0acaa 100644 --- a/src/script_implementations/rune/wrappers/static_data/libraries/static_data.rs +++ b/src/script_implementations/rune/wrappers/static_data/libraries/static_data.rs @@ -17,7 +17,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { } #[derive(Debug, rune::Any)] -struct RuneStaticData(Arc); +pub struct RuneStaticData(pub Arc); impl_rune_wrapper!(&Arc, RuneStaticData); diff --git a/src/script_implementations/rune/wrappers/static_data/mod.rs b/src/script_implementations/rune/wrappers/static_data/mod.rs index 07e1eae..8177cc3 100644 --- a/src/script_implementations/rune/wrappers/static_data/mod.rs +++ b/src/script_implementations/rune/wrappers/static_data/mod.rs @@ -1,9 +1,9 @@ mod ability; -mod form; +pub mod form; mod growth_rate; -mod item; +pub mod item; mod learnable_moves; -mod libraries; +pub mod libraries; mod move_data; mod nature; mod species; diff --git a/src/script_implementations/rune/wrappers/static_data/statistic_set.rs b/src/script_implementations/rune/wrappers/static_data/statistic_set.rs index 19ee331..1c6b233 100644 --- a/src/script_implementations/rune/wrappers/static_data/statistic_set.rs +++ b/src/script_implementations/rune/wrappers/static_data/statistic_set.rs @@ -4,15 +4,15 @@ use rune::Any; use std::sync::Arc; pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { - module.ty::()?; - module.function_meta(RuneStatisticSet::get)?; - module.function_meta(RuneStatisticSet::set)?; - module.function_meta(RuneStatisticSet::hp)?; - module.function_meta(RuneStatisticSet::attack)?; - module.function_meta(RuneStatisticSet::defense)?; - module.function_meta(RuneStatisticSet::special_attack)?; - module.function_meta(RuneStatisticSet::special_defense)?; - module.function_meta(RuneStatisticSet::speed)?; + module.ty::()?; + module.function_meta(RuneU32StatisticSet::get)?; + module.function_meta(RuneU32StatisticSet::set)?; + module.function_meta(RuneU32StatisticSet::hp)?; + module.function_meta(RuneU32StatisticSet::attack)?; + module.function_meta(RuneU32StatisticSet::defense)?; + module.function_meta(RuneU32StatisticSet::special_attack)?; + module.function_meta(RuneU32StatisticSet::special_defense)?; + module.function_meta(RuneU32StatisticSet::speed)?; module.ty::()?; module.function_meta(RuneStaticStatisticSet::get)?; @@ -27,10 +27,10 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { } #[derive(Debug, Any)] -pub struct RuneStatisticSet(Arc>); +pub struct RuneU32StatisticSet(Arc>); -impl_rune_wrapper!(&Arc>, RuneStatisticSet); -impl RuneStatisticSet { +impl_rune_wrapper!(&Arc>, RuneU32StatisticSet); +impl RuneU32StatisticSet { #[rune::function] fn get(&self, stat: Statistic) -> u32 { self.0.get_stat(stat) } diff --git a/src/static_data/mod.rs b/src/static_data/mod.rs index 8145426..21dc08f 100755 --- a/src/static_data/mod.rs +++ b/src/static_data/mod.rs @@ -1,34 +1,22 @@ use crate::StringKey; -#[doc(inline)] -pub use growth_rates::*; -#[doc(inline)] -pub use items::*; -#[doc(inline)] -pub use libraries::*; -#[doc(inline)] -pub use moves::*; -#[doc(inline)] -pub use natures::*; -#[doc(inline)] -pub use species_data::*; -#[doc(inline)] -pub use statistic_set::*; -#[doc(inline)] -pub use statistics::*; -#[doc(inline)] -pub use time_of_day::*; +#[doc(inline)] pub use growth_rates::*; +#[doc(inline)] pub use items::*; +#[doc(inline)] pub use libraries::*; +#[doc(inline)] pub use moves::*; +#[doc(inline)] pub use natures::*; +#[doc(inline)] pub use species_data::*; +#[doc(inline)] pub use statistic_set::*; +#[doc(inline)] pub use statistics::*; +#[doc(inline)] pub use time_of_day::*; use std::fmt::{Display, Formatter}; #[cfg(test)] pub(crate) mod tests { use super::*; - #[doc(inline)] - pub use moves::tests::*; - #[doc(inline)] - pub use natures::tests::*; - #[doc(inline)] - pub use species_data::tests::*; + #[doc(inline)] pub use moves::tests::*; + #[doc(inline)] pub use natures::tests::*; + #[doc(inline)] pub use species_data::tests::*; } /// Growth rates define how fast a Pokemon can level up. diff --git a/src/static_data/species_data/mod.rs b/src/static_data/species_data/mod.rs index 8c7aad6..f0e1753 100755 --- a/src/static_data/species_data/mod.rs +++ b/src/static_data/species_data/mod.rs @@ -1,15 +1,9 @@ -#[doc(inline)] -pub use ability::*; -#[doc(inline)] -pub use evolution_data::*; -#[doc(inline)] -pub use form::*; -#[doc(inline)] -pub use gender::*; -#[doc(inline)] -pub use learnable_moves::*; -#[doc(inline)] -pub use species::*; +#[doc(inline)] pub use ability::*; +#[doc(inline)] pub use evolution_data::*; +#[doc(inline)] pub use form::*; +#[doc(inline)] pub use gender::*; +#[doc(inline)] pub use learnable_moves::*; +#[doc(inline)] pub use species::*; #[cfg(test)] pub(crate) mod tests { diff --git a/src/static_data/statistic_set.rs b/src/static_data/statistic_set.rs index 8b05f02..e024365 100755 --- a/src/static_data/statistic_set.rs +++ b/src/static_data/statistic_set.rs @@ -54,29 +54,17 @@ where } /// The health point stat value. - pub fn hp(&self) -> T { - self.hp.load(Ordering::Relaxed) - } + pub fn hp(&self) -> T { self.hp.load(Ordering::Relaxed) } /// The physical attack stat value. - pub fn attack(&self) -> T { - self.attack.load(Ordering::Relaxed) - } + pub fn attack(&self) -> T { self.attack.load(Ordering::Relaxed) } /// The physical defense stat value. - pub fn defense(&self) -> T { - self.defense.load(Ordering::Relaxed) - } + pub fn defense(&self) -> T { self.defense.load(Ordering::Relaxed) } /// The special attack stat value. - pub fn special_attack(&self) -> T { - self.special_attack.load(Ordering::Relaxed) - } + pub fn special_attack(&self) -> T { self.special_attack.load(Ordering::Relaxed) } /// The special defense stat value. - pub fn special_defense(&self) -> T { - self.special_defense.load(Ordering::Relaxed) - } + pub fn special_defense(&self) -> T { self.special_defense.load(Ordering::Relaxed) } /// The speed stat value. - pub fn speed(&self) -> T { - self.speed.load(Ordering::Relaxed) - } + pub fn speed(&self) -> T { self.speed.load(Ordering::Relaxed) } /// Get the value of a specific stat pub fn get_stat(&self, stat: Statistic) -> T { @@ -165,29 +153,17 @@ where } /// The health point stat value. - pub const fn hp(&self) -> T { - self.hp - } + pub const fn hp(&self) -> T { self.hp } /// The physical attack stat value. - pub const fn attack(&self) -> T { - self.attack - } + pub const fn attack(&self) -> T { self.attack } /// The physical defense stat value. - pub const fn defense(&self) -> T { - self.defense - } + pub const fn defense(&self) -> T { self.defense } /// The special attack stat value. - pub const fn special_attack(&self) -> T { - self.special_attack - } + pub const fn special_attack(&self) -> T { self.special_attack } /// The special defense stat value. - pub const fn special_defense(&self) -> T { - self.special_defense - } + pub const fn special_defense(&self) -> T { self.special_defense } /// The speed stat value. - pub const fn speed(&self) -> T { - self.speed - } + pub const fn speed(&self) -> T { self.speed } /// Get the value of a specific stat pub const fn get_stat(&self, stat: Statistic) -> T { @@ -245,14 +221,10 @@ where { /// The lowest value a value on the set can have. #[allow(clippy::unwrap_used)] // Should never fail - pub fn min() -> T { - ::from(MIN).unwrap() - } + pub fn min() -> T { ::from(MIN).unwrap() } /// The highest value a value on the set can have. #[allow(clippy::unwrap_used)] // Should never fail - pub fn max() -> T { - ::from(MAX).unwrap() - } + pub fn max() -> T { ::from(MAX).unwrap() } /// Takes the underlying primary value, clamp it between the two values, and give it back as /// atomic. @@ -274,29 +246,17 @@ where } /// The health point stat value. - pub fn hp(&self) -> T { - self.hp.load(Ordering::Relaxed) - } + pub fn hp(&self) -> T { self.hp.load(Ordering::Relaxed) } /// The physical attack stat value. - pub fn attack(&self) -> T { - self.attack.load(Ordering::Relaxed) - } + pub fn attack(&self) -> T { self.attack.load(Ordering::Relaxed) } /// The physical defense stat value. - pub fn defense(&self) -> T { - self.defense.load(Ordering::Relaxed) - } + pub fn defense(&self) -> T { self.defense.load(Ordering::Relaxed) } /// The special attack stat value. - pub fn special_attack(&self) -> T { - self.special_attack.load(Ordering::Relaxed) - } + pub fn special_attack(&self) -> T { self.special_attack.load(Ordering::Relaxed) } /// The special defense stat value. - pub fn special_defense(&self) -> T { - self.special_defense.load(Ordering::Relaxed) - } + pub fn special_defense(&self) -> T { self.special_defense.load(Ordering::Relaxed) } /// The speed stat value. - pub fn speed(&self) -> T { - self.speed.load(Ordering::Relaxed) - } + pub fn speed(&self) -> T { self.speed.load(Ordering::Relaxed) } /// Gets a specific stat. pub fn get_stat(&self, stat: Statistic) -> T { @@ -399,6 +359,28 @@ where } } +impl From<&ClampedStatisticSet> for StatisticSet +where + T: PrimitiveAtom, + T: Atom, + T: PrimitiveAtomInteger, + ::Repr: PrimitiveAtomInteger, + T: AtomInteger, + T: NumCast, + T: PrimInt, +{ + fn from(value: &ClampedStatisticSet) -> Self { + Self { + hp: Atomic::::new(value.hp()), + attack: Atomic::::new(value.attack()), + defense: Atomic::::new(value.defense()), + special_attack: Atomic::::new(value.special_attack()), + special_defense: Atomic::::new(value.special_defense()), + speed: Atomic::::new(value.speed()), + } + } +} + #[cfg(test)] mod tests { use super::*;