Large amounts of work on Rune
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2024-05-11 16:01:04 +02:00
parent 4ec07ca049
commit 42bee5e37c
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
27 changed files with 751 additions and 306 deletions

View File

@ -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<LearnedMove> {
&self.used_move
}
pub fn used_move(&self) -> &Arc<LearnedMove> { &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<usize> {
Ok(self.choice_data.user.get_script_count()? + 1)
}
fn get_script_count(&self) -> Result<usize> { Ok(self.choice_data.user.get_script_count()? + 1) }
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
&self.choice_data.script_source_data
}
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> { &self.choice_data.script_source_data }
fn get_own_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
scripts.push((&self.script).into());
}
fn get_own_scripts(&self, scripts: &mut Vec<ScriptWrapper>) { scripts.push((&self.script).into()); }
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
self.get_own_scripts(scripts);
@ -260,13 +226,9 @@ impl ItemChoice {
}
impl ScriptSource for ItemChoice {
fn get_script_count(&self) -> Result<usize> {
Ok(0)
}
fn get_script_count(&self) -> Result<usize> { Ok(0) }
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
&self.choice_data.script_source_data
}
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> { &self.choice_data.script_source_data }
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
@ -299,13 +261,9 @@ impl SwitchChoice {
}
impl ScriptSource for SwitchChoice {
fn get_script_count(&self) -> Result<usize> {
Ok(0)
}
fn get_script_count(&self) -> Result<usize> { Ok(0) }
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
&self.choice_data.script_source_data
}
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> { &self.choice_data.script_source_data }
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
@ -337,13 +295,9 @@ impl FleeChoice {
}
impl ScriptSource for FleeChoice {
fn get_script_count(&self) -> Result<usize> {
Ok(0)
}
fn get_script_count(&self) -> Result<usize> { Ok(0) }
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
&self.choice_data.script_source_data
}
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> { &self.choice_data.script_source_data }
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
@ -376,13 +330,9 @@ impl PassChoice {
}
impl ScriptSource for PassChoice {
fn get_script_count(&self) -> Result<usize> {
Ok(0)
}
fn get_script_count(&self) -> Result<usize> { Ok(0) }
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
&self.choice_data.script_source_data
}
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> { &self.choice_data.script_source_data }
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
@ -392,17 +342,13 @@ impl ScriptSource for PassChoice {
}
impl PartialEq<Self> 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<std::cmp::Ordering> {
Some(self.cmp(other))
}
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) }
}
impl Ord for TurnChoice {

View File

@ -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<dyn MoveData> {
&self.move_data
}
pub fn move_data(&self) -> &Arc<dyn MoveData> { &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) {

View File

@ -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<Option<Arc<dyn Item>>> { &self.data.held_item }
pub fn held_item(&self) -> Option<Arc<dyn Item>> { 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<u8> { 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<Arc<dyn Ability>> {
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.

View File

@ -96,10 +96,7 @@ impl Into<anyhow_ext::Result<SerializedPokemon>> 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<anyhow_ext::Result<SerializedPokemon>> 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

View File

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

View File

@ -78,16 +78,12 @@ extern "C" fn pokemon_display_form(handle: FFIHandle<Pokemon>) -> FFIHandle<Arc<
/// The level of the Pokemon.
/// [See also](https://bulbapedia.bulbagarden.net/wiki/Level)
#[no_mangle]
extern "C" fn pokemon_level(handle: FFIHandle<Pokemon>) -> LevelInt {
handle.from_ffi_handle().level()
}
extern "C" fn pokemon_level(handle: FFIHandle<Pokemon>) -> 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<Pokemon>) -> u32 {
handle.from_ffi_handle().experience()
}
extern "C" fn pokemon_experience(handle: FFIHandle<Pokemon>) -> 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<Pokemon>) -> u32 {
/// The gender of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_gender(handle: FFIHandle<Pokemon>) -> Gender {
handle.from_ffi_handle().gender()
}
extern "C" fn pokemon_gender(handle: FFIHandle<Pokemon>) -> 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<Pokemon>) -> u8 {
handle.from_ffi_handle().coloring()
}
extern "C" fn pokemon_coloring(handle: FFIHandle<Pokemon>) -> u8 { handle.from_ffi_handle().coloring() }
/// Gets the held item of a Pokemon
#[no_mangle]
extern "C" fn pokemon_held_item(handle: FFIHandle<Pokemon>) -> FFIHandle<Arc<dyn Item>> {
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<Pokemon>) -> FFIResult
/// The current health of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_current_health(handle: FFIHandle<Pokemon>) -> u32 {
handle.from_ffi_handle().current_health()
}
extern "C" fn pokemon_current_health(handle: FFIHandle<Pokemon>) -> u32 { handle.from_ffi_handle().current_health() }
/// The max health of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_max_health(handle: FFIHandle<Pokemon>) -> u32 {
handle.from_ffi_handle().max_health()
}
extern "C" fn pokemon_max_health(handle: FFIHandle<Pokemon>) -> u32 { handle.from_ffi_handle().max_health() }
/// The current weight of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_weight(handle: FFIHandle<Pokemon>) -> f32 {
handle.from_ffi_handle().weight()
}
extern "C" fn pokemon_weight(handle: FFIHandle<Pokemon>) -> f32 { handle.from_ffi_handle().weight() }
/// The current height of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_height(handle: FFIHandle<Pokemon>) -> f32 {
handle.from_ffi_handle().height()
}
extern "C" fn pokemon_height(handle: FFIHandle<Pokemon>) -> 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<Pokemon>) -> u8 {
/// The amount of types the Pokemon has.
#[no_mangle]
extern "C" fn pokemon_types_length(ptr: FFIHandle<Pokemon>) -> usize {
ptr.from_ffi_handle().types().len()
}
extern "C" fn pokemon_types_length(ptr: FFIHandle<Pokemon>) -> 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<Pokemon>) -> u8 {
/// Returns whether something overrides the ability.
#[no_mangle]
extern "C" fn pokemon_is_ability_overriden(handle: FFIHandle<Pokemon>) -> 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<Pokemon>, form: FFIHandle<Ar
/// Whether or not the Pokemon is useable in a battle.
#[no_mangle]
extern "C" fn pokemon_is_usable(handle: FFIHandle<Pokemon>) -> u8 {
u8::from(handle.from_ffi_handle().is_usable())
}
extern "C" fn pokemon_is_usable(handle: FFIHandle<Pokemon>) -> 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<Pokemon>) -> u8 {
u8::from(handle.from_ffi_handle().is_fainted())
}
extern "C" fn pokemon_is_fainted(handle: FFIHandle<Pokemon>) -> 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<Pokemon>) {
handle.from_ffi_handle().clear_status()
}
extern "C" fn pokemon_clear_status(handle: FFIHandle<Pokemon>) { handle.from_ffi_handle().clear_status() }
/// Returns a serialized version of the Pokemon as xml.
#[cfg(feature = "serde")]

