use crate::app_interface::list::ImmutableList; use crate::app_interface::{ Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Pokemon, Statistic, }; use crate::handling::ScriptCapabilities; use crate::{ExternRef, ExternalReferenceType, ScriptPtr, StringKey, TurnChoice, TypeIdentifier}; use core::any::Any; use core::fmt::Debug; pub trait Script { fn new() -> Self where Self: Sized; fn get_name(&self) -> &'static str; fn get_capabilities(&self) -> &[ScriptCapabilities]; /// This function is ran when a volatile effect is added while that volatile effect already is /// in place. Instead of adding the volatile effect twice, it will execute this function instead. fn stack(&self) {} /// This function is ran when this script stops being in effect, and is removed from its owner. fn on_remove(&self) {} /// This function is ran when this script starts being in effect. fn on_initialize( &self, _library: &DynamicLibrary, _parameters: Option>, ) { } /// 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 /// something has happened during a turn. fn on_before_turn(&self, _choice: TurnChoice) {} /// This function allows you to modify the effective speed of the Pokemon. This is ran before /// turn ordering, so overriding here will allow you to put certain Pokemon before others. fn change_speed(&self, _choice: TurnChoice, _speed: &mut u32) {} /// This function allows you to modify the effective priority of the Pokemon. This is ran before /// turn ordering, so overriding here will allow you to put certain Pokemon before others. Note /// that this is only relevant on move choices, as other turn choice types do not have a priority. fn change_priority(&self, _choice: TurnChoice, _priority: &mut i8) {} /// This function allows you to change the move that is used during execution. This is useful for /// moves such as metronome, where the move chosen actually differs from the move used. fn change_move(&self, _choice: TurnChoice, _move_name: &mut StringKey) {} /// This function allows you to change a move into a multi-hit move. The number of hits set here /// gets used as the number of hits. If set to 0, this will behave as if the move missed on its /// first hit. fn change_number_of_hits(&self, _choice: TurnChoice, _number_of_hits: &mut u8) {} /// This function allows you to prevent a move from running. If this gets set to true, the move /// ends execution here. No PP will be decreased in this case. fn prevent_move(&self, _move: ExecutingMove, _prevent: &mut bool) {} /// This function makes the move fail. If the fail field gets set to true, the move ends execution, /// and fail events get triggered. fn fail_move(&self, _move: ExecutingMove, _fail: &mut bool) {} /// Similar to [`Self::prevent_move`]. This function will also stop execution, but PP will be /// decreased. fn stop_before_move(&self, _move: ExecutingMove, _stop: &mut bool) {} /// This function runs just before the move starts its execution. fn on_before_move(&self, _move: ExecutingMove) {} /// This function allows a script to prevent a move that is targeted at its owner. If set to true /// the move fails, and fail events get triggered. fn fail_incoming_move(&self, _move: ExecutingMove, _target: Pokemon, _fail: &mut bool) {} /// This function allows a script to make its owner invulnerable to an incoming move. fn is_invulnerable(&self, _move: ExecutingMove, _target: Pokemon, _invulnerable: &mut bool) {} /// This function occurs when a move gets missed. This runs on the scripts belonging to the executing /// move, which include the scripts that are attached to the owner of the script. fn on_move_miss(&self, _move: ExecutingMove, _target: Pokemon) {} /// This function allows the script to change the actual type that is used for the move on a target. fn change_move_type( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _move_type: &mut TypeIdentifier, ) { } /// This function allows the script to change how effective a move is on a target. fn change_effectiveness( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _effectiveness: &mut f32, ) { } /// This function allows a script to block an outgoing move from being critical. fn block_critical( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _block_critical: &mut bool, ) { } /// This function allows a script to block an incoming move from being critical. fn block_incoming_critical( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _block_critical: &mut bool, ) { } /// This function allows a script to modify the accuracy of a move used. This value represents /// the percentage accuracy, so anything above 100% will make it always hit. fn change_accuracy( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _accuracy: &mut u8, ) { } /// This function allows a script to change the critical stage of the move used. fn change_critical_stage( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _stage: &mut u8, ) { } /// This function allows a script to change the damage modifier of a critical hit. This will only /// run when a hit is critical. fn change_critical_modifier( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _modifier: &mut f32, ) { } /// This function allows a script to change the damage modifier of a Same Type Attack Bonus, which /// occurs when the user has the move type as one of its own types. fn change_stab_modifier( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _modifier: &mut f32, ) { } /// This function allows a script to change the effective base power of a move hit. fn change_base_power( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _base_power: &mut u8, ) { } /// This function allows a script to bypass defensive stat boosts for a move hit. fn bypass_defensive_stat_boost( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _bypass: &mut bool, ) { } /// This function allows a script to bypass offensive stat boosts for a move hit. fn bypass_offensive_stat_boost( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _bypass: &mut bool, ) { } /// This function allows a script to change the actual offensive stat values used when calculating damage fn change_offensive_stat_value( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _amount: &mut u32, ) { } /// This function allows a script to change the actual defensive stat values used when calculating damage. fn change_defensive_stat_value( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _amount: &mut u32, ) { } /// This function allows a script to change the raw modifier we retrieved from the stats of the /// defender and attacker. fn change_damage_stat_modifier( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _modifier: &mut f32, ) { } /// This function allows a script to apply a raw multiplier to the damage done by a move. fn change_damage_modifier( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _modifier: &mut f32, ) { } /// This function allows a script to modify the outgoing damage done by a move. fn change_damage(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _damage: &mut u32) {} /// This function allows a script to modify the incoming damage done by a move. fn change_incoming_damage( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _damage: &mut u32, ) { } /// This function triggers when an incoming hit happens. This triggers after the damage is done, /// but before the secondary effect of the move happens. fn on_incoming_hit(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) {} /// This function triggers when an opponent on the field faints. fn on_opponent_faints(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) {} /// This function allows a script attached to a Pokemon or its parents to prevent stat boost /// changes on that Pokemon. fn prevent_stat_boost_change( &self, _target: Pokemon, _stat: Statistic, _amount: i8, _self_inflicted: bool, _prevent: &mut bool, ) { } /// This function allows a script attached to a Pokemon or its parents to modify the amount by /// which the stat boost will change. If the stat boost is done by the user itself, self /// inflicted will be true, otherwise it will be false. fn change_stat_boost_change( &self, _target: Pokemon, _stat: Statistic, _self_inflicted: bool, _amount: &mut i8, ) { } /// This function allows a script attached to a Pokemon or its parents to prevent an incoming /// secondary effect. This means the move will still hit and do damage, but not trigger its /// secondary effect. Note that this function is not called for status moves. fn prevent_secondary_effect( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _prevent: &mut bool, ) { } /// This function allows a script attached to a move or its parents to change the chance the /// secondary effect of a move will trigger. The chance is depicted in percentage here, so /// changing this to above or equal to 100 will make it always hit, while setting it to equal or /// below 0 will make it never hit. fn change_effect_chance( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _chance: &mut f32, ) { } /// This function allows a script attached to a Pokemon or its parents to change the chance the /// secondary effect of an incoming move will trigger. The chance is depicted in percentage here, /// so changing this to above or equal to 100 will make it always hit, while setting it to equal /// or below 0 will make it never hit. fn change_incoming_effect_chance( &self, _move: ExecutingMove, _target: Pokemon, _hit: u8, _chance: &mut f32, ) { } /// This function triggers when the move uses its secondary effect. Moves should implement their /// secondary effects here. Status moves should implement their actual functionality in this /// function as well, as status moves effects are defined as secondary effects for simplicity. fn on_secondary_effect(&self, _move: ExecutingMove, _target: Pokemon, _hit: u8) {} /// This function triggers on a move or its parents when all hits on a target are finished. fn on_after_hits(&self, _move: ExecutingMove, _target: Pokemon) {} /// This function prevents the Pokemon it is attached to from being able to switch out. fn prevent_self_switch(&self, _choice: TurnChoice, _prevent: &mut bool) {} /// This function allows the prevention of switching for any opponent. fn prevent_opponent_switch(&self, _choice: TurnChoice, _prevent: &mut bool) {} /// This function is called on a move and its parents when the move fails. fn on_fail(&self, _target: Pokemon) {} /// This function is called on a script when an opponent fails. fn on_opponent_fail(&self, _target: Pokemon) {} /// This function allows preventing the running away of the Pokemon its attached to fn prevent_self_run_away(&self, _choice: TurnChoice, _prevent: &mut bool) {} /// This function prevents a Pokemon on another side than where its attached to from running away. fn prevent_opponent_run_away(&self, _choice: TurnChoice, _prevent: &mut bool) {} /// This function id triggered on all scripts active in the battle after all choices have finished /// running. Note that choices are not active anymore here, so their scripts do not call this /// function. fn on_end_turn(&self) {} /// This function is triggered on a Pokemon and its parents when the given Pokemon takes damage. fn on_damage( &self, _pokemon: Pokemon, _source: DamageSource, _old_health: u32, _new_health: u32, ) { } /// This function is triggered on a Pokemon and its parents when the given Pokemon faints. fn on_faint(&self, _pokemon: Pokemon, _source: DamageSource) {} /// This function is triggered on a Pokemon and its parents when the given Pokemon is switched into /// the battlefield. fn on_switch_in(&self, _pokemon: Pokemon) {} /// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the /// held item it had. fn on_after_held_item_consume(&self, _pokemon: Pokemon, _item: &Item) {} /// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience, /// and allows for changing this amount of experience. fn change_experience_gained( &self, _fainted_mon: Pokemon, _winning_mon: Pokemon, _amount: &mut u32, ) { } /// This function is triggered on a Pokemon and its parents when the given Pokemon gains experience, /// and allows for making the experience be shared across multiple Pokemon. fn share_experience(&self, _fainted_mon: Pokemon, _winning_mon: Pokemon, _shares: &mut bool) {} /// This function is triggered on a battle and its parents when something attempts to change the /// weather, and allows for blocking the weather change. fn block_weather(&self, _battle: Battle, _blocked: &mut bool) {} /// 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 /// example status effects that change capture rates. fn change_capture_rate_bonus(&self, _target: Pokemon, _pokeball: Item, _modifier: &mut u8) {} fn as_any(&self) -> &dyn Any; #[cfg(not(feature = "mock_data"))] fn get_owner(&self) -> Option where T: ExternalReferenceType, Self: Sized, { unsafe { script_get_owner(ScriptPtr::from_existing(self)) .cast::() .get_value() } } } impl Debug for dyn Script { fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { core::fmt::Result::Ok(()) } } #[cfg(not(feature = "mock_data"))] extern "wasm" { fn script_get_owner(pointer: ScriptPtr) -> ExternRef; }