From 4ec07ca0491c3f207ccbc31f0a0835a732d0c614 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Wed, 8 May 2024 15:46:09 +0200 Subject: [PATCH] Large amounts of work on Rune --- src/dynamic_data/flow/choice_queue.rs | 5 +- src/dynamic_data/flow/mod.rs | 8 +- .../libraries/evolution_library.rs | 1 + src/dynamic_data/models/battle.rs | 89 ++++-------- src/dynamic_data/models/battle_side.rs | 81 +++-------- src/dynamic_data/models/pokemon.rs | 1 + src/dynamic_data/script_handling/mod.rs | 41 ++---- src/script_implementations/rune/script.rs | 67 +++++---- .../rune/script_resolver.rs | 17 ++- .../wrappers/dynamic_data/executing_move.rs | 10 +- .../rune/wrappers/mod.rs | 129 +++++++++++++++--- .../rune/wrappers/parameters.rs | 31 +++++ .../rune/wrappers/static_data/ability.rs | 34 +++++ .../rune/wrappers/static_data/form.rs | 67 +++++++++ .../rune/wrappers/static_data/growth_rate.rs | 27 ++++ .../rune/wrappers/static_data/item.rs | 47 +++++++ .../wrappers/static_data/learnable_moves.rs | 40 ++++++ .../libraries/growth_rate_library.rs | 29 ++++ .../static_data/libraries/library_settings.rs | 23 ++++ .../wrappers/static_data/libraries/mod.rs | 68 +++++++++ .../static_data/libraries/nature_library.rs | 27 ++++ .../static_data/libraries/static_data.rs | 48 +++++++ .../static_data/libraries/type_library.rs | 39 ++++++ .../rune/wrappers/static_data/mod.rs | 20 ++- .../rune/wrappers/static_data/move_data.rs | 89 ++++++++++++ .../rune/wrappers/static_data/nature.rs | 17 ++- .../rune/wrappers/static_data/species.rs | 56 ++++++++ .../wrappers/static_data/statistic_set.rs | 45 ++++-- src/static_data/growth_rates.rs | 8 +- src/static_data/items.rs | 29 ++-- src/static_data/libraries/data_library.rs | 25 ++-- .../libraries/growth_rate_library.rs | 6 +- src/static_data/libraries/nature_library.rs | 10 +- src/static_data/libraries/type_library.rs | 38 ++---- src/static_data/mod.rs | 22 +-- src/static_data/moves/mod.rs | 11 +- src/static_data/moves/move_data.rs | 49 ++----- src/static_data/moves/secondary_effect.rs | 3 - src/static_data/species_data/gender.rs | 1 + src/static_data/species_data/mod.rs | 2 - src/static_data/statistics.rs | 3 +- tests/data/scripts/moves/test.rn | 3 +- tests/integration.rs | 10 +- 43 files changed, 979 insertions(+), 397 deletions(-) create mode 100644 src/script_implementations/rune/wrappers/parameters.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/ability.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/form.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/growth_rate.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/item.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/learnable_moves.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/libraries/growth_rate_library.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/libraries/library_settings.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/libraries/mod.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/libraries/nature_library.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/libraries/static_data.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/libraries/type_library.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/move_data.rs create mode 100644 src/script_implementations/rune/wrappers/static_data/species.rs diff --git a/src/dynamic_data/flow/choice_queue.rs b/src/dynamic_data/flow/choice_queue.rs index 711499a..2952815 100755 --- a/src/dynamic_data/flow/choice_queue.rs +++ b/src/dynamic_data/flow/choice_queue.rs @@ -68,9 +68,7 @@ impl ChoiceQueue { } /// Check if we have any choices remaining. - pub fn has_next(&self) -> bool { - self.current.load(Ordering::Relaxed) < self.queue.read().len() - } + pub fn has_next(&self) -> bool { self.current.load(Ordering::Relaxed) < self.queue.read().len() } /// This resorts the yet to be executed choices. This can be useful for dealing with situations /// such as Pokemon changing forms just after the very start of a turn, when turn order has @@ -163,7 +161,6 @@ mod tests { use crate::defines::LevelInt; use crate::dynamic_data::{DynamicLibrary, PassChoice}; use crate::static_data::{AbilityIndex, Gender}; - use std::sync::Arc; #[test] fn create_empty_queue() { let queue = ChoiceQueue::new(Vec::new()); diff --git a/src/dynamic_data/flow/mod.rs b/src/dynamic_data/flow/mod.rs index f3f1b1a..252b72a 100755 --- a/src/dynamic_data/flow/mod.rs +++ b/src/dynamic_data/flow/mod.rs @@ -1,9 +1,5 @@ -#[doc(inline)] -pub use choice_queue::*; -#[doc(inline)] -pub use target_resolver::*; -#[doc(inline)] -pub use turn_runner::*; +#[doc(inline)] pub use choice_queue::*; +#[doc(inline)] pub use target_resolver::*; /// Data for enqueueing and retrieving choices. mod choice_queue; diff --git a/src/dynamic_data/libraries/evolution_library.rs b/src/dynamic_data/libraries/evolution_library.rs index a5dc14c..00574dd 100644 --- a/src/dynamic_data/libraries/evolution_library.rs +++ b/src/dynamic_data/libraries/evolution_library.rs @@ -4,6 +4,7 @@ use crate::static_data::{EvolutionMethod, TimeOfDay}; /// A library for handling the checking of evolution requirements. pub trait EvolutionLibrary { /// Checks if the given Pokemon fulfills the given evolution conditions. + #[allow(dead_code)] fn pokemon_fulfills_evolution_conditions(&self, pokemon: &Pokemon, method: &EvolutionMethod) -> bool; } diff --git a/src/dynamic_data/models/battle.rs b/src/dynamic_data/models/battle.rs index 65adf95..d8b9795 100755 --- a/src/dynamic_data/models/battle.rs +++ b/src/dynamic_data/models/battle.rs @@ -125,57 +125,31 @@ impl Battle { } /// The library the battle uses for handling. - pub fn library(&self) -> &Arc { - &self.data.library - } + pub fn library(&self) -> &Arc { &self.data.library } /// A list of all different parties in the battle. - pub fn parties(&self) -> &Vec> { - &self.data.parties - } + pub fn parties(&self) -> &Vec> { &self.data.parties } /// Whether or not Pokemon can flee from the battle. - pub fn can_flee(&self) -> bool { - self.data.can_flee - } + pub fn can_flee(&self) -> bool { self.data.can_flee } /// The number of sides in the battle. Typically 2. - pub fn number_of_sides(&self) -> u8 { - self.data.number_of_sides - } + pub fn number_of_sides(&self) -> u8 { self.data.number_of_sides } /// The number of Pokemon that can be on each side. - pub fn pokemon_per_side(&self) -> u8 { - self.data.pokemon_per_side - } + pub fn pokemon_per_side(&self) -> u8 { self.data.pokemon_per_side } /// A list of all sides in the battle. - pub fn sides(&self) -> &Vec { - &self.data.sides - } + pub fn sides(&self) -> &Vec { &self.data.sides } /// The RNG used for the battle. - pub fn random(&self) -> &Arc { - &self.data.random - } + pub fn random(&self) -> &Arc { &self.data.random } /// Whether or not the battle has ended. - pub fn has_ended(&self) -> bool { - self.data.has_ended.load(Ordering::Relaxed) - } + pub fn has_ended(&self) -> bool { self.data.has_ended.load(Ordering::Relaxed) } /// The eventual result of the battle. Inconclusive until the battle is ended. - pub fn result(&self) -> BattleResult { - *self.data.result.read() - } + pub fn result(&self) -> BattleResult { *self.data.result.read() } /// The handler to send all events to. - pub fn event_hook(&self) -> &EventHook { - &self.data.event_hook - } + pub fn event_hook(&self) -> &EventHook { &self.data.event_hook } /// The index of the current turn. 0 until all choices - pub fn current_turn(&self) -> u32 { - self.data.current_turn.load(Ordering::Relaxed) - } + pub fn current_turn(&self) -> u32 { self.data.current_turn.load(Ordering::Relaxed) } /// The time in nanoseconds the last turn took to run. Defaults to 0. - pub fn last_turn_time(&self) -> u64 { - self.data.last_turn_time.load(Ordering::Relaxed) - } + pub fn last_turn_time(&self) -> u64 { self.data.last_turn_time.load(Ordering::Relaxed) } /// A queue of the yet to be executed choices in a turn. - pub fn current_turn_queue(&self) -> &RwLock>> { - &self.data.current_turn_queue - } + pub fn current_turn_queue(&self) -> &RwLock>> { &self.data.current_turn_queue } /// Get a Pokemon on the battlefield, on a specific side and an index on that side. pub fn get_pokemon(&self, side: u8, index: u8) -> Option { @@ -379,28 +353,21 @@ impl Battle { } /// Gets the inner pointer to the reference counted data. - pub fn as_ptr(&self) -> *const c_void { - Arc::as_ptr(&self.data) as *const c_void - } + pub fn as_ptr(&self) -> *const c_void { Arc::as_ptr(&self.data) as *const c_void } } impl PartialEq for Battle { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.data, &other.data) - } + fn eq(&self, other: &Self) -> bool { Arc::ptr_eq(&self.data, &other.data) } } impl WeakBattleReference { /// Attempts to upgrade the weak reference to a strong reference. If the strong reference has /// been dropped, this returns None. - pub fn upgrade(&self) -> Option { - self.data.upgrade().map(|battle| Battle { data: battle }) - } + pub fn upgrade(&self) -> Option { self.data.upgrade().map(|battle| Battle { data: battle }) } /// Gets the inner pointer to the reference counted data. - pub(crate) fn as_ptr(&self) -> *const c_void { - self.data.as_ptr() as *const c_void - } + #[cfg(feature = "wasm")] + pub(crate) fn as_ptr(&self) -> *const c_void { self.data.as_ptr() as *const c_void } } unsafe impl Send for WeakBattleReference {} @@ -408,17 +375,13 @@ unsafe impl Send for WeakBattleReference {} unsafe impl Sync for WeakBattleReference {} impl PartialEq for WeakBattleReference { - fn eq(&self, other: &Self) -> bool { - self.data.ptr_eq(&other.data) - } + fn eq(&self, other: &Self) -> bool { self.data.ptr_eq(&other.data) } } impl Eq for WeakBattleReference {} impl VolatileScriptsOwner for Battle { - fn volatile_scripts(&self) -> &Arc { - &self.data.volatile_scripts - } + fn volatile_scripts(&self) -> &Arc { &self.data.volatile_scripts } fn load_volatile_script(&self, key: &StringKey) -> Result>> { self.data.library.load_script(self.into(), ScriptCategory::Battle, key) @@ -426,13 +389,9 @@ impl VolatileScriptsOwner for Battle { } impl ScriptSource for Battle { - fn get_script_count(&self) -> Result { - Ok(1) - } + fn get_script_count(&self) -> Result { Ok(1) } - fn get_script_source_data(&self) -> &RwLock { - &self.data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.data.script_source_data } fn get_own_scripts(&self, scripts: &mut Vec) { scripts.push((&self.data.weather).into()); @@ -457,7 +416,5 @@ pub enum BattleResult { impl BattleResult { /// Whether or not the battle has a winner. - pub fn is_conclusive(&self) -> bool { - matches!(self, Self::Conclusive(_)) - } + pub fn is_conclusive(&self) -> bool { matches!(self, Self::Conclusive(_)) } } diff --git a/src/dynamic_data/models/battle_side.rs b/src/dynamic_data/models/battle_side.rs index fddca8e..76d6e02 100755 --- a/src/dynamic_data/models/battle_side.rs +++ b/src/dynamic_data/models/battle_side.rs @@ -101,30 +101,18 @@ impl BattleSide { } /// The index of the side on the battle. - pub fn index(&self) -> u8 { - self.data.index - } + pub fn index(&self) -> u8 { self.data.index } /// The number of Pokemon that can be on the side. - pub fn pokemon_per_side(&self) -> u8 { - self.data.pokemon_per_side - } + pub fn pokemon_per_side(&self) -> u8 { self.data.pokemon_per_side } /// A list of pokemon currently on the battlefield. - pub fn pokemon(&self) -> RwLockReadGuard<'_, RawRwLock, Vec>> { - self.data.pokemon.read() - } + pub fn pokemon(&self) -> RwLockReadGuard<'_, RawRwLock, Vec>> { self.data.pokemon.read() } /// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts. - pub fn choices(&self) -> &RwLock>>> { - &self.data.choices - } + pub fn choices(&self) -> &RwLock>>> { &self.data.choices } /// The slots on the side that can still be filled. Once all slots are set to false, this side /// has lost the battle. - pub fn fillable_slots(&self) -> &Vec { - &self.data.fillable_slots - } + pub fn fillable_slots(&self) -> &Vec { &self.data.fillable_slots } /// The number of choices that are set. - pub fn choices_set(&self) -> u8 { - self.data.choices_set.load(Ordering::SeqCst) - } + pub fn choices_set(&self) -> u8 { self.data.choices_set.load(Ordering::SeqCst) } /// A reference to the battle we're part of. pub fn battle(&self) -> Result { self.data @@ -133,18 +121,12 @@ impl BattleSide { .ok_or(anyhow!("Battle was not set, but requested")) } /// Whether or not this side has fled. - pub fn has_fled_battle(&self) -> bool { - self.data.has_fled_battle.load(Ordering::SeqCst) - } + pub fn has_fled_battle(&self) -> bool { self.data.has_fled_battle.load(Ordering::SeqCst) } /// The volatile scripts that are attached to the side. - pub fn volatile_scripts(&self) -> &Arc { - &self.data.volatile_scripts - } + pub fn volatile_scripts(&self) -> &Arc { &self.data.volatile_scripts } /// Whether every Pokemon on this side has its choices - pub fn all_choices_set(&self) -> bool { - self.choices_set() == self.data.pokemon_per_side - } + pub fn all_choices_set(&self) -> bool { self.choices_set() == self.data.pokemon_per_side } /// Returns true if there are slots that need to be filled with a new pokemon, that have parties /// responsible for them. Returns false if all slots are filled with usable pokemon, or slots are @@ -190,9 +172,7 @@ impl BattleSide { } /// Forcibly removes a Pokemon from the field. - pub fn force_clear_pokemon(&mut self, index: u8) { - self.data.pokemon.write().get_mut(index as usize).take(); - } + pub fn force_clear_pokemon(&mut self, index: u8) { self.data.pokemon.write().get_mut(index as usize).take(); } /// Switches out a spot on the field for a different Pokemon. pub fn set_pokemon(&self, index: u8, pokemon: Option) -> Result<()> { @@ -296,9 +276,7 @@ impl BattleSide { } /// Mark the side as fled. - pub fn mark_as_fled(&mut self) { - self.data.has_fled_battle.store(true, Ordering::SeqCst); - } + pub fn mark_as_fled(&mut self) { self.data.has_fled_battle.store(true, Ordering::SeqCst); } /// Gets a random Pokemon on the given side. pub fn get_random_creature_index(&self) -> Result { @@ -364,28 +342,21 @@ impl BattleSide { } /// Gets the inner pointer to the reference counted data. - pub fn as_ptr(&self) -> *const c_void { - Arc::as_ptr(&self.data) as *const c_void - } + pub fn as_ptr(&self) -> *const c_void { Arc::as_ptr(&self.data) as *const c_void } } impl PartialEq for BattleSide { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.data, &other.data) - } + fn eq(&self, other: &Self) -> bool { Arc::ptr_eq(&self.data, &other.data) } } impl WeakBattleSideReference { /// Upgrades the weak reference to a strong reference, returning `None` if the side has been /// dropped. - pub fn upgrade(&self) -> Option { - self.data.upgrade().map(|data| BattleSide { data }) - } + pub fn upgrade(&self) -> Option { self.data.upgrade().map(|data| BattleSide { data }) } /// Gets the underlying pointer to the data of the side. - pub(crate) fn as_ptr(&self) -> *const c_void { - self.data.as_ptr() as *const c_void - } + #[cfg(feature = "wasm")] + pub(crate) fn as_ptr(&self) -> *const c_void { self.data.as_ptr() as *const c_void } } unsafe impl Send for WeakBattleSideReference {} @@ -393,15 +364,11 @@ unsafe impl Send for WeakBattleSideReference {} unsafe impl Sync for WeakBattleSideReference {} impl PartialEq for WeakBattleSideReference { - fn eq(&self, other: &Self) -> bool { - self.data.ptr_eq(&other.data) - } + fn eq(&self, other: &Self) -> bool { self.data.ptr_eq(&other.data) } } impl VolatileScriptsOwner for BattleSide { - fn volatile_scripts(&self) -> &Arc { - &self.data.volatile_scripts - } + fn volatile_scripts(&self) -> &Arc { &self.data.volatile_scripts } fn load_volatile_script(&self, key: &StringKey) -> Result>> { self.battle()? @@ -411,17 +378,11 @@ impl VolatileScriptsOwner for BattleSide { } impl ScriptSource for BattleSide { - fn get_script_count(&self) -> Result { - Ok(self.battle()?.get_script_count()? + 1) - } + fn get_script_count(&self) -> Result { Ok(self.battle()?.get_script_count()? + 1) } - fn get_script_source_data(&self) -> &RwLock { - &self.data.script_source_data - } + fn get_script_source_data(&self) -> &RwLock { &self.data.script_source_data } - fn get_own_scripts(&self, scripts: &mut Vec) { - scripts.push((&self.data.volatile_scripts).into()); - } + fn get_own_scripts(&self, scripts: &mut Vec) { scripts.push((&self.data.volatile_scripts).into()); } fn collect_scripts(&self, scripts: &mut Vec) -> Result<()> { self.get_own_scripts(scripts); diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index 7b2c3cd..6727379 100755 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -941,6 +941,7 @@ impl WeakPokemonReference { } /// Gets the pointer to the underlying data. + #[cfg(feature = "wasm")] pub(crate) fn as_ptr(&self) -> *const c_void { self.data.as_ptr() as *const c_void } } diff --git a/src/dynamic_data/script_handling/mod.rs b/src/dynamic_data/script_handling/mod.rs index 6723053..a1e4955 100755 --- a/src/dynamic_data/script_handling/mod.rs +++ b/src/dynamic_data/script_handling/mod.rs @@ -169,15 +169,11 @@ pub enum ScriptWrapper { } impl From<&ScriptContainer> for ScriptWrapper { - fn from(c: &ScriptContainer) -> Self { - ScriptWrapper::Script(Arc::downgrade(c.arc())) - } + fn from(c: &ScriptContainer) -> Self { ScriptWrapper::Script(Arc::downgrade(c.arc())) } } impl From<&Arc> for ScriptWrapper { - fn from(c: &Arc) -> Self { - ScriptWrapper::Set(Arc::downgrade(c)) - } + fn from(c: &Arc) -> Self { ScriptWrapper::Set(Arc::downgrade(c)) } } /// This struct allows for the iteration over scripts. @@ -291,7 +287,6 @@ mod tests { use std::any::Any; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; - use crate::dynamic_data::script_handling::script::ScriptContainer; use crate::StringKey; use super::*; @@ -323,17 +318,11 @@ mod tests { } impl Script for TestScript { - fn name(&self) -> Result<&StringKey> { - Ok(&self.name) - } + fn name(&self) -> Result<&StringKey> { Ok(&self.name) } - fn get_marked_for_deletion(&self) -> &AtomicBool { - &self.is_marked_for_deletion - } + fn get_marked_for_deletion(&self) -> &AtomicBool { &self.is_marked_for_deletion } - fn get_suppressed_count(&self) -> &AtomicUsize { - &self.suppressed_count - } + fn get_suppressed_count(&self) -> &AtomicUsize { &self.suppressed_count } fn add_suppression(&self) {} @@ -344,13 +333,9 @@ mod tests { Ok(()) } - fn as_any(&self) -> &dyn Any { - self - } + fn as_any(&self) -> &dyn Any { self } - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } + fn as_any_mut(&mut self) -> &mut dyn Any { self } } #[test] @@ -551,17 +536,11 @@ mod tests { } impl ScriptSource for TestScriptSource { - fn get_script_count(&self) -> Result { - Ok(1) - } + fn get_script_count(&self) -> Result { Ok(1) } - fn get_script_source_data(&self) -> &RwLock { - &self.data - } + fn get_script_source_data(&self) -> &RwLock { &self.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); diff --git a/src/script_implementations/rune/script.rs b/src/script_implementations/rune/script.rs index 5a0d4b5..da8dd5c 100644 --- a/src/script_implementations/rune/script.rs +++ b/src/script_implementations/rune/script.rs @@ -1,4 +1,4 @@ -use crate::dynamic_data::{DynamicLibrary, ExecutingMove, Pokemon, Script, ScriptOwnerData, TurnChoice}; +use crate::dynamic_data::{DynamicLibrary, ExecutingMove, Pokemon, Script, TurnChoice}; use crate::script_implementations::rune::wrappers::*; use crate::script_implementations::rune::RuneScriptType; use crate::static_data::Parameter; @@ -22,8 +22,6 @@ pub struct RuneScript { /// A script can be suppressed by other scripts. If a script is suppressed by at least one script /// we will not execute its methods. This holds the number of suppressions on the script. suppressed_count: AtomicUsize, - /// The owner of this script (where the script is attached to) - owner: ScriptOwnerData, script_type: Arc, @@ -39,7 +37,6 @@ impl RuneScript { pub fn new( name: StringKey, object: Shared, - owner: ScriptOwnerData, script_type: Arc, runtime: Arc, unit: Arc, @@ -49,7 +46,6 @@ impl RuneScript { state: RwLock::new(object), marked_for_deletion: Default::default(), suppressed_count: Default::default(), - owner, script_type, runtime, unit, @@ -82,39 +78,10 @@ impl Script for RuneScript { Ok(()) } - fn block_critical( - &self, - move_data: &Arc, - target: &Pokemon, - hit: u8, - block_critical: &mut bool, - ) -> anyhow::Result<()> { - if let Some(hash) = self.script_type.fn_block_critical { - let mut vm = rune::runtime::Vm::new(self.runtime.clone(), self.unit.clone()); - todo!() - // let block_critical_handle = RuneValueWrapper::new_mut(block_critical); - // let read_lock = self.state.read(); - // let state = read_lock.deref(); - // - // vm.execute( - // hash, - // vec![ - // Value::Object(state.clone()), - // Value::from(move_data.wrap()?), - // Value::from(target.wrap()?), - // Value::from(hit), - // Value::from(block_critical_handle.clone().wrap()?), - // ], - // )?; - // *block_critical = block_critical_handle.value(); - } - Ok(()) - } - fn change_speed(&self, choice: &Arc, speed: &mut u32) -> anyhow::Result<()> { 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_value_reference(*speed as i64)?; + let speed_handle = wrap_int_reference(*speed as i64)?; let read_lock = self.state.read(); let state = read_lock.deref(); @@ -132,7 +99,35 @@ impl Script for RuneScript { return Err(anyhow::anyhow!("Error executing script: {}", e)); } - *speed = get_value_reference(speed_handle)? as u32; + *speed = get_int_reference_value(speed_handle)? as u32; + } + Ok(()) + } + + fn block_critical( + &self, + move_data: &Arc, + target: &Pokemon, + hit: u8, + block_critical: &mut bool, + ) -> anyhow::Result<()> { + 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::from(move_data.wrap()), + Value::from(target.wrap()), + Value::from(hit), + block_critical_handle.clone(), + ], + )?; + *block_critical = get_bool_reference_value(block_critical_handle)?; } Ok(()) } diff --git a/src/script_implementations/rune/script_resolver.rs b/src/script_implementations/rune/script_resolver.rs index 35ce821..d675d6b 100644 --- a/src/script_implementations/rune/script_resolver.rs +++ b/src/script_implementations/rune/script_resolver.rs @@ -1,5 +1,6 @@ use crate::dynamic_data::{ItemScript, Script, ScriptCategory, ScriptOwnerData, ScriptResolver}; use crate::script_implementations::rune::script::RuneScript; +use crate::script_implementations::rune::wrappers::RuneWrapper; use crate::script_implementations::rune::RuneScriptType; use crate::static_data::Item; use crate::StringKey; @@ -10,6 +11,7 @@ use rune::diagnostics::Diagnostic; use rune::runtime::{RuntimeContext, Shared}; use rune::{Context, Diagnostics, Options, Source, Sources, Unit}; use std::any::Any; +use std::convert::TryFrom; use std::path::Path; use std::sync::Arc; @@ -38,11 +40,22 @@ impl ScriptResolver for RuneScriptResolver { return Ok(None); }; - let state = Shared::new(rune::runtime::Object::new())?; + let mut o = rune::runtime::Object::new(); + + let owner_obj = match owner { + ScriptOwnerData::Pokemon(p) => Some(p.upgrade().unwrap().wrap()), + ScriptOwnerData::BattleSide(_) => None, //FIXME + ScriptOwnerData::Battle(_) => None, //FIXME + ScriptOwnerData::None => None, + }; + if let Some(owner_obj) = owner_obj { + o.insert(rune::alloc::String::try_from("owner")?, owner_obj.into())?; + } + + let state = Shared::new(o)?; let script = Arc::new(RuneScript::new( script_key.clone(), state, - owner, script_type.clone(), self.runtime.clone(), self.unit.clone(), 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 5fece81..e412871 100644 --- a/src/script_implementations/rune/wrappers/dynamic_data/executing_move.rs +++ b/src/script_implementations/rune/wrappers/dynamic_data/executing_move.rs @@ -6,6 +6,10 @@ use std::sync::Arc; pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { module.ty::()?; + module.function_meta(RuneExecutingMove::target_count)?; + module.function_meta(RuneExecutingMove::number_of_hits)?; + module.function_meta(RuneExecutingMove::user)?; + Ok(()) } @@ -14,11 +18,11 @@ pub struct RuneExecutingMove(Arc); impl RuneExecutingMove { #[rune::function] - pub fn target_count(&self) -> usize { self.0.target_count() } + fn target_count(&self) -> usize { self.0.target_count() } #[rune::function] - pub fn number_of_hits(&self) -> u8 { self.0.number_of_hits() } + fn number_of_hits(&self) -> u8 { self.0.number_of_hits() } #[rune::function] - pub fn user(&self) -> Shared { self.0.user().wrap() } + fn user(&self) -> Shared { self.0.user().wrap() } } impl_rune_wrapper!(&Arc, RuneExecutingMove); diff --git a/src/script_implementations/rune/wrappers/mod.rs b/src/script_implementations/rune/wrappers/mod.rs index 3cbfd3e..5d4d525 100644 --- a/src/script_implementations/rune/wrappers/mod.rs +++ b/src/script_implementations/rune/wrappers/mod.rs @@ -1,7 +1,9 @@ -use rune::runtime::{AnyObj, Shared}; +use rune::runtime::{AnyObj, Protocol, Shared, VmResult}; use rune::{Any, Value}; +use std::num::Saturating; mod dynamic_data; +mod parameters; mod static_data; pub trait RuneWrapper { @@ -11,40 +13,57 @@ pub trait RuneWrapper { pub fn module() -> anyhow::Result { let mut module = rune::Module::new(); module.ty::()?; + module.function_meta(RuneValueIntWrapper::rn_as_int)?; + module.function_meta(RuneValueIntWrapper::set_value)?; + module.associated_function(Protocol::ADD_ASSIGN, RuneValueIntWrapper::add_assign)?; + module.associated_function(Protocol::SUB_ASSIGN, RuneValueIntWrapper::sub_assign)?; + module.associated_function(Protocol::DIV_ASSIGN, RuneValueIntWrapper::div_assign)?; + module.associated_function(Protocol::MUL_ASSIGN, RuneValueIntWrapper::mul_assign)?; + module.associated_function(Protocol::PARTIAL_EQ, RuneValueIntWrapper::partial_eq)?; + module.associated_function(Protocol::EQ, RuneValueIntWrapper::eq)?; + module.associated_function(Protocol::STRING_DISPLAY, RuneValueIntWrapper::string_display)?; + + module.ty::()?; + module.function_meta(RuneValueBoolWrapper::rn_as_bool)?; + module.function_meta(RuneValueBoolWrapper::set_value)?; + module.associated_function(Protocol::EQ, RuneValueBoolWrapper::eq)?; + module.associated_function(Protocol::STRING_DISPLAY, RuneValueBoolWrapper::string_display)?; + + module.ty::()?; + module.associated_function(Protocol::STRING_DISPLAY, RuneStringKey::string_display)?; + + parameters::register(&mut module)?; dynamic_data::register(&mut module)?; static_data::register(&mut module)?; Ok(module) } -pub fn wrap_value_reference(value: i64) -> anyhow::Result { +pub fn wrap_int_reference(value: i64) -> anyhow::Result { Ok(Value::Any(Shared::new(AnyObj::new(RuneValueIntWrapper::new(value))?)?)) } -pub fn get_value_reference(value: Value) -> anyhow::Result { +pub fn wrap_bool_reference(value: bool) -> anyhow::Result { + Ok(Value::Any(Shared::new(AnyObj::new(RuneValueBoolWrapper::new(value))?)?)) +} + +pub fn get_int_reference_value(value: Value) -> anyhow::Result { let obj = value.into_any().into_result()?; let obj = obj.take()?; let obj = match obj.downcast_borrow_ref::() { Some(obj) => obj, None => return Err(anyhow::anyhow!("Value is not a RuneValueIntWrapper")), }; - Ok(obj.value()) + Ok(obj.as_int()) } -#[derive(Any, Clone)] -struct RuneValueIntWrapper { - #[rune(get, set)] - value: i64, -} - -impl RuneValueIntWrapper { - pub fn new(value: i64) -> Self { Self { value } } - - pub fn value(&self) -> i64 { self.value } - pub fn set_value(&mut self, value: i64) { self.value = value; } -} - -impl RuneWrapper for RuneValueIntWrapper { - fn wrap(self) -> Shared { Shared::new(AnyObj::new(self).unwrap()).unwrap() } +pub fn get_bool_reference_value(value: Value) -> anyhow::Result { + let obj = value.into_any().into_result()?; + let obj = obj.take()?; + let obj = match obj.downcast_borrow_ref::() { + Some(obj) => obj, + None => return Err(anyhow::anyhow!("Value is not a RuneValueBoolWrapper")), + }; + Ok(obj.as_bool()) } macro_rules! impl_rune_wrapper { @@ -57,4 +76,76 @@ macro_rules! impl_rune_wrapper { }; } +use crate::StringKey; use impl_rune_wrapper; + +#[derive(Any, Clone)] +struct RuneValueIntWrapper { + value: Saturating, +} + +impl RuneValueIntWrapper { + pub fn new(value: i64) -> Self { + Self { + value: Saturating(value), + } + } + + pub fn as_int(&self) -> i64 { self.value.0 } + + #[rune::function(path = RuneValueIntWrapper::as_int)] + fn rn_as_int(&self) -> i64 { self.value.0 } + + #[rune::function] + fn set_value(&mut self, value: i64) { self.value.0 = value; } + + fn add_assign(&mut self, other: i64) { self.value += other; } + + fn sub_assign(&mut self, other: i64) { self.value -= other; } + + fn div_assign(&mut self, other: i64) { self.value /= other; } + + fn mul_assign(&mut self, other: i64) { self.value *= other; } + + fn partial_eq(&self, b: i64) -> VmResult { VmResult::Ok(self.value.0 == b) } + + fn eq(&self, b: i64) -> VmResult { VmResult::Ok(self.value.0 == b) } + + fn string_display(&self) -> VmResult { VmResult::Ok(format!("{}", self.value.0)) } +} + +#[derive(Any, Clone)] +struct RuneValueBoolWrapper { + value: bool, +} + +impl RuneValueBoolWrapper { + pub fn new(value: bool) -> Self { Self { value } } + + pub fn as_bool(&self) -> bool { self.value } + + #[rune::function(path = RuneValueIntWrapper::as_bool)] + fn rn_as_bool(&self) -> bool { self.value } + + #[rune::function] + fn set_value(&mut self, value: bool) { self.value = value; } + + fn string_display(&self) -> VmResult { VmResult::Ok(format!("{}", self.value)) } + + fn eq(&self, b: bool) -> VmResult { VmResult::Ok(self.value == b) } +} + +#[derive(Any, Clone, Debug)] +pub(super) struct RuneStringKey(StringKey); + +impl RuneStringKey { + pub fn new(value: StringKey) -> Self { Self(value) } + + fn string_display(&self) -> VmResult { VmResult::Ok(format!("{}", self.0)) } +} + +impl RuneWrapper for &StringKey { + fn wrap(self) -> Shared { + Shared::new(AnyObj::new(RuneStringKey(self.clone())).unwrap()).unwrap() + } +} diff --git a/src/script_implementations/rune/wrappers/parameters.rs b/src/script_implementations/rune/wrappers/parameters.rs new file mode 100644 index 0000000..3b9b756 --- /dev/null +++ b/src/script_implementations/rune/wrappers/parameters.rs @@ -0,0 +1,31 @@ +use crate::script_implementations::rune::wrappers::{RuneStringKey, RuneWrapper}; +use crate::static_data::Parameter; +use rune::runtime::{AnyObj, Shared}; +use rune::Any; +use std::ops::Deref; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + Ok(()) +} + +#[derive(Debug, Any)] +pub(super) enum RuneParameter { + Int(#[rune(get)] i32), + Float(#[rune(get)] f32), + String(#[rune(get)] RuneStringKey), + Bool(#[rune(get)] bool), +} + +impl RuneWrapper for &Arc { + fn wrap(self) -> Shared { + let p = match self.deref() { + Parameter::Bool(b) => RuneParameter::Bool(*b), + Parameter::Int(i) => RuneParameter::Int(*i as i32), + Parameter::Float(f) => RuneParameter::Float(*f), + Parameter::String(s) => RuneParameter::String(RuneStringKey::new(s.clone())), + }; + Shared::new(AnyObj::new(p).unwrap()).unwrap() + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/ability.rs b/src/script_implementations/rune/wrappers/static_data/ability.rs new file mode 100644 index 0000000..102478e --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/ability.rs @@ -0,0 +1,34 @@ +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::Ability; +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(RuneAbility::name)?; + module.function_meta(RuneAbility::effect)?; + module.function_meta(RuneAbility::get_parameter)?; + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneAbility(Arc); + +impl_rune_wrapper!(&Arc, RuneAbility); + +impl RuneAbility { + #[rune::function] + fn name(&self) -> Shared { self.0.name().wrap() } + + #[rune::function] + fn effect(&self) -> Shared { self.0.effect().wrap() } + + #[rune::function(vm_result)] + fn get_parameter(&self, key: RuneStringKey) -> Option> { + match self.0.parameters().get(&key.0) { + None => None, + Some(p) => Some(p.wrap()), + } + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/form.rs b/src/script_implementations/rune/wrappers/static_data/form.rs new file mode 100644 index 0000000..56c9891 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/form.rs @@ -0,0 +1,67 @@ +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::{AbilityIndex, Form, Statistic}; +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(RuneForm::name)?; + module.function_meta(RuneForm::height)?; + module.function_meta(RuneForm::weight)?; + module.function_meta(RuneForm::base_experience)?; + module.function_meta(RuneForm::types)?; + module.function_meta(RuneForm::base_stats)?; + module.function_meta(RuneForm::abilities)?; + module.function_meta(RuneForm::hidden_abilities)?; + module.function_meta(RuneForm::has_flag)?; + module.function_meta(RuneForm::get_type)?; + module.function_meta(RuneForm::get_base_stat)?; + module.function_meta(RuneForm::get_ability)?; + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneForm(Arc); + +impl_rune_wrapper!(&Arc, RuneForm); + +impl RuneForm { + #[rune::function] + fn name(&self) -> Shared { self.0.name().wrap() } + + #[rune::function] + fn height(&self) -> f32 { self.0.height() } + + #[rune::function] + fn weight(&self) -> f32 { self.0.weight() } + + #[rune::function] + fn base_experience(&self) -> u32 { self.0.base_experience() } + + #[rune::function] + fn types(&self) -> Vec { self.0.types().iter().map(|t| u8::from(*t)).collect() } + + #[rune::function] + fn base_stats(&self) -> Shared { self.0.base_stats().wrap() } + + #[rune::function] + fn abilities(&self) -> Vec> { self.0.abilities().iter().map(|a| a.wrap()).collect() } + + #[rune::function] + fn hidden_abilities(&self) -> Vec> { self.0.hidden_abilities().iter().map(|a| a.wrap()).collect() } + + #[rune::function] + fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) } + + #[rune::function] + fn get_type(&self, index: usize) -> anyhow::Result { self.0.get_type(index).map(|t| u8::from(t)) } + + #[rune::function] + fn get_base_stat(&self, statistic: Statistic) -> u16 { self.0.get_base_stat(statistic) } + + #[rune::function] + fn get_ability(&self, hidden: bool, index: u8) -> anyhow::Result> { + self.0.get_ability(AbilityIndex { hidden, index }).map(|a| a.wrap()) + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/growth_rate.rs b/src/script_implementations/rune/wrappers/static_data/growth_rate.rs new file mode 100644 index 0000000..a589475 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/growth_rate.rs @@ -0,0 +1,27 @@ +use crate::defines::LevelInt; +use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use crate::static_data::GrowthRate; +use rune::Any; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneGrowthRate::calculate_level)?; + module.function_meta(RuneGrowthRate::calculate_experience)?; + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneGrowthRate(Arc); + +impl_rune_wrapper!(&Arc, RuneGrowthRate); + +impl RuneGrowthRate { + #[rune::function] + fn calculate_level(&self, experience: u32) -> i32 { self.0.calculate_level(experience) as i32 } + + #[rune::function] + fn calculate_experience(&self, level: LevelInt) -> Result { + self.0.calculate_experience(level).map_err(|e| e.to_string()) + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/item.rs b/src/script_implementations/rune/wrappers/static_data/item.rs new file mode 100644 index 0000000..76635c3 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/item.rs @@ -0,0 +1,47 @@ +use std::sync::Arc; + +use rune::runtime::{AnyObj, Shared}; +use rune::Any; + +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::{BattleItemCategory, Item, ItemCategory}; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.ty::()?; + + module.ty::()?; + module.function_meta(RuneItem::name)?; + module.function_meta(RuneItem::category)?; + module.function_meta(RuneItem::battle_category)?; + module.function_meta(RuneItem::price)?; + module.function_meta(RuneItem::flags)?; + module.function_meta(RuneItem::has_flag)?; + + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneItem(Arc); + +impl_rune_wrapper!(&Arc, RuneItem); + +impl RuneItem { + #[rune::function] + fn name(&self) -> Shared { self.0.name().clone().wrap() } + + #[rune::function] + fn category(&self) -> ItemCategory { self.0.category() } + + #[rune::function] + fn battle_category(&self) -> BattleItemCategory { self.0.battle_category() } + + #[rune::function] + fn price(&self) -> i32 { self.0.price() } + + #[rune::function] + fn flags(&self) -> Vec> { self.0.flags().iter().map(|s| s.clone().wrap()).collect() } + + #[rune::function] + fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) } +} diff --git a/src/script_implementations/rune/wrappers/static_data/learnable_moves.rs b/src/script_implementations/rune/wrappers/static_data/learnable_moves.rs new file mode 100644 index 0000000..47bc6a1 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/learnable_moves.rs @@ -0,0 +1,40 @@ +use crate::defines::LevelInt; +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::LearnableMoves; +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(RuneLearnableMoves::get_learned_by_level)?; + module.function_meta(RuneLearnableMoves::get_distinct_level_moves)?; + module.function_meta(RuneLearnableMoves::learns_move)?; + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneLearnableMoves(Arc); + +impl_rune_wrapper!(&Arc, RuneLearnableMoves); + +impl RuneLearnableMoves { + #[rune::function] + fn get_learned_by_level(&self, level: LevelInt) -> Option>> { + self.0 + .get_learned_by_level(level) + .map(|v| v.into_iter().map(|s| s.wrap()).collect()) + } + + #[rune::function] + fn get_distinct_level_moves(&self) -> Vec> { + self.0 + .get_distinct_level_moves() + .into_iter() + .map(|s| s.wrap()) + .collect() + } + + #[rune::function] + fn learns_move(&self, moveName: &RuneStringKey) -> bool { self.0.get_distinct_level_moves().contains(&moveName.0) } +} diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/growth_rate_library.rs b/src/script_implementations/rune/wrappers/static_data/libraries/growth_rate_library.rs new file mode 100644 index 0000000..361acbb --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/libraries/growth_rate_library.rs @@ -0,0 +1,29 @@ +use crate::defines::LevelInt; +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey}; +use crate::static_data::GrowthRateLibrary; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneGrowthRateLibrary::calculate_level)?; + module.function_meta(RuneGrowthRateLibrary::calculate_experience)?; + + Ok(()) +} + +#[derive(Debug, rune::Any)] +struct RuneGrowthRateLibrary(Arc); + +impl_rune_wrapper!(&Arc, RuneGrowthRateLibrary); + +impl RuneGrowthRateLibrary { + #[rune::function] + fn calculate_level(&self, growth_rate: &RuneStringKey, experience: u32) -> anyhow::Result { + self.0.calculate_level(&growth_rate.0, experience) + } + + #[rune::function] + fn calculate_experience(&self, growth_rate: &RuneStringKey, level: LevelInt) -> anyhow::Result { + self.0.calculate_experience(&growth_rate.0, level) + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/library_settings.rs b/src/script_implementations/rune/wrappers/static_data/libraries/library_settings.rs new file mode 100644 index 0000000..b408ac7 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/libraries/library_settings.rs @@ -0,0 +1,23 @@ +use crate::script_implementations::rune::wrappers::impl_rune_wrapper; +use crate::static_data::LibrarySettings; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneLibrarySettings::maximum_level)?; + module.function_meta(RuneLibrarySettings::shiny_rate)?; + Ok(()) +} + +#[derive(Debug, rune::Any)] +struct RuneLibrarySettings(Arc); + +impl_rune_wrapper!(&Arc, RuneLibrarySettings); + +impl RuneLibrarySettings { + #[rune::function] + fn maximum_level(&self) -> i64 { self.0.maximum_level() as i64 } + + #[rune::function] + fn shiny_rate(&self) -> i64 { self.0.shiny_rate() as i64 } +} diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs b/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs new file mode 100644 index 0000000..76f0518 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/libraries/mod.rs @@ -0,0 +1,68 @@ +mod growth_rate_library; +mod library_settings; +mod nature_library; +mod static_data; +mod type_library; + +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::{AbilityLibrary, ItemLibrary, MoveLibrary, SpeciesLibrary}; +use rune::runtime::{AnyObj, Shared}; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneAbilityLibrary::get)?; + module.function_meta(RuneAbilityLibrary::len)?; + module.function_meta(RuneAbilityLibrary::get_key_by_index)?; + + module.ty::()?; + module.function_meta(RuneItemLibrary::get)?; + module.function_meta(RuneItemLibrary::len)?; + module.function_meta(RuneItemLibrary::get_key_by_index)?; + + module.ty::()?; + module.function_meta(RuneMoveLibrary::get)?; + module.function_meta(RuneMoveLibrary::len)?; + module.function_meta(RuneMoveLibrary::get_key_by_index)?; + + module.ty::()?; + module.function_meta(RuneSpeciesLibrary::get)?; + module.function_meta(RuneSpeciesLibrary::len)?; + module.function_meta(RuneSpeciesLibrary::get_key_by_index)?; + + growth_rate_library::register(module)?; + library_settings::register(module)?; + nature_library::register(module)?; + type_library::register(module)?; + + static_data::register(module)?; + + Ok(()) +} + +macro_rules! impl_rune_data_library_wrapper { + ($t:ident, $wrapped_type:ty) => { + #[derive(Debug, rune::Any)] + struct $t($wrapped_type); + + impl_rune_wrapper!(&$wrapped_type, $t); + + impl $t { + #[rune::function] + fn get(&self, key: &RuneStringKey) -> Option> { self.0.get(&key.0).map(|v| v.wrap()) } + + #[rune::function] + fn len(&self) -> usize { self.0.len() } + + #[rune::function] + fn get_key_by_index(&self, index: usize) -> Option> { + self.0.get_key_by_index(index).map(|v| v.wrap()) + } + } + }; +} + +impl_rune_data_library_wrapper!(RuneAbilityLibrary, Arc); +impl_rune_data_library_wrapper!(RuneItemLibrary, Arc); +impl_rune_data_library_wrapper!(RuneMoveLibrary, Arc); +impl_rune_data_library_wrapper!(RuneSpeciesLibrary, Arc); diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/nature_library.rs b/src/script_implementations/rune/wrappers/static_data/libraries/nature_library.rs new file mode 100644 index 0000000..5b5d920 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/libraries/nature_library.rs @@ -0,0 +1,27 @@ +use crate::script_implementations::rune::wrappers::static_data::nature::RuneNature; +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::NatureLibrary; +use rune::runtime::{AnyObj, Shared}; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneNatureLibrary::get_nature)?; + module.function_meta(RuneNatureLibrary::get_nature_name)?; + Ok(()) +} + +#[derive(Debug, rune::Any)] +struct RuneNatureLibrary(Arc); + +impl_rune_wrapper!(&Arc, RuneNatureLibrary); + +impl RuneNatureLibrary { + #[rune::function] + fn get_nature(&self, key: RuneStringKey) -> Option> { self.0.get_nature(&key.0).map(|v| v.wrap()) } + + #[rune::function] + fn get_nature_name(&self, nature: &RuneNature) -> RuneStringKey { + RuneStringKey(self.0.get_nature_name(&nature.0).unwrap()) + } +} 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 new file mode 100644 index 0000000..0bd3cb0 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/libraries/static_data.rs @@ -0,0 +1,48 @@ +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper}; +use crate::static_data::StaticData; +use rune::runtime::{AnyObj, Shared}; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneStaticData::settings)?; + module.function_meta(RuneStaticData::species)?; + module.function_meta(RuneStaticData::moves)?; + module.function_meta(RuneStaticData::items)?; + module.function_meta(RuneStaticData::growth_rates)?; + module.function_meta(RuneStaticData::types)?; + module.function_meta(RuneStaticData::natures)?; + module.function_meta(RuneStaticData::abilities)?; + Ok(()) +} + +#[derive(Debug, rune::Any)] +struct RuneStaticData(Arc); + +impl_rune_wrapper!(&Arc, RuneStaticData); + +impl RuneStaticData { + #[rune::function] + fn settings(&self) -> Shared { self.0.settings().wrap() } + + #[rune::function] + fn species(&self) -> Shared { self.0.species().wrap() } + + #[rune::function] + fn moves(&self) -> Shared { self.0.moves().wrap() } + + #[rune::function] + fn items(&self) -> Shared { self.0.items().wrap() } + + #[rune::function] + fn growth_rates(&self) -> Shared { self.0.growth_rates().wrap() } + + #[rune::function] + fn types(&self) -> Shared { self.0.types().wrap() } + + #[rune::function] + fn natures(&self) -> Shared { self.0.natures().wrap() } + + #[rune::function] + fn abilities(&self) -> Shared { self.0.abilities().wrap() } +} diff --git a/src/script_implementations/rune/wrappers/static_data/libraries/type_library.rs b/src/script_implementations/rune/wrappers/static_data/libraries/type_library.rs new file mode 100644 index 0000000..55868ba --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/libraries/type_library.rs @@ -0,0 +1,39 @@ +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::TypeLibrary; +use rune::runtime::{AnyObj, Shared}; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.function_meta(RuneTypeLibrary::get_type_id)?; + module.function_meta(RuneTypeLibrary::get_type_name)?; + module.function_meta(RuneTypeLibrary::get_single_effectiveness)?; + module.function_meta(RuneTypeLibrary::get_effectiveness)?; + Ok(()) +} + +#[derive(Debug, rune::Any)] +struct RuneTypeLibrary(Arc); + +impl_rune_wrapper!(&Arc, RuneTypeLibrary); + +impl RuneTypeLibrary { + #[rune::function] + fn get_type_id(&self, key: &RuneStringKey) -> Option { self.0.get_type_id(&key.0).map(|v| v.into()) } + + #[rune::function] + fn get_type_name(&self, t: u8) -> Option> { self.0.get_type_name(t.into()).map(|v| v.wrap()) } + + #[rune::function] + fn get_single_effectiveness(&self, attacking: u8, defending: u8) -> anyhow::Result { + self.0.get_single_effectiveness(attacking.into(), defending.into()) + } + + #[rune::function] + fn get_effectiveness(&self, attacking: u8, defending: &[u8]) -> anyhow::Result { + self.0.get_effectiveness( + attacking.into(), + &defending.iter().map(|v| (*v).into()).collect::>(), + ) + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/mod.rs b/src/script_implementations/rune/wrappers/static_data/mod.rs index 684e2e2..07e1eae 100644 --- a/src/script_implementations/rune/wrappers/static_data/mod.rs +++ b/src/script_implementations/rune/wrappers/static_data/mod.rs @@ -1,12 +1,30 @@ +mod ability; +mod form; +mod growth_rate; +mod item; +mod learnable_moves; +mod libraries; +mod move_data; mod nature; +mod species; mod statistic_set; -use crate::static_data::{Statistic, TimeOfDay}; +use crate::static_data::{Gender, Statistic, TimeOfDay}; pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { module.ty::()?; module.ty::()?; + module.ty::()?; statistic_set::register(module)?; nature::register(module)?; + item::register(module)?; + growth_rate::register(module)?; + form::register(module)?; + ability::register(module)?; + learnable_moves::register(module)?; + species::register(module)?; + move_data::register(module)?; + + libraries::register(module)?; Ok(()) } diff --git a/src/script_implementations/rune/wrappers/static_data/move_data.rs b/src/script_implementations/rune/wrappers/static_data/move_data.rs new file mode 100644 index 0000000..15b07d3 --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/move_data.rs @@ -0,0 +1,89 @@ +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect}; +use rune::runtime::{AnyObj, Object, Shared}; +use rune::{Any, Value}; +use std::convert::TryFrom; +use std::sync::Arc; + +pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { + module.ty::()?; + module.ty::()?; + module.ty::()?; + module.function_meta(RuneMoveData::name)?; + module.function_meta(RuneMoveData::move_type)?; + module.function_meta(RuneMoveData::category)?; + module.function_meta(RuneMoveData::base_power)?; + module.function_meta(RuneMoveData::accuracy)?; + module.function_meta(RuneMoveData::base_usages)?; + module.function_meta(RuneMoveData::target)?; + module.function_meta(RuneMoveData::priority)?; + module.function_meta(RuneMoveData::secondary_effect)?; + module.function_meta(RuneMoveData::has_flag)?; + + module.ty::()?; + module.function_meta(RuneSecondaryEffect::chance)?; + module.function_meta(RuneSecondaryEffect::effect_name)?; + module.function_meta(RuneSecondaryEffect::parameters)?; + + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneMoveData(Arc); + +impl_rune_wrapper!(&Arc, RuneMoveData); + +impl RuneMoveData { + #[rune::function] + fn name(&self) -> Shared { self.0.name().wrap() } + + #[rune::function] + fn move_type(&self) -> u8 { u8::from(self.0.move_type()) } + + #[rune::function] + fn category(&self) -> MoveCategory { self.0.category() } + + #[rune::function] + fn base_power(&self) -> u8 { self.0.base_power() } + + #[rune::function] + fn accuracy(&self) -> u8 { self.0.accuracy() } + + #[rune::function] + fn base_usages(&self) -> u8 { self.0.base_usages() } + + #[rune::function] + fn target(&self) -> MoveTarget { self.0.target() } + + #[rune::function] + fn priority(&self) -> i8 { self.0.priority() } + + #[rune::function] + fn secondary_effect(&self) -> Option> { self.0.secondary_effect().as_ref().map(|x| x.wrap()) } + + #[rune::function] + fn has_flag(&self, flag: RuneStringKey) -> bool { self.0.has_flag(&flag.0) } +} + +#[derive(Debug, Any)] +pub struct RuneSecondaryEffect(Arc); + +impl_rune_wrapper!(&Arc, RuneSecondaryEffect); + +impl RuneSecondaryEffect { + #[rune::function] + fn chance(&self) -> f32 { self.0.chance() } + + #[rune::function] + fn effect_name(&self) -> Shared { self.0.effect_name().wrap() } + + #[rune::function] + fn parameters(&self) -> anyhow::Result { + let pars = self.0.parameters(); + let mut o = Object::with_capacity(pars.len())?; + for (key, value) in pars.iter() { + o.insert(rune::alloc::String::try_from(key.str())?, Value::from(value.wrap()))?; + } + Ok(o) + } +} diff --git a/src/script_implementations/rune/wrappers/static_data/nature.rs b/src/script_implementations/rune/wrappers/static_data/nature.rs index 8356d51..e29fcde 100644 --- a/src/script_implementations/rune/wrappers/static_data/nature.rs +++ b/src/script_implementations/rune/wrappers/static_data/nature.rs @@ -5,27 +5,32 @@ use std::sync::Arc; pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { module.ty::()?; + module.function_meta(RuneNature::increased_stat)?; + module.function_meta(RuneNature::decreased_stat)?; + module.function_meta(RuneNature::increased_modifier)?; + module.function_meta(RuneNature::decreased_modifier)?; + module.function_meta(RuneNature::get_stat_modifier)?; Ok(()) } #[derive(Debug, Any)] -pub struct RuneNature(Arc); +pub struct RuneNature(pub Arc); impl_rune_wrapper!(&Arc, RuneNature); impl RuneNature { #[rune::function] - pub fn increased_stat(&self) -> Statistic { self.0.increased_stat() } + fn increased_stat(&self) -> Statistic { self.0.increased_stat() } #[rune::function] - pub fn decreased_stat(&self) -> Statistic { self.0.decreased_stat() } + fn decreased_stat(&self) -> Statistic { self.0.decreased_stat() } #[rune::function] - pub fn increased_modifier(&self) -> f32 { self.0.increased_modifier() } + fn increased_modifier(&self) -> f32 { self.0.increased_modifier() } #[rune::function] - pub fn decreased_modifier(&self) -> f32 { self.0.decreased_modifier() } + fn decreased_modifier(&self) -> f32 { self.0.decreased_modifier() } #[rune::function] - pub fn get_stat_modifier(&self, stat: Statistic) -> f32 { self.0.get_stat_modifier(stat) } + fn get_stat_modifier(&self, stat: Statistic) -> f32 { self.0.get_stat_modifier(stat) } } diff --git a/src/script_implementations/rune/wrappers/static_data/species.rs b/src/script_implementations/rune/wrappers/static_data/species.rs new file mode 100644 index 0000000..11c214a --- /dev/null +++ b/src/script_implementations/rune/wrappers/static_data/species.rs @@ -0,0 +1,56 @@ +use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper}; +use crate::static_data::Species; +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(RuneSpecies::id)?; + module.function_meta(RuneSpecies::name)?; + module.function_meta(RuneSpecies::gender_rate)?; + module.function_meta(RuneSpecies::growth_rate)?; + module.function_meta(RuneSpecies::capture_rate)?; + module.function_meta(RuneSpecies::base_happiness)?; + module.function_meta(RuneSpecies::get_form)?; + module.function_meta(RuneSpecies::get_default_form)?; + module.function_meta(RuneSpecies::has_flag)?; + + Ok(()) +} + +#[derive(Debug, Any)] +pub struct RuneSpecies(Arc); + +impl_rune_wrapper!(&Arc, RuneSpecies); + +impl RuneSpecies { + #[rune::function] + fn id(&self) -> u16 { self.0.id() } + + #[rune::function] + fn name(&self) -> Shared { self.0.name().wrap() } + + #[rune::function] + fn gender_rate(&self) -> f32 { self.0.gender_rate() } + + #[rune::function] + fn growth_rate(&self) -> Shared { self.0.growth_rate().wrap() } + + #[rune::function] + fn capture_rate(&self) -> u8 { self.0.capture_rate() } + + #[rune::function] + fn base_happiness(&self) -> u8 { self.0.base_happiness() } + + #[rune::function] + fn get_form(&self, name: &RuneStringKey) -> Option> { + self.0.get_form(&name.0).map(|form| form.wrap()) + } + + #[rune::function] + fn get_default_form(&self) -> anyhow::Result> { self.0.get_default_form().map(|v| v.wrap()) } + + #[rune::function] + fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) } +} 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 86e2d19..19ee331 100644 --- a/src/script_implementations/rune/wrappers/static_data/statistic_set.rs +++ b/src/script_implementations/rune/wrappers/static_data/statistic_set.rs @@ -5,7 +5,24 @@ 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(RuneStaticStatisticSet::get)?; + module.function_meta(RuneStaticStatisticSet::hp)?; + module.function_meta(RuneStaticStatisticSet::attack)?; + module.function_meta(RuneStaticStatisticSet::defense)?; + module.function_meta(RuneStaticStatisticSet::special_attack)?; + module.function_meta(RuneStaticStatisticSet::special_defense)?; + module.function_meta(RuneStaticStatisticSet::speed)?; + Ok(()) } @@ -15,28 +32,28 @@ pub struct RuneStatisticSet(Arc>); impl_rune_wrapper!(&Arc>, RuneStatisticSet); impl RuneStatisticSet { #[rune::function] - pub fn get(&self, stat: Statistic) -> u32 { self.0.get_stat(stat) } + fn get(&self, stat: Statistic) -> u32 { self.0.get_stat(stat) } #[rune::function] - pub fn set(&mut self, stat: Statistic, value: u32) { self.0.set_stat(stat, value) } + fn set(&mut self, stat: Statistic, value: u32) { self.0.set_stat(stat, value) } #[rune::function] - pub fn hp(&self) -> u32 { self.0.hp() } + fn hp(&self) -> u32 { self.0.hp() } #[rune::function] - pub fn attack(&self) -> u32 { self.0.attack() } + fn attack(&self) -> u32 { self.0.attack() } #[rune::function] - pub fn defense(&self) -> u32 { self.0.defense() } + fn defense(&self) -> u32 { self.0.defense() } #[rune::function] - pub fn special_attack(&self) -> u32 { self.0.special_attack() } + fn special_attack(&self) -> u32 { self.0.special_attack() } #[rune::function] - pub fn special_defense(&self) -> u32 { self.0.special_defense() } + fn special_defense(&self) -> u32 { self.0.special_defense() } #[rune::function] - pub fn speed(&self) -> u32 { self.0.speed() } + fn speed(&self) -> u32 { self.0.speed() } } #[derive(Debug, Any)] @@ -46,22 +63,22 @@ impl_rune_wrapper!(&Arc>, RuneStaticStatisticSet); impl RuneStaticStatisticSet { #[rune::function] - pub fn get(&self, stat: Statistic) -> u16 { self.0.get_stat(stat) } + fn get(&self, stat: Statistic) -> u16 { self.0.get_stat(stat) } #[rune::function] - pub fn hp(&self) -> u16 { self.0.hp() } + fn hp(&self) -> u16 { self.0.hp() } #[rune::function] - pub fn attack(&self) -> u16 { self.0.attack() } + fn attack(&self) -> u16 { self.0.attack() } #[rune::function] - pub fn defense(&self) -> u16 { self.0.defense() } + fn defense(&self) -> u16 { self.0.defense() } #[rune::function] - pub fn special_attack(&self) -> u16 { self.0.special_attack() } + fn special_attack(&self) -> u16 { self.0.special_attack() } #[rune::function] - pub fn special_defense(&self) -> u16 { self.0.special_defense() } + fn special_defense(&self) -> u16 { self.0.special_defense() } #[rune::function] pub fn speed(&self) -> u16 { self.0.speed() } diff --git a/src/static_data/growth_rates.rs b/src/static_data/growth_rates.rs index ffa242e..28cdafe 100755 --- a/src/static_data/growth_rates.rs +++ b/src/static_data/growth_rates.rs @@ -2,9 +2,10 @@ use crate::defines::LevelInt; use crate::VecExt; use anyhow::Result; use anyhow_ext::ensure; +use std::fmt::Debug; /// A growth rate defines how much experience is required per level. -pub trait GrowthRate { +pub trait GrowthRate: Debug { /// Calculate the level something with this growth rate would have at a certain experience. fn calculate_level(&self, experience: u32) -> LevelInt; /// Calculate the experience something with this growth rate would have at a certain level. @@ -12,6 +13,7 @@ pub trait GrowthRate { } /// An implementation of the growth rate that uses a lookup table for experience. +#[derive(Debug)] pub struct LookupGrowthRate { /// The lookup Vec. experience: Vec, @@ -20,9 +22,7 @@ pub struct LookupGrowthRate { impl LookupGrowthRate { /// Instantiates a new lookup growth rate. The experience vec should be the amount of experience /// required per level, with the first element being the experience required for level 1 (generally 0). - pub fn new(experience: Vec) -> LookupGrowthRate { - LookupGrowthRate { experience } - } + pub fn new(experience: Vec) -> LookupGrowthRate { LookupGrowthRate { experience } } } impl GrowthRate for LookupGrowthRate { diff --git a/src/static_data/items.rs b/src/static_data/items.rs index acaf440..93dac03 100755 --- a/src/static_data/items.rs +++ b/src/static_data/items.rs @@ -1,6 +1,5 @@ use hashbrown::HashSet; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +#[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::any::Any; use std::fmt::Debug; @@ -9,6 +8,7 @@ use crate::StringKey; /// An item category defines which bag slot items are stored in. #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "rune", derive(rune::Any))] #[repr(u8)] pub enum ItemCategory { /// This is where most items should go. @@ -32,6 +32,7 @@ pub enum ItemCategory { /// A battle item category defines how the item is categorized when in battle. #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "rune", derive(rune::Any))] #[repr(u8)] pub enum BattleItemCategory { /// This item can't be used in battle. @@ -99,30 +100,18 @@ impl ItemImpl { impl Item for ItemImpl { /// The name of the item. - fn name(&self) -> &StringKey { - &self.name - } + fn name(&self) -> &StringKey { &self.name } /// Which bag slot items are stored in. - fn category(&self) -> ItemCategory { - self.category - } + fn category(&self) -> ItemCategory { self.category } /// How the item is categorized when in battle. - fn battle_category(&self) -> BattleItemCategory { - self.battle_category - } + fn battle_category(&self) -> BattleItemCategory { self.battle_category } /// The buying value of the item. - fn price(&self) -> i32 { - self.price - } + fn price(&self) -> i32 { self.price } /// A set of arbitrary flags that can be set on the item. - fn flags(&self) -> &HashSet { - &self.flags - } + fn flags(&self) -> &HashSet { &self.flags } /// Checks whether the item has a specific flag. - fn has_flag(&self, key: &StringKey) -> bool { - self.flags.contains(key) - } + fn has_flag(&self, key: &StringKey) -> bool { self.flags.contains(key) } } #[cfg(test)] diff --git a/src/static_data/libraries/data_library.rs b/src/static_data/libraries/data_library.rs index d42f404..b2e4e69 100755 --- a/src/static_data/libraries/data_library.rs +++ b/src/static_data/libraries/data_library.rs @@ -1,4 +1,5 @@ use anyhow_ext::Result; +use std::fmt::Debug; use std::sync::Arc; use indexmap::IndexMap; @@ -8,7 +9,7 @@ use crate::StringKey; /// A data library is a collection of methods to set up a default library, where values are stored /// by both key, while keeping their insertion order. -pub trait DataLibrary { +pub trait DataLibrary: Debug { /// Returns the underlying map. fn map(&self) -> &IndexMap>; /// Returns the underlying map in mutable manner. @@ -25,32 +26,22 @@ pub trait DataLibrary { fn remove(&self, key: &StringKey) { #[allow(clippy::unwrap_used)] // We know this cant fail. let self_mut = unsafe { (self as *const Self as *mut Self).as_mut() }.unwrap(); - self_mut.get_modify().remove(key); + self_mut.get_modify().swap_remove(key); } /// Gets a value from the library. - fn get(&self, key: &StringKey) -> Option> { - self.map().get::(key).cloned() - } + fn get(&self, key: &StringKey) -> Option> { self.map().get::(key).cloned() } /// Gets a value from the library. - fn get_by_hash(&self, key: u32) -> Option> { - self.map().get::(&key).cloned() - } + fn get_by_hash(&self, key: u32) -> Option> { self.map().get::(&key).cloned() } /// Gets a value from the library by the index where it is stored. - fn get_key_by_index(&self, index: usize) -> Option { - self.map().get_index(index).map(|a| a.0.clone()) - } + fn get_key_by_index(&self, index: usize) -> Option { self.map().get_index(index).map(|a| a.0.clone()) } /// Gets the amount of values in the library. - fn len(&self) -> usize { - self.map().len() - } + fn len(&self) -> usize { self.map().len() } /// Returns whether the library has no values. - fn is_empty(&self) -> bool { - self.map().is_empty() - } + fn is_empty(&self) -> bool { self.map().is_empty() } /// Gets a random value from the library. fn random_value(&self, rand: &mut Random) -> Result<&Arc> { diff --git a/src/static_data/libraries/growth_rate_library.rs b/src/static_data/libraries/growth_rate_library.rs index a52163f..0262052 100755 --- a/src/static_data/libraries/growth_rate_library.rs +++ b/src/static_data/libraries/growth_rate_library.rs @@ -61,9 +61,7 @@ impl GrowthRateLibrary for GrowthRateLibraryImpl { } impl Debug for GrowthRateLibraryImpl { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("GrowthRateLibrary").finish() - } + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("GrowthRateLibrary").finish() } } #[cfg(test)] @@ -72,8 +70,6 @@ impl Debug for GrowthRateLibraryImpl { pub mod tests { use super::*; use crate::static_data::growth_rates::LookupGrowthRate; - use crate::static_data::libraries::growth_rate_library::GrowthRateLibrary; - use crate::static_data::GrowthRateLibraryImpl; pub fn build() -> GrowthRateLibraryImpl { let mut lib = GrowthRateLibraryImpl::new(1); diff --git a/src/static_data/libraries/nature_library.rs b/src/static_data/libraries/nature_library.rs index 220ed65..6003092 100644 --- a/src/static_data/libraries/nature_library.rs +++ b/src/static_data/libraries/nature_library.rs @@ -38,14 +38,10 @@ impl NatureLibraryImpl { impl NatureLibrary for NatureLibraryImpl { /// Adds a new nature with name to the library. - fn load_nature(&self, name: StringKey, nature: Arc) { - self.map.write().insert(name, nature); - } + fn load_nature(&self, name: StringKey, nature: Arc) { self.map.write().insert(name, nature); } /// Gets a nature by name. - fn get_nature(&self, key: &StringKey) -> Option> { - self.map.read().get(key).cloned() - } + fn get_nature(&self, key: &StringKey) -> Option> { self.map.read().get(key).cloned() } fn get_random_nature(&self, rand: &mut Random) -> Result> { let map = self.map.read(); @@ -80,7 +76,7 @@ impl NatureLibrary for NatureLibraryImpl { pub mod tests { use super::*; use crate::static_data::statistics::Statistic; - use crate::static_data::{NatureImpl, NatureLibrary, NatureLibraryImpl}; + use crate::static_data::NatureImpl; pub fn build() -> NatureLibraryImpl { let lib = NatureLibraryImpl::new(2); diff --git a/src/static_data/libraries/type_library.rs b/src/static_data/libraries/type_library.rs index c29bd43..d261f89 100755 --- a/src/static_data/libraries/type_library.rs +++ b/src/static_data/libraries/type_library.rs @@ -11,27 +11,18 @@ use crate::{PkmnError, StringKey}; #[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Hash, Atom)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[repr(transparent)] -pub struct TypeIdentifier { - /// The unique internal value. - val: u8, -} +pub struct TypeIdentifier(u8); impl From for TypeIdentifier { - fn from(val: u8) -> Self { - Self { val } - } + fn from(val: u8) -> Self { Self(val) } } impl From for u8 { - fn from(id: TypeIdentifier) -> Self { - id.val - } + fn from(id: TypeIdentifier) -> Self { id.0 } } impl Display for TypeIdentifier { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "TypeId({})", self.val) - } + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "TypeId({})", self.0) } } /// All data related to types and effectiveness. @@ -87,18 +78,16 @@ impl TypeLibraryImpl { defending: TypeIdentifier, ) -> Result { Ok(*lock - .get((attacking.val - 1) as usize) + .get((attacking.0 - 1) as usize) .ok_or(PkmnError::InvalidTypeIdentifier { type_id: attacking })? - .get((defending.val - 1) as usize) + .get((defending.0 - 1) as usize) .ok_or(PkmnError::InvalidTypeIdentifier { type_id: defending })?) } } impl TypeLibrary for TypeLibraryImpl { /// Gets the type identifier for a type with a name. - fn get_type_id(&self, key: &StringKey) -> Option { - self.types.read().get(key).cloned() - } + fn get_type_id(&self, key: &StringKey) -> Option { self.types.read().get(key).cloned() } /// Gets the type name from the type identifier. fn get_type_name(&self, t: TypeIdentifier) -> Option { @@ -133,13 +122,11 @@ impl TypeLibrary for TypeLibraryImpl { let mut types_write_lock = self.types.write(); let mut effectiveness_write_lock = self.effectiveness.write(); - let id = TypeIdentifier { - val: (types_write_lock.len() + 1) as u8, - }; + let id = TypeIdentifier((types_write_lock.len() + 1) as u8); types_write_lock.insert(name.clone(), id); - effectiveness_write_lock.resize((id.val) as usize, vec![]); + effectiveness_write_lock.resize((id.0) as usize, vec![]); for effectiveness in &mut effectiveness_write_lock.iter_mut() { - effectiveness.resize((id.val) as usize, 1.0) + effectiveness.resize((id.0) as usize, 1.0) } id } @@ -154,9 +141,9 @@ impl TypeLibrary for TypeLibraryImpl { *self .effectiveness .write() - .get_mut((attacking.val - 1) as usize) + .get_mut((attacking.0 - 1) as usize) .ok_or(PkmnError::InvalidTypeIdentifier { type_id: attacking })? - .get_mut((defending.val - 1) as usize) + .get_mut((defending.0 - 1) as usize) .ok_or(PkmnError::InvalidTypeIdentifier { type_id: defending })? = effectiveness; Ok(()) } @@ -169,7 +156,6 @@ pub mod tests { use assert_approx_eq::assert_approx_eq; use super::*; - use crate::static_data::libraries::type_library::TypeLibrary; pub fn build() -> TypeLibraryImpl { let mut lib = TypeLibraryImpl::new(2); diff --git a/src/static_data/mod.rs b/src/static_data/mod.rs index c413118..8145426 100755 --- a/src/static_data/mod.rs +++ b/src/static_data/mod.rs @@ -24,12 +24,6 @@ use std::fmt::{Display, Formatter}; pub(crate) mod tests { use super::*; #[doc(inline)] - pub use growth_rates::tests::*; - #[doc(inline)] - pub use items::tests::*; - #[doc(inline)] - pub use libraries::tests::*; - #[doc(inline)] pub use moves::tests::*; #[doc(inline)] pub use natures::tests::*; @@ -71,27 +65,19 @@ pub enum Parameter { } impl From for Parameter { - fn from(b: bool) -> Self { - Parameter::Bool(b) - } + fn from(b: bool) -> Self { Parameter::Bool(b) } } impl From for Parameter { - fn from(i: i64) -> Self { - Parameter::Int(i) - } + fn from(i: i64) -> Self { Parameter::Int(i) } } impl From for Parameter { - fn from(f: f32) -> Self { - Parameter::Float(f) - } + fn from(f: f32) -> Self { Parameter::Float(f) } } impl From for Parameter { - fn from(s: StringKey) -> Self { - Parameter::String(s) - } + fn from(s: StringKey) -> Self { Parameter::String(s) } } impl Display for Parameter { diff --git a/src/static_data/moves/mod.rs b/src/static_data/moves/mod.rs index bd16a64..6c184c4 100755 --- a/src/static_data/moves/mod.rs +++ b/src/static_data/moves/mod.rs @@ -1,16 +1,11 @@ -#[doc(inline)] -pub use move_data::*; -#[doc(inline)] -pub use secondary_effect::*; +#[doc(inline)] pub use move_data::*; +#[doc(inline)] pub use secondary_effect::*; #[cfg(test)] pub(crate) mod tests { use super::*; - #[doc(inline)] - pub use move_data::tests::*; - #[doc(inline)] - pub use secondary_effect::tests::*; + #[doc(inline)] pub use move_data::tests::*; } /// The data belonging to a certain move. diff --git a/src/static_data/moves/move_data.rs b/src/static_data/moves/move_data.rs index 5f7f7a3..69d487c 100755 --- a/src/static_data/moves/move_data.rs +++ b/src/static_data/moves/move_data.rs @@ -1,6 +1,5 @@ use hashbrown::HashSet; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +#[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::fmt::Debug; use std::sync::Arc; @@ -11,6 +10,7 @@ use crate::StringKey; #[derive(Copy, Clone, PartialEq, Eq, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "rune", derive(rune::Any))] #[repr(u8)] pub enum MoveCategory { /// A physical move uses the physical attack stats and physical defense stats to calculate damage. @@ -24,6 +24,7 @@ pub enum MoveCategory { /// The move target defines what kind of targets the move can touch. #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "rune", derive(rune::Any))] #[repr(u8)] pub enum MoveTarget { /// Adjacent allows a move to target any Pokemon that is either directly to the left or right of @@ -149,54 +150,32 @@ impl MoveDataImpl { impl MoveData for MoveDataImpl { /// The name of the move. - fn name(&self) -> &StringKey { - &self.name - } + fn name(&self) -> &StringKey { &self.name } /// The attacking type of the move. - fn move_type(&self) -> TypeIdentifier { - self.move_type - } + fn move_type(&self) -> TypeIdentifier { self.move_type } /// The category of the move. - fn category(&self) -> MoveCategory { - self.category - } + fn category(&self) -> MoveCategory { self.category } /// The base power, not considering any modifiers, the move has. - fn base_power(&self) -> u8 { - self.base_power - } + fn base_power(&self) -> u8 { self.base_power } /// The accuracy of the move in percentage. Should be 255 for moves that always hit. - fn accuracy(&self) -> u8 { - self.accuracy - } + fn accuracy(&self) -> u8 { self.accuracy } /// The number of times the move can be used. This can be modified on actually learned moves using /// PP-Ups - fn base_usages(&self) -> u8 { - self.base_usages - } + fn base_usages(&self) -> u8 { self.base_usages } /// How the move handles targets. - fn target(&self) -> MoveTarget { - self.target - } + fn target(&self) -> MoveTarget { self.target } /// The priority of the move. A higher priority means the move should go before other moves. - fn priority(&self) -> i8 { - self.priority - } + fn priority(&self) -> i8 { self.priority } /// The optional secondary effect the move has. - fn secondary_effect(&self) -> &Option> { - &self.secondary_effect - } + fn secondary_effect(&self) -> &Option> { &self.secondary_effect } /// Checks if the move has a specific flag. - fn has_flag(&self, key: &StringKey) -> bool { - self.flags.contains::(key) - } + fn has_flag(&self, key: &StringKey) -> bool { self.flags.contains::(key) } /// Checks if the move has a specific flag. - fn has_flag_by_hash(&self, key_hash: u32) -> bool { - self.flags.contains::(&key_hash) - } + fn has_flag_by_hash(&self, key_hash: u32) -> bool { self.flags.contains::(&key_hash) } } #[cfg(test)] diff --git a/src/static_data/moves/secondary_effect.rs b/src/static_data/moves/secondary_effect.rs index b897e3e..692c083 100755 --- a/src/static_data/moves/secondary_effect.rs +++ b/src/static_data/moves/secondary_effect.rs @@ -52,9 +52,6 @@ pub(crate) mod tests { use super::*; use assert_approx_eq::assert_approx_eq; - use crate::static_data::moves::secondary_effect::SecondaryEffect; - use crate::static_data::SecondaryEffectImpl; - mockall::mock! { #[derive(Debug)] pub SecondaryEffect{} diff --git a/src/static_data/species_data/gender.rs b/src/static_data/species_data/gender.rs index 9a8e6e1..c10b620 100755 --- a/src/static_data/species_data/gender.rs +++ b/src/static_data/species_data/gender.rs @@ -4,6 +4,7 @@ /// that allows for a more progressive gender system for those that want it? #[derive(Eq, PartialEq, Copy, Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr))] +#[cfg_attr(feature = "rune", derive(rune::Any))] #[repr(u8)] pub enum Gender { /// The Pokemon has no gender. diff --git a/src/static_data/species_data/mod.rs b/src/static_data/species_data/mod.rs index 53c33b9..8c7aad6 100755 --- a/src/static_data/species_data/mod.rs +++ b/src/static_data/species_data/mod.rs @@ -13,9 +13,7 @@ pub use species::*; #[cfg(test)] pub(crate) mod tests { - pub use super::ability::tests::*; pub use super::form::tests::*; - pub use super::learnable_moves::tests::*; pub use super::species::tests::*; } diff --git a/src/static_data/statistics.rs b/src/static_data/statistics.rs index 1f228b1..ade129b 100755 --- a/src/static_data/statistics.rs +++ b/src/static_data/statistics.rs @@ -1,5 +1,4 @@ -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +#[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// Stats are numerical values on Pokemon that are used in battle. #[derive(Debug, PartialEq, Eq, Copy, Clone)] diff --git a/tests/data/scripts/moves/test.rn b/tests/data/scripts/moves/test.rn index 421630d..5342d85 100644 --- a/tests/data/scripts/moves/test.rn +++ b/tests/data/scripts/moves/test.rn @@ -6,7 +6,8 @@ impl TestMove { pub fn change_speed(self, choice, speed) { println(`change_speed: ${choice.speed()}`); println(`user level: ${choice.user().level()}`); - speed.value = 100; + println(`owner: ${self.owner.level()}`); + speed += 100; } } diff --git a/tests/integration.rs b/tests/integration.rs index a85f99b..c748e40 100755 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -51,8 +51,16 @@ fn validate_library_load() { fn rune_test() { let result = library_loader::load_library(); let library = result.library; + let p1 = PokemonBuilder::new(library.clone(), "charizard".into(), 100) + .build() + .unwrap(); + let script = library - .load_script(ScriptOwnerData::None, ScriptCategory::Move, &"TestMove".into()) + .load_script( + ScriptOwnerData::Pokemon(p1.weak()), + ScriptCategory::Move, + &"TestMove".into(), + ) .unwrap() .unwrap(); assert_eq!(script.name().unwrap().str(), "TestMove");