View File

@ -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<Shared<Object>>,
state: Shared<Object>,
/// 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<Object> { 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),

View File

@ -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::<RuneBattle>()?;
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<AnyObj> { self.0.library().wrap() }
#[rune::function]
fn parties(&self) -> Vec<Shared<AnyObj>> { 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<Shared<AnyObj>> { self.0.sides().iter().map(|s| s.wrap()).collect() }
#[rune::function]
fn random(&self) -> Shared<AnyObj> { 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<Shared<AnyObj>> {
self.0.get_pokemon(side, index).map(|v| v.wrap())
}
#[rune::function]
fn set_weather(&self, weather: Option<RuneStringKey>) -> anyhow::Result<()> {
self.0.set_weather(weather.map(|w| w.0))
}
}

View File

@ -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::<RuneBattleParty>()?;
Ok(())
}
#[derive(Debug, Clone, Any)]
pub struct RuneBattleParty(pub Arc<BattleParty>);
impl_rune_wrapper!(&Arc<BattleParty>, RuneBattleParty);

View File

@ -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::<RuneBattleRandom>()?;
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<BattleRandom>);
impl_rune_wrapper!(&Arc<BattleRandom>, 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<bool> {
self.0.effect_chance(chance, &executing_move.0, &target.0, hit_number)
}
}

View File

@ -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::<RuneBattleSide>()?;
Ok(())
}
#[derive(Debug, Clone, Any)]
pub struct RuneBattleSide(pub BattleSide);
impl_rune_wrapper!(&BattleSide, RuneBattleSide);
impl RuneBattleSide {}

View File

