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_pcg = "0.3"
|
||||
hashbrown = "0.14"
|
||||
indexmap = "2.0"
|
||||
indexmap = "2.2"
|
||||
parking_lot = "0.12"
|
||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||
serde_repr = "0.1"
|
||||
serde-xml-rs = { version = "0.6", optional = true }
|
||||
uuid = "1.5"
|
||||
uuid = "1.8"
|
||||
paste = { version = "1.0" }
|
||||
arcstr = { version = "1.1", features = ["std"] }
|
||||
arcstr = { version = "1.2", features = ["std"] }
|
||||
enum-display-derive = "0.1"
|
||||
anyhow = "1.0"
|
||||
anyhow_ext = "0.2"
|
||||
|
@ -66,12 +66,12 @@ thiserror = "1.0"
|
|||
stdext = "0.3"
|
||||
|
||||
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]
|
||||
csv = "1.3"
|
||||
project-root = "0.2"
|
||||
serde_yaml = "0.9"
|
||||
serde_yml = "0.0.7"
|
||||
serde_json = "1.0"
|
||||
serde_plain = "1.0"
|
||||
# Allow us to assert whether floats are approximately a value
|
||||
|
|
|
@ -427,7 +427,7 @@ impl Pokemon {
|
|||
.library
|
||||
.static_data()
|
||||
.abilities()
|
||||
.get(ability)
|
||||
.get(&ability)
|
||||
.ok_or(PkmnError::InvalidAbilityName {
|
||||
ability: ability.clone(),
|
||||
})?)
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::script_implementations::rune::RuneScriptType;
|
|||
use crate::static_data::Parameter;
|
||||
use crate::StringKey;
|
||||
use hashbrown::HashMap;
|
||||
use rune::runtime::{Object, RuntimeContext, Shared, VmError, VmResult};
|
||||
use rune::runtime::{RuntimeContext, VmError, VmResult};
|
||||
use rune::{Unit, Value};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||
|
@ -12,7 +12,7 @@ use std::sync::Arc;
|
|||
|
||||
pub struct RuneScript {
|
||||
name: StringKey,
|
||||
state: Shared<Object>,
|
||||
state: Value,
|
||||
/// Returns an atomic bool for internal marking of deletion. This is currently only specifically
|
||||
/// used for deletion of a script while we are holding a reference to it (i.e. executing a script
|
||||
/// hook on it).
|
||||
|
@ -34,7 +34,7 @@ unsafe impl Sync for RuneScript {}
|
|||
impl RuneScript {
|
||||
pub fn new(
|
||||
name: StringKey,
|
||||
object: Shared<Object>,
|
||||
object: Value,
|
||||
script_type: Arc<RuneScriptType>,
|
||||
runtime: Arc<RuntimeContext>,
|
||||
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 {
|
||||
|
@ -68,12 +68,12 @@ impl Script for RuneScript {
|
|||
if pars.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let state = self.state.clone();
|
||||
|
||||
let mut binding = self.state.clone().into_struct()?;
|
||||
let state = binding.data_mut();
|
||||
for par in pars {
|
||||
let key = rune::alloc::string::String::try_from(par.0.str())?;
|
||||
state
|
||||
.borrow_mut()?
|
||||
.insert(key, parameter_to_rune_value(par.1.as_ref())?)?;
|
||||
state.insert(key, parameter_to_rune_value(par.1.as_ref())?)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -87,8 +87,8 @@ impl Script for RuneScript {
|
|||
.execute(
|
||||
hash,
|
||||
vec![
|
||||
Value::Object(self.state.clone()),
|
||||
Value::from(choice.wrap()),
|
||||
rune::to_value(self.state.clone())?,
|
||||
rune::to_value(choice.wrap())?,
|
||||
speed_handle.clone(),
|
||||
],
|
||||
)?
|
||||
|
@ -116,10 +116,10 @@ impl Script for RuneScript {
|
|||
vm.execute(
|
||||
hash,
|
||||
vec![
|
||||
Value::Object(self.state.clone()),
|
||||
Value::from(move_data.wrap()),
|
||||
Value::from(target.wrap()),
|
||||
Value::from(hit),
|
||||
self.state.clone(),
|
||||
move_data.wrap(),
|
||||
target.wrap(),
|
||||
rune::to_value(hit)?,
|
||||
block_critical_handle.clone(),
|
||||
],
|
||||
)?;
|
||||
|
|
|
@ -8,7 +8,7 @@ use hashbrown::HashMap;
|
|||
use rune::compile::meta::AssociatedKind;
|
||||
use rune::compile::{ComponentRef, MetaError};
|
||||
use rune::diagnostics::Diagnostic;
|
||||
use rune::runtime::{RuntimeContext, Shared};
|
||||
use rune::runtime::RuntimeContext;
|
||||
use rune::{Context, Diagnostics, Options, Source, Sources, Unit};
|
||||
use std::any::Any;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -52,7 +52,7 @@ impl ScriptResolver for RuneScriptResolver {
|
|||
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(
|
||||
script_key.clone(),
|
||||
state,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::dynamic_data::Battle;
|
||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::Any;
|
||||
use rune::{Any, Value};
|
||||
|
||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||
module.ty::<RuneBattle>()?;
|
||||
|
@ -27,10 +26,10 @@ impl_rune_wrapper!(&Battle, RuneBattle);
|
|||
|
||||
impl RuneBattle {
|
||||
#[rune::function]
|
||||
fn library(&self) -> Shared<AnyObj> { self.0.library().wrap() }
|
||||
fn library(&self) -> Value { self.0.library().wrap() }
|
||||
|
||||
#[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]
|
||||
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() }
|
||||
|
||||
#[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]
|
||||
fn random(&self) -> Shared<AnyObj> { self.0.random().wrap() }
|
||||
fn random(&self) -> Value { self.0.random().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn has_ended(&self) -> bool { self.0.has_ended() }
|
||||
|
@ -54,9 +53,7 @@ impl RuneBattle {
|
|||
fn current_turn(&self) -> u32 { self.0.current_turn() }
|
||||
|
||||
#[rune::function]
|
||||
fn get_pokemon(&self, side: u8, index: u8) -> Option<Shared<AnyObj>> {
|
||||
self.0.get_pokemon(side, index).map(|v| v.wrap())
|
||||
}
|
||||
fn get_pokemon(&self, side: u8, index: u8) -> Option<Value> { self.0.get_pokemon(side, index).map(|v| v.wrap()) }
|
||||
|
||||
#[rune::function]
|
||||
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::resolve_script_data;
|
||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
||||
use rune::runtime::{AnyObj, Object, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -29,19 +29,19 @@ impl RuneExecutingMove {
|
|||
#[rune::function]
|
||||
fn number_of_hits(&self) -> u8 { self.0.number_of_hits() }
|
||||
#[rune::function]
|
||||
fn user(&self) -> Shared<AnyObj> { self.0.user().wrap() }
|
||||
fn user(&self) -> Value { self.0.user().wrap() }
|
||||
|
||||
#[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]
|
||||
fn use_move(&self) -> Shared<AnyObj> { self.0.use_move().wrap() }
|
||||
fn use_move(&self) -> Value { self.0.use_move().wrap() }
|
||||
|
||||
#[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]
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -24,7 +24,7 @@ impl_rune_wrapper!(&Arc<LearnedMove>, RuneLearnedMove);
|
|||
|
||||
impl RuneLearnedMove {
|
||||
#[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]
|
||||
fn max_pp(&self) -> u8 { self.0.max_pp() }
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::dynamic_data::ScriptContainer;
|
||||
use crate::script_implementations::rune::script::RuneScript;
|
||||
use rune::runtime::{Object, Shared};
|
||||
|
||||
mod battle;
|
||||
mod battle_party;
|
||||
|
@ -26,7 +25,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_script_data(container: &ScriptContainer) -> Option<Shared<Object>> {
|
||||
fn resolve_script_data(container: &ScriptContainer) -> Option<rune::Value> {
|
||||
container
|
||||
.get()
|
||||
.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::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use crate::static_data::{Gender, Statistic};
|
||||
use rune::runtime::{AnyObj, Object, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
|
||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||
|
@ -69,25 +69,25 @@ pub struct RunePokemon(pub Pokemon);
|
|||
|
||||
impl RunePokemon {
|
||||
#[rune::function]
|
||||
fn library(&self) -> Shared<AnyObj> { self.0.library().wrap() }
|
||||
fn library(&self) -> Value { self.0.library().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn species(&self) -> Shared<AnyObj> { self.0.species().wrap() }
|
||||
fn species(&self) -> Value { self.0.species().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn form(&self) -> Shared<AnyObj> { self.0.form().wrap() }
|
||||
fn form(&self) -> Value { self.0.form().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn has_different_display_species(&self) -> bool { self.0.has_different_display_species() }
|
||||
|
||||
#[rune::function]
|
||||
fn display_species(&self) -> Shared<AnyObj> { self.0.display_species().wrap() }
|
||||
fn display_species(&self) -> Value { self.0.display_species().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn has_different_display_form(&self) -> bool { self.0.has_different_display_form() }
|
||||
|
||||
#[rune::function]
|
||||
fn display_form(&self) -> Shared<AnyObj> { self.0.display_form().wrap() }
|
||||
fn display_form(&self) -> Value { self.0.display_form().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn level(&self) -> LevelInt { self.0.level() }
|
||||
|
@ -105,18 +105,16 @@ impl RunePokemon {
|
|||
fn coloring(&self) -> u8 { self.0.coloring() }
|
||||
|
||||
#[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]
|
||||
fn has_held_item(&self, key: RuneStringKey) -> bool { self.0.has_held_item(&key.0) }
|
||||
|
||||
#[rune::function]
|
||||
fn set_held_item(&mut self, key: RuneItem) -> Option<Shared<AnyObj>> {
|
||||
self.0.set_held_item(&key.0).map(|v| v.wrap())
|
||||
}
|
||||
fn set_held_item(&mut self, key: RuneItem) -> Option<Value> { self.0.set_held_item(&key.0).map(|v| v.wrap()) }
|
||||
|
||||
#[rune::function]
|
||||
fn remove_held_item(&mut self) -> Option<Shared<AnyObj>> { self.0.remove_held_item().map(|v| v.wrap()) }
|
||||
fn remove_held_item(&mut self) -> Option<Value> { self.0.remove_held_item().map(|v| v.wrap()) }
|
||||
|
||||
#[rune::function]
|
||||
fn consume_held_item(&mut self) -> anyhow::Result<bool> { self.0.consume_held_item() }
|
||||
|
@ -149,19 +147,19 @@ impl RunePokemon {
|
|||
fn types(&self) -> Vec<u8> { self.0.types().iter().map(|v| u8::from(*v)).collect() }
|
||||
|
||||
#[rune::function]
|
||||
fn learned_moves(&self) -> Vec<Option<Shared<AnyObj>>> {
|
||||
fn learned_moves(&self) -> Vec<Option<Value>> {
|
||||
let l = self.0.learned_moves().read();
|
||||
l.iter().map(|v| v.as_ref().map(|l| l.wrap())).collect()
|
||||
}
|
||||
|
||||
#[rune::function]
|
||||
fn flat_stats(&self) -> Shared<AnyObj> { self.0.flat_stats().wrap() }
|
||||
fn flat_stats(&self) -> Value { self.0.flat_stats().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn is_egg(&self) -> bool { self.0.is_egg() }
|
||||
|
||||
#[rune::function]
|
||||
fn boosted_stats(&self) -> Shared<AnyObj> { self.0.boosted_stats().wrap() }
|
||||
fn boosted_stats(&self) -> Value { self.0.boosted_stats().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
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) }
|
||||
|
||||
#[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]
|
||||
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() }
|
||||
|
||||
#[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]
|
||||
fn allowed_experience_gain(&self) -> bool { self.0.allowed_experience_gain() }
|
||||
|
||||
#[rune::function]
|
||||
fn nature(&self) -> Shared<AnyObj> { self.0.nature().wrap() }
|
||||
fn nature(&self) -> Value { self.0.nature().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
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() }
|
||||
|
||||
#[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]
|
||||
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);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::dynamic_data::TurnChoice;
|
||||
use crate::script_implementations::rune::wrappers::RuneWrapper;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -62,7 +62,7 @@ impl RuneTurnChoice {
|
|||
}
|
||||
|
||||
#[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]
|
||||
fn speed(&self) -> u32 { self.get_turn_choice().speed() }
|
||||
|
@ -75,7 +75,7 @@ impl RuneTurnChoice {
|
|||
}
|
||||
|
||||
impl RuneWrapper for &Arc<TurnChoice> {
|
||||
fn wrap(self) -> Shared<AnyObj> {
|
||||
fn wrap(self) -> Value {
|
||||
let o = match self.as_ref() {
|
||||
TurnChoice::Move(_) => RuneTurnChoice::Move(RuneMoveChoice(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::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]
|
||||
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]
|
||||
fn target_side(&self) -> u8 { self.move_choice().target_side() }
|
||||
|
@ -108,5 +108,5 @@ impl RuneMoveChoice {
|
|||
fn priority(&self) -> i8 { self.move_choice().priority() }
|
||||
|
||||
#[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::runtime::{AnyObj, Protocol, Shared, VmResult};
|
||||
use rune::runtime::{Protocol, VmResult};
|
||||
use rune::{Any, Value};
|
||||
use std::num::Saturating;
|
||||
|
||||
|
@ -8,7 +8,7 @@ mod parameters;
|
|||
mod static_data;
|
||||
|
||||
pub trait RuneWrapper {
|
||||
fn wrap(self) -> Shared<AnyObj>;
|
||||
fn wrap(self) -> Value;
|
||||
}
|
||||
|
||||
pub fn module() -> anyhow::Result<rune::Module> {
|
||||
|
@ -33,6 +33,8 @@ pub fn module() -> anyhow::Result<rune::Module> {
|
|||
|
||||
module.ty::<RuneStringKey>()?;
|
||||
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)?;
|
||||
dynamic_data::register(&mut module)?;
|
||||
|
@ -40,30 +42,24 @@ pub fn module() -> anyhow::Result<rune::Module> {
|
|||
Ok(module)
|
||||
}
|
||||
|
||||
pub fn wrap_int_reference(value: i64) -> anyhow::Result<Value> {
|
||||
Ok(Value::Any(Shared::new(AnyObj::new(RuneValueIntWrapper::new(value))?)?))
|
||||
}
|
||||
pub fn wrap_int_reference(value: i64) -> anyhow::Result<Value> { Ok(rune::to_value(RuneValueIntWrapper::new(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> {
|
||||
let obj = value.into_any().into_result()?;
|
||||
let obj = obj.take()?;
|
||||
let obj = match obj.downcast_borrow_ref::<RuneValueIntWrapper>() {
|
||||
Some(obj) => obj,
|
||||
None => return Err(anyhow::anyhow!("Value is not a RuneValueIntWrapper")),
|
||||
let obj = match value.into_any::<RuneValueIntWrapper>() {
|
||||
Ok(obj) => obj,
|
||||
Err(_) => return Err(anyhow::anyhow!("Value is not a RuneValueIntWrapper")),
|
||||
};
|
||||
Ok(obj.as_int())
|
||||
}
|
||||
|
||||
pub fn get_bool_reference_value(value: Value) -> anyhow::Result<bool> {
|
||||
let obj = value.into_any().into_result()?;
|
||||
let obj = obj.take()?;
|
||||
let obj = match obj.downcast_borrow_ref::<RuneValueBoolWrapper>() {
|
||||
Some(obj) => obj,
|
||||
None => return Err(anyhow::anyhow!("Value is not a RuneValueBoolWrapper")),
|
||||
let obj = match value.into_any::<RuneValueBoolWrapper>() {
|
||||
Ok(obj) => obj,
|
||||
Err(_) => return Err(anyhow::anyhow!("Value is not a RuneValueBoolWrapper")),
|
||||
};
|
||||
Ok(obj.as_bool())
|
||||
}
|
||||
|
@ -71,9 +67,7 @@ pub fn get_bool_reference_value(value: Value) -> anyhow::Result<bool> {
|
|||
macro_rules! impl_rune_wrapper {
|
||||
($t:ty, $wrapped_type:ident) => {
|
||||
impl crate::script_implementations::rune::wrappers::RuneWrapper for $t {
|
||||
fn wrap(self) -> rune::runtime::Shared<rune::runtime::AnyObj> {
|
||||
rune::runtime::Shared::new(rune::runtime::AnyObj::new($wrapped_type(self.clone())).unwrap()).unwrap()
|
||||
}
|
||||
fn wrap(self) -> rune::runtime::Value { rune::to_value($wrapped_type(self.clone())).unwrap() }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -82,6 +76,7 @@ use crate::StringKey;
|
|||
use impl_rune_wrapper;
|
||||
|
||||
#[derive(Any, Clone)]
|
||||
#[rune(name = RefInt)]
|
||||
struct RuneValueIntWrapper {
|
||||
value: Saturating<i64>,
|
||||
}
|
||||
|
@ -106,10 +101,12 @@ impl RuneValueIntWrapper {
|
|||
fn sub_assign(&mut self, other: i64) { self.value -= other; }
|
||||
|
||||
fn div_assign(&mut self, other: Value) {
|
||||
match other {
|
||||
Value::Integer(other) => self.value /= other,
|
||||
Value::Float(other) => self.div_assign_f64(other),
|
||||
_ => (),
|
||||
match other.as_integer() {
|
||||
Ok(other) => self.value /= 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) {
|
||||
match other {
|
||||
Value::Integer(other) => self.value *= other,
|
||||
Value::Float(other) => self.mul_assign_f64(other),
|
||||
_ => (),
|
||||
match other.as_integer() {
|
||||
Ok(other) => self.value *= other,
|
||||
Err(_) => match other.as_float() {
|
||||
Ok(other) => self.mul_assign_f64(other),
|
||||
Err(_) => (),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,6 +154,7 @@ impl RuneValueIntWrapper {
|
|||
}
|
||||
|
||||
#[derive(Any, Clone)]
|
||||
#[rune(name = RefBool)]
|
||||
struct RuneValueBoolWrapper(bool);
|
||||
|
||||
impl RuneValueBoolWrapper {
|
||||
|
@ -178,6 +178,7 @@ impl RuneValueBoolWrapper {
|
|||
}
|
||||
|
||||
#[derive(Any, Clone, Debug)]
|
||||
#[rune(name = StringKey)]
|
||||
pub(super) struct RuneStringKey(pub StringKey);
|
||||
|
||||
impl RuneStringKey {
|
||||
|
@ -188,24 +189,39 @@ impl RuneStringKey {
|
|||
rune::vm_write!(f, "{}", self.0);
|
||||
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 {
|
||||
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)]
|
||||
mod test {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use anyhow::Result;
|
||||
use rune::diagnostics::Diagnostic;
|
||||
use rune::{Context, Diagnostics, Options, Source, Vm};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn setup_script(script: &str) -> Vm {
|
||||
let mut context = Context::with_default_modules().unwrap();
|
||||
context.install(module().unwrap()).unwrap();
|
||||
pub fn setup_script(script: &str) -> Result<Vm> {
|
||||
let mut context = Context::with_default_modules()?;
|
||||
context.install(module()?)?;
|
||||
|
||||
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 options = Options::default();
|
||||
|
@ -218,381 +234,431 @@ mod test {
|
|||
.with_context(&context)
|
||||
.with_diagnostics(&mut diagnostics)
|
||||
.with_options(&options)
|
||||
.build()
|
||||
.unwrap();
|
||||
if !diagnostics.is_empty() {
|
||||
panic!("Diagnostics: {:?}", diagnostics);
|
||||
.build();
|
||||
if !diagnostics.is_empty() && diagnostics.has_error() {
|
||||
let error_message = 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 {
|
||||
($vm:expr, $func:expr, $val:expr) => {{
|
||||
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]
|
||||
fn test_int_wrapper_set_value() {
|
||||
fn test_int_wrapper_set_value() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a.set_value(5);
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_as_int() {
|
||||
fn test_int_wrapper_as_int() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
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 = res.as_integer().unwrap();
|
||||
let res = res.as_integer()?;
|
||||
assert_eq!(res, 10);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_add() {
|
||||
fn test_int_wrapper_add() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a += 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_add_overflow() {
|
||||
fn test_int_wrapper_add_overflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a += 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MAX)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_sub() {
|
||||
fn test_int_wrapper_sub() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a -= 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_underflow() {
|
||||
fn test_int_wrapper_underflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a -= 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MIN).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MIN)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_mul() {
|
||||
fn test_int_wrapper_mul() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a *= 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_mul_float() {
|
||||
fn test_int_wrapper_mul_float() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a *= 0.5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_mul_overflow() {
|
||||
fn test_int_wrapper_mul_overflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a *= 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MAX)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_mul_float_overflow() {
|
||||
fn test_int_wrapper_mul_float_overflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a *= 10.0;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MAX)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_mul_float_underflow() {
|
||||
fn test_int_wrapper_mul_float_underflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a *= 10.0;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MIN).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MIN)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_div() {
|
||||
fn test_int_wrapper_div() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a /= 5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_div_float() {
|
||||
fn test_int_wrapper_div_float() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a /= 0.5;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(10).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(10)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_div_float_overflow() {
|
||||
fn test_int_wrapper_div_float_overflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a /= 0.0001;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MAX).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MAX)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_div_float_underflow() {
|
||||
fn test_int_wrapper_div_float_underflow() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
a /= 0.0001;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_int_reference(i64::MIN).unwrap();
|
||||
)?;
|
||||
let val = wrap_int_reference(i64::MIN)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_eq() {
|
||||
fn test_int_wrapper_eq() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
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 = res.as_bool().unwrap();
|
||||
let res = res.as_bool()?;
|
||||
assert_eq!(res, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_ineq() {
|
||||
fn test_int_wrapper_ineq() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(a) {
|
||||
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 = res.as_bool().unwrap();
|
||||
let res = res.as_bool()?;
|
||||
assert_eq!(res, false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_wrapper_string_display() {
|
||||
fn test_int_wrapper_string_display() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_int(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 = res.into_string().unwrap().take().unwrap().into_std();
|
||||
let res = res.into_string()?.into_std();
|
||||
assert_eq!(res, "5");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_wrapper_set_value() {
|
||||
fn test_bool_wrapper_set_value() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_bool(a) {
|
||||
a.set_value(true);
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = wrap_bool_reference(false).unwrap();
|
||||
)?;
|
||||
let val = wrap_bool_reference(false)?;
|
||||
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);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_wrapper_as_bool() {
|
||||
fn test_bool_wrapper_as_bool() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_bool(a) {
|
||||
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 = res.as_bool().unwrap();
|
||||
let res = res.as_bool()?;
|
||||
assert_eq!(res, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_wrapper_eq() {
|
||||
fn test_bool_wrapper_eq() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_bool(a) {
|
||||
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 = res.as_bool().unwrap();
|
||||
let res = res.as_bool()?;
|
||||
assert_eq!(res, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_wrapper_ineq() {
|
||||
fn test_bool_wrapper_ineq() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_bool(a) {
|
||||
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 = res.as_bool().unwrap();
|
||||
let res = res.as_bool()?;
|
||||
assert_eq!(res, false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_wrapper_string_display() {
|
||||
fn test_bool_wrapper_string_display() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_bool(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 = res.into_string().unwrap().take().unwrap().into_std();
|
||||
let res = res.into_string()?.into_std();
|
||||
assert_eq!(res, "true");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_key_wrapper_string_display() {
|
||||
fn test_string_key_wrapper_string_display() -> Result<()> {
|
||||
let mut vm = setup_script(
|
||||
r#"
|
||||
pub fn test_string_key(a) {
|
||||
`${a}`
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let val = RuneStringKey::new(StringKey::from("test"));
|
||||
let val = Shared::new(AnyObj::new(val).unwrap()).unwrap();
|
||||
let arg = Value::Any(val);
|
||||
)?;
|
||||
let val = StringKey::from("test");
|
||||
let arg = val.wrap();
|
||||
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");
|
||||
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::static_data::Parameter;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
@ -11,6 +11,7 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Any)]
|
||||
#[rune(name = Parameter)]
|
||||
pub(super) enum RuneParameter {
|
||||
Int(#[rune(get)] i32),
|
||||
Float(#[rune(get)] f32),
|
||||
|
@ -19,13 +20,13 @@ pub(super) enum RuneParameter {
|
|||
}
|
||||
|
||||
impl RuneWrapper for &Arc<Parameter> {
|
||||
fn wrap(self) -> Shared<AnyObj> {
|
||||
fn wrap(self) -> Value {
|
||||
let p = match self.deref() {
|
||||
Parameter::Bool(b) => RuneParameter::Bool(*b),
|
||||
Parameter::Int(i) => RuneParameter::Int(*i as i32),
|
||||
Parameter::Float(f) => RuneParameter::Float(*f),
|
||||
Parameter::String(s) => RuneParameter::String(RuneStringKey::new(s.clone())),
|
||||
};
|
||||
Shared::new(AnyObj::new(p).unwrap()).unwrap()
|
||||
rune::to_value(p).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use crate::static_data::Ability;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use crate::StringKey;
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -19,16 +20,101 @@ impl_rune_wrapper!(&Arc<dyn Ability>, RuneAbility);
|
|||
|
||||
impl RuneAbility {
|
||||
#[rune::function]
|
||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
||||
fn name(&self) -> Value { self.0.name().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn effect(&self) -> Shared<AnyObj> { self.0.effect().wrap() }
|
||||
fn effect(&self) -> Value { self.0.effect().wrap() }
|
||||
|
||||
#[rune::function(vm_result)]
|
||||
fn get_parameter(&self, key: RuneStringKey) -> Option<Shared<AnyObj>> {
|
||||
match self.0.parameters().get(&key.0) {
|
||||
None => None,
|
||||
Some(p) => Some(p.wrap()),
|
||||
#[rune::function]
|
||||
fn get_parameter(&self, key: Value) -> Option<Value> {
|
||||
if let Ok(s) = key.borrow_string_ref() {
|
||||
return self.0.parameters().get(&StringKey::new(&s)).map(|v| v.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::static_data::{AbilityIndex, Form, Statistic};
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use crate::StringKey;
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -22,13 +23,14 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Any)]
|
||||
#[rune(name = Form)]
|
||||
pub struct RuneForm(pub Arc<dyn Form>);
|
||||
|
||||
impl_rune_wrapper!(&Arc<dyn Form>, RuneForm);
|
||||
|
||||
impl RuneForm {
|
||||
#[rune::function]
|
||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
||||
fn name(&self) -> Value { self.0.name().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn height(&self) -> f32 { self.0.height() }
|
||||
|
@ -40,28 +42,286 @@ impl RuneForm {
|
|||
fn base_experience(&self) -> u32 { self.0.base_experience() }
|
||||
|
||||
#[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]
|
||||
fn base_stats(&self) -> Shared<AnyObj> { self.0.base_stats().wrap() }
|
||||
fn base_stats(&self) -> Value { self.0.base_stats().wrap() }
|
||||
|
||||
#[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]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
fn get_base_stat(&self, statistic: Statistic) -> u16 { self.0.get_base_stat(statistic) }
|
||||
|
||||
#[rune::function]
|
||||
fn get_ability(&self, hidden: bool, index: u8) -> anyhow::Result<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())
|
||||
}
|
||||
}
|
||||
|
||||
#[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 }
|
||||
|
||||
#[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())
|
||||
}
|
||||
}
|
||||
|
||||
#[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 rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
|
||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
|
@ -28,7 +28,7 @@ impl_rune_wrapper!(&Arc<dyn Item>, RuneItem);
|
|||
|
||||
impl RuneItem {
|
||||
#[rune::function]
|
||||
fn name(&self) -> Shared<AnyObj> { self.0.name().clone().wrap() }
|
||||
fn name(&self) -> Value { self.0.name().clone().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn category(&self) -> ItemCategory { self.0.category() }
|
||||
|
@ -40,8 +40,34 @@ impl RuneItem {
|
|||
fn price(&self) -> i32 { self.0.price() }
|
||||
|
||||
#[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]
|
||||
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::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use crate::static_data::LearnableMoves;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -20,14 +20,14 @@ impl_rune_wrapper!(&Arc<dyn LearnableMoves>, RuneLearnableMoves);
|
|||
|
||||
impl RuneLearnableMoves {
|
||||
#[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
|
||||
.get_learned_by_level(level)
|
||||
.map(|v| v.into_iter().map(|s| s.wrap()).collect())
|
||||
}
|
||||
|
||||
#[rune::function]
|
||||
fn get_distinct_level_moves(&self) -> Vec<Shared<AnyObj>> {
|
||||
fn get_distinct_level_moves(&self) -> Vec<Value> {
|
||||
self.0
|
||||
.get_distinct_level_moves()
|
||||
.into_iter()
|
||||
|
|
|
@ -6,7 +6,7 @@ mod type_library;
|
|||
|
||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use crate::static_data::{AbilityLibrary, ItemLibrary, MoveLibrary, SpeciesLibrary};
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||
|
@ -49,13 +49,13 @@ macro_rules! impl_rune_data_library_wrapper {
|
|||
|
||||
impl $t {
|
||||
#[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]
|
||||
fn len(&self) -> usize { self.0.len() }
|
||||
|
||||
#[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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::script_implementations::rune::wrappers::static_data::nature::RuneNature;
|
||||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use crate::static_data::NatureLibrary;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||
|
@ -18,7 +18,7 @@ impl_rune_wrapper!(&Arc<dyn NatureLibrary>, RuneNatureLibrary);
|
|||
|
||||
impl RuneNatureLibrary {
|
||||
#[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]
|
||||
fn get_nature_name(&self, nature: &RuneNature) -> RuneStringKey {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
|
||||
use crate::static_data::StaticData;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
|
||||
|
@ -23,26 +23,26 @@ impl_rune_wrapper!(&Arc<dyn StaticData>, RuneStaticData);
|
|||
|
||||
impl RuneStaticData {
|
||||
#[rune::function]
|
||||
fn settings(&self) -> Shared<AnyObj> { self.0.settings().wrap() }
|
||||
fn settings(&self) -> Value { self.0.settings().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn species(&self) -> Shared<AnyObj> { self.0.species().wrap() }
|
||||
fn species(&self) -> Value { self.0.species().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn moves(&self) -> Shared<AnyObj> { self.0.moves().wrap() }
|
||||
fn moves(&self) -> Value { self.0.moves().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn items(&self) -> Shared<AnyObj> { self.0.items().wrap() }
|
||||
fn items(&self) -> Value { self.0.items().wrap() }
|
||||
|
||||
#[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]
|
||||
fn types(&self) -> Shared<AnyObj> { self.0.types().wrap() }
|
||||
fn types(&self) -> Value { self.0.types().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn natures(&self) -> Shared<AnyObj> { self.0.natures().wrap() }
|
||||
fn natures(&self) -> Value { self.0.natures().wrap() }
|
||||
|
||||
#[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::static_data::TypeLibrary;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use std::sync::Arc;
|
||||
|
||||
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()) }
|
||||
|
||||
#[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]
|
||||
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::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
|
||||
use rune::runtime::{AnyObj, Object, Shared};
|
||||
use rune::{Any, Value};
|
||||
use rune::runtime::{Object, Value};
|
||||
use rune::Any;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -35,7 +35,7 @@ impl_rune_wrapper!(&Arc<dyn MoveData>, RuneMoveData);
|
|||
|
||||
impl RuneMoveData {
|
||||
#[rune::function]
|
||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
||||
fn name(&self) -> Value { self.0.name().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn move_type(&self) -> u8 { u8::from(self.0.move_type()) }
|
||||
|
@ -59,7 +59,7 @@ impl RuneMoveData {
|
|||
fn priority(&self) -> i8 { self.0.priority() }
|
||||
|
||||
#[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]
|
||||
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() }
|
||||
|
||||
#[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]
|
||||
fn parameters(&self) -> anyhow::Result<Object> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneStringKey, RuneWrapper};
|
||||
use crate::static_data::Species;
|
||||
use rune::runtime::{AnyObj, Shared};
|
||||
use rune::runtime::Value;
|
||||
use rune::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -29,13 +29,13 @@ impl RuneSpecies {
|
|||
fn id(&self) -> u16 { self.0.id() }
|
||||
|
||||
#[rune::function]
|
||||
fn name(&self) -> Shared<AnyObj> { self.0.name().wrap() }
|
||||
fn name(&self) -> Value { self.0.name().wrap() }
|
||||
|
||||
#[rune::function]
|
||||
fn gender_rate(&self) -> f32 { self.0.gender_rate() }
|
||||
|
||||
#[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]
|
||||
fn capture_rate(&self) -> u8 { self.0.capture_rate() }
|
||||
|
@ -44,12 +44,10 @@ impl RuneSpecies {
|
|||
fn base_happiness(&self) -> u8 { self.0.base_happiness() }
|
||||
|
||||
#[rune::function]
|
||||
fn get_form(&self, name: &RuneStringKey) -> Option<Shared<AnyObj>> {
|
||||
self.0.get_form(&name.0).map(|form| form.wrap())
|
||||
}
|
||||
fn get_form(&self, name: &RuneStringKey) -> Option<Value> { self.0.get_form(&name.0).map(|form| form.wrap()) }
|
||||
|
||||
#[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]
|
||||
fn has_flag(&self, key: &RuneStringKey) -> bool { self.0.has_flag(&key.0) }
|
||||
|
|
|
@ -12,20 +12,28 @@ use crate::StringKey;
|
|||
#[repr(u8)]
|
||||
pub enum ItemCategory {
|
||||
/// This is where most items should go.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
MiscItem,
|
||||
/// Pokeballs are used for capturing Pokemons.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Pokeball,
|
||||
/// Medicine is used for healing HP, PP, and status effects
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Medicine,
|
||||
/// Berry is used for all berries.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Berry,
|
||||
/// TMHM is used for Technical and Hidden Machines.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
TMHM,
|
||||
/// Form Changer is used for items that change forms, such as mega stones.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
FormChanger,
|
||||
/// Key Items are single stored items, generally used for story progression.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
KeyItem,
|
||||
/// Mail is used for mail items.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Mail,
|
||||
}
|
||||
|
||||
|
@ -36,14 +44,19 @@ pub enum ItemCategory {
|
|||
#[repr(u8)]
|
||||
pub enum BattleItemCategory {
|
||||
/// This item can't be used in battle.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
None,
|
||||
/// This item is used for healing Pokemon.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Healing,
|
||||
/// This item is used for healing Pokemon from a status.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
StatusHealing,
|
||||
/// This item is used for capturing Pokemon.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Pokeball,
|
||||
/// This item does not belong in above categories, but is still a battle item.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
MiscBattleItem,
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ use std::fmt::{Display, Formatter};
|
|||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
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 natures::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>;
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
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.
|
||||
fn has_flag(&self, key: &StringKey) -> bool;
|
||||
|
@ -118,56 +118,32 @@ impl FormImpl {
|
|||
|
||||
impl Form for FormImpl {
|
||||
/// The name of the form.
|
||||
fn name(&self) -> &StringKey {
|
||||
&self.name
|
||||
}
|
||||
fn name(&self) -> &StringKey { &self.name }
|
||||
/// The height of the form in meters.
|
||||
fn height(&self) -> f32 {
|
||||
self.height
|
||||
}
|
||||
fn height(&self) -> f32 { self.height }
|
||||
/// The weight of the form in kilograms.
|
||||
fn weight(&self) -> f32 {
|
||||
self.weight
|
||||
}
|
||||
fn weight(&self) -> f32 { self.weight }
|
||||
/// The base amount of experience that is gained when beating a Pokemon with this form.
|
||||
fn base_experience(&self) -> u32 {
|
||||
self.base_experience
|
||||
}
|
||||
fn base_experience(&self) -> u32 { self.base_experience }
|
||||
/// The normal types a Pokemon with this form has.
|
||||
fn types(&self) -> &Vec<TypeIdentifier> {
|
||||
&self.types
|
||||
}
|
||||
fn types(&self) -> &Vec<TypeIdentifier> { &self.types }
|
||||
/// The inherent values of a form of species that are used for the stats of a Pokemon.
|
||||
fn base_stats(&self) -> &Arc<StaticStatisticSet<u16>> {
|
||||
&self.base_stats
|
||||
}
|
||||
fn base_stats(&self) -> &Arc<StaticStatisticSet<u16>> { &self.base_stats }
|
||||
/// The possible abilities a Pokemon with this form can have.
|
||||
fn abilities(&self) -> &Vec<StringKey> {
|
||||
&self.abilities
|
||||
}
|
||||
fn abilities(&self) -> &Vec<StringKey> { &self.abilities }
|
||||
/// The possible hidden abilities a Pokemon with this form can have.
|
||||
fn hidden_abilities(&self) -> &Vec<StringKey> {
|
||||
&self.hidden_abilities
|
||||
}
|
||||
fn hidden_abilities(&self) -> &Vec<StringKey> { &self.hidden_abilities }
|
||||
|
||||
/// The moves a Pokemon with this form can learn.
|
||||
fn moves(&self) -> &Arc<dyn LearnableMoves> {
|
||||
&self.moves
|
||||
}
|
||||
fn moves(&self) -> &Arc<dyn LearnableMoves> { &self.moves }
|
||||
/// Arbitrary flags can be set on a form for scripting use.
|
||||
fn flags(&self) -> &HashSet<StringKey> {
|
||||
&self.flags
|
||||
}
|
||||
fn flags(&self) -> &HashSet<StringKey> { &self.flags }
|
||||
|
||||
/// Get a type of the move at a certain index.
|
||||
fn get_type(&self, index: usize) -> Result<TypeIdentifier> {
|
||||
Ok(*self.types.get_res(index)?)
|
||||
}
|
||||
fn get_type(&self, index: usize) -> Result<TypeIdentifier> { Ok(*self.types.get_res(index)?) }
|
||||
|
||||
/// Gets a single base stat value.
|
||||
fn get_base_stat(&self, stat: Statistic) -> u16 {
|
||||
self.base_stats.get_stat(stat)
|
||||
}
|
||||
fn get_base_stat(&self, stat: Statistic) -> u16 { self.base_stats.get_stat(stat) }
|
||||
|
||||
/// Find the index of an ability that can be on this form.
|
||||
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex> {
|
||||
|
@ -191,39 +167,35 @@ impl Form for FormImpl {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
Ok(self.hidden_abilities.get_res(index.index as usize)?)
|
||||
self.hidden_abilities.get_res(index.index as usize).map(|s| s.clone())
|
||||
} 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.
|
||||
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");
|
||||
self.abilities
|
||||
.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.
|
||||
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");
|
||||
self.hidden_abilities
|
||||
.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.
|
||||
fn has_flag(&self, key: &StringKey) -> bool {
|
||||
self.flags.contains(key)
|
||||
}
|
||||
fn has_flag(&self, key: &StringKey) -> bool { self.flags.contains(key) }
|
||||
|
||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool {
|
||||
self.flags.contains::<u32>(&key_hash)
|
||||
}
|
||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool { self.flags.contains::<u32>(&key_hash) }
|
||||
|
||||
fn eq(&self, other: &dyn Form) -> bool {
|
||||
std::ptr::eq(self, other as *const dyn Form as *const Self)
|
||||
}
|
||||
fn eq(&self, other: &dyn Form) -> bool { std::ptr::eq(self, other as *const dyn Form as *const Self) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -249,9 +221,9 @@ pub(crate) mod tests {
|
|||
fn get_type(&self, index: usize) -> Result<TypeIdentifier>;
|
||||
fn get_base_stat(&self, stat: Statistic) -> u16;
|
||||
fn find_ability_index(&self, ability: &dyn Ability) -> Option<AbilityIndex>;
|
||||
fn get_ability<'a>(&'a self, index: AbilityIndex) -> Result<&'a StringKey>;
|
||||
fn get_random_ability<'a>(&'a self, rand: &mut Random) -> Result<&'a StringKey>;
|
||||
fn get_random_hidden_ability<'a>(&'a self, rand: &mut Random) -> Result<&'a StringKey>;
|
||||
fn get_ability(&self, index: AbilityIndex) -> Result<StringKey>;
|
||||
fn get_random_ability(&self, rand: &mut Random) -> Result<StringKey>;
|
||||
fn get_random_hidden_ability(&self, rand: &mut Random) -> Result<StringKey>;
|
||||
fn has_flag(&self, key: &StringKey) -> bool;
|
||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
|
||||
fn eq(&self, other: &dyn Form) -> bool;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
pub(crate) mod tests {
|
||||
pub use super::form::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.
|
||||
|
|
|
@ -7,15 +7,21 @@
|
|||
#[repr(u8)]
|
||||
pub enum Statistic {
|
||||
/// Health Points determine how much damage a Pokemon can receive before fainting.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
HP,
|
||||
/// Attack determines how much damage a Pokemon deals when using a physical attack.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Attack,
|
||||
/// Defense determines how much damage a Pokemon receives when it is hit by a physical attack.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Defense,
|
||||
/// Special Attack determines how much damage a Pokemon deals when using a special attack.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
SpecialAttack,
|
||||
/// Special Defense determines how much damage a Pokemon receives when it is hit by a special attack.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
SpecialDefense,
|
||||
/// Speed determines the order that a Pokemon can act in battle.
|
||||
#[cfg_attr(feature = "rune", rune(constructor))]
|
||||
Speed,
|
||||
}
|
||||
|
|
|
@ -10,12 +10,10 @@ fn integration_tests(input: &Path) {
|
|||
let mut str: String = "".to_string();
|
||||
let mut file = File::open(input).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);
|
||||
test_case.run_test(get_library());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic_single_turn() {
|
||||
integration_tests(Path::new("tests/test_cases/basic_single_turn.yaml"));
|
||||
}
|
||||
fn basic_single_turn() { integration_tests(Path::new("tests/test_cases/basic_single_turn.yaml")); }
|
||||
|
|
Loading…
Reference in New Issue