#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Event {
BeforeTurn,
ResidualOrder,
AfterTurn,
BeforeMove,
ModifyMove,
ModifyType,
ModifyCritRatio,
Accuracy,
Invulnerability,
ModifyDamage,
Effectiveness,
AfterMove,
TryHit,
Damage,
DamagingHit,
Heal,
AfterFaint,
TrySetStatus,
AfterSetStatus,
TryBoost,
AfterBoost,
ModifyStat,
WeatherModifyStat,
Start,
End,
Faint,
SwitchIn,
SwitchOut,
SetWeather,
FieldResidual,
SideResidual,
OnMiss,
Residual,
Custom(u16),
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum RelayVar {
Unit,
Int(i64),
Damage(u16),
Accuracy(u8),
Bool(bool),
}
impl RelayVar {
pub fn as_int(self) -> i64 {
if let RelayVar::Int(v) = self {
v
} else {
0
}
}
pub fn as_damage(self) -> u16 {
if let RelayVar::Damage(v) = self {
v
} else {
0
}
}
pub fn as_accuracy(self) -> u8 {
if let RelayVar::Accuracy(v) = self {
v
} else {
0
}
}
pub fn as_bool(self) -> bool {
matches!(self, RelayVar::Bool(true))
}
pub fn scale(self, num: u32, den: u32) -> RelayVar {
let den = den.max(1);
match self {
RelayVar::Int(v) => {
let scaled = (v as i128) * (num as i128) / (den as i128);
RelayVar::Int(scaled as i64)
}
RelayVar::Damage(v) => {
let scaled = (v as u64) * (num as u64) / (den as u64);
RelayVar::Damage(scaled.min(u16::MAX as u64) as u16)
}
RelayVar::Accuracy(v) => {
let scaled = (v as u32) * num / den;
RelayVar::Accuracy(scaled.min(u8::MAX as u32) as u8)
}
other => other,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum HandlerResult {
Unchanged,
Set(RelayVar),
Fail,
FailSilent,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EffectId(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EffectType {
Move,
Status,
Condition,
}
impl EffectType {
pub fn sub_order(self) -> u8 {
match self {
EffectType::Condition => 2,
EffectType::Status => 4,
EffectType::Move => 6,
}
}
}
pub type HandlerFn<P> = fn(
ctx: &mut super::ctx::BattleCtx<'_, P>,
relay: RelayVar,
target: crate::battle::BattlerRef,
source: crate::battle::BattlerRef,
source_effect: EffectId,
) -> HandlerResult;
pub struct EventHook<P: super::ctx::EffectProvider + ?Sized> {
pub event: Event,
pub call: HandlerFn<P>,
pub order: u32,
pub priority: i32,
pub sub_order: Option<u8>,
}
impl<P: super::ctx::EffectProvider + ?Sized> Clone for EventHook<P> {
fn clone(&self) -> Self {
Self {
event: self.event,
call: self.call,
order: self.order,
priority: self.priority,
sub_order: self.sub_order,
}
}
}
impl<P: super::ctx::EffectProvider + ?Sized> Copy for EventHook<P> {}
pub struct Effect<P: super::ctx::EffectProvider + ?Sized> {
pub id: EffectId,
pub kind: EffectType,
pub hooks: &'static [EventHook<P>],
}