@ -13,8 +13,10 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
Ok(())
}
#[derive(Debug, Any)]
pub struct RuneExecutingMove(Arc<ExecutingMove>);
#[derive(Debug, Clone, Any)]
pub struct RuneExecutingMove(pub Arc<ExecutingMove>);
impl_rune_wrapper!(&Arc<ExecutingMove>, RuneExecutingMove);
impl RuneExecutingMove {
#[rune::function]
@ -24,5 +26,3 @@ impl RuneExecutingMove {
#[rune::function]
fn user(&self) -> Shared<AnyObj> { self.0.user().wrap() }
}
impl_rune_wrapper!(&Arc<ExecutingMove>, RuneExecutingMove);

View File

@ -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::<RuneLearnedMove>()?;
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<LearnedMove>);
impl_rune_wrapper!(&Arc<LearnedMove>, RuneLearnedMove);
impl RuneLearnedMove {
#[rune::function]
fn move_data(&self) -> Shared<AnyObj> { 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) }
}

View File

@ -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::<RuneBattleStatCalculator>()?;
module.function_meta(RuneBattleStatCalculator::calculate_flat_stat)?;
module.function_meta(RuneBattleStatCalculator::calculate_boosted_stat)?;
module.ty::<RuneMiscLibrary>()?;
module.function_meta(RuneMiscLibrary::can_flee)?;
module.function_meta(RuneMiscLibrary::time_of_day)?;
module.ty::<RuneDynamicLibrary>()?;
module.function_meta(RuneDynamicLibrary::battle_stat_calculator)?;
module.function_meta(RuneDynamicLibrary::misc_library)?;
Ok(())
}
#[derive(Debug, Clone, Any)]
pub struct RuneBattleStatCalculator(Arc<dyn BattleStatCalculator>);
impl_rune_wrapper!(&Arc<dyn BattleStatCalculator>, RuneBattleStatCalculator);
impl RuneBattleStatCalculator {
#[rune::function]
fn calculate_flat_stat(&self, pokemon: RunePokemon, stat: Statistic) -> anyhow::Result<u32> {
self.0.calculate_flat_stat(&pokemon.0, stat)
}
#[rune::function]
fn calculate_boosted_stat(&self, pokemon: RunePokemon, stat: Statistic) -> anyhow::Result<u32> {
self.0.calculate_boosted_stat(&pokemon.0, stat)
}
}
#[derive(Debug, Clone, Any)]
pub struct RuneMiscLibrary(Arc<dyn MiscLibrary>);
impl_rune_wrapper!(&Arc<dyn MiscLibrary>, 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<dyn DynamicLibrary>);
impl_rune_wrapper!(&Arc<dyn DynamicLibrary>, 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()) }
}

View File

@ -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(())
}
fn resolve_script_data(container: &ScriptContainer) -> Option<Shared<Object>> {
container
.get()
.map(|v| {
v.read()
.as_ref()
.map(|v| v.clone().as_any().downcast_ref::<RuneScript>().map(|s| s.get_state()))
})
.flatten()
.flatten()
}

View File

