Loads of cleanup
continuous-integration/drone/push Build was killed
Details
continuous-integration/drone/push Build was killed
Details
This commit is contained in:
parent
aa3ceaed3e
commit
efd1acdfa5
|
@ -14,7 +14,7 @@ path = "src/lib.rs"
|
||||||
[features]
|
[features]
|
||||||
ffi = []
|
ffi = []
|
||||||
serde = ["dep:serde"]
|
serde = ["dep:serde"]
|
||||||
wasm = ["dep:wasmer", "dep:unique-type-id", "dep:unique-type-id-derive"]
|
wasm = ["dep:wasmer"]
|
||||||
default = ["serde", "wasm", "ffi"]
|
default = ["serde", "wasm", "ffi"]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
@ -53,8 +53,7 @@ indexmap = "1.8.2"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
||||||
wasmer = { version = "3.0.0-beta", optional = true, default-features = true }
|
wasmer = { version = "3.0.0-beta", optional = true, default-features = true }
|
||||||
unique-type-id = { version = "1.0.0", optional = true }
|
uuid = "1.2.2"
|
||||||
unique-type-id-derive = { version = "1.0.0", optional = true }
|
|
||||||
paste = { version = "1.0.8" }
|
paste = { version = "1.0.8" }
|
||||||
arcstr = { version = "1.1.4", features = ["std"] }
|
arcstr = { version = "1.1.4", features = ["std"] }
|
||||||
enum-display-derive = "0.1.1"
|
enum-display-derive = "0.1.1"
|
||||||
|
|
|
@ -32,7 +32,6 @@ struct CommonChoiceData {
|
||||||
|
|
||||||
/// This enum defines a single choice for a Pokemon for a battle turn.
|
/// This enum defines a single choice for a Pokemon for a battle turn.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub enum TurnChoice {
|
pub enum TurnChoice {
|
||||||
/// A move choice tells a Pokemon to use a move on a target for this turn.
|
/// A move choice tells a Pokemon to use a move on a target for this turn.
|
||||||
Move(MoveChoice),
|
Move(MoveChoice),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::dynamic_data::choices::TurnChoice;
|
use crate::dynamic_data::choices::TurnChoice;
|
||||||
use crate::dynamic_data::script_handling::ScriptSource;
|
use crate::dynamic_data::script_handling::ScriptSource;
|
||||||
use crate::dynamic_data::Pokemon;
|
use crate::dynamic_data::Pokemon;
|
||||||
use crate::{script_hook, ValueIdentifiable};
|
use crate::{script_hook, ValueIdentifiable, ValueIdentifier};
|
||||||
use parking_lot::lock_api::MappedRwLockReadGuard;
|
use parking_lot::lock_api::MappedRwLockReadGuard;
|
||||||
use parking_lot::{RawRwLock, RwLock, RwLockReadGuard};
|
use parking_lot::{RawRwLock, RwLock, RwLockReadGuard};
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@ use parking_lot::{RawRwLock, RwLock, RwLockReadGuard};
|
||||||
/// helper functions to change the turn order while doing the execution. This is needed, as several
|
/// helper functions to change the turn order while doing the execution. This is needed, as several
|
||||||
/// moves in Pokemon actively mess with this order.
|
/// moves in Pokemon actively mess with this order.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct ChoiceQueue {
|
pub struct ChoiceQueue {
|
||||||
|
/// A unique identifier so we know what value this is.
|
||||||
|
identifier: ValueIdentifier,
|
||||||
/// Our storage of turn choices. Starts out completely filled, then slowly empties as turns get
|
/// Our storage of turn choices. Starts out completely filled, then slowly empties as turns get
|
||||||
/// executed.
|
/// executed.
|
||||||
queue: RwLock<Vec<Option<TurnChoice>>>,
|
queue: RwLock<Vec<Option<TurnChoice>>>,
|
||||||
|
@ -26,6 +28,7 @@ impl ChoiceQueue {
|
||||||
pub(crate) fn new(mut queue: Vec<Option<TurnChoice>>) -> Self {
|
pub(crate) fn new(mut queue: Vec<Option<TurnChoice>>) -> Self {
|
||||||
queue.sort_unstable_by(|a, b| b.cmp(a));
|
queue.sort_unstable_by(|a, b| b.cmp(a));
|
||||||
Self {
|
Self {
|
||||||
|
identifier: Default::default(),
|
||||||
queue: RwLock::new(queue),
|
queue: RwLock::new(queue),
|
||||||
current: 0,
|
current: 0,
|
||||||
}
|
}
|
||||||
|
@ -119,6 +122,12 @@ impl ChoiceQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ValueIdentifiable for ChoiceQueue {
|
||||||
|
fn value_identifier(&self) -> ValueIdentifier {
|
||||||
|
self.identifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -14,7 +14,6 @@ use crate::{PkmnResult, StringKey, ValueIdentifiable, ValueIdentifier};
|
||||||
/// The dynamic library stores a static data library, as well as holding different libraries and
|
/// The dynamic library stores a static data library, as well as holding different libraries and
|
||||||
/// calculators that might be customized between different generations and implementations.
|
/// calculators that might be customized between different generations and implementations.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct DynamicLibrary {
|
pub struct DynamicLibrary {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
@ -87,7 +86,7 @@ impl DynamicLibrary {
|
||||||
/// Loads an item script with the given unique key. If no script can be created with this
|
/// Loads an item script with the given unique key. If no script can be created with this
|
||||||
/// combinations, returns None. Note that ItemScripts are immutable, as their script should be
|
/// combinations, returns None. Note that ItemScripts are immutable, as their script should be
|
||||||
/// shared between all different usages.
|
/// shared between all different usages.
|
||||||
pub fn load_item_script(&self, _key: &Arc<Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
pub fn load_item_script(&self, _key: &Arc<dyn Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub trait ScriptResolver: Debug + ValueIdentifiable {
|
||||||
/// Loads an item script with the given unique key. If no script can be created with this
|
/// Loads an item script with the given unique key. If no script can be created with this
|
||||||
/// combinations, returns None. Note that ItemScripts are immutable, as their script should be
|
/// combinations, returns None. Note that ItemScripts are immutable, as their script should be
|
||||||
/// shared between all different usages.
|
/// shared between all different usages.
|
||||||
fn load_item_script(&self, _key: &Item) -> PkmnResult<Option<Arc<dyn ItemScript>>>;
|
fn load_item_script(&self, _key: &dyn Item) -> PkmnResult<Option<Arc<dyn ItemScript>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
@ -77,7 +77,7 @@ impl ScriptResolver for EmptyScriptResolver {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_item_script(&self, _key: &Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
fn load_item_script(&self, _key: &dyn Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ use crate::{script_hook, PkmnResult, StringKey, ValueIdentifiable, ValueIdentifi
|
||||||
|
|
||||||
/// A pokemon battle, with any amount of sides and pokemon per side.
|
/// A pokemon battle, with any amount of sides and pokemon per side.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct Battle {
|
pub struct Battle {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
/// A battle party is a wrapper around a party, with the indices for which the party is responsible
|
/// A battle party is a wrapper around a party, with the indices for which the party is responsible
|
||||||
/// on the field attached.
|
/// on the field attached.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct BattleParty {
|
pub struct BattleParty {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -9,7 +9,6 @@ use crate::{script_hook, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// The RNG for a battle.
|
/// The RNG for a battle.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct BattleRandom {
|
pub struct BattleRandom {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -18,7 +18,6 @@ use crate::{script_hook, PkmnResult, StringKey, ValueIdentifiable, ValueIdentifi
|
||||||
|
|
||||||
/// A side on a battle.
|
/// A side on a battle.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct BattleSide {
|
pub struct BattleSide {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -11,12 +11,14 @@ use crate::dynamic_data::script_handling::{ScriptSource, ScriptSourceData, Scrip
|
||||||
use crate::dynamic_data::ScriptContainer;
|
use crate::dynamic_data::ScriptContainer;
|
||||||
use crate::dynamic_data::TargetList;
|
use crate::dynamic_data::TargetList;
|
||||||
use crate::static_data::{MoveData, TypeIdentifier};
|
use crate::static_data::{MoveData, TypeIdentifier};
|
||||||
use crate::{PkmnResult, PokemonError};
|
use crate::{PkmnResult, PokemonError, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// A hit data is the data for a single hit, on a single target.
|
/// A hit data is the data for a single hit, on a single target.
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct HitData {
|
pub struct HitData {
|
||||||
|
/// A unique identifier so we know what value this is.
|
||||||
|
identifier: ValueIdentifier,
|
||||||
/// Whether or not the hit is critical.
|
/// Whether or not the hit is critical.
|
||||||
critical: AtomicBool,
|
critical: AtomicBool,
|
||||||
/// The base power of the hit.
|
/// The base power of the hit.
|
||||||
|
@ -85,8 +87,10 @@ impl HitData {
|
||||||
|
|
||||||
/// An executing move is the data of the move for while it is executing.
|
/// An executing move is the data of the move for while it is executing.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct ExecutingMove {
|
pub struct ExecutingMove {
|
||||||
|
/// A unique identifier so we know what value this is.
|
||||||
|
identifier: ValueIdentifier,
|
||||||
/// The number of hits this move has.
|
/// The number of hits this move has.
|
||||||
number_of_hits: u8,
|
number_of_hits: u8,
|
||||||
/// A list of hits for this move. For multi target multi hit moves, this stores the hits linearly,
|
/// A list of hits for this move. For multi target multi hit moves, this stores the hits linearly,
|
||||||
|
@ -122,6 +126,7 @@ impl ExecutingMove {
|
||||||
hits.push(HitData::default())
|
hits.push(HitData::default())
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
|
identifier: Default::default(),
|
||||||
number_of_hits,
|
number_of_hits,
|
||||||
hits,
|
hits,
|
||||||
user,
|
user,
|
||||||
|
@ -218,3 +223,15 @@ impl ScriptSource for ExecutingMove {
|
||||||
self.user.get_own_scripts(scripts);
|
self.user.get_own_scripts(scripts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ValueIdentifiable for ExecutingMove {
|
||||||
|
fn value_identifier(&self) -> ValueIdentifier {
|
||||||
|
self.identifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ValueIdentifiable for HitData {
|
||||||
|
fn value_identifier(&self) -> ValueIdentifier {
|
||||||
|
self.identifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
/// A learned move is the data attached to a Pokemon for a move it has learned. It has information
|
/// A learned move is the data attached to a Pokemon for a move it has learned. It has information
|
||||||
/// such as the remaining amount of users, how it has been learned, etc.
|
/// such as the remaining amount of users, how it has been learned, etc.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct LearnedMove {
|
pub struct LearnedMove {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -26,7 +26,6 @@ use crate::{script_hook, PkmnResult, StringKey, ValueIdentifiable, ValueIdentifi
|
||||||
|
|
||||||
/// An individual Pokemon as we know and love them.
|
/// An individual Pokemon as we know and love them.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct Pokemon {
|
pub struct Pokemon {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
@ -57,7 +56,7 @@ pub struct Pokemon {
|
||||||
/// currently not used, and can be used for other implementations.
|
/// currently not used, and can be used for other implementations.
|
||||||
coloring: u8,
|
coloring: u8,
|
||||||
/// The held item of the Pokemon.
|
/// The held item of the Pokemon.
|
||||||
held_item: RwLock<Option<Arc<Item>>>,
|
held_item: RwLock<Option<Arc<dyn Item>>>,
|
||||||
/// The remaining health points of the Pokemon.
|
/// The remaining health points of the Pokemon.
|
||||||
current_health: AtomicU32,
|
current_health: AtomicU32,
|
||||||
|
|
||||||
|
@ -238,7 +237,7 @@ impl Pokemon {
|
||||||
self.coloring
|
self.coloring
|
||||||
}
|
}
|
||||||
/// Gets the held item of a Pokemon
|
/// Gets the held item of a Pokemon
|
||||||
pub fn held_item(&self) -> &RwLock<Option<Arc<Item>>> {
|
pub fn held_item(&self) -> &RwLock<Option<Arc<dyn Item>>> {
|
||||||
&self.held_item
|
&self.held_item
|
||||||
}
|
}
|
||||||
/// Checks whether the Pokemon is holding a specific item.
|
/// Checks whether the Pokemon is holding a specific item.
|
||||||
|
@ -250,11 +249,11 @@ impl Pokemon {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
/// Changes the held item of the Pokemon. Returns the previously held item.
|
/// Changes the held item of the Pokemon. Returns the previously held item.
|
||||||
pub fn set_held_item(&self, item: &Arc<Item>) -> Option<Arc<Item>> {
|
pub fn set_held_item(&self, item: &Arc<dyn Item>) -> Option<Arc<dyn Item>> {
|
||||||
self.held_item.write().replace(item.clone())
|
self.held_item.write().replace(item.clone())
|
||||||
}
|
}
|
||||||
/// Removes the held item from the Pokemon. Returns the previously held item.
|
/// Removes the held item from the Pokemon. Returns the previously held item.
|
||||||
pub fn remove_held_item(&self) -> Option<Arc<Item>> {
|
pub fn remove_held_item(&self) -> Option<Arc<dyn Item>> {
|
||||||
self.held_item.write().take()
|
self.held_item.write().take()
|
||||||
}
|
}
|
||||||
/// Makes the Pokemon uses its held item.
|
/// Makes the Pokemon uses its held item.
|
||||||
|
@ -524,7 +523,7 @@ impl Pokemon {
|
||||||
.set(ability_script)
|
.set(ability_script)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
// Ensure the ability script gets initialized with the parameters for the ability.
|
// Ensure the ability script gets initialized with the parameters for the ability.
|
||||||
.on_initialize(self.library.as_ref(), self.active_ability().parameters())
|
.on_initialize(self.library.as_ref(), self.active_ability().parameters().to_vec())
|
||||||
} else {
|
} else {
|
||||||
self.ability_script.clear();
|
self.ability_script.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// A list of Pokemon belonging to a trainer.
|
/// A list of Pokemon belonging to a trainer.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct PokemonParty {
|
pub struct PokemonParty {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub trait Script: Send + Sync {
|
||||||
/// This function is ran when this script stops being in effect, and is removed from its owner.
|
/// This function is ran when this script stops being in effect, and is removed from its owner.
|
||||||
fn on_remove(&self) {}
|
fn on_remove(&self) {}
|
||||||
/// This function is ran when this script starts being in effect.
|
/// This function is ran when this script starts being in effect.
|
||||||
fn on_initialize(&self, _library: &DynamicLibrary, _pars: &[EffectParameter]) {}
|
fn on_initialize(&self, _library: &DynamicLibrary, _pars: Vec<EffectParameter>) {}
|
||||||
/// This function is ran just before the start of the turn. Everyone has made its choices here,
|
/// This function is ran just before the start of the turn. Everyone has made its choices here,
|
||||||
/// and the turn is about to start. This is a great place to initialize data if you need to know
|
/// and the turn is about to start. This is a great place to initialize data if you need to know
|
||||||
/// something has happened during a turn.
|
/// something has happened during a turn.
|
||||||
|
@ -240,7 +240,7 @@ pub trait Script: Send + Sync {
|
||||||
fn on_switch_in(&self, _pokemon: &Pokemon) {}
|
fn on_switch_in(&self, _pokemon: &Pokemon) {}
|
||||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the
|
/// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the
|
||||||
/// held item it had.
|
/// held item it had.
|
||||||
fn on_after_held_item_consume(&self, _pokemon: &Pokemon, _item: &Item) {}
|
fn on_after_held_item_consume(&self, _pokemon: &Pokemon, _item: &dyn Item) {}
|
||||||
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
/// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience,
|
||||||
/// and allows for changing this amount of experience.
|
/// and allows for changing this amount of experience.
|
||||||
fn change_experience_gained(&self, _fainted_mon: &Pokemon, _winning_mon: &Pokemon, _amount: &mut u32) {}
|
fn change_experience_gained(&self, _fainted_mon: &Pokemon, _winning_mon: &Pokemon, _amount: &mut u32) {}
|
||||||
|
@ -253,7 +253,7 @@ pub trait Script: Send + Sync {
|
||||||
/// This function is called when a Pokeball is thrown at a Pokemon, and allows modifying the catch
|
/// This function is called when a Pokeball is thrown at a Pokemon, and allows modifying the catch
|
||||||
/// rate of this attempt. Pokeball modifier effects should be implemented here, as well as for
|
/// rate of this attempt. Pokeball modifier effects should be implemented here, as well as for
|
||||||
/// example status effects that change capture rates.
|
/// example status effects that change capture rates.
|
||||||
fn change_capture_rate_bonus(&self, _target: &Pokemon, _pokeball: &Item, _modifier: &mut u8) {}
|
fn change_capture_rate_bonus(&self, _target: &Pokemon, _pokeball: &dyn Item, _modifier: &mut u8) {}
|
||||||
|
|
||||||
/// Helper function to turn the self into an Any for downcasting.
|
/// Helper function to turn the self into an Any for downcasting.
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
|
|
@ -84,7 +84,7 @@ ffi_arc_getter!(Pokemon, coloring, u8);
|
||||||
|
|
||||||
/// Gets the held item of a Pokemon
|
/// Gets the held item of a Pokemon
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<dyn Item>> {
|
||||||
if let Some(v) = ptr.as_ref().held_item().read().as_ref() {
|
if let Some(v) = ptr.as_ref().held_item().read().as_ref() {
|
||||||
v.clone().into()
|
v.clone().into()
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,8 +103,8 @@ extern "C" fn pokemon_has_held_item(ptr: ExternPointer<Arc<Pokemon>>, name: *con
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_set_held_item(
|
extern "C" fn pokemon_set_held_item(
|
||||||
ptr: ExternPointer<Arc<Pokemon>>,
|
ptr: ExternPointer<Arc<Pokemon>>,
|
||||||
item: ExternPointer<Arc<Item>>,
|
item: ExternPointer<Arc<dyn Item>>,
|
||||||
) -> IdentifiablePointer<Arc<Item>> {
|
) -> IdentifiablePointer<Arc<dyn Item>> {
|
||||||
if let Some(v) = ptr.as_ref().set_held_item(item.as_ref()) {
|
if let Some(v) = ptr.as_ref().set_held_item(item.as_ref()) {
|
||||||
v.into()
|
v.into()
|
||||||
} else {
|
} else {
|
||||||
|
@ -114,7 +114,7 @@ extern "C" fn pokemon_set_held_item(
|
||||||
|
|
||||||
/// Removes the held item from the Pokemon. Returns the previously held item.
|
/// Removes the held item from the Pokemon. Returns the previously held item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_remove_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
extern "C" fn pokemon_remove_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<dyn Item>> {
|
||||||
if let Some(v) = ptr.as_ref().remove_held_item() {
|
if let Some(v) = ptr.as_ref().remove_held_item() {
|
||||||
v.into()
|
v.into()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -129,9 +129,9 @@ impl<T> From<*mut T> for ExternPointer<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
|
impl<T: ValueIdentifiable + ?Sized> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
|
||||||
fn from(v: Arc<T>) -> Self {
|
fn from(v: Arc<T>) -> Self {
|
||||||
let id = unsafe { transmute(v.value_identifier()) };
|
let id = v.value_identifier().value();
|
||||||
Self {
|
Self {
|
||||||
ptr: Box::into_raw(Box::new(v)),
|
ptr: Box::into_raw(Box::new(v)),
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::ffi::{ffi_arc_getter, ExternPointer, IdentifiablePointer, OwnedPtr};
|
use crate::ffi::{ffi_arc_getter, ExternPointer, IdentifiablePointer, OwnedPtr};
|
||||||
use crate::static_data::{BattleItemCategory, Item, ItemCategory};
|
use crate::static_data::{BattleItemCategory, Item, ItemCategory, ItemImpl};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
|
@ -15,36 +15,38 @@ unsafe extern "C" fn item_new(
|
||||||
price: i32,
|
price: i32,
|
||||||
flags: *const *const c_char,
|
flags: *const *const c_char,
|
||||||
flags_length: usize,
|
flags_length: usize,
|
||||||
) -> IdentifiablePointer<Arc<Item>> {
|
) -> IdentifiablePointer<Arc<dyn Item>> {
|
||||||
let flags = std::slice::from_raw_parts(flags, flags_length);
|
let flags = std::slice::from_raw_parts(flags, flags_length);
|
||||||
let name: StringKey = CStr::from_ptr(name).to_str().unwrap().into();
|
let name: StringKey = CStr::from_ptr(name).to_str().unwrap().into();
|
||||||
let mut flags_set: HashSet<StringKey> = HashSet::with_capacity(flags_length);
|
let mut flags_set: HashSet<StringKey> = HashSet::with_capacity(flags_length);
|
||||||
for flag in flags {
|
for flag in flags {
|
||||||
flags_set.insert(CStr::from_ptr(*flag).to_str().unwrap().into());
|
flags_set.insert(CStr::from_ptr(*flag).to_str().unwrap().into());
|
||||||
}
|
}
|
||||||
Arc::new(Item::new(&name, category, battle_category, price, flags_set)).into()
|
|
||||||
|
let item: Arc<dyn Item> = Arc::new(ItemImpl::new(&name, category, battle_category, price, flags_set));
|
||||||
|
item.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drops a reference counted item.
|
/// Drops a reference counted item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_drop(ptr: OwnedPtr<Arc<Item>>) {
|
unsafe extern "C" fn item_drop(ptr: OwnedPtr<Arc<dyn Item>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The name of the item.
|
/// The name of the item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_name(ptr: ExternPointer<Arc<Item>>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn item_name(ptr: ExternPointer<Arc<dyn Item>>) -> OwnedPtr<c_char> {
|
||||||
let name = ptr.as_ref().name();
|
let name = ptr.as_ref().name();
|
||||||
CString::new(name.str()).unwrap().into_raw()
|
CString::new(name.str()).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi_arc_getter!(Item, category, ItemCategory);
|
ffi_arc_getter!(dyn Item, category, ItemCategory);
|
||||||
ffi_arc_getter!(Item, battle_category, BattleItemCategory);
|
ffi_arc_getter!(dyn Item, battle_category, BattleItemCategory);
|
||||||
ffi_arc_getter!(Item, price, i32);
|
ffi_arc_getter!(dyn Item, price, i32);
|
||||||
|
|
||||||
/// Checks whether the item has a specific flag.
|
/// Checks whether the item has a specific flag.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_has_flag(ptr: ExternPointer<Arc<Item>>, flag: *const c_char) -> u8 {
|
unsafe extern "C" fn item_has_flag(ptr: ExternPointer<Arc<dyn Item>>, flag: *const c_char) -> u8 {
|
||||||
let flag = CStr::from_ptr(flag).into();
|
let flag = CStr::from_ptr(flag).into();
|
||||||
u8::from(ptr.as_ref().has_flag(&flag))
|
u8::from(ptr.as_ref().has_flag(&flag))
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,4 +75,4 @@ macro_rules! library_interface {
|
||||||
library_interface!(SpeciesLibrary, Species);
|
library_interface!(SpeciesLibrary, Species);
|
||||||
library_interface!(MoveLibrary, MoveData);
|
library_interface!(MoveLibrary, MoveData);
|
||||||
library_interface!(AbilityLibrary, Ability);
|
library_interface!(AbilityLibrary, Ability);
|
||||||
library_interface!(ItemLibrary, Item);
|
library_interface!(ItemLibrary, dyn Item);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// The too many arguments is annoying, especially for when we create constructor, disable.
|
|
||||||
#![allow(clippy::too_many_arguments, clippy::needless_range_loop)]
|
#![allow(clippy::too_many_arguments, clippy::needless_range_loop)]
|
||||||
#![allow(clippy::not_unsafe_ptr_arg_deref)]
|
#![allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(clippy::missing_docs_in_private_items)]
|
#![deny(clippy::missing_docs_in_private_items)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
#![feature(fn_traits)]
|
#![feature(fn_traits)]
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
|
|
||||||
//! PkmnLib
|
//! PkmnLib
|
||||||
//! PkmnLib is a full featured implementation of Pokemon. while currently focused on implementing
|
//! PkmnLib is a full featured implementation of Pokemon. while currently focused on implementing
|
||||||
|
|
|
@ -77,7 +77,7 @@ register! {
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
script_ptr: u32
|
script_ptr: u32
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let side = side.value_func(&env).unwrap();
|
let side : &BattleSide = side.value_func(&env).unwrap();
|
||||||
unsafe{
|
unsafe{
|
||||||
let env = env.data().data();
|
let env = env.data().data();
|
||||||
let name_ptr = env.script_function_cache().script_get_name(&env).unwrap().call(&mut env.store_mut(), script_ptr).unwrap();
|
let name_ptr = env.script_function_cache().script_get_name(&env).unwrap().call(&mut env.store_mut(), script_ptr).unwrap();
|
||||||
|
|
|
@ -44,9 +44,9 @@ register! {
|
||||||
let script = env.data().data().get_loaded_script(script);
|
let script = env.data().data().get_loaded_script(script);
|
||||||
if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
match script.get_owner() {
|
match script.get_owner() {
|
||||||
ScriptOwnerData::Pokemon(p) => env.data().data().get_extern_ref_index(p.load(Ordering::Relaxed).as_ref().unwrap()),
|
ScriptOwnerData::Pokemon(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::Pokemon>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||||
ScriptOwnerData::BattleSide(p) => env.data().data().get_extern_ref_index(p.load(Ordering::Relaxed).as_ref().unwrap()),
|
ScriptOwnerData::BattleSide(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::BattleSide>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||||
ScriptOwnerData::Battle(p) => env.data().data().get_extern_ref_index(p.load(Ordering::Relaxed).as_ref().unwrap()),
|
ScriptOwnerData::Battle(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::Battle>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||||
ScriptOwnerData::None => 0,
|
ScriptOwnerData::None => 0,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,7 +16,7 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<DynamicLibrary> {
|
) -> ExternRef<DynamicLibrary> {
|
||||||
let lib = pokemon.value_func(&env).unwrap().library();
|
let lib = pokemon.value_func(&env).unwrap().library().as_ref();
|
||||||
ExternRef::func_new(&env, lib)
|
ExternRef::func_new(&env, lib)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ register! {
|
||||||
fn pokemon_get_held_item(
|
fn pokemon_get_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<Item> {
|
) -> ExternRef<dyn Item> {
|
||||||
let read_lock = pokemon.value_func(&env).unwrap().held_item().read();
|
let read_lock = pokemon.value_func(&env).unwrap().held_item().read();
|
||||||
if let Some(item) = read_lock.as_ref() {
|
if let Some(item) = read_lock.as_ref() {
|
||||||
ExternRef::func_new(&env, item.as_ref())
|
ExternRef::func_new(&env, item.as_ref())
|
||||||
|
@ -231,7 +231,7 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
script_ptr: u32
|
script_ptr: u32
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let pokemon = pokemon.value_func(&env).unwrap();
|
let pokemon : &Pokemon = pokemon.value_func(&env).unwrap();
|
||||||
unsafe{
|
unsafe{
|
||||||
let env = env.data().data();
|
let env = env.data().data();
|
||||||
let name_ptr = env.script_function_cache().script_get_name(&env).unwrap().call(&mut env.store_mut(), script_ptr).unwrap();
|
let name_ptr = env.script_function_cache().script_get_name(&env).unwrap().call(&mut env.store_mut(), script_ptr).unwrap();
|
||||||
|
|
|
@ -109,7 +109,9 @@ fn _error(env: FunctionEnvMut<WebAssemblyEnv>, message: u32, file: u32, line: u3
|
||||||
|
|
||||||
/// Get a single item from an earlier passed VecExternRef
|
/// Get a single item from an earlier passed VecExternRef
|
||||||
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> u32 {
|
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> u32 {
|
||||||
env.data().data().get_extern_vec_ref_extern_ref(reference, index)
|
env.data()
|
||||||
|
.data()
|
||||||
|
.get_extern_vec_ref_extern_ref(reference as usize, index as usize) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the hash value of a StringKey.
|
/// Gets the hash value of a StringKey.
|
||||||
|
|
|
@ -1,38 +1,62 @@
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::Item;
|
use crate::static_data::{DataLibrary, Item, ItemLibrary};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
fn item_library_get_item(
|
||||||
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
lib: ExternRef<ItemLibrary>,
|
||||||
|
string_key: ExternRef<StringKey>,
|
||||||
|
) -> ExternRef<dyn Item> {
|
||||||
|
let lib = lib.value_func(&env).unwrap();
|
||||||
|
let m = lib.get(string_key.value_func(&env).unwrap());
|
||||||
|
if let Some(v) = m {
|
||||||
|
ExternRef::func_new(&env, v)
|
||||||
|
} else {
|
||||||
|
ExternRef::null()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn item_library_get_item_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<ItemLibrary>, hash: u32) -> ExternRef<dyn Item> {
|
||||||
|
let lib = lib.value_func(&env).unwrap();
|
||||||
|
let m = lib.get_by_hash(hash);
|
||||||
|
if let Some(v) = m {
|
||||||
|
ExternRef::func_new(&env, v)
|
||||||
|
} else {
|
||||||
|
ExternRef::null()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn item_get_price(
|
fn item_get_price(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
item: ExternRef<Item>,
|
item: ExternRef<dyn Item>,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
item.value_func(&env).unwrap().price()
|
item.value_func_arc(&env).unwrap().price()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_get_name(
|
fn item_get_name(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
item: ExternRef<Item>,
|
item: ExternRef<dyn Item>,
|
||||||
) -> ExternRef<StringKey> {
|
) -> ExternRef<StringKey> {
|
||||||
ExternRef::func_new(&env, item.value_func(&env).unwrap().name())
|
ExternRef::func_new(&env, item.value_func_arc(&env).unwrap().name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_get_category(
|
fn item_get_category(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
item: ExternRef<Item>,
|
item: ExternRef<dyn Item>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
unsafe { transmute(item.value_func(&env).unwrap().category()) }
|
unsafe { transmute(item.value_func_arc(&env).unwrap().category()) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_get_battle_category(
|
fn item_get_battle_category(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
item: ExternRef<Item>,
|
item: ExternRef<dyn Item>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
unsafe { transmute(item.value_func(&env).unwrap().battle_category()) }
|
unsafe { transmute(item.value_func_arc(&env).unwrap().battle_category()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::ValueIdentifiable;
|
||||||
|
use std::any::Any;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -5,7 +7,6 @@ use std::sync::Arc;
|
||||||
use crate::script_implementations::wasm::script_resolver::{
|
use crate::script_implementations::wasm::script_resolver::{
|
||||||
WebAssemblyEnv, WebAssemblyEnvironmentData, WebAssemblyScriptResolver,
|
WebAssemblyEnv, WebAssemblyEnvironmentData, WebAssemblyScriptResolver,
|
||||||
};
|
};
|
||||||
use unique_type_id::UniqueTypeId;
|
|
||||||
use wasmer::FromToNativeWasmType;
|
use wasmer::FromToNativeWasmType;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -13,36 +14,36 @@ use wasmer::FunctionEnvMut;
|
||||||
/// requiring us to make copies. Instead, we pass a simple increment index, that we can then use
|
/// requiring us to make copies. Instead, we pass a simple increment index, that we can then use
|
||||||
/// to find the relevant data.
|
/// to find the relevant data.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub(crate) struct ExternRef<T: UniqueTypeId<u64>> {
|
pub(crate) struct ExternRef<T: ?Sized> {
|
||||||
/// The lookup index we can use to find the data.
|
/// The lookup index we can use to find the data.
|
||||||
index: u32,
|
index: usize,
|
||||||
/// Phantom data so we can get a type generic.
|
/// Phantom data so we can get a type generic.
|
||||||
_phantom: PhantomData<T>,
|
_phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
||||||
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
|
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
|
||||||
/// this data and type, we use that instead.
|
/// this data and type, we use that instead.
|
||||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &T) -> Self {
|
pub fn new(env: &WebAssemblyEnvironmentData, value: &dyn Any) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: env.get_extern_ref_index(value),
|
index: env.get_extern_ref_index::<T>(value),
|
||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiates a new ExternRef for a bit of data using the function environment. If we already
|
/// Instantiates a new ExternRef for a bit of data using the function environment. If we already
|
||||||
/// have made an Extern Ref for this data and type, we use that instead.
|
/// have made an Extern Ref for this data and type, we use that instead.
|
||||||
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: &T) -> Self {
|
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: &dyn Any) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: env.data().data().get_extern_ref_index(value),
|
index: env.data().data().get_extern_ref_index::<T>(value),
|
||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
||||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self {
|
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &dyn Any) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: resolver.environment_data().get_extern_ref_index(value),
|
index: resolver.environment_data().get_extern_ref_index::<T>(value),
|
||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,24 +58,49 @@ impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||||
/// value when it was passed before. If these types do not match, this will panic.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value_func<'a, 'b>(&'a self, env: &'b FunctionEnvMut<WebAssemblyEnv>) -> Option<&'b T> {
|
pub fn value_func<'a, 'b>(&'a self, env: &'b FunctionEnvMut<WebAssemblyEnv>) -> Option<&'b T>
|
||||||
|
where
|
||||||
|
T: Sized + 'static,
|
||||||
|
{
|
||||||
self.value(&env.data().data())
|
self.value(&env.data().data())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||||
/// value when it was passed before. If these types do not match, this will panic.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value<'a, 'b, 'c>(&'a self, env: &'b Arc<WebAssemblyEnvironmentData>) -> Option<&'c T> {
|
pub fn value_func_arc(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Option<Arc<T>>
|
||||||
let ptr = env.get_extern_ref_value(self.index) as *const T;
|
where
|
||||||
unsafe { ptr.as_ref() }
|
T: 'static,
|
||||||
|
{
|
||||||
|
self.value_arc(&env.data().data())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||||
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
|
pub fn value<'a, 'b, 'c>(&'a self, env: &'b Arc<WebAssemblyEnvironmentData>) -> Option<&'c T>
|
||||||
|
where
|
||||||
|
T: Sized + 'static,
|
||||||
|
{
|
||||||
|
env.get_extern_ref_value::<T>(self.index).downcast_ref::<T>()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||||
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
|
pub fn value_arc(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<Arc<T>>
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
{
|
||||||
|
env.get_extern_ref_value::<T>(self.index)
|
||||||
|
.downcast_ref::<Arc<T>>()
|
||||||
|
.cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: UniqueTypeId<u64>> FromToNativeWasmType for ExternRef<T> {
|
unsafe impl<T: ?Sized> FromToNativeWasmType for ExternRef<T> {
|
||||||
type Native = i32;
|
type Native = i32;
|
||||||
|
|
||||||
fn from_native(native: Self::Native) -> Self {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: native as u32,
|
index: native as usize,
|
||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,16 +114,16 @@ unsafe impl<T: UniqueTypeId<u64>> FromToNativeWasmType for ExternRef<T> {
|
||||||
/// actually passing raw memory, or requiring us to make copies.
|
/// actually passing raw memory, or requiring us to make copies.
|
||||||
pub(crate) struct VecExternRef<T> {
|
pub(crate) struct VecExternRef<T> {
|
||||||
/// The lookup index we can use to find the data.
|
/// The lookup index we can use to find the data.
|
||||||
index: u32,
|
index: usize,
|
||||||
/// The number of items in the vec.
|
/// The number of items in the vec.
|
||||||
size: u32,
|
size: u32,
|
||||||
/// Phantom data so we can get a type generic.
|
/// Phantom data so we can get a type generic.
|
||||||
_phantom: PhantomData<T>,
|
_phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: UniqueTypeId<u64>> VecExternRef<T> {
|
impl<T: 'static> VecExternRef<T> {
|
||||||
/// Instantiates a new VecExternRef for a given slice.
|
/// Instantiates a new VecExternRef for a given slice.
|
||||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &[T]) -> Self {
|
pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: env.get_extern_vec_ref_index(value),
|
index: env.get_extern_vec_ref_index(value),
|
||||||
size: value.len() as u32,
|
size: value.len() as u32,
|
||||||
|
@ -106,20 +132,20 @@ impl<T: UniqueTypeId<u64>> VecExternRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: UniqueTypeId<u64>> FromToNativeWasmType for VecExternRef<T> {
|
unsafe impl<T> FromToNativeWasmType for VecExternRef<T> {
|
||||||
type Native = i64;
|
type Native = i64;
|
||||||
|
|
||||||
fn from_native(native: Self::Native) -> Self {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
let split: (u32, u32) = unsafe { transmute(native) };
|
let split: (u32, u32) = unsafe { transmute(native) };
|
||||||
Self {
|
Self {
|
||||||
index: split.0,
|
index: split.0 as usize,
|
||||||
size: split.1,
|
size: split.1,
|
||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_native(self) -> Self::Native {
|
fn to_native(self) -> Self::Native {
|
||||||
let v: i64 = unsafe { transmute((self.index, self.size)) };
|
let v: i64 = unsafe { transmute((self.index as u32, self.size)) };
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,14 +125,14 @@ impl Script for WebAssemblyScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_initialize(&self, library: &DynamicLibrary, pars: &[EffectParameter]) {
|
fn on_initialize(&self, library: &DynamicLibrary, pars: Vec<EffectParameter>) {
|
||||||
if !self.has_capability(&WebAssemblyScriptCapabilities::Initialize) {
|
if !self.has_capability(&WebAssemblyScriptCapabilities::Initialize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let env = &self.environment;
|
let env = &self.environment;
|
||||||
if let Some(func) = env.script_function_cache().on_initialize(env) {
|
if let Some(func) = env.script_function_cache().on_initialize(env) {
|
||||||
call_func!(func, env, self, ex_ref!(env, library), vec_ex_ref!(env, pars));
|
call_func!(func, env, self, ex_ref!(env, library), vec_ex_ref!(env, &pars));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,7 +757,7 @@ impl Script for WebAssemblyScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_after_held_item_consume(&self, pokemon: &Pokemon, item: &Item) {
|
fn on_after_held_item_consume(&self, pokemon: &Pokemon, item: &dyn Item) {
|
||||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnAfterHeldItemConsume) {
|
if !self.has_capability(&WebAssemblyScriptCapabilities::OnAfterHeldItemConsume) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -807,7 +807,7 @@ impl Script for WebAssemblyScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_capture_rate_bonus(&self, target: &Pokemon, pokeball: &Item, modifier: &mut u8) {
|
fn change_capture_rate_bonus(&self, target: &Pokemon, pokeball: &dyn Item, modifier: &mut u8) {
|
||||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeCaptureRate) {
|
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeCaptureRate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,11 +165,11 @@ script_function_cache! {
|
||||||
on_damage(ExternRef<Pokemon>, u8, u32, u32)
|
on_damage(ExternRef<Pokemon>, u8, u32, u32)
|
||||||
on_faint(ExternRef<Pokemon>, u8)
|
on_faint(ExternRef<Pokemon>, u8)
|
||||||
on_switch_in(ExternRef<Pokemon>)
|
on_switch_in(ExternRef<Pokemon>)
|
||||||
on_after_held_item_consume(ExternRef<Pokemon>, ExternRef<Item>)
|
on_after_held_item_consume(ExternRef<Pokemon>, ExternRef<dyn Item>)
|
||||||
change_experience_gained(ExternRef<Pokemon>, ExternRef<Pokemon>, WasmPtr<u32>)
|
change_experience_gained(ExternRef<Pokemon>, ExternRef<Pokemon>, WasmPtr<u32>)
|
||||||
share_experience(ExternRef<Pokemon>, ExternRef<Pokemon>, WasmPtr<bool>)
|
share_experience(ExternRef<Pokemon>, ExternRef<Pokemon>, WasmPtr<bool>)
|
||||||
block_weather(ExternRef<Battle>, WasmPtr<bool>)
|
block_weather(ExternRef<Battle>, WasmPtr<bool>)
|
||||||
change_capture_rate_bonus(ExternRef<Pokemon>, ExternRef<Item>, WasmPtr<u8>)
|
change_capture_rate_bonus(ExternRef<Pokemon>, ExternRef<dyn Item>, WasmPtr<u8>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScriptFunctionCache {
|
impl ScriptFunctionCache {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::any::Any;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::mem::{align_of, forget, size_of};
|
use std::mem::{align_of, forget, size_of};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
@ -5,7 +6,6 @@ use std::sync::{Arc, Weak};
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use parking_lot::lock_api::RwLockReadGuard;
|
use parking_lot::lock_api::RwLockReadGuard;
|
||||||
use parking_lot::{RawRwLock, RwLock};
|
use parking_lot::{RawRwLock, RwLock};
|
||||||
use unique_type_id::UniqueTypeId;
|
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
AsStoreMut, AsStoreRef, Cranelift, EngineBuilder, Extern, Features, Function, FunctionEnv, Imports, Instance,
|
AsStoreMut, AsStoreRef, Cranelift, EngineBuilder, Extern, Features, Function, FunctionEnv, Imports, Instance,
|
||||||
Memory, Module, Store, StoreMut, StoreRef, TypedFunction, Value,
|
Memory, Module, Store, StoreMut, StoreRef, TypedFunction, Value,
|
||||||
|
@ -189,7 +189,7 @@ impl ScriptResolver for WebAssemblyScriptResolver {
|
||||||
self.environment_data.setup_script(script, category, script_key, owner)
|
self.environment_data.setup_script(script, category, script_key, owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_item_script(&self, _key: &Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
fn load_item_script(&self, _key: &dyn Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,17 +215,17 @@ pub struct WebAssemblyEnvironmentData {
|
||||||
/// we instead keep track of all the data we've sent to WASM, and pass the ID of that data to WASM. This allows us
|
/// we instead keep track of all the data we've sent to WASM, and pass the ID of that data to WASM. This allows us
|
||||||
/// to only operate on data we know WASM owns. We currently store this data in this continuous Vec, and give the index
|
/// to only operate on data we know WASM owns. We currently store this data in this continuous Vec, and give the index
|
||||||
/// of the data as the ID.
|
/// of the data as the ID.
|
||||||
extern_ref_pointers: RwLock<Vec<*const u8>>,
|
extern_ref_pointers: RwLock<Vec<*const dyn Any>>,
|
||||||
/// To make sure we send the same identifier to WASM when we send the same piece of data multiple times, we have a
|
/// To make sure we send the same identifier to WASM when we send the same piece of data multiple times, we have a
|
||||||
/// backwards lookup on extern_ref_pointers. This allows us to get the index for a given piece of data.
|
/// backwards lookup on extern_ref_pointers. This allows us to get the index for a given piece of data.
|
||||||
extern_ref_pointers_lookup: RwLock<HashMap<ExternRefLookupKey, u32>>,
|
extern_ref_pointers_lookup: RwLock<HashMap<ExternRefLookupKey, usize>>,
|
||||||
/// As an added security measure on our extern refs, we keep track of the types of the extern ref data we've sent.
|
/// As an added security measure on our extern refs, we keep track of the types of the extern ref data we've sent.
|
||||||
/// This prevents illegal arbitrary memory operations, where we expect type X, but the actual type is Y, which would
|
/// This prevents illegal arbitrary memory operations, where we expect type X, but the actual type is Y, which would
|
||||||
/// allow for modifying memory we might not want to. If we get a type mismatch, we will panic, preventing this.
|
/// allow for modifying memory we might not want to. If we get a type mismatch, we will panic, preventing this.
|
||||||
extern_ref_type_lookup: RwLock<HashSet<ExternRefLookupKey>>,
|
extern_ref_type_lookup: RwLock<HashSet<ExternRefLookupKey>>,
|
||||||
|
|
||||||
/// Additional security for data slices passed to WASM.
|
/// Additional security for data slices passed to WASM.
|
||||||
extern_vec_ref_lookup: RwLock<HashMap<u32, Vec<u32>>>,
|
extern_vec_ref_lookup: RwLock<HashMap<usize, Vec<usize>>>,
|
||||||
|
|
||||||
/// The memory inside of the WASM container.
|
/// The memory inside of the WASM container.
|
||||||
memory: RwLock<Option<Memory>>,
|
memory: RwLock<Option<Memory>>,
|
||||||
|
@ -257,14 +257,13 @@ pub struct WebAssemblyEnvironmentData {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A quick lookup so we can find the extern ref of the value.
|
/// A quick lookup so we can find the extern ref of the value.
|
||||||
|
#[allow(clippy::vtable_address_comparisons)]
|
||||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||||
struct ExternRefLookupKey {
|
struct ExternRefLookupKey {
|
||||||
/// The raw pointer to the data
|
/// The raw pointer to the data
|
||||||
pub ptr: *const u8,
|
pub ptr: *const dyn Any,
|
||||||
/// Whether or not the reference is a Vec
|
/// Whether or not the reference is a Vec
|
||||||
pub is_vec: bool,
|
pub is_vec: bool,
|
||||||
/// The unique identifier of the type.
|
|
||||||
pub t: u64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebAssemblyEnvironmentData {
|
impl WebAssemblyEnvironmentData {
|
||||||
|
@ -359,8 +358,8 @@ impl WebAssemblyEnvironmentData {
|
||||||
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
||||||
/// of this code.
|
/// of this code.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_extern_ref_index<T: UniqueTypeId<u64> + ?Sized>(&self, value: &T) -> u32 {
|
pub fn get_extern_ref_index<T: ?Sized>(&self, value: &dyn Any) -> usize {
|
||||||
self.get_extern_ref_from_ptr(value as *const T as *const u8, T::id().0, false)
|
self.get_extern_ref_from_identifier::<T>(value, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a numeric value from any given value. This is not a true Extern Ref from WASM, as this
|
/// Get a numeric value from any given value. This is not a true Extern Ref from WASM, as this
|
||||||
|
@ -369,18 +368,18 @@ impl WebAssemblyEnvironmentData {
|
||||||
/// access can be touched through this, and we ensure the value is the correct type. In the future,
|
/// access can be touched through this, and we ensure the value is the correct type. In the future,
|
||||||
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
||||||
/// of this code.
|
/// of this code.
|
||||||
pub fn get_extern_vec_ref_index<T: UniqueTypeId<u64>>(&self, value: &[T]) -> u32 {
|
pub fn get_extern_vec_ref_index<T: 'static>(&self, value: &Vec<T>) -> usize {
|
||||||
let mut vec = Vec::with_capacity(value.len());
|
let mut vec = Vec::with_capacity(value.len());
|
||||||
for v in value {
|
for v in value {
|
||||||
vec.push(self.get_extern_ref_index(v));
|
vec.push(self.get_extern_ref_index::<T>(v));
|
||||||
}
|
}
|
||||||
let p = self.get_extern_ref_from_ptr(value as *const [T] as *const u8, T::id().0, true);
|
let p = self.get_extern_ref_from_identifier::<Vec<T>>(value, true);
|
||||||
self.extern_vec_ref_lookup.write().insert(p, vec);
|
self.extern_vec_ref_lookup.write().insert(p, vec);
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an extern ref belonging to a vector we have passed to WASM.
|
/// Get an extern ref belonging to a vector we have passed to WASM.
|
||||||
pub fn get_extern_vec_ref_extern_ref(&self, extern_vec_ref: u32, index: u32) -> u32 {
|
pub fn get_extern_vec_ref_extern_ref(&self, extern_vec_ref: usize, index: usize) -> usize {
|
||||||
let r = self.extern_vec_ref_lookup.read();
|
let r = self.extern_vec_ref_lookup.read();
|
||||||
let v = r.get(&extern_vec_ref).unwrap();
|
let v = r.get(&extern_vec_ref).unwrap();
|
||||||
v[index as usize]
|
v[index as usize]
|
||||||
|
@ -389,47 +388,43 @@ impl WebAssemblyEnvironmentData {
|
||||||
/// Gets the extern ref index belonging to a specific pointer. If none exists, this will create
|
/// Gets the extern ref index belonging to a specific pointer. If none exists, this will create
|
||||||
/// a new one.
|
/// a new one.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_extern_ref_from_ptr(&self, ptr: *const u8, type_id: u64, is_vec: bool) -> u32 {
|
fn get_extern_ref_from_identifier<T: ?Sized>(&self, value: &dyn Any, is_vec: bool) -> usize {
|
||||||
if let Some(v) = self.extern_ref_pointers_lookup.read().get(&ExternRefLookupKey {
|
if let Some(v) = self.extern_ref_pointers_lookup.read().get(&ExternRefLookupKey {
|
||||||
ptr,
|
ptr: value as *const dyn Any,
|
||||||
is_vec,
|
is_vec,
|
||||||
t: type_id,
|
|
||||||
}) {
|
}) {
|
||||||
return *v as u32;
|
return *v as usize;
|
||||||
}
|
}
|
||||||
let index = {
|
let index = {
|
||||||
let mut extern_ref_guard = self.extern_ref_pointers.write();
|
let mut extern_ref_guard = self.extern_ref_pointers.write();
|
||||||
extern_ref_guard.push(ptr);
|
extern_ref_guard.push(value as *const dyn Any);
|
||||||
extern_ref_guard.len() as u32
|
extern_ref_guard.len()
|
||||||
};
|
};
|
||||||
self.extern_ref_pointers_lookup.write().insert(
|
self.extern_ref_pointers_lookup.write().insert(
|
||||||
ExternRefLookupKey {
|
ExternRefLookupKey {
|
||||||
ptr,
|
ptr: value as *const dyn Any,
|
||||||
is_vec,
|
is_vec,
|
||||||
t: type_id,
|
|
||||||
},
|
},
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
self.extern_ref_type_lookup.write().insert(ExternRefLookupKey {
|
self.extern_ref_type_lookup.write().insert(ExternRefLookupKey {
|
||||||
ptr,
|
ptr: value as *const dyn Any,
|
||||||
is_vec,
|
is_vec,
|
||||||
t: type_id,
|
|
||||||
});
|
});
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value from the extern ref lookup. This turns an earlier registered index back into
|
/// Gets a value from the extern ref lookup. This turns an earlier registered index back into
|
||||||
/// its proper value, validates its type, and returns the value.
|
/// its proper value, validates its type, and returns the value.
|
||||||
pub fn get_extern_ref_value<T: UniqueTypeId<u64>>(&self, index: u32) -> &T {
|
pub fn get_extern_ref_value<'a, 'b, T: ?Sized>(&'a self, index: usize) -> &'b dyn Any {
|
||||||
let read_guard = self.extern_ref_pointers.read();
|
let read_guard = self.extern_ref_pointers.read();
|
||||||
let ptr = read_guard.get((index - 1) as usize).unwrap();
|
let ptr = read_guard.get(index - 1).unwrap();
|
||||||
if self
|
if self
|
||||||
.extern_ref_type_lookup
|
.extern_ref_type_lookup
|
||||||
.read()
|
.read()
|
||||||
.get(&ExternRefLookupKey {
|
.get(&ExternRefLookupKey {
|
||||||
ptr: *ptr,
|
ptr: *ptr,
|
||||||
is_vec: false,
|
is_vec: false,
|
||||||
t: T::id().0,
|
|
||||||
})
|
})
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
|
@ -439,7 +434,7 @@ impl WebAssemblyEnvironmentData {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { (*ptr as *const T).as_ref().unwrap() }
|
unsafe { ptr.as_ref().unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The WASM store.
|
/// The WASM store.
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::any::Any;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
|
use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
|
@ -44,10 +46,26 @@ pub enum BattleItemCategory {
|
||||||
MiscBattleItem,
|
MiscBattleItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
||||||
|
pub trait Item: ValueIdentifiable + Debug + Any {
|
||||||
|
/// The name of the item.
|
||||||
|
fn name(&self) -> &StringKey;
|
||||||
|
/// Which bag slot items are stored in.
|
||||||
|
fn category(&self) -> ItemCategory;
|
||||||
|
/// How the item is categorized when in battle.
|
||||||
|
fn battle_category(&self) -> BattleItemCategory;
|
||||||
|
/// The buying value of the item.
|
||||||
|
fn price(&self) -> i32;
|
||||||
|
/// A set of arbitrary flags that can be set on the item.
|
||||||
|
fn flags(&self) -> &HashSet<StringKey>;
|
||||||
|
|
||||||
|
/// Checks whether the item has a specific flag.
|
||||||
|
fn has_flag(&self, key: &StringKey) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
pub struct ItemImpl {
|
||||||
pub struct Item {
|
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
/// The name of the item.
|
/// The name of the item.
|
||||||
|
@ -62,7 +80,7 @@ pub struct Item {
|
||||||
flags: HashSet<StringKey>,
|
flags: HashSet<StringKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl ItemImpl {
|
||||||
/// Instantiates an item.
|
/// Instantiates an item.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: &StringKey,
|
name: &StringKey,
|
||||||
|
@ -70,8 +88,8 @@ impl Item {
|
||||||
battle_category: BattleItemCategory,
|
battle_category: BattleItemCategory,
|
||||||
price: i32,
|
price: i32,
|
||||||
flags: HashSet<StringKey>,
|
flags: HashSet<StringKey>,
|
||||||
) -> Item {
|
) -> ItemImpl {
|
||||||
Item {
|
ItemImpl {
|
||||||
identifier: Default::default(),
|
identifier: Default::default(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
category,
|
category,
|
||||||
|
@ -80,35 +98,37 @@ impl Item {
|
||||||
flags,
|
flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Item for ItemImpl {
|
||||||
/// The name of the item.
|
/// The name of the item.
|
||||||
pub fn name(&self) -> &StringKey {
|
fn name(&self) -> &StringKey {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
/// Which bag slot items are stored in.
|
/// Which bag slot items are stored in.
|
||||||
pub fn category(&self) -> ItemCategory {
|
fn category(&self) -> ItemCategory {
|
||||||
self.category
|
self.category
|
||||||
}
|
}
|
||||||
/// How the item is categorized when in battle.
|
/// How the item is categorized when in battle.
|
||||||
pub fn battle_category(&self) -> BattleItemCategory {
|
fn battle_category(&self) -> BattleItemCategory {
|
||||||
self.battle_category
|
self.battle_category
|
||||||
}
|
}
|
||||||
/// The buying value of the item.
|
/// The buying value of the item.
|
||||||
pub fn price(&self) -> i32 {
|
fn price(&self) -> i32 {
|
||||||
self.price
|
self.price
|
||||||
}
|
}
|
||||||
/// A set of arbitrary flags that can be set on the item.
|
/// A set of arbitrary flags that can be set on the item.
|
||||||
pub fn flags(&self) -> &HashSet<StringKey> {
|
fn flags(&self) -> &HashSet<StringKey> {
|
||||||
&self.flags
|
&self.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether the item has a specific flag.
|
/// Checks whether the item has a specific flag.
|
||||||
pub fn has_flag(&self, key: &StringKey) -> bool {
|
fn has_flag(&self, key: &StringKey) -> bool {
|
||||||
self.flags.contains(key)
|
self.flags.contains(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueIdentifiable for Item {
|
impl ValueIdentifiable for ItemImpl {
|
||||||
fn value_identifier(&self) -> ValueIdentifier {
|
fn value_identifier(&self) -> ValueIdentifier {
|
||||||
self.identifier
|
self.identifier
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl AbilityLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<'_, Ability> for AbilityLibrary {
|
impl DataLibrary<Ability> for AbilityLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Arc<Ability>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<Ability>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::StringKey;
|
||||||
|
|
||||||
/// A data library is a collection of methods to set up a default library, where values are stored
|
/// A data library is a collection of methods to set up a default library, where values are stored
|
||||||
/// by both key, while keeping their insertion order.
|
/// by both key, while keeping their insertion order.
|
||||||
pub trait DataLibrary<'a, T: 'a> {
|
pub trait DataLibrary<T: ?Sized> {
|
||||||
/// Returns the underlying map.
|
/// Returns the underlying map.
|
||||||
fn map(&self) -> &IndexMap<StringKey, Arc<T>>;
|
fn map(&self) -> &IndexMap<StringKey, Arc<T>>;
|
||||||
/// Returns the underlying map in mutable manner.
|
/// Returns the underlying map in mutable manner.
|
||||||
|
@ -24,18 +24,18 @@ pub trait DataLibrary<'a, T: 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value from the library.
|
/// Gets a value from the library.
|
||||||
fn get(&'a self, key: &StringKey) -> Option<&Arc<T>> {
|
fn get(&self, key: &StringKey) -> Option<&Arc<T>> {
|
||||||
self.map().get::<StringKey>(key)
|
self.map().get::<StringKey>(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value from the library.
|
/// Gets a value from the library.
|
||||||
fn get_by_hash(&'a self, key: u32) -> Option<&Arc<T>> {
|
fn get_by_hash(&self, key: u32) -> Option<&Arc<T>> {
|
||||||
self.map().get::<u32>(&key)
|
self.map().get::<u32>(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value from the library by the index where it is stored.
|
/// Gets a value from the library by the index where it is stored.
|
||||||
fn get_key_by_index(&'a self, index: usize) -> Option<&StringKey> {
|
fn get_key_by_index(&self, index: usize) -> Option<StringKey> {
|
||||||
self.map().get_index(index).map(|a| a.0)
|
self.map().get_index(index).map(|a| a.0.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the amount of values in the library.
|
/// Gets the amount of values in the library.
|
||||||
|
|
|
@ -8,12 +8,12 @@ use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// A library to store all items.
|
/// A library to store all items.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct ItemLibrary {
|
pub struct ItemLibrary {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
/// The underlying data structure.
|
/// The underlying data structure.
|
||||||
map: IndexMap<StringKey, Arc<Item>>,
|
map: IndexMap<StringKey, Arc<dyn Item>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemLibrary {
|
impl ItemLibrary {
|
||||||
|
@ -26,12 +26,12 @@ impl ItemLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<'_, Item> for ItemLibrary {
|
impl DataLibrary<dyn Item> for ItemLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Arc<Item>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Item>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<Item>> {
|
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<dyn Item>> {
|
||||||
&mut self.map
|
&mut self.map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,11 @@ pub mod tests {
|
||||||
|
|
||||||
use crate::static_data::libraries::data_library::DataLibrary;
|
use crate::static_data::libraries::data_library::DataLibrary;
|
||||||
use crate::static_data::libraries::item_library::ItemLibrary;
|
use crate::static_data::libraries::item_library::ItemLibrary;
|
||||||
use crate::static_data::Item;
|
use crate::static_data::ItemImpl;
|
||||||
use crate::static_data::{BattleItemCategory, ItemCategory};
|
use crate::static_data::{BattleItemCategory, ItemCategory};
|
||||||
|
|
||||||
fn build_item() -> Item {
|
fn build_item() -> ItemImpl {
|
||||||
Item::new(
|
ItemImpl::new(
|
||||||
&"foo".into(),
|
&"foo".into(),
|
||||||
ItemCategory::MiscItem,
|
ItemCategory::MiscItem,
|
||||||
BattleItemCategory::MiscBattleItem,
|
BattleItemCategory::MiscBattleItem,
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// This library holds several misc settings for the library.
|
/// This library holds several misc settings for the library.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct LibrarySettings {
|
pub struct LibrarySettings {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// A library to store all data for moves.
|
/// A library to store all data for moves.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct MoveLibrary {
|
pub struct MoveLibrary {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
@ -26,7 +26,7 @@ impl MoveLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<'_, MoveData> for MoveLibrary {
|
impl DataLibrary<MoveData> for MoveLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Arc<MoveData>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<MoveData>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// A library to store all data for Pokemon species.
|
/// A library to store all data for Pokemon species.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct SpeciesLibrary {
|
pub struct SpeciesLibrary {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
@ -26,7 +26,7 @@ impl SpeciesLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DataLibrary<'a, Species> for SpeciesLibrary {
|
impl DataLibrary<Species> for SpeciesLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Arc<Species>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<Species>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// The storage for all different libraries.
|
/// The storage for all different libraries.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct StaticData {
|
pub struct StaticData {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -26,7 +26,6 @@ impl From<TypeIdentifier> for u8 {
|
||||||
|
|
||||||
/// All data related to types and effectiveness.
|
/// All data related to types and effectiveness.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct TypeLibrary {
|
pub struct TypeLibrary {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -36,8 +36,7 @@ mod statistics;
|
||||||
|
|
||||||
/// A parameter for an effect. This is basically a simple way to dynamically store multiple different
|
/// A parameter for an effect. This is basically a simple way to dynamically store multiple different
|
||||||
/// primitives on data.
|
/// primitives on data.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub enum EffectParameter {
|
pub enum EffectParameter {
|
||||||
/// A boolean value.
|
/// A boolean value.
|
||||||
Bool(ValueIdentifier, bool),
|
Bool(ValueIdentifier, bool),
|
||||||
|
|
|
@ -61,7 +61,6 @@ pub enum MoveTarget {
|
||||||
|
|
||||||
/// A move is the skill Pokémon primarily use in battle. This is the data related to that.
|
/// A move is the skill Pokémon primarily use in battle. This is the data related to that.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct MoveData {
|
pub struct MoveData {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -11,7 +11,6 @@ use crate::{Random, ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
/// The data belonging to a Pokemon with certain characteristics.
|
/// The data belonging to a Pokemon with certain characteristics.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct Species {
|
pub struct Species {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
|
|
@ -12,7 +12,6 @@ use super::statistics::Statistic;
|
||||||
///
|
///
|
||||||
/// As all data in this type is atomic, threaded access to this struct is completely legal.
|
/// As all data in this type is atomic, threaded access to this struct is completely legal.
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct StatisticSet<T>
|
pub struct StatisticSet<T>
|
||||||
where
|
where
|
||||||
T: PrimitiveAtom,
|
T: PrimitiveAtom,
|
||||||
|
@ -236,7 +235,6 @@ where
|
||||||
/// A clamped statistic set holds the 6 normal stats for a Pokemon, but ensures it always remains
|
/// A clamped statistic set holds the 6 normal stats for a Pokemon, but ensures it always remains
|
||||||
/// between two values (inclusive on the two values).
|
/// between two values (inclusive on the two values).
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct ClampedStatisticSet<T, const MIN: i64, const MAX: i64>
|
pub struct ClampedStatisticSet<T, const MIN: i64, const MAX: i64>
|
||||||
where
|
where
|
||||||
T: PrimitiveAtom,
|
T: PrimitiveAtom,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
use arcstr::ArcStr;
|
use arcstr::ArcStr;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -13,7 +14,7 @@ use std::sync::LazyLock;
|
||||||
/// free speed out of it. Note that StringKeys also compare case insensitive, so that for example
|
/// free speed out of it. Note that StringKeys also compare case insensitive, so that for example
|
||||||
/// `charmander` == `Charmander`.
|
/// `charmander` == `Charmander`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
|
||||||
pub struct StringKey {
|
pub struct StringKey {
|
||||||
/// The underlying reference counted string.
|
/// The underlying reference counted string.
|
||||||
str: ArcStr,
|
str: ArcStr,
|
||||||
|
@ -122,6 +123,12 @@ impl From<&CStr> for StringKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ValueIdentifiable for StringKey {
|
||||||
|
fn value_identifier(&self) -> ValueIdentifier {
|
||||||
|
ValueIdentifier::new(self.hash as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts a character to lowercased in a const safe way.
|
/// Converts a character to lowercased in a const safe way.
|
||||||
const fn to_lower(c: u8) -> u8 {
|
const fn to_lower(c: u8) -> u8 {
|
||||||
if c >= b'A' && c <= b'Z' {
|
if c >= b'A' && c <= b'Z' {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
static CURRENT: AtomicUsize = AtomicUsize::new(1);
|
static CURRENT: AtomicUsize = AtomicUsize::new(1);
|
||||||
|
|
||||||
/// An extremely basic way to identify a piece of data.
|
/// An extremely basic way to identify a piece of data.
|
||||||
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ValueIdentifier(usize);
|
pub struct ValueIdentifier(usize);
|
||||||
|
|
||||||
|
@ -14,6 +14,18 @@ impl Default for ValueIdentifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ValueIdentifier {
|
||||||
|
/// Creates an identifier by number.
|
||||||
|
pub(crate) fn new(v: usize) -> Self {
|
||||||
|
Self(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the underlying numeric integer of the value
|
||||||
|
pub fn value(&self) -> usize {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An object with a specific identifier.
|
/// An object with a specific identifier.
|
||||||
pub trait ValueIdentifiable {
|
pub trait ValueIdentifiable {
|
||||||
/// Get the identifier for the current object.
|
/// Get the identifier for the current object.
|
||||||
|
|
|
@ -16,7 +16,7 @@ use pkmn_lib::dynamic_data::Gen7DamageLibrary;
|
||||||
use pkmn_lib::dynamic_data::Gen7MiscLibrary;
|
use pkmn_lib::dynamic_data::Gen7MiscLibrary;
|
||||||
use pkmn_lib::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
|
use pkmn_lib::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
|
||||||
use pkmn_lib::static_data::{
|
use pkmn_lib::static_data::{
|
||||||
Ability, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, GrowthRateLibrary, Item,
|
Ability, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, GrowthRateLibrary, ItemImpl,
|
||||||
ItemLibrary, LearnableMoves, LibrarySettings, LookupGrowthRate, MoveData, MoveLibrary, Nature, NatureLibrary,
|
ItemLibrary, LearnableMoves, LibrarySettings, LookupGrowthRate, MoveData, MoveLibrary, Nature, NatureLibrary,
|
||||||
SecondaryEffect, Species, StaticData, StaticStatisticSet, Statistic, TypeLibrary,
|
SecondaryEffect, Species, StaticData, StaticStatisticSet, Statistic, TypeLibrary,
|
||||||
};
|
};
|
||||||
|
@ -117,7 +117,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) {
|
||||||
|
|
||||||
lib.add(
|
lib.add(
|
||||||
&name,
|
&name,
|
||||||
Arc::new(Item::new(&name, category, battle_category, price as i32, flags)),
|
Arc::new(ItemImpl::new(&name, category, battle_category, price as i32, flags)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue