2022-06-18 15:52:39 +02:00

229 lines
8.0 KiB
Rust

use crate::dynamic_data::choices::{MoveChoice, TurnChoice};
use crate::dynamic_data::models::battle::Battle;
use crate::dynamic_data::models::damage_source::DamageSource;
use crate::dynamic_data::models::executing_move::ExecutingMove;
use crate::dynamic_data::models::pokemon::Pokemon;
use crate::static_data::moves::secondary_effect::EffectParameter;
use crate::static_data::{Item, Statistic};
use crate::StringKey;
use parking_lot::{MappedRwLockReadGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::any::Any;
use std::fmt::{Debug, Formatter};
use std::sync::Arc;
pub trait Script {
fn name(&self) -> &StringKey;
fn is_suppressed(&self) -> bool {
self.get_suppressed_count() > 0
}
fn get_suppressed_count(&self) -> usize;
fn add_suppression(&mut self);
fn remove_suppression(&mut self);
fn stack(&mut self) {}
fn on_remove(&mut self) {}
fn on_initialize(&mut self, _pars: &[EffectParameter]) {}
fn on_before_turn(&mut self, _choice: &TurnChoice) {}
fn change_speed(&mut self, _choice: &TurnChoice, _speed: &mut u32) {}
fn change_priority(&mut self, _choice: &TurnChoice, _priority: &mut i8) {}
fn change_move(&mut self, _choice: &MoveChoice, _move_name: &mut StringKey) {}
fn change_number_of_hits(&mut self, _choice: &MoveChoice, _number_of_hits: &mut u8) {}
fn prevent_move(&mut self, _move: &ExecutingMove, _prevent: &mut bool) {}
fn fail_move(&mut self, _move: &ExecutingMove, _fail: &mut bool) {}
fn stop_before_move(&mut self, _move: &ExecutingMove, _stop: &mut bool) {}
fn on_before_move(&mut self, _move: &ExecutingMove) {}
fn fail_incoming_move(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _fail: &mut bool) {}
fn is_invulnerable(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _invulnerable: &mut bool) {}
fn on_move_miss(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>) {}
fn change_move_type(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _move_type: &mut u8) {}
fn change_effectiveness(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_effectiveness: &mut f32,
) {
}
fn block_critical(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _block_critical: &mut bool) {}
fn block_incoming_critical(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_block_critical: &mut bool,
) {
}
fn change_critical_stage(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _stage: &mut u8) {}
fn change_critical_modifier(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_modifier: &mut f32,
) {
}
fn change_stab_modifier(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _modifier: &mut f32) {}
fn change_base_power(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _base_power: &mut u8) {}
fn change_damage_stats_user(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_stats_user: &mut Arc<Pokemon>,
) {
}
fn bypass_defensive_stat_boost(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_bypass: &mut bool,
) {
}
fn bypass_offensive_stat_boost(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_bypass: &mut bool,
) {
}
fn change_offensive_stat_value(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_amount: &mut u32,
) {
}
fn change_defensive_stat_value(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_amount: &mut u32,
) {
}
fn change_damage_stat_modifier(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_modifier: &mut f32,
) {
}
fn change_damage_modifier(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _modifier: &mut f32) {
}
fn change_damage(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _damage: &mut u32) {}
fn change_incoming_damage(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _damage: &mut u32) {}
fn on_incoming_hit(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8) {}
fn on_opponent_faints(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8) {}
fn prevent_stat_boost_change(
&mut self,
_target: &Pokemon,
_stat: Statistic,
_amount: i8,
_self_inflicted: bool,
_prevent: &mut bool,
) {
}
fn change_stat_boost_change(
&mut self,
_target: &Pokemon,
_stat: Statistic,
_self_inflicted: bool,
_amount: *mut i8,
) {
}
fn prevent_secondary_effect(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_prevent: &mut bool,
) {
}
fn change_effect_chance(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8, _chance: &mut f32) {}
fn change_incoming_effect_chance(
&mut self,
_move: &ExecutingMove,
_target: &Arc<Pokemon>,
_hit: u8,
_chance: &mut f32,
) {
}
fn on_secondary_effect(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>, _hit: u8) {}
fn on_after_hits(&mut self, _move: &ExecutingMove, _target: &Arc<Pokemon>) {}
fn prevent_self_switch(&mut self, _choice: &TurnChoice, _prevent: &mut bool) {}
fn prevent_opponent_switch(&mut self, _choice: &TurnChoice, _prevent: &mut bool) {}
fn on_fail(&mut self, _target: &Pokemon) {}
fn on_opponent_fail(&mut self, _target: &Pokemon) {}
fn prevent_self_run_away(&mut self, _choice: &TurnChoice, _prevent: &mut bool) {}
fn prevent_opponent_run_away(&mut self, _choice: &TurnChoice, _prevent: &mut bool) {}
fn on_end_turn(&mut self) {}
fn on_damage(&mut self, _pokemon: &Pokemon, _source: DamageSource, _old_health: u32, _new_health: u32) {}
fn on_faint(&mut self, _pokemon: &Pokemon, _source: DamageSource) {}
fn on_switch_in(&mut self, _pokemon: &Pokemon) {}
fn on_after_held_item_consume(&mut self, _pokemon: &Pokemon, _item: &Item) {}
fn change_experience_gained(&mut self, _fainted_mon: &Pokemon, _winning_mon: &Pokemon, _amount: &mut u32) {}
fn share_experience(&mut self, _fainted_mon: &Pokemon, _winning_mon: &Pokemon, _shares: &mut bool) {}
fn block_weather(&mut self, _battle: &Battle, _blocked: &mut bool) {}
fn change_capture_rate_bonus(&mut self, _target: &Pokemon, _pokeball: &Item, _modifier: &mut u8) {}
fn as_any(&self) -> &dyn Any;
}
impl Debug for dyn Script {
fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}
type ScriptHolder = Arc<RwLock<Option<Box<dyn Script>>>>;
#[derive(Default, Debug, Clone)]
pub struct ScriptContainer {
script: ScriptHolder,
}
impl ScriptContainer {
pub fn new(script: Box<dyn Script>) -> ScriptContainer {
Self {
script: Arc::new(RwLock::new(Some(script))),
}
}
pub fn get(&self) -> RwLockWriteGuard<'_, Option<Box<dyn Script>>> {
self.script.write()
}
pub fn set(&self, script: Box<dyn Script>) {
self.script.write().replace(script);
}
pub fn clear(&self) {
self.script.write().take();
}
pub fn arc(&self) -> &ScriptHolder {
&self.script
}
pub fn get_as<T: 'static>(&self) -> MappedRwLockReadGuard<T> {
RwLockReadGuard::map(self.script.read(), |a| unsafe {
let ptr = a.as_ref().as_ref().unwrap().as_ref() as *const dyn Script;
let any = ptr.as_ref().unwrap().as_any();
any.downcast_ref::<T>().unwrap()
})
}
}
impl From<ScriptHolder> for ScriptContainer {
fn from(a: ScriptHolder) -> Self {
Self { script: a }
}
}