@ -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::<DamageSource>()?;
module.ty::<RunePokemon>()?;
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<AnyObj> { self.0.library().wrap() }
#[rune::function]
fn species(&self) -> Shared<AnyObj> { self.0.species().wrap() }
#[rune::function]
fn form(&self) -> Shared<AnyObj> { 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<AnyObj> { 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<AnyObj> { 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<Shared<AnyObj>> { 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<Shared<AnyObj>> {
self.0.set_held_item(&key.0).map(|v| v.wrap())
}
#[rune::function]
fn remove_held_item(&mut self) -> Option<Shared<AnyObj>> { self.0.remove_held_item().map(|v| v.wrap()) }
#[rune::function]
fn consume_held_item(&mut self) -> anyhow::Result<bool> { 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<String> { 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<u8> { self.0.types().iter().map(|v| u8::from(*v)).collect() }
#[rune::function]
fn learned_moves(&self) -> Vec<Option<Shared<AnyObj>>> {
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<AnyObj> { self.0.flat_stats().wrap() }
#[rune::function]
fn is_egg(&self) -> bool { self.0.is_egg() }
#[rune::function]
fn boosted_stats(&self) -> Shared<AnyObj> { 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<bool> {
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<Shared<AnyObj>> { self.0.get_battle().map(|v| v.wrap()) }
#[rune::function]
fn get_battle_side_index(&self) -> Option<u8> { self.0.get_battle_side_index() }
#[rune::function]
fn get_battle_index(&self) -> Option<u8> { 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<Shared<AnyObj>> { 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<AnyObj> { 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<Shared<Object>> { resolve_script_data(&self.0.status()) }
#[rune::function]
fn ability_script(&self) -> Option<Shared<Object>> { resolve_script_data(&self.0.ability_script()) }
}
impl_rune_wrapper!(&Pokemon, RunePokemon);

View File

@ -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::<RuneTurnChoice>()?;
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::<RuneMoveChoice>()?;
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::<RuneItemChoice>()?;
module.ty::<RuneSwitchChoice>()?;
module.ty::<RuneFleeChoice>()?;
module.ty::<RunePassChoice>()?;
Ok(())
}
#[derive(Any)]
pub struct RuneTurnChoice(Arc<TurnChoice>);
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<TurnChoice>, RuneTurnChoice);
#[derive(Debug, Clone, Any)]
pub struct RuneMoveChoice(Arc<TurnChoice>);
#[derive(Debug, Clone, Any)]
pub struct RuneItemChoice(Arc<TurnChoice>);
#[derive(Debug, Clone, Any)]
pub struct RuneSwitchChoice(Arc<TurnChoice>);
#[derive(Debug, Clone, Any)]
pub struct RuneFleeChoice(Arc<TurnChoice>);
#[derive(Debug, Clone, Any)]
pub struct RunePassChoice(Arc<TurnChoice>);
impl RuneTurnChoice {
pub fn get_turn_choice(&self) -> &Arc<TurnChoice> {
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<AnyObj> { 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<TurnChoice> {
fn wrap(self) -> Shared<AnyObj> {
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<AnyObj> { 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<AnyObj> { self.move_choice().user().wrap() }
}

View File

@ -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<AnyObj> {
Shared::new(AnyObj::new(RuneStringKey(self.clone())).unwrap()).unwrap()
}
fn wrap(self) -> Shared<AnyObj> { Shared::new(AnyObj::new(RuneStringKey(self.clone())).unwrap()).unwrap() }
}

View File

@ -22,7 +22,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
}
#[derive(Debug, Any)]
pub struct RuneForm(Arc<dyn Form>);
pub struct RuneForm(pub Arc<dyn Form>);
impl_rune_wrapper!(&Arc<dyn Form>, RuneForm);

View File

@ -22,7 +22,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
}
#[derive(Debug, Any)]
pub struct RuneItem(Arc<dyn Item>);
pub struct RuneItem(pub Arc<dyn Item>);
impl_rune_wrapper!(&Arc<dyn Item>, RuneItem);

View File

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

View File

@ -17,7 +17,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
}
#[derive(Debug, rune::Any)]
struct RuneStaticData(Arc<dyn StaticData>);
pub struct RuneStaticData(pub Arc<dyn StaticData>);
impl_rune_wrapper!(&Arc<dyn StaticData>, RuneStaticData);

View File

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

View File

@ -4,15 +4,15 @@ use rune::Any;
use std::sync::Arc;
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
module.ty::<RuneStatisticSet>()?;
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::<RuneU32StatisticSet>()?;
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::<RuneStaticStatisticSet>()?;
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<StatisticSet<u32>>);
pub struct RuneU32StatisticSet(Arc<StatisticSet<u32>>);
impl_rune_wrapper!(&Arc<StatisticSet<u32>>, RuneStatisticSet);
impl RuneStatisticSet {
impl_rune_wrapper!(&Arc<StatisticSet<u32>>, RuneU32StatisticSet);
impl RuneU32StatisticSet {
#[rune::function]
fn get(&self, stat: Statistic) -> u32 { self.0.get_stat(stat) }

View File

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

View File

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

View File

@ -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 {
<T as NumCast>::from(MIN).unwrap()
}
pub fn min() -> T { <T as NumCast>::from(MIN).unwrap() }
/// The highest value a value on the set can have.
#[allow(clippy::unwrap_used)] // Should never fail
pub fn max() -> T {
<T as NumCast>::from(MAX).unwrap()
}
pub fn max() -> T { <T as NumCast>::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<T, const MIN: i64, const MAX: i64> From<&ClampedStatisticSet<T, MIN, MAX>> for StatisticSet<T>
where
T: PrimitiveAtom,
T: Atom,
T: PrimitiveAtomInteger,
<T as Atom>::Repr: PrimitiveAtomInteger,
T: AtomInteger,
T: NumCast,
T: PrimInt,
{
fn from(value: &ClampedStatisticSet<T, MIN, MAX>) -> Self {
Self {
hp: Atomic::<T>::new(value.hp()),
attack: Atomic::<T>::new(value.attack()),
defense: Atomic::<T>::new(value.defense()),
special_attack: Atomic::<T>::new(value.special_attack()),
special_defense: Atomic::<T>::new(value.special_defense()),
speed: Atomic::<T>::new(value.speed()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;