Update to rune 0.14, more tests
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
535f6bf79b
commit
92ff5bd0a1
10
Cargo.toml
10
Cargo.toml
|
@ -51,14 +51,14 @@ chrono = "0.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
rand_pcg = "0.3"
|
rand_pcg = "0.3"
|
||||||
hashbrown = "0.14"
|
hashbrown = "0.14"
|
||||||
indexmap = "2.0"
|
indexmap = "2.2"
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||||
serde_repr = "0.1"
|
serde_repr = "0.1"
|
||||||
serde-xml-rs = { version = "0.6", optional = true }
|
serde-xml-rs = { version = "0.6", optional = true }
|
||||||
uuid = "1.5"
|
uuid = "1.8"
|
||||||
paste = { version = "1.0" }
|
paste = { version = "1.0" }
|
||||||
arcstr = { version = "1.1", features = ["std"] }
|
arcstr = { version = "1.2", features = ["std"] }
|
||||||
enum-display-derive = "0.1"
|
enum-display-derive = "0.1"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
anyhow_ext = "0.2"
|
anyhow_ext = "0.2"
|
||||||
|
@ -66,12 +66,12 @@ thiserror = "1.0"
|
||||||
stdext = "0.3"
|
stdext = "0.3"
|
||||||
|
|
||||||
wasmer = { version = "4.2", optional = true, default-features = false, features = ["sys", "wat", "llvm"] }
|
wasmer = { version = "4.2", optional = true, default-features = false, features = ["sys", "wat", "llvm"] }
|
||||||
rune = { version = "0.13.2", optional = true }
|
rune = { version = "0.14.0", optional = true, git = "https://github.com/rune-rs/rune" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
csv = "1.3"
|
csv = "1.3"
|
||||||
project-root = "0.2"
|
project-root = "0.2"
|
||||||
serde_yaml = "0.9"
|
serde_yml = "0.0.7"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_plain = "1.0"
|
serde_plain = "1.0"
|
||||||
# Allow us to assert whether floats are approximately a value
|
# Allow us to assert whether floats are approximately a value
|
||||||
|
|
|
@ -427,7 +427,7 @@ impl Pokemon {
|
||||||
.library
|
.library
|
||||||
.static_data()
|
.static_data()
|
||||||
.abilities()
|
.abilities()
|
||||||
.get(ability)
|
.get(&ability)
|
||||||
.ok_or(PkmnError::InvalidAbilityName {
|
.ok_or(PkmnError::InvalidAbilityName {
|
||||||
ability: ability.clone(),
|
ability: ability.clone(),
|
||||||
})?)
|
})?)
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::script_implementations::rune::RuneScriptType;
|
||||||
use crate::static_data::Parameter;
|
use crate::static_data::Parameter;
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use rune::runtime::{Object, RuntimeContext, Shared, VmError, VmResult};
|
use rune::runtime::{RuntimeContext, VmError, VmResult};
|
||||||
use rune::{Unit, Value};
|
use rune::{Unit, Value};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||||
|
@ -12,7 +12,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
pub struct RuneScript {
|
pub struct RuneScript {
|
||||||
name: StringKey,
|
name: StringKey,
|
||||||
state: Shared<Object>,
|
state: Value,
|
||||||
/// Returns an atomic bool for internal marking of deletion. This is currently only specifically
|
/// 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
|
/// used for deletion of a script while we are holding a reference to it (i.e. executing a script
|
||||||
/// hook on it).
|
/// hook on it).
|
||||||
|
@ -34,7 +34,7 @@ unsafe impl Sync for RuneScript {}
|
||||||
impl RuneScript {
|
impl RuneScript {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: StringKey,
|
name: StringKey,
|
||||||
object: Shared<Object>,
|
object: Value,
|
||||||
script_type: Arc<RuneScriptType>,
|
script_type: Arc<RuneScriptType>,
|
||||||
runtime: Arc<RuntimeContext>,
|
runtime: Arc<RuntimeContext>,
|
||||||
unit: Arc<Unit>,
|
unit: Arc<Unit>,
|
||||||
|
@ -50,7 +50,7 @@ impl RuneScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_state(&self) -> Shared<Object> { self.state.clone() }
|
pub(crate) fn get_state(&self) -> Value { self.state.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Script for RuneScript {
|
impl Script for RuneScript {
|
||||||
|
@ -68,12 +68,12 @@ impl Script for RuneScript {
|
||||||
if pars.is_empty() {
|
if pars.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let state = self.state.clone();
|
|
||||||
|
let mut binding = self.state.clone().into_struct()?;
|
||||||
|
let state = binding.data_mut();
|
||||||
for par in pars {
|
for par in pars {
|
||||||
let key = rune::alloc::string::String::try_from(par.0.str())?;
|
let key = rune::alloc::string::String::try_from(par.0.str())?;
|
||||||
state
|
state.insert(key, parameter_to_rune_value(par.1.as_ref())?)?;
|
||||||
.borrow_mut()?
|
|
||||||
.insert(key, parameter_to_rune_value(par.1.as_ref())?)?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,8 @@ impl Script for RuneScript {
|
||||||
.execute(
|
.execute(
|
||||||
hash,
|
hash,
|
||||||
vec![
|
vec![
|
||||||
Value::Object(self.state.clone()),
|
rune::to_value(self.state.clone())?,
|
||||||
Value::from(choice.wrap()),
|
rune::to_value(choice.wrap())?,
|
||||||
speed_handle.clone(),
|
speed_handle.clone(),
|
||||||
],
|
],
|
||||||
)?
|
)?
|
||||||
|
@ -116,10 +116,10 @@ impl Script for RuneScript {
|
||||||
vm.execute(
|
vm.execute(
|
||||||
hash,
|
hash,
|
||||||
vec![
|
vec![
|
||||||
Value::Object(self.state.clone()),
|
self.state.clone(),
|
||||||
Value::from(move_data.wrap()),
|
move_data.wrap(),
|
||||||
Value::from(target.wrap()),
|
target.wrap(),
|
||||||
Value::from(hit),
|
rune::to_value(hit)?,
|
||||||
block_critical_handle.clone(),
|
block_critical_handle.clone(),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use hashbrown::HashMap;
|
||||||
use rune::compile::meta::AssociatedKind;
|
use rune::compile::meta::AssociatedKind;
|
||||||
use rune::compile::{ComponentRef, MetaError};
|
use rune::compile::{ComponentRef, MetaError};
|
||||||
use rune::diagnostics::Diagnostic;
|
use rune::diagnostics::Diagnostic;
|
||||||
use rune::runtime::{RuntimeContext, Shared};
|
use rune::runtime::RuntimeContext;
|
||||||
use rune::{Context, Diagnostics, Options, Source, Sources, Unit};
|
use rune::{Context, Diagnostics, Options, Source, Sources, Unit};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -52,7 +52,7 @@ impl ScriptResolver for RuneScriptResolver {
|
||||||
o.insert(rune::alloc::String::try_from("owner")?, owner_obj.into())?;
|
o.insert(rune::alloc::String::try_from("owner")?, owner_obj.into())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = Shared::new(o)?;
|
let state = rune::to_value(o)?;
|
||||||
let script = Arc::new(RuneScript::new(
|
let script = Arc::new(RuneScript::new(
|
||||||
script_key.clone(),
|
script_key.clone(),
|
||||||
state,
|
state,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::dynamic_data::Battle;
|
use crate::dynamic_data::Battle;
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::{Any, Value};
|
||||||
use rune::Any;
|
|
||||||
|
|
||||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
module.ty::<RuneBattle>()?;
|
module.ty::<RuneBattle>()?;
|
||||||
|
@ -27,10 +26,10 @@ impl_rune_wrapper!(&Battle, RuneBattle);
|
||||||
|
|
||||||
impl RuneBattle {
|
impl RuneBattle {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn library(&self) -> Shared<AnyObj> { self.0.library().wrap() }
|
fn library(&self) -> Value { self.0.library().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn parties(&self) -> Vec<Shared<AnyObj>> { self.0.parties().iter().map(|p| p.wrap()).collect() }
|
fn parties(&self) -> Vec<Value> { self.0.parties().iter().map(|p| p.wrap()).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn can_flee(&self) -> bool { self.0.can_flee() }
|
fn can_flee(&self) -> bool { self.0.can_flee() }
|
||||||
|
@ -42,10 +41,10 @@ impl RuneBattle {
|
||||||
fn pokemon_per_side(&self) -> u8 { self.0.pokemon_per_side() }
|
fn pokemon_per_side(&self) -> u8 { self.0.pokemon_per_side() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn sides(&self) -> Vec<Shared<AnyObj>> { self.0.sides().iter().map(|s| s.wrap()).collect() }
|
fn sides(&self) -> Vec<Value> { self.0.sides().iter().map(|s| s.wrap()).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn random(&self) -> Shared<AnyObj> { self.0.random().wrap() }
|
fn random(&self) -> Value { self.0.random().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_ended(&self) -> bool { self.0.has_ended() }
|
fn has_ended(&self) -> bool { self.0.has_ended() }
|
||||||
|
@ -54,9 +53,7 @@ impl RuneBattle {
|
||||||
fn current_turn(&self) -> u32 { self.0.current_turn() }
|
fn current_turn(&self) -> u32 { self.0.current_turn() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_pokemon(&self, side: u8, index: u8) -> Option<Shared<AnyObj>> {
|
fn get_pokemon(&self, side: u8, index: u8) -> Option<Value> { self.0.get_pokemon(side, index).map(|v| v.wrap()) }
|
||||||
self.0.get_pokemon(side, index).map(|v| v.wrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn set_weather(&self, weather: Option<RuneStringKey>) -> anyhow::Result<()> {
|
fn set_weather(&self, weather: Option<RuneStringKey>) -> anyhow::Result<()> {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::dynamic_data::{ExecutingMove, HitData};
|
||||||
use crate::script_implementations::rune::wrappers::dynamic_data::pokemon::RunePokemon;
|
use crate::script_implementations::rune::wrappers::dynamic_data::pokemon::RunePokemon;
|
||||||
use crate::script_implementations::rune::wrappers::dynamic_data::resolve_script_data;
|
use crate::script_implementations::rune::wrappers::dynamic_data::resolve_script_data;
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
||||||
use rune::runtime::{AnyObj, Object, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -29,19 +29,19 @@ impl RuneExecutingMove {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn number_of_hits(&self) -> u8 { self.0.number_of_hits() }
|
fn number_of_hits(&self) -> u8 { self.0.number_of_hits() }
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn user(&self) -> Shared<AnyObj> { self.0.user().wrap() }
|
fn user(&self) -> Value { self.0.user().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn chosen_move(&self) -> Shared<AnyObj> { self.0.chosen_move().wrap() }
|
fn chosen_move(&self) -> Value { self.0.chosen_move().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn use_move(&self) -> Shared<AnyObj> { self.0.use_move().wrap() }
|
fn use_move(&self) -> Value { self.0.use_move().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn script(&self) -> Option<Shared<Object>> { resolve_script_data(self.0.script()) }
|
fn script(&self) -> Option<Value> { resolve_script_data(self.0.script()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_hit_data(&self, for_target: RunePokemon, hit: u8) -> anyhow::Result<Shared<AnyObj>> {
|
fn get_hit_data(&self, for_target: RunePokemon, hit: u8) -> anyhow::Result<Value> {
|
||||||
self.0.get_hit_data(&for_target.0, hit).map(|hit_data| hit_data.wrap())
|
self.0.get_hit_data(&for_target.0, hit).map(|hit_data| hit_data.wrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ impl_rune_wrapper!(&Arc<LearnedMove>, RuneLearnedMove);
|
||||||
|
|
||||||
impl RuneLearnedMove {
|
impl RuneLearnedMove {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn move_data(&self) -> Shared<AnyObj> { self.0.move_data().wrap() }
|
fn move_data(&self) -> Value { self.0.move_data().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn max_pp(&self) -> u8 { self.0.max_pp() }
|
fn max_pp(&self) -> u8 { self.0.max_pp() }
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::dynamic_data::ScriptContainer;
|
use crate::dynamic_data::ScriptContainer;
|
||||||
use crate::script_implementations::rune::script::RuneScript;
|
use crate::script_implementations::rune::script::RuneScript;
|
||||||
use rune::runtime::{Object, Shared};
|
|
||||||
|
|
||||||
mod battle;
|
mod battle;
|
||||||
mod battle_party;
|
mod battle_party;
|
||||||
|
@ -26,7 +25,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_script_data(container: &ScriptContainer) -> Option<Shared<Object>> {
|
fn resolve_script_data(container: &ScriptContainer) -> Option<rune::Value> {
|
||||||
container
|
container
|
||||||
.get()
|
.get()
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
|
|
|
@ -5,7 +5,7 @@ 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::static_data::item::RuneItem;
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::{Gender, Statistic};
|
use crate::static_data::{Gender, Statistic};
|
||||||
use rune::runtime::{AnyObj, Object, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
|
|
||||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
|
@ -69,25 +69,25 @@ pub struct RunePokemon(pub Pokemon);
|
||||||
|
|
||||||
impl RunePokemon {
|
impl RunePokemon {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn library(&self) -> Shared<AnyObj> { self.0.library().wrap() }
|
fn library(&self) -> Value { self.0.library().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn species(&self) -> Shared<AnyObj> { self.0.species().wrap() }
|
fn species(&self) -> Value { self.0.species().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn form(&self) -> Shared<AnyObj> { self.0.form().wrap() }
|
fn form(&self) -> Value { self.0.form().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_different_display_species(&self) -> bool { self.0.has_different_display_species() }
|
fn has_different_display_species(&self) -> bool { self.0.has_different_display_species() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn display_species(&self) -> Shared<AnyObj> { self.0.display_species().wrap() }
|
fn display_species(&self) -> Value { self.0.display_species().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_different_display_form(&self) -> bool { self.0.has_different_display_form() }
|
fn has_different_display_form(&self) -> bool { self.0.has_different_display_form() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn display_form(&self) -> Shared<AnyObj> { self.0.display_form().wrap() }
|
fn display_form(&self) -> Value { self.0.display_form().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn level(&self) -> LevelInt { self.0.level() }
|
fn level(&self) -> LevelInt { self.0.level() }
|
||||||
|
@ -105,18 +105,16 @@ impl RunePokemon {
|
||||||
fn coloring(&self) -> u8 { self.0.coloring() }
|
fn coloring(&self) -> u8 { self.0.coloring() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn held_item(&self) -> Option<Shared<AnyObj>> { self.0.held_item().map(|v| v.wrap()) }
|
fn held_item(&self) -> Option<Value> { self.0.held_item().map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_held_item(&self, key: RuneStringKey) -> bool { self.0.has_held_item(&key.0) }
|
fn has_held_item(&self, key: RuneStringKey) -> bool { self.0.has_held_item(&key.0) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn set_held_item(&mut self, key: RuneItem) -> Option<Shared<AnyObj>> {
|
fn set_held_item(&mut self, key: RuneItem) -> Option<Value> { self.0.set_held_item(&key.0).map(|v| v.wrap()) }
|
||||||
self.0.set_held_item(&key.0).map(|v| v.wrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn remove_held_item(&mut self) -> Option<Shared<AnyObj>> { self.0.remove_held_item().map(|v| v.wrap()) }
|
fn remove_held_item(&mut self) -> Option<Value> { self.0.remove_held_item().map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn consume_held_item(&mut self) -> anyhow::Result<bool> { self.0.consume_held_item() }
|
fn consume_held_item(&mut self) -> anyhow::Result<bool> { self.0.consume_held_item() }
|
||||||
|
@ -149,19 +147,19 @@ impl RunePokemon {
|
||||||
fn types(&self) -> Vec<u8> { self.0.types().iter().map(|v| u8::from(*v)).collect() }
|
fn types(&self) -> Vec<u8> { self.0.types().iter().map(|v| u8::from(*v)).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn learned_moves(&self) -> Vec<Option<Shared<AnyObj>>> {
|
fn learned_moves(&self) -> Vec<Option<Value>> {
|
||||||
let l = self.0.learned_moves().read();
|
let l = self.0.learned_moves().read();
|
||||||
l.iter().map(|v| v.as_ref().map(|l| l.wrap())).collect()
|
l.iter().map(|v| v.as_ref().map(|l| l.wrap())).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn flat_stats(&self) -> Shared<AnyObj> { self.0.flat_stats().wrap() }
|
fn flat_stats(&self) -> Value { self.0.flat_stats().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn is_egg(&self) -> bool { self.0.is_egg() }
|
fn is_egg(&self) -> bool { self.0.is_egg() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn boosted_stats(&self) -> Shared<AnyObj> { self.0.boosted_stats().wrap() }
|
fn boosted_stats(&self) -> Value { self.0.boosted_stats().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn stat_boost(&self, stat: Statistic) -> i8 { self.0.stat_boost(stat) }
|
fn stat_boost(&self, stat: Statistic) -> i8 { self.0.stat_boost(stat) }
|
||||||
|
@ -178,7 +176,7 @@ impl RunePokemon {
|
||||||
fn get_effort_value(&self, stat: Statistic) -> u8 { self.0.effort_values().get_stat(stat) }
|
fn get_effort_value(&self, stat: Statistic) -> u8 { self.0.effort_values().get_stat(stat) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_battle(&self) -> Option<Shared<AnyObj>> { self.0.get_battle().map(|v| v.wrap()) }
|
fn get_battle(&self) -> Option<Value> { self.0.get_battle().map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_battle_side_index(&self) -> Option<u8> { self.0.get_battle_side_index() }
|
fn get_battle_side_index(&self) -> Option<u8> { self.0.get_battle_side_index() }
|
||||||
|
@ -190,13 +188,13 @@ impl RunePokemon {
|
||||||
fn is_ability_overridden(&self) -> bool { self.0.is_ability_overridden() }
|
fn is_ability_overridden(&self) -> bool { self.0.is_ability_overridden() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn active_ability(&self) -> anyhow::Result<Shared<AnyObj>> { self.0.active_ability().map(|v| v.wrap()) }
|
fn active_ability(&self) -> anyhow::Result<Value> { self.0.active_ability().map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn allowed_experience_gain(&self) -> bool { self.0.allowed_experience_gain() }
|
fn allowed_experience_gain(&self) -> bool { self.0.allowed_experience_gain() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn nature(&self) -> Shared<AnyObj> { self.0.nature().wrap() }
|
fn nature(&self) -> Value { self.0.nature().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn change_form(&self, form: RuneForm) -> anyhow::Result<()> { self.0.change_form(&form.0) }
|
fn change_form(&self, form: RuneForm) -> anyhow::Result<()> { self.0.change_form(&form.0) }
|
||||||
|
@ -219,10 +217,10 @@ impl RunePokemon {
|
||||||
fn clear_status(&self) { self.0.clear_status() }
|
fn clear_status(&self) { self.0.clear_status() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn status_script(&self) -> Option<Shared<Object>> { resolve_script_data(&self.0.status()) }
|
fn status_script(&self) -> Option<Value> { resolve_script_data(&self.0.status()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn ability_script(&self) -> Option<Shared<Object>> { resolve_script_data(&self.0.ability_script()) }
|
fn ability_script(&self) -> Option<Value> { resolve_script_data(&self.0.ability_script()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_rune_wrapper!(&Pokemon, RunePokemon);
|
impl_rune_wrapper!(&Pokemon, RunePokemon);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::dynamic_data::TurnChoice;
|
use crate::dynamic_data::TurnChoice;
|
||||||
use crate::script_implementations::rune::wrappers::RuneWrapper;
|
use crate::script_implementations::rune::wrappers::RuneWrapper;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ impl RuneTurnChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn user(&self) -> Shared<AnyObj> { self.get_turn_choice().user().wrap() }
|
fn user(&self) -> Value { self.get_turn_choice().user().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn speed(&self) -> u32 { self.get_turn_choice().speed() }
|
fn speed(&self) -> u32 { self.get_turn_choice().speed() }
|
||||||
|
@ -75,7 +75,7 @@ impl RuneTurnChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RuneWrapper for &Arc<TurnChoice> {
|
impl RuneWrapper for &Arc<TurnChoice> {
|
||||||
fn wrap(self) -> Shared<AnyObj> {
|
fn wrap(self) -> Value {
|
||||||
let o = match self.as_ref() {
|
let o = match self.as_ref() {
|
||||||
TurnChoice::Move(_) => RuneTurnChoice::Move(RuneMoveChoice(self.clone())),
|
TurnChoice::Move(_) => RuneTurnChoice::Move(RuneMoveChoice(self.clone())),
|
||||||
TurnChoice::Item(_) => RuneTurnChoice::Item(RuneItemChoice(self.clone())),
|
TurnChoice::Item(_) => RuneTurnChoice::Item(RuneItemChoice(self.clone())),
|
||||||
|
@ -83,7 +83,7 @@ impl RuneWrapper for &Arc<TurnChoice> {
|
||||||
TurnChoice::Flee(_) => RuneTurnChoice::Flee(RuneFleeChoice(self.clone())),
|
TurnChoice::Flee(_) => RuneTurnChoice::Flee(RuneFleeChoice(self.clone())),
|
||||||
TurnChoice::Pass(_) => RuneTurnChoice::Pass(RunePassChoice(self.clone())),
|
TurnChoice::Pass(_) => RuneTurnChoice::Pass(RunePassChoice(self.clone())),
|
||||||
};
|
};
|
||||||
Shared::new(AnyObj::new(o).unwrap()).unwrap()
|
rune::to_value(o).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ impl RuneMoveChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn used_move(&self) -> Shared<AnyObj> { self.move_choice().used_move().wrap() }
|
fn used_move(&self) -> Value { self.move_choice().used_move().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn target_side(&self) -> u8 { self.move_choice().target_side() }
|
fn target_side(&self) -> u8 { self.move_choice().target_side() }
|
||||||
|
@ -108,5 +108,5 @@ impl RuneMoveChoice {
|
||||||
fn priority(&self) -> i8 { self.move_choice().priority() }
|
fn priority(&self) -> i8 { self.move_choice().priority() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn user(&self) -> Shared<AnyObj> { self.move_choice().user().wrap() }
|
fn user(&self) -> Value { self.move_choice().user().wrap() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rune::alloc::fmt::TryWrite;
|
use rune::alloc::fmt::TryWrite;
|
||||||
use rune::runtime::{AnyObj, Protocol, Shared, VmResult};
|
use rune::runtime::{Protocol, VmResult};
|
||||||
use rune::{Any, Value};
|
use rune::{Any, Value};
|
||||||
use std::num::Saturating;
|
use std::num::Saturating;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ mod parameters;
|
||||||
mod static_data;
|
mod static_data;
|
||||||
|
|
||||||
pub trait RuneWrapper {
|
pub trait RuneWrapper {
|
||||||
fn wrap(self) -> Shared<AnyObj>;
|
fn wrap(self) -> Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module() -> anyhow::Result<rune::Module> {
|
pub fn module() -> anyhow::Result<rune::Module> {
|
||||||
|
@ -33,6 +33,8 @@ pub fn module() -> anyhow::Result<rune::Module> {
|
||||||
|
|
||||||
module.ty::<RuneStringKey>()?;
|
module.ty::<RuneStringKey>()?;
|
||||||
module.function_meta(RuneStringKey::string_display)?;
|
module.function_meta(RuneStringKey::string_display)?;
|
||||||
|
module.associated_function(Protocol::PARTIAL_EQ, RuneStringKey::eq)?;
|
||||||
|
module.associated_function(Protocol::EQ, RuneStringKey::eq)?;
|
||||||
|
|
||||||
parameters::register(&mut module)?;
|
parameters::register(&mut module)?;
|
||||||
dynamic_data::register(&mut module)?;
|
dynamic_data::register(&mut module)?;
|
||||||
|
@ -40,30 +42,24 @@ pub fn module() -> anyhow::Result<rune::Module> {
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wrap_int_reference(value: i64) -> anyhow::Result<Value> {
|
pub fn wrap_int_reference(value: i64) -> anyhow::Result<Value> { Ok(rune::to_value(RuneValueIntWrapper::new(value))?) }
|
||||||
Ok(Value::Any(Shared::new(AnyObj::new(RuneValueIntWrapper::new(value))?)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wrap_bool_reference(value: bool) -> anyhow::Result<Value> {
|
pub fn wrap_bool_reference(value: bool) -> anyhow::Result<Value> {
|
||||||
Ok(Value::Any(Shared::new(AnyObj::new(RuneValueBoolWrapper::new(value))?)?))
|
Ok(rune::to_value(RuneValueBoolWrapper::new(value))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_int_reference_value(value: Value) -> anyhow::Result<i64> {
|
pub fn get_int_reference_value(value: Value) -> anyhow::Result<i64> {
|
||||||
let obj = value.into_any().into_result()?;
|
let obj = match value.into_any::<RuneValueIntWrapper>() {
|
||||||
let obj = obj.take()?;
|
Ok(obj) => obj,
|
||||||
let obj = match obj.downcast_borrow_ref::<RuneValueIntWrapper>() {
|
Err(_) => return Err(anyhow::anyhow!("Value is not a RuneValueIntWrapper")),
|
||||||
Some(obj) => obj,
|
|
||||||
None => return Err(anyhow::anyhow!("Value is not a RuneValueIntWrapper")),
|
|
||||||
};
|
};
|
||||||
Ok(obj.as_int())
|
Ok(obj.as_int())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bool_reference_value(value: Value) -> anyhow::Result<bool> {
|
pub fn get_bool_reference_value(value: Value) -> anyhow::Result<bool> {
|
||||||
let obj = value.into_any().into_result()?;
|
let obj = match value.into_any::<RuneValueBoolWrapper>() {
|
||||||
let obj = obj.take()?;
|
Ok(obj) => obj,
|
||||||
let obj = match obj.downcast_borrow_ref::<RuneValueBoolWrapper>() {
|
Err(_) => return Err(anyhow::anyhow!("Value is not a RuneValueBoolWrapper")),
|
||||||
Some(obj) => obj,
|
|
||||||
None => return Err(anyhow::anyhow!("Value is not a RuneValueBoolWrapper")),
|
|
||||||
};
|
};
|
||||||
Ok(obj.as_bool())
|
Ok(obj.as_bool())
|
||||||
}
|
}
|
||||||
|
@ -71,9 +67,7 @@ pub fn get_bool_reference_value(value: Value) -> anyhow::Result<bool> {
|
||||||
macro_rules! impl_rune_wrapper {
|
macro_rules! impl_rune_wrapper {
|
||||||
($t:ty, $wrapped_type:ident) => {
|
($t:ty, $wrapped_type:ident) => {
|
||||||
impl crate::script_implementations::rune::wrappers::RuneWrapper for $t {
|
impl crate::script_implementations::rune::wrappers::RuneWrapper for $t {
|
||||||
fn wrap(self) -> rune::runtime::Shared<rune::runtime::AnyObj> {
|
fn wrap(self) -> rune::runtime::Value { rune::to_value($wrapped_type(self.clone())).unwrap() }
|
||||||
rune::runtime::Shared::new(rune::runtime::AnyObj::new($wrapped_type(self.clone())).unwrap()).unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -82,6 +76,7 @@ use crate::StringKey;
|
||||||
use impl_rune_wrapper;
|
use impl_rune_wrapper;
|
||||||
|
|
||||||
#[derive(Any, Clone)]
|
#[derive(Any, Clone)]
|
||||||
|
#[rune(name = RefInt)]
|
||||||
struct RuneValueIntWrapper {
|
struct RuneValueIntWrapper {
|
||||||
value: Saturating<i64>,
|
value: Saturating<i64>,
|
||||||
}
|
}
|
||||||
|
@ -106,10 +101,12 @@ impl RuneValueIntWrapper {
|
||||||
fn sub_assign(&mut self, other: i64) { self.value -= other; }
|
fn sub_assign(&mut self, other: i64) { self.value -= other; }
|
||||||
|
|
||||||
fn div_assign(&mut self, other: Value) {
|
fn div_assign(&mut self, other: Value) {
|
||||||
match other {
|
match other.as_integer() {
|
||||||
Value::Integer(other) => self.value /= other,
|
Ok(other) => self.value /= other,
|
||||||
Value::Float(other) => self.div_assign_f64(other),
|
Err(_) => match other.as_float() {
|
||||||
_ => (),
|
Ok(other) => self.div_assign_f64(other),
|
||||||
|
Err(_) => (),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,10 +122,12 @@ impl RuneValueIntWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul_assign(&mut self, other: Value) {
|
fn mul_assign(&mut self, other: Value) {
|
||||||
match other {
|
match other.as_integer() {
|
||||||
Value::Integer(other) => self.value *= other,
|
Ok(other) => self.value *= other,
|
||||||
Value::Float(other) => self.mul_assign_f64(other),
|
Err(_) => match other.as_float() {
|
||||||
_ => (),
|
Ok(other) => self.mul_assign_f64(other),
|
||||||
|
Err(_) => (),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +154,7 @@ impl RuneValueIntWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Any, Clone)]
|
#[derive(Any, Clone)]
|
||||||
|
#[rune(name = RefBool)]
|
||||||
struct RuneValueBoolWrapper(bool);
|
struct RuneValueBoolWrapper(bool);
|
||||||
|
|
||||||
impl RuneValueBoolWrapper {
|
impl RuneValueBoolWrapper {
|
||||||
|
@ -178,6 +178,7 @@ impl RuneValueBoolWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Any, Clone, Debug)]
|
#[derive(Any, Clone, Debug)]
|
||||||
|
#[rune(name = StringKey)]
|
||||||
pub(super) struct RuneStringKey(pub StringKey);
|
pub(super) struct RuneStringKey(pub StringKey);
|
||||||
|
|
||||||
impl RuneStringKey {
|
impl RuneStringKey {
|
||||||
|
@ -188,24 +189,39 @@ impl RuneStringKey {
|
||||||
rune::vm_write!(f, "{}", self.0);
|
rune::vm_write!(f, "{}", self.0);
|
||||||
VmResult::Ok(())
|
VmResult::Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eq(&self, b: Value) -> VmResult<bool> {
|
||||||
|
match b.borrow_string_ref() {
|
||||||
|
Ok(s) => VmResult::Ok(self.0 == StringKey::new(&s)),
|
||||||
|
Err(_) => {
|
||||||
|
let b = b.borrow_any_ref::<RuneStringKey>();
|
||||||
|
match b {
|
||||||
|
Ok(b) => VmResult::Ok(self.0 == b.0),
|
||||||
|
_ => VmResult::Ok(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RuneWrapper for &StringKey {
|
impl RuneWrapper for &StringKey {
|
||||||
fn wrap(self) -> Shared<AnyObj> { Shared::new(AnyObj::new(RuneStringKey(self.clone())).unwrap()).unwrap() }
|
fn wrap(self) -> Value { rune::to_value(RuneStringKey(self.clone())).unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use anyhow::Result;
|
||||||
|
use rune::diagnostics::Diagnostic;
|
||||||
use rune::{Context, Diagnostics, Options, Source, Vm};
|
use rune::{Context, Diagnostics, Options, Source, Vm};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn setup_script(script: &str) -> Vm {
|
pub fn setup_script(script: &str) -> Result<Vm> {
|
||||||
let mut context = Context::with_default_modules().unwrap();
|
let mut context = Context::with_default_modules()?;
|
||||||
context.install(module().unwrap()).unwrap();
|
context.install(module()?)?;
|
||||||
|
|
||||||
let mut sources = rune::Sources::new();
|
let mut sources = rune::Sources::new();
|
||||||
sources.insert(Source::memory(script).unwrap()).unwrap();
|
sources.insert(Source::memory(script)?)?;
|
||||||
let mut diagnostics = Diagnostics::new();
|
let mut diagnostics = Diagnostics::new();
|
||||||
|
|
||||||
let mut options = Options::default();
|
let mut options = Options::default();
|
||||||
|
@ -218,381 +234,431 @@ mod test {
|
||||||
.with_context(&context)
|
.with_context(&context)
|
||||||
.with_diagnostics(&mut diagnostics)
|
.with_diagnostics(&mut diagnostics)
|
||||||
.with_options(&options)
|
.with_options(&options)
|
||||||
.build()
|
.build();
|
||||||
.unwrap();
|
if !diagnostics.is_empty() && diagnostics.has_error() {
|
||||||
if !diagnostics.is_empty() {
|
let error_message = diagnostics
|
||||||
panic!("Diagnostics: {:?}", diagnostics);
|
.diagnostics()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|d| match d {
|
||||||
|
Diagnostic::Fatal(f) => Some(f.to_string()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
return Err(anyhow::anyhow!("Error building Rune script: {}", error_message));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vm::new(Arc::new(context.runtime().unwrap()), Arc::new(unit))
|
Ok(Vm::new(Arc::new(context.runtime()?), Arc::new(unit?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! execute_vm {
|
macro_rules! execute_vm {
|
||||||
($vm:expr, $func:expr, $val:expr) => {{
|
($vm:expr, $func:expr, $val:expr) => {{
|
||||||
let args = vec![$val.clone()];
|
let args = vec![$val.clone()];
|
||||||
$vm.execute([$func], args).unwrap().complete().into_result().unwrap()
|
$vm.execute([$func], args)?.complete().into_result()?
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use execute_vm;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_set_value() {
|
fn test_int_wrapper_set_value() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a.set_value(5);
|
a.set_value(5);
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 5);
|
assert_eq!(v, 5);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_as_int() {
|
fn test_int_wrapper_as_int() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a.as_int()
|
a.as_int()
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
let res = execute_vm!(vm, "test_int", val);
|
let res = execute_vm!(vm, "test_int", val);
|
||||||
let res = res.as_integer().unwrap();
|
let res = res.as_integer()?;
|
||||||
assert_eq!(res, 10);
|
assert_eq!(res, 10);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_add() {
|
fn test_int_wrapper_add() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a += 5;
|
a += 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 15);
|
assert_eq!(v, 15);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_add_overflow() {
|
fn test_int_wrapper_add_overflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a += 5;
|
a += 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
let val = wrap_int_reference(i64::MAX)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MAX);
|
assert_eq!(v, i64::MAX);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_sub() {
|
fn test_int_wrapper_sub() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a -= 5;
|
a -= 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 5);
|
assert_eq!(v, 5);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_underflow() {
|
fn test_int_wrapper_underflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a -= 5;
|
a -= 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MIN).unwrap();
|
let val = wrap_int_reference(i64::MIN)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MIN);
|
assert_eq!(v, i64::MIN);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_mul() {
|
fn test_int_wrapper_mul() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a *= 5;
|
a *= 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 50);
|
assert_eq!(v, 50);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_mul_float() {
|
fn test_int_wrapper_mul_float() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a *= 0.5;
|
a *= 0.5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 5);
|
assert_eq!(v, 5);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_mul_overflow() {
|
fn test_int_wrapper_mul_overflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a *= 5;
|
a *= 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
let val = wrap_int_reference(i64::MAX)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MAX);
|
assert_eq!(v, i64::MAX);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_mul_float_overflow() {
|
fn test_int_wrapper_mul_float_overflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a *= 10.0;
|
a *= 10.0;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
let val = wrap_int_reference(i64::MAX)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MAX);
|
assert_eq!(v, i64::MAX);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_mul_float_underflow() {
|
fn test_int_wrapper_mul_float_underflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a *= 10.0;
|
a *= 10.0;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MIN).unwrap();
|
let val = wrap_int_reference(i64::MIN)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MIN);
|
assert_eq!(v, i64::MIN);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_div() {
|
fn test_int_wrapper_div() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a /= 5;
|
a /= 5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 2);
|
assert_eq!(v, 2);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_div_float() {
|
fn test_int_wrapper_div_float() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a /= 0.5;
|
a /= 0.5;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(10).unwrap();
|
let val = wrap_int_reference(10)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, 20);
|
assert_eq!(v, 20);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_div_float_overflow() {
|
fn test_int_wrapper_div_float_overflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a /= 0.0001;
|
a /= 0.0001;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
let val = wrap_int_reference(i64::MAX)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MAX);
|
assert_eq!(v, i64::MAX);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_div_float_underflow() {
|
fn test_int_wrapper_div_float_underflow() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a /= 0.0001;
|
a /= 0.0001;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(i64::MIN).unwrap();
|
let val = wrap_int_reference(i64::MIN)?;
|
||||||
execute_vm!(vm, "test_int", val);
|
execute_vm!(vm, "test_int", val);
|
||||||
let v = get_int_reference_value(val).unwrap();
|
let v = get_int_reference_value(val)?;
|
||||||
assert_eq!(v, i64::MIN);
|
assert_eq!(v, i64::MIN);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_eq() {
|
fn test_int_wrapper_eq() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a == 5
|
a == 5
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(5).unwrap();
|
let val = wrap_int_reference(5)?;
|
||||||
let res = execute_vm!(vm, "test_int", val);
|
let res = execute_vm!(vm, "test_int", val);
|
||||||
let res = res.as_bool().unwrap();
|
let res = res.as_bool()?;
|
||||||
assert_eq!(res, true);
|
assert_eq!(res, true);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_ineq() {
|
fn test_int_wrapper_ineq() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
a == 5
|
a == 5
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(6).unwrap();
|
let val = wrap_int_reference(6)?;
|
||||||
let res = execute_vm!(vm, "test_int", val);
|
let res = execute_vm!(vm, "test_int", val);
|
||||||
let res = res.as_bool().unwrap();
|
let res = res.as_bool()?;
|
||||||
assert_eq!(res, false);
|
assert_eq!(res, false);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_wrapper_string_display() {
|
fn test_int_wrapper_string_display() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_int(a) {
|
pub fn test_int(a) {
|
||||||
`${a}`
|
`${a}`
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_int_reference(5).unwrap();
|
let val = wrap_int_reference(5)?;
|
||||||
let res = execute_vm!(vm, "test_int", val);
|
let res = execute_vm!(vm, "test_int", val);
|
||||||
let res = res.into_string().unwrap().take().unwrap().into_std();
|
let res = res.into_string()?.into_std();
|
||||||
assert_eq!(res, "5");
|
assert_eq!(res, "5");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bool_wrapper_set_value() {
|
fn test_bool_wrapper_set_value() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_bool(a) {
|
pub fn test_bool(a) {
|
||||||
a.set_value(true);
|
a.set_value(true);
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_bool_reference(false).unwrap();
|
let val = wrap_bool_reference(false)?;
|
||||||
execute_vm!(vm, "test_bool", val);
|
execute_vm!(vm, "test_bool", val);
|
||||||
let v = get_bool_reference_value(val).unwrap();
|
let v = get_bool_reference_value(val)?;
|
||||||
assert_eq!(v, true);
|
assert_eq!(v, true);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bool_wrapper_as_bool() {
|
fn test_bool_wrapper_as_bool() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_bool(a) {
|
pub fn test_bool(a) {
|
||||||
a.as_bool()
|
a.as_bool()
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_bool_reference(true).unwrap();
|
let val = wrap_bool_reference(true)?;
|
||||||
let res = execute_vm!(vm, "test_bool", val);
|
let res = execute_vm!(vm, "test_bool", val);
|
||||||
let res = res.as_bool().unwrap();
|
let res = res.as_bool()?;
|
||||||
assert_eq!(res, true);
|
assert_eq!(res, true);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bool_wrapper_eq() {
|
fn test_bool_wrapper_eq() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_bool(a) {
|
pub fn test_bool(a) {
|
||||||
a == true
|
a == true
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_bool_reference(true).unwrap();
|
let val = wrap_bool_reference(true)?;
|
||||||
let res = execute_vm!(vm, "test_bool", val);
|
let res = execute_vm!(vm, "test_bool", val);
|
||||||
let res = res.as_bool().unwrap();
|
let res = res.as_bool()?;
|
||||||
assert_eq!(res, true);
|
assert_eq!(res, true);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bool_wrapper_ineq() {
|
fn test_bool_wrapper_ineq() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_bool(a) {
|
pub fn test_bool(a) {
|
||||||
a == true
|
a == true
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_bool_reference(false).unwrap();
|
let val = wrap_bool_reference(false)?;
|
||||||
let res = execute_vm!(vm, "test_bool", val);
|
let res = execute_vm!(vm, "test_bool", val);
|
||||||
let res = res.as_bool().unwrap();
|
let res = res.as_bool()?;
|
||||||
assert_eq!(res, false);
|
assert_eq!(res, false);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bool_wrapper_string_display() {
|
fn test_bool_wrapper_string_display() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_bool(a) {
|
pub fn test_bool(a) {
|
||||||
`${a}`
|
`${a}`
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = wrap_bool_reference(true).unwrap();
|
let val = wrap_bool_reference(true)?;
|
||||||
let res = execute_vm!(vm, "test_bool", val);
|
let res = execute_vm!(vm, "test_bool", val);
|
||||||
let res = res.into_string().unwrap().take().unwrap().into_std();
|
let res = res.into_string()?.into_std();
|
||||||
assert_eq!(res, "true");
|
assert_eq!(res, "true");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_string_key_wrapper_string_display() {
|
fn test_string_key_wrapper_string_display() -> Result<()> {
|
||||||
let mut vm = setup_script(
|
let mut vm = setup_script(
|
||||||
r#"
|
r#"
|
||||||
pub fn test_string_key(a) {
|
pub fn test_string_key(a) {
|
||||||
`${a}`
|
`${a}`
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
)?;
|
||||||
let val = RuneStringKey::new(StringKey::from("test"));
|
let val = StringKey::from("test");
|
||||||
let val = Shared::new(AnyObj::new(val).unwrap()).unwrap();
|
let arg = val.wrap();
|
||||||
let arg = Value::Any(val);
|
|
||||||
let res = execute_vm!(vm, "test_string_key", arg);
|
let res = execute_vm!(vm, "test_string_key", arg);
|
||||||
let res = res.into_string().unwrap().take().unwrap().into_std();
|
let res = res.into_string()?.into_std();
|
||||||
assert_eq!(res, "test");
|
assert_eq!(res, "test");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_string_key_wrapper_eq() -> Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_string_key(a) {
|
||||||
|
a == "test"
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let val = StringKey::from("test");
|
||||||
|
let arg = val.wrap();
|
||||||
|
let res = execute_vm!(vm, "test_string_key", arg);
|
||||||
|
let res = res.as_bool()?;
|
||||||
|
assert_eq!(res, true);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::script_implementations::rune::wrappers::{RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::Parameter;
|
use crate::static_data::Parameter;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -11,6 +11,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Any)]
|
#[derive(Debug, Any)]
|
||||||
|
#[rune(name = Parameter)]
|
||||||
pub(super) enum RuneParameter {
|
pub(super) enum RuneParameter {
|
||||||
Int(#[rune(get)] i32),
|
Int(#[rune(get)] i32),
|
||||||
Float(#[rune(get)] f32),
|
Float(#[rune(get)] f32),
|
||||||
|
@ -19,13 +20,13 @@ pub(super) enum RuneParameter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RuneWrapper for &Arc<Parameter> {
|
impl RuneWrapper for &Arc<Parameter> {
|
||||||
fn wrap(self) -> Shared<AnyObj> {
|
fn wrap(self) -> Value {
|
||||||
let p = match self.deref() {
|
let p = match self.deref() {
|
||||||
Parameter::Bool(b) => RuneParameter::Bool(*b),
|
Parameter::Bool(b) => RuneParameter::Bool(*b),
|
||||||
Parameter::Int(i) => RuneParameter::Int(*i as i32),
|
Parameter::Int(i) => RuneParameter::Int(*i as i32),
|
||||||
Parameter::Float(f) => RuneParameter::Float(*f),
|
Parameter::Float(f) => RuneParameter::Float(*f),
|
||||||
Parameter::String(s) => RuneParameter::String(RuneStringKey::new(s.clone())),
|
Parameter::String(s) => RuneParameter::String(RuneStringKey::new(s.clone())),
|
||||||
};
|
};
|
||||||
Shared::new(AnyObj::new(p).unwrap()).unwrap()
|
rune::to_value(p).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::Ability;
|
use crate::static_data::Ability;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use crate::StringKey;
|
||||||
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -19,16 +20,101 @@ impl_rune_wrapper!(&Arc<dyn Ability>, RuneAbility);
|
||||||
|
|
||||||
impl RuneAbility {
|
impl RuneAbility {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
fn name(&self) -> Value { self.0.name().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn effect(&self) -> Shared<AnyObj> { self.0.effect().wrap() }
|
fn effect(&self) -> Value { self.0.effect().wrap() }
|
||||||
|
|
||||||
#[rune::function(vm_result)]
|
#[rune::function]
|
||||||
fn get_parameter(&self, key: RuneStringKey) -> Option<Shared<AnyObj>> {
|
fn get_parameter(&self, key: Value) -> Option<Value> {
|
||||||
match self.0.parameters().get(&key.0) {
|
if let Ok(s) = key.borrow_string_ref() {
|
||||||
None => None,
|
return self.0.parameters().get(&StringKey::new(&s)).map(|v| v.wrap());
|
||||||
Some(p) => Some(p.wrap()),
|
}
|
||||||
|
if let Ok(v) = key.into_any::<RuneStringKey>() {
|
||||||
|
self.0.parameters().get(&v.0).map(|v| v.wrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::super::tests::{execute_vm, setup_script};
|
||||||
|
use super::*;
|
||||||
|
use crate::static_data::tests::MockAbility;
|
||||||
|
use crate::static_data::Parameter;
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ability_name() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_ability(ability) {
|
||||||
|
let name = ability.name();
|
||||||
|
assert_eq!(name, "TestAbility");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut ability = MockAbility::new();
|
||||||
|
ability.expect_name().once().return_const(StringKey::new("TestAbility"));
|
||||||
|
let ability: Arc<dyn Ability> = Arc::new(ability);
|
||||||
|
let wrapped = ability.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_ability", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ability_effect() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_ability(ability) {
|
||||||
|
let effect = ability.effect();
|
||||||
|
assert_eq!(effect, "TestEffect");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut ability = MockAbility::new();
|
||||||
|
ability
|
||||||
|
.expect_effect()
|
||||||
|
.once()
|
||||||
|
.return_const(StringKey::new("TestEffect"));
|
||||||
|
let ability: Arc<dyn Ability> = Arc::new(ability);
|
||||||
|
let wrapped = ability.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_ability", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ability_get_parameter() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_ability(ability) {
|
||||||
|
let value = ability.get_parameter("test_key");
|
||||||
|
match value {
|
||||||
|
Some(v) => {
|
||||||
|
match v {
|
||||||
|
Parameter::String(s) => assert_eq!(s, "TestValue"),
|
||||||
|
_ => panic!("Invalid value type"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => panic!("Value not found"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut ability = MockAbility::new();
|
||||||
|
ability.expect_parameters().once().return_const({
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(
|
||||||
|
StringKey::new("test_key"),
|
||||||
|
Arc::new(Parameter::String(StringKey::new("TestValue"))),
|
||||||
|
);
|
||||||
|
map
|
||||||
|
});
|
||||||
|
let a: Arc<dyn Ability> = Arc::new(ability);
|
||||||
|
let wrapped = a.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_ability", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::{AbilityIndex, Form, Statistic};
|
use crate::static_data::{AbilityIndex, Form, Statistic};
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use crate::StringKey;
|
||||||
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -22,13 +23,14 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Any)]
|
#[derive(Debug, Any)]
|
||||||
|
#[rune(name = Form)]
|
||||||
pub struct RuneForm(pub Arc<dyn Form>);
|
pub struct RuneForm(pub Arc<dyn Form>);
|
||||||
|
|
||||||
impl_rune_wrapper!(&Arc<dyn Form>, RuneForm);
|
impl_rune_wrapper!(&Arc<dyn Form>, RuneForm);
|
||||||
|
|
||||||
impl RuneForm {
|
impl RuneForm {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
fn name(&self) -> Value { self.0.name().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn height(&self) -> f32 { self.0.height() }
|
fn height(&self) -> f32 { self.0.height() }
|
||||||
|
@ -40,28 +42,286 @@ impl RuneForm {
|
||||||
fn base_experience(&self) -> u32 { self.0.base_experience() }
|
fn base_experience(&self) -> u32 { self.0.base_experience() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn types(&self) -> Vec<u8> { self.0.types().iter().map(|t| u8::from(*t)).collect() }
|
fn types(&self) -> Vec<i64> { self.0.types().iter().map(|t| u8::from(*t) as i64).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn base_stats(&self) -> Shared<AnyObj> { self.0.base_stats().wrap() }
|
fn base_stats(&self) -> Value { self.0.base_stats().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn abilities(&self) -> Vec<Shared<AnyObj>> { self.0.abilities().iter().map(|a| a.wrap()).collect() }
|
fn abilities(&self) -> Vec<Value> { self.0.abilities().iter().map(|a| a.wrap()).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn hidden_abilities(&self) -> Vec<Shared<AnyObj>> { self.0.hidden_abilities().iter().map(|a| a.wrap()).collect() }
|
fn hidden_abilities(&self) -> Vec<Value> { self.0.hidden_abilities().iter().map(|a| a.wrap()).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) }
|
fn has_flag(&self, key: Value) -> bool {
|
||||||
|
if let Ok(s) = key.borrow_string_ref() {
|
||||||
|
return self.0.has_flag(&StringKey::new(&s));
|
||||||
|
}
|
||||||
|
if let Ok(v) = key.into_any::<RuneStringKey>() {
|
||||||
|
return self.0.has_flag(&v.0);
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_type(&self, index: usize) -> anyhow::Result<u8> { self.0.get_type(index).map(|t| u8::from(t)) }
|
fn get_type(&self, index: usize) -> anyhow::Result<i64> { self.0.get_type(index).map(|t| u8::from(t) as i64) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_base_stat(&self, statistic: Statistic) -> u16 { self.0.get_base_stat(statistic) }
|
fn get_base_stat(&self, statistic: Statistic) -> u16 { self.0.get_base_stat(statistic) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_ability(&self, hidden: bool, index: u8) -> anyhow::Result<Shared<AnyObj>> {
|
fn get_ability(&self, hidden: bool, index: i64) -> anyhow::Result<Value> {
|
||||||
|
if index > u8::MAX as i64 || index < 0 {
|
||||||
|
return Err(anyhow::anyhow!("Index out of bounds"));
|
||||||
|
}
|
||||||
|
let index = index as u8;
|
||||||
self.0.get_ability(AbilityIndex { hidden, index }).map(|a| a.wrap())
|
self.0.get_ability(AbilityIndex { hidden, index }).map(|a| a.wrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::super::tests::{execute_vm, setup_script};
|
||||||
|
use super::*;
|
||||||
|
use crate::static_data::tests::MockForm;
|
||||||
|
use crate::static_data::{StaticStatisticSet, TypeIdentifier};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_name() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let name = form.name();
|
||||||
|
assert_eq!(name, "TestForm");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_name().once().return_const(StringKey::new("TestForm"));
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_height() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let height = form.height();
|
||||||
|
assert_eq!(height, 1.0);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_height().once().return_const(1.0);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_weight() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let weight = form.weight();
|
||||||
|
assert_eq!(weight, 1.0);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_weight().once().return_const(1.0);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_base_experience() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let base_experience = form.base_experience();
|
||||||
|
assert_eq!(base_experience, 1);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_base_experience().once().return_const(1u32);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_types() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let types = form.types();
|
||||||
|
assert_eq!(types[0], 1);
|
||||||
|
assert_eq!(types[1], 2);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_types()
|
||||||
|
.once()
|
||||||
|
.return_const(vec![TypeIdentifier::from(1u8), TypeIdentifier::from(2u8)]);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_base_stats() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let base_stats = form.base_stats();
|
||||||
|
assert_eq!(base_stats.hp(), 1);
|
||||||
|
assert_eq!(base_stats.attack(), 2);
|
||||||
|
assert_eq!(base_stats.defense(), 3);
|
||||||
|
assert_eq!(base_stats.special_attack(), 4);
|
||||||
|
assert_eq!(base_stats.special_defense(), 5);
|
||||||
|
assert_eq!(base_stats.speed(), 6);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_base_stats()
|
||||||
|
.once()
|
||||||
|
.return_const(Arc::new(StaticStatisticSet::<u16>::new(1, 2, 3, 4, 5, 6)));
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_abilities() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let abilities = form.abilities();
|
||||||
|
assert_eq!(abilities.len(), 1);
|
||||||
|
assert_eq!(abilities[0], "TestAbility");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_abilities()
|
||||||
|
.once()
|
||||||
|
.return_const(vec![StringKey::new("TestAbility")]);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_hidden_abilities() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let abilities = form.hidden_abilities();
|
||||||
|
assert_eq!(abilities.len(), 1);
|
||||||
|
assert_eq!(abilities[0], "TestAbility");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_hidden_abilities()
|
||||||
|
.once()
|
||||||
|
.return_const(vec![StringKey::new("TestAbility")]);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_has_flag() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let has_flag = form.has_flag("test_key");
|
||||||
|
assert_eq!(has_flag, true);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_has_flag().once().return_const(true);
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_get_type() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let type_id = form.get_type(0)?;
|
||||||
|
assert_eq!(type_id, 1);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_get_type()
|
||||||
|
.once()
|
||||||
|
.returning(|_| Ok(TypeIdentifier::from(1u8)));
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_get_base_stat() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let base_stat = form.get_base_stat(Statistic::HP);
|
||||||
|
assert_eq!(base_stat, 1);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_get_base_stat()
|
||||||
|
.once()
|
||||||
|
.return_const(StaticStatisticSet::<u16>::new(1, 2, 3, 4, 5, 6).hp());
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_form_get_ability() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_form(form) {
|
||||||
|
let ability = form.get_ability(false, 0)?;
|
||||||
|
assert_eq!(ability, "TestAbility");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut form = MockForm::new();
|
||||||
|
form.expect_get_ability()
|
||||||
|
.once()
|
||||||
|
.returning(move |_| Ok(StringKey::new("TestAbility")));
|
||||||
|
let form: Arc<dyn Form> = Arc::new(form);
|
||||||
|
let wrapped = form.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_form", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,59 @@ impl RuneGrowthRate {
|
||||||
fn calculate_level(&self, experience: u32) -> i32 { self.0.calculate_level(experience) as i32 }
|
fn calculate_level(&self, experience: u32) -> i32 { self.0.calculate_level(experience) as i32 }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn calculate_experience(&self, level: LevelInt) -> Result<u32, String> {
|
fn calculate_experience(&self, level: i64) -> Result<u32, String> {
|
||||||
|
if level < 0 {
|
||||||
|
return Err("Level cannot be negative".to_string());
|
||||||
|
}
|
||||||
|
if level > LevelInt::MAX as i64 {
|
||||||
|
return Err(format!("Level cannot be greater than {}", LevelInt::MAX));
|
||||||
|
}
|
||||||
|
let level = level as LevelInt;
|
||||||
|
|
||||||
self.0.calculate_experience(level).map_err(|e| e.to_string())
|
self.0.calculate_experience(level).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::super::tests::{execute_vm, setup_script};
|
||||||
|
use super::*;
|
||||||
|
use crate::script_implementations::rune::wrappers::RuneWrapper;
|
||||||
|
use crate::static_data::tests::MockGrowthRate;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_calculate_level() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_growth_rate(growth_rate) {
|
||||||
|
let level = growth_rate.calculate_level(10);
|
||||||
|
assert_eq!(level, 10);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut growth_rate = MockGrowthRate::new();
|
||||||
|
growth_rate.expect_calculate_level().returning(|_| 10);
|
||||||
|
let growth_rate: Arc<dyn GrowthRate> = Arc::new(growth_rate);
|
||||||
|
let wrapped = growth_rate.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_growth_rate", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_calculate_experience() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_growth_rate(growth_rate) {
|
||||||
|
let experience = growth_rate.calculate_experience(10)?;
|
||||||
|
assert_eq!(experience, 10);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut growth_rate = MockGrowthRate::new();
|
||||||
|
growth_rate.expect_calculate_experience().returning(|_| Ok(10));
|
||||||
|
let growth_rate: Arc<dyn GrowthRate> = Arc::new(growth_rate);
|
||||||
|
let wrapped = growth_rate.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_growth_rate", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
|
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
|
@ -28,7 +28,7 @@ impl_rune_wrapper!(&Arc<dyn Item>, RuneItem);
|
||||||
|
|
||||||
impl RuneItem {
|
impl RuneItem {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn name(&self) -> Shared<AnyObj> { self.0.name().clone().wrap() }
|
fn name(&self) -> Value { self.0.name().clone().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn category(&self) -> ItemCategory { self.0.category() }
|
fn category(&self) -> ItemCategory { self.0.category() }
|
||||||
|
@ -40,8 +40,34 @@ impl RuneItem {
|
||||||
fn price(&self) -> i32 { self.0.price() }
|
fn price(&self) -> i32 { self.0.price() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn flags(&self) -> Vec<Shared<AnyObj>> { self.0.flags().iter().map(|s| s.clone().wrap()).collect() }
|
fn flags(&self) -> Vec<Value> { self.0.flags().iter().map(|s| s.clone().wrap()).collect() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) }
|
fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::super::tests::{execute_vm, setup_script};
|
||||||
|
use super::*;
|
||||||
|
use crate::static_data::tests::MockItem;
|
||||||
|
use crate::StringKey;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_name() -> anyhow::Result<()> {
|
||||||
|
let mut vm = setup_script(
|
||||||
|
r#"
|
||||||
|
pub fn test_item(item) {
|
||||||
|
let name = item.name();
|
||||||
|
assert_eq!(name, "Test Item");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
let mut item = MockItem::new();
|
||||||
|
item.expect_name().once().return_const(StringKey::new("Test Item"));
|
||||||
|
let item: Arc<dyn Item> = Arc::new(item);
|
||||||
|
let wrapped = item.wrap();
|
||||||
|
execute_vm!(&mut vm, "test_item", wrapped);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::LearnableMoves;
|
use crate::static_data::LearnableMoves;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ impl_rune_wrapper!(&Arc<dyn LearnableMoves>, RuneLearnableMoves);
|
||||||
|
|
||||||
impl RuneLearnableMoves {
|
impl RuneLearnableMoves {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_learned_by_level(&self, level: LevelInt) -> Option<Vec<Shared<AnyObj>>> {
|
fn get_learned_by_level(&self, level: LevelInt) -> Option<Vec<Value>> {
|
||||||
self.0
|
self.0
|
||||||
.get_learned_by_level(level)
|
.get_learned_by_level(level)
|
||||||
.map(|v| v.into_iter().map(|s| s.wrap()).collect())
|
.map(|v| v.into_iter().map(|s| s.wrap()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_distinct_level_moves(&self) -> Vec<Shared<AnyObj>> {
|
fn get_distinct_level_moves(&self) -> Vec<Value> {
|
||||||
self.0
|
self.0
|
||||||
.get_distinct_level_moves()
|
.get_distinct_level_moves()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -6,7 +6,7 @@ mod type_library;
|
||||||
|
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::{AbilityLibrary, ItemLibrary, MoveLibrary, SpeciesLibrary};
|
use crate::static_data::{AbilityLibrary, ItemLibrary, MoveLibrary, SpeciesLibrary};
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
|
@ -49,13 +49,13 @@ macro_rules! impl_rune_data_library_wrapper {
|
||||||
|
|
||||||
impl $t {
|
impl $t {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get(&self, key: &RuneStringKey) -> Option<Shared<AnyObj>> { self.0.get(&key.0).map(|v| v.wrap()) }
|
fn get(&self, key: &RuneStringKey) -> Option<Value> { self.0.get(&key.0).map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn len(&self) -> usize { self.0.len() }
|
fn len(&self) -> usize { self.0.len() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_key_by_index(&self, index: usize) -> Option<Shared<AnyObj>> {
|
fn get_key_by_index(&self, index: usize) -> Option<Value> {
|
||||||
self.0.get_key_by_index(index).map(|v| v.wrap())
|
self.0.get_key_by_index(index).map(|v| v.wrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::script_implementations::rune::wrappers::static_data::nature::RuneNature;
|
use crate::script_implementations::rune::wrappers::static_data::nature::RuneNature;
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::NatureLibrary;
|
use crate::static_data::NatureLibrary;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
|
@ -18,7 +18,7 @@ impl_rune_wrapper!(&Arc<dyn NatureLibrary>, RuneNatureLibrary);
|
||||||
|
|
||||||
impl RuneNatureLibrary {
|
impl RuneNatureLibrary {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_nature(&self, key: RuneStringKey) -> Option<Shared<AnyObj>> { self.0.get_nature(&key.0).map(|v| v.wrap()) }
|
fn get_nature(&self, key: RuneStringKey) -> Option<Value> { self.0.get_nature(&key.0).map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_nature_name(&self, nature: &RuneNature) -> RuneStringKey {
|
fn get_nature_name(&self, nature: &RuneNature) -> RuneStringKey {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
||||||
use crate::static_data::StaticData;
|
use crate::static_data::StaticData;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
|
@ -23,26 +23,26 @@ impl_rune_wrapper!(&Arc<dyn StaticData>, RuneStaticData);
|
||||||
|
|
||||||
impl RuneStaticData {
|
impl RuneStaticData {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn settings(&self) -> Shared<AnyObj> { self.0.settings().wrap() }
|
fn settings(&self) -> Value { self.0.settings().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn species(&self) -> Shared<AnyObj> { self.0.species().wrap() }
|
fn species(&self) -> Value { self.0.species().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn moves(&self) -> Shared<AnyObj> { self.0.moves().wrap() }
|
fn moves(&self) -> Value { self.0.moves().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn items(&self) -> Shared<AnyObj> { self.0.items().wrap() }
|
fn items(&self) -> Value { self.0.items().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn growth_rates(&self) -> Shared<AnyObj> { self.0.growth_rates().wrap() }
|
fn growth_rates(&self) -> Value { self.0.growth_rates().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn types(&self) -> Shared<AnyObj> { self.0.types().wrap() }
|
fn types(&self) -> Value { self.0.types().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn natures(&self) -> Shared<AnyObj> { self.0.natures().wrap() }
|
fn natures(&self) -> Value { self.0.natures().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn abilities(&self) -> Shared<AnyObj> { self.0.abilities().wrap() }
|
fn abilities(&self) -> Value { self.0.abilities().wrap() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::TypeLibrary;
|
use crate::static_data::TypeLibrary;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||||
|
@ -22,7 +22,7 @@ impl RuneTypeLibrary {
|
||||||
fn get_type_id(&self, key: &RuneStringKey) -> Option<u8> { self.0.get_type_id(&key.0).map(|v| v.into()) }
|
fn get_type_id(&self, key: &RuneStringKey) -> Option<u8> { self.0.get_type_id(&key.0).map(|v| v.into()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_type_name(&self, t: u8) -> Option<Shared<AnyObj>> { self.0.get_type_name(t.into()).map(|v| v.wrap()) }
|
fn get_type_name(&self, t: u8) -> Option<Value> { self.0.get_type_name(t.into()).map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_single_effectiveness(&self, attacking: u8, defending: u8) -> anyhow::Result<f32> {
|
fn get_single_effectiveness(&self, attacking: u8, defending: u8) -> anyhow::Result<f32> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
|
use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
|
||||||
use rune::runtime::{AnyObj, Object, Shared};
|
use rune::runtime::{Object, Value};
|
||||||
use rune::{Any, Value};
|
use rune::Any;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ impl_rune_wrapper!(&Arc<dyn MoveData>, RuneMoveData);
|
||||||
|
|
||||||
impl RuneMoveData {
|
impl RuneMoveData {
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
fn name(&self) -> Value { self.0.name().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn move_type(&self) -> u8 { u8::from(self.0.move_type()) }
|
fn move_type(&self) -> u8 { u8::from(self.0.move_type()) }
|
||||||
|
@ -59,7 +59,7 @@ impl RuneMoveData {
|
||||||
fn priority(&self) -> i8 { self.0.priority() }
|
fn priority(&self) -> i8 { self.0.priority() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn secondary_effect(&self) -> Option<Shared<AnyObj>> { self.0.secondary_effect().as_ref().map(|x| x.wrap()) }
|
fn secondary_effect(&self) -> Option<Value> { self.0.secondary_effect().as_ref().map(|x| x.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_flag(&self, flag: RuneStringKey) -> bool { self.0.has_flag(&flag.0) }
|
fn has_flag(&self, flag: RuneStringKey) -> bool { self.0.has_flag(&flag.0) }
|
||||||
|
@ -75,7 +75,7 @@ impl RuneSecondaryEffect {
|
||||||
fn chance(&self) -> f32 { self.0.chance() }
|
fn chance(&self) -> f32 { self.0.chance() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn effect_name(&self) -> Shared<AnyObj> { self.0.effect_name().wrap() }
|
fn effect_name(&self) -> Value { self.0.effect_name().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn parameters(&self) -> anyhow::Result<Object> {
|
fn parameters(&self) -> anyhow::Result<Object> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||||
use crate::static_data::Species;
|
use crate::static_data::Species;
|
||||||
use rune::runtime::{AnyObj, Shared};
|
use rune::runtime::Value;
|
||||||
use rune::Any;
|
use rune::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ impl RuneSpecies {
|
||||||
fn id(&self) -> u16 { self.0.id() }
|
fn id(&self) -> u16 { self.0.id() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
fn name(&self) -> Value { self.0.name().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn gender_rate(&self) -> f32 { self.0.gender_rate() }
|
fn gender_rate(&self) -> f32 { self.0.gender_rate() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn growth_rate(&self) -> Shared<AnyObj> { self.0.growth_rate().wrap() }
|
fn growth_rate(&self) -> Value { self.0.growth_rate().wrap() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn capture_rate(&self) -> u8 { self.0.capture_rate() }
|
fn capture_rate(&self) -> u8 { self.0.capture_rate() }
|
||||||
|
@ -44,12 +44,10 @@ impl RuneSpecies {
|
||||||
fn base_happiness(&self) -> u8 { self.0.base_happiness() }
|
fn base_happiness(&self) -> u8 { self.0.base_happiness() }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_form(&self, name: &RuneStringKey) -> Option<Shared<AnyObj>> {
|
fn get_form(&self, name: &RuneStringKey) -> Option<Value> { self.0.get_form(&name.0).map(|form| form.wrap()) }
|
||||||
self.0.get_form(&name.0).map(|form| form.wrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn get_default_form(&self) -> anyhow::Result<Shared<AnyObj>> { self.0.get_default_form().map(|v| v.wrap()) }
|
fn get_default_form(&self) -> anyhow::Result<Value> { self.0.get_default_form().map(|v| v.wrap()) }
|
||||||
|
|
||||||
#[rune::function]
|
#[rune::function]
|
||||||
fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) }
|
fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) }
|
||||||
|
|
|
@ -12,20 +12,28 @@ use crate::StringKey;
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum ItemCategory {
|
pub enum ItemCategory {
|
||||||
/// This is where most items should go.
|
/// This is where most items should go.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
MiscItem,
|
MiscItem,
|
||||||
/// Pokeballs are used for capturing Pokemons.
|
/// Pokeballs are used for capturing Pokemons.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Pokeball,
|
Pokeball,
|
||||||
/// Medicine is used for healing HP, PP, and status effects
|
/// Medicine is used for healing HP, PP, and status effects
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Medicine,
|
Medicine,
|
||||||
/// Berry is used for all berries.
|
/// Berry is used for all berries.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Berry,
|
Berry,
|
||||||
/// TMHM is used for Technical and Hidden Machines.
|
/// TMHM is used for Technical and Hidden Machines.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
TMHM,
|
TMHM,
|
||||||
/// Form Changer is used for items that change forms, such as mega stones.
|
/// Form Changer is used for items that change forms, such as mega stones.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
FormChanger,
|
FormChanger,
|
||||||
/// Key Items are single stored items, generally used for story progression.
|
/// Key Items are single stored items, generally used for story progression.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
KeyItem,
|
KeyItem,
|
||||||
/// Mail is used for mail items.
|
/// Mail is used for mail items.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Mail,
|
Mail,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +44,19 @@ pub enum ItemCategory {
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum BattleItemCategory {
|
pub enum BattleItemCategory {
|
||||||
/// This item can't be used in battle.
|
/// This item can't be used in battle.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
None,
|
None,
|
||||||
/// This item is used for healing Pokemon.
|
/// This item is used for healing Pokemon.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Healing,
|
Healing,
|
||||||
/// This item is used for healing Pokemon from a status.
|
/// This item is used for healing Pokemon from a status.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
StatusHealing,
|
StatusHealing,
|
||||||
/// This item is used for capturing Pokemon.
|
/// This item is used for capturing Pokemon.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Pokeball,
|
Pokeball,
|
||||||
/// This item does not belong in above categories, but is still a battle item.
|
/// This item does not belong in above categories, but is still a battle item.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
MiscBattleItem,
|
MiscBattleItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ use std::fmt::{Display, Formatter};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
#[doc(inline)] pub use growth_rates::tests::*;
|
||||||
|
#[doc(inline)] pub use items::tests::*;
|
||||||
#[doc(inline)] pub use moves::tests::*;
|
#[doc(inline)] pub use moves::tests::*;
|
||||||
#[doc(inline)] pub use natures::tests::*;
|
#[doc(inline)] pub use natures::tests::*;
|
||||||
#[doc(inline)] pub use species_data::tests::*;
|
#[doc(inline)] pub use species_data::tests::*;
|
||||||
|
|
|
@ -44,12 +44,12 @@ pub trait Form: Debug {
|
||||||
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex>;
|
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex>;
|
||||||
|
|
||||||
/// Gets an ability from the form.
|
/// Gets an ability from the form.
|
||||||
fn get_ability(&self, index: AbilityIndex) -> Result<&StringKey>;
|
fn get_ability(&self, index: AbilityIndex) -> Result<StringKey>;
|
||||||
|
|
||||||
/// Gets a random ability from the form.
|
/// Gets a random ability from the form.
|
||||||
fn get_random_ability(&self, rand: &mut Random) -> Result<&StringKey>;
|
fn get_random_ability(&self, rand: &mut Random) -> Result<StringKey>;
|
||||||
/// Gets a random hidden ability from the form.
|
/// Gets a random hidden ability from the form.
|
||||||
fn get_random_hidden_ability(&self, rand: &mut Random) -> Result<&StringKey>;
|
fn get_random_hidden_ability(&self, rand: &mut Random) -> Result<StringKey>;
|
||||||
|
|
||||||
/// Check if the form has a specific flag set.
|
/// Check if the form has a specific flag set.
|
||||||
fn has_flag(&self, key: &StringKey) -> bool;
|
fn has_flag(&self, key: &StringKey) -> bool;
|
||||||
|
@ -118,56 +118,32 @@ impl FormImpl {
|
||||||
|
|
||||||
impl Form for FormImpl {
|
impl Form for FormImpl {
|
||||||
/// The name of the form.
|
/// The name of the form.
|
||||||
fn name(&self) -> &StringKey {
|
fn name(&self) -> &StringKey { &self.name }
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
/// The height of the form in meters.
|
/// The height of the form in meters.
|
||||||
fn height(&self) -> f32 {
|
fn height(&self) -> f32 { self.height }
|
||||||
self.height
|
|
||||||
}
|
|
||||||
/// The weight of the form in kilograms.
|
/// The weight of the form in kilograms.
|
||||||
fn weight(&self) -> f32 {
|
fn weight(&self) -> f32 { self.weight }
|
||||||
self.weight
|
|
||||||
}
|
|
||||||
/// The base amount of experience that is gained when beating a Pokemon with this form.
|
/// The base amount of experience that is gained when beating a Pokemon with this form.
|
||||||
fn base_experience(&self) -> u32 {
|
fn base_experience(&self) -> u32 { self.base_experience }
|
||||||
self.base_experience
|
|
||||||
}
|
|
||||||
/// The normal types a Pokemon with this form has.
|
/// The normal types a Pokemon with this form has.
|
||||||
fn types(&self) -> &Vec<TypeIdentifier> {
|
fn types(&self) -> &Vec<TypeIdentifier> { &self.types }
|
||||||
&self.types
|
|
||||||
}
|
|
||||||
/// The inherent values of a form of species that are used for the stats of a Pokemon.
|
/// The inherent values of a form of species that are used for the stats of a Pokemon.
|
||||||
fn base_stats(&self) -> &Arc<StaticStatisticSet<u16>> {
|
fn base_stats(&self) -> &Arc<StaticStatisticSet<u16>> { &self.base_stats }
|
||||||
&self.base_stats
|
|
||||||
}
|
|
||||||
/// The possible abilities a Pokemon with this form can have.
|
/// The possible abilities a Pokemon with this form can have.
|
||||||
fn abilities(&self) -> &Vec<StringKey> {
|
fn abilities(&self) -> &Vec<StringKey> { &self.abilities }
|
||||||
&self.abilities
|
|
||||||
}
|
|
||||||
/// The possible hidden abilities a Pokemon with this form can have.
|
/// The possible hidden abilities a Pokemon with this form can have.
|
||||||
fn hidden_abilities(&self) -> &Vec<StringKey> {
|
fn hidden_abilities(&self) -> &Vec<StringKey> { &self.hidden_abilities }
|
||||||
&self.hidden_abilities
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The moves a Pokemon with this form can learn.
|
/// The moves a Pokemon with this form can learn.
|
||||||
fn moves(&self) -> &Arc<dyn LearnableMoves> {
|
fn moves(&self) -> &Arc<dyn LearnableMoves> { &self.moves }
|
||||||
&self.moves
|
|
||||||
}
|
|
||||||
/// Arbitrary flags can be set on a form for scripting use.
|
/// Arbitrary flags can be set on a form for scripting use.
|
||||||
fn flags(&self) -> &HashSet<StringKey> {
|
fn flags(&self) -> &HashSet<StringKey> { &self.flags }
|
||||||
&self.flags
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a type of the move at a certain index.
|
/// Get a type of the move at a certain index.
|
||||||
fn get_type(&self, index: usize) -> Result<TypeIdentifier> {
|
fn get_type(&self, index: usize) -> Result<TypeIdentifier> { Ok(*self.types.get_res(index)?) }
|
||||||
Ok(*self.types.get_res(index)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a single base stat value.
|
/// Gets a single base stat value.
|
||||||
fn get_base_stat(&self, stat: Statistic) -> u16 {
|
fn get_base_stat(&self, stat: Statistic) -> u16 { self.base_stats.get_stat(stat) }
|
||||||
self.base_stats.get_stat(stat)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find the index of an ability that can be on this form.
|
/// Find the index of an ability that can be on this form.
|
||||||
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex> {
|
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex> {
|
||||||
|
@ -191,39 +167,35 @@ impl Form for FormImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an ability from the form.
|
/// Gets an ability from the form.
|
||||||
fn get_ability(&self, index: AbilityIndex) -> Result<&StringKey> {
|
fn get_ability(&self, index: AbilityIndex) -> Result<StringKey> {
|
||||||
if index.hidden {
|
if index.hidden {
|
||||||
Ok(self.hidden_abilities.get_res(index.index as usize)?)
|
self.hidden_abilities.get_res(index.index as usize).map(|s| s.clone())
|
||||||
} else {
|
} else {
|
||||||
Ok(self.abilities.get_res(index.index as usize)?)
|
self.abilities.get_res(index.index as usize).map(|s| s.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a random ability from the form.
|
/// Gets a random ability from the form.
|
||||||
fn get_random_ability(&self, rand: &mut Random) -> Result<&StringKey> {
|
fn get_random_ability(&self, rand: &mut Random) -> Result<StringKey> {
|
||||||
ensure!(!self.abilities.is_empty(), "No abilities on form");
|
ensure!(!self.abilities.is_empty(), "No abilities on form");
|
||||||
self.abilities
|
self.abilities
|
||||||
.get_res(rand.get_between_unsigned(0, self.abilities.len() as u32) as usize)
|
.get_res(rand.get_between_unsigned(0, self.abilities.len() as u32) as usize)
|
||||||
|
.map(|s| s.clone())
|
||||||
}
|
}
|
||||||
/// Gets a random hidden ability from the form.
|
/// Gets a random hidden ability from the form.
|
||||||
fn get_random_hidden_ability(&self, rand: &mut Random) -> Result<&StringKey> {
|
fn get_random_hidden_ability(&self, rand: &mut Random) -> Result<StringKey> {
|
||||||
ensure!(!self.hidden_abilities.is_empty(), "No hidden abilities on form");
|
ensure!(!self.hidden_abilities.is_empty(), "No hidden abilities on form");
|
||||||
self.hidden_abilities
|
self.hidden_abilities
|
||||||
.get_res(rand.get_between_unsigned(0, self.hidden_abilities.len() as u32) as usize)
|
.get_res(rand.get_between_unsigned(0, self.hidden_abilities.len() as u32) as usize)
|
||||||
|
.map(|s| s.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the form has a specific flag set.
|
/// Check if the form has a specific flag set.
|
||||||
fn has_flag(&self, key: &StringKey) -> bool {
|
fn has_flag(&self, key: &StringKey) -> bool { self.flags.contains(key) }
|
||||||
self.flags.contains(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool {
|
fn has_flag_by_hash(&self, key_hash: u32) -> bool { self.flags.contains::<u32>(&key_hash) }
|
||||||
self.flags.contains::<u32>(&key_hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eq(&self, other: &dyn Form) -> bool {
|
fn eq(&self, other: &dyn Form) -> bool { std::ptr::eq(self, other as *const dyn Form as *const Self) }
|
||||||
std::ptr::eq(self, other as *const dyn Form as *const Self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -249,9 +221,9 @@ pub(crate) mod tests {
|
||||||
fn get_type(&self, index: usize) -> Result<TypeIdentifier>;
|
fn get_type(&self, index: usize) -> Result<TypeIdentifier>;
|
||||||
fn get_base_stat(&self, stat: Statistic) -> u16;
|
fn get_base_stat(&self, stat: Statistic) -> u16;
|
||||||
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex>;
|
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex>;
|
||||||
fn get_ability<'a>(&'a self, index: AbilityIndex) -> Result<&'a StringKey>;
|
fn get_ability(&self, index: AbilityIndex) -> Result<StringKey>;
|
||||||
fn get_random_ability<'a>(&'a self, rand: &mut Random) -> Result<&'a StringKey>;
|
fn get_random_ability(&self, rand: &mut Random) -> Result<StringKey>;
|
||||||
fn get_random_hidden_ability<'a>(&'a self, rand: &mut Random) -> Result<&'a StringKey>;
|
fn get_random_hidden_ability(&self, rand: &mut Random) -> Result<StringKey>;
|
||||||
fn has_flag(&self, key: &StringKey) -> bool;
|
fn has_flag(&self, key: &StringKey) -> bool;
|
||||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
|
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
|
||||||
fn eq(&self, other: &dyn Form) -> bool;
|
fn eq(&self, other: &dyn Form) -> bool;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
pub use super::form::tests::*;
|
pub use super::form::tests::*;
|
||||||
pub use super::species::tests::*;
|
pub use super::species::tests::*;
|
||||||
|
pub use super::ability::tests::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An ability is a passive effect in battle that is attached to a Pokemon.
|
/// An ability is a passive effect in battle that is attached to a Pokemon.
|
||||||
|
|
|
@ -7,15 +7,21 @@
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Statistic {
|
pub enum Statistic {
|
||||||
/// Health Points determine how much damage a Pokemon can receive before fainting.
|
/// Health Points determine how much damage a Pokemon can receive before fainting.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
HP,
|
HP,
|
||||||
/// Attack determines how much damage a Pokemon deals when using a physical attack.
|
/// Attack determines how much damage a Pokemon deals when using a physical attack.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Attack,
|
Attack,
|
||||||
/// Defense determines how much damage a Pokemon receives when it is hit by a physical attack.
|
/// Defense determines how much damage a Pokemon receives when it is hit by a physical attack.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Defense,
|
Defense,
|
||||||
/// Special Attack determines how much damage a Pokemon deals when using a special attack.
|
/// Special Attack determines how much damage a Pokemon deals when using a special attack.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
SpecialAttack,
|
SpecialAttack,
|
||||||
/// Special Defense determines how much damage a Pokemon receives when it is hit by a special attack.
|
/// Special Defense determines how much damage a Pokemon receives when it is hit by a special attack.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
SpecialDefense,
|
SpecialDefense,
|
||||||
/// Speed determines the order that a Pokemon can act in battle.
|
/// Speed determines the order that a Pokemon can act in battle.
|
||||||
|
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||||
Speed,
|
Speed,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,10 @@ fn integration_tests(input: &Path) {
|
||||||
let mut str: String = "".to_string();
|
let mut str: String = "".to_string();
|
||||||
let mut file = File::open(input).unwrap();
|
let mut file = File::open(input).unwrap();
|
||||||
file.read_to_string(&mut str).unwrap();
|
file.read_to_string(&mut str).unwrap();
|
||||||
let test_case = serde_yaml::from_str::<TestCase>(&str).unwrap();
|
let test_case = serde_yml::from_str::<TestCase>(&str).unwrap();
|
||||||
println!(" Running integration test {}", test_case.name);
|
println!(" Running integration test {}", test_case.name);
|
||||||
test_case.run_test(get_library());
|
test_case.run_test(get_library());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_single_turn() {
|
fn basic_single_turn() { integration_tests(Path::new("tests/test_cases/basic_single_turn.yaml")); }
|
||||||
integration_tests(Path::new("tests/test_cases/basic_single_turn.yaml"));
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue