use std::fmt::Debug; use std::sync::Arc; use crate::dynamic_data::{ItemScript, Script, ScriptOwnerData}; use crate::static_data::Item; use crate::{PkmnResult, StringKey}; /// A script resolver deals with the resolving of scripts. These scripts are non-hardcoded /// implementations of different effects in Pokemon. This allows for things such as generational /// differences, and custom implementations. pub trait ScriptResolver: Debug { /// Loads a standard script with a given unique combination of category and key. If no script /// can be created with this combination, returns None. fn load_script( &self, owner: ScriptOwnerData, category: ScriptCategory, script_key: &StringKey, ) -> PkmnResult>>; /// 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 /// shared between all different usages. fn load_item_script(&self, _key: &Item) -> PkmnResult>>; } /// A script category defines a sub-group of scripts. This can be used to have multiple scripts with /// the same name, but a different script. It should be completely valid for a move to have the same /// name as an ability, or more commonly: for a script attached to a Pokemon to have the same name as /// a move that placed it there. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(u8)] pub enum ScriptCategory { /// A script that belongs to a move. This generally is only the script that is attached to a /// [`MoveChoice`](crate::dynamic_data::MoveChoice) and [`ExecutingMove`](crate::dynamic_data::ExecutingMove) Move = 0, /// An ability script. Scripts in this category are always abilities, and therefore always /// attached to a Pokemon. Ability = 1, /// A non volatile status script. Scripts in this category are always non volatile statuses, and /// therefore always attached to a Pokemon. Status = 2, /// A volatile status script. Scripts in this category are always volatile status effects, and /// therefore always attached to a Pokemon. Pokemon = 3, /// A script that can be attached to an entire side. Side = 4, /// A script that can be attached to the entire battle. Battle = 5, /// A special script for held items. As they're part of a held item, they're attached to a Pokemon. ItemBattleTrigger = 6, } /// A basic empty script resolver, that always returns None. #[derive(Debug)] pub struct EmptyScriptResolver {} impl ScriptResolver for EmptyScriptResolver { fn load_script( &self, _owner: ScriptOwnerData, _category: ScriptCategory, _script_key: &StringKey, ) -> PkmnResult>> { Ok(None) } fn load_item_script(&self, _key: &Item) -> PkmnResult>> { Ok(None) } }