use core::fmt;
use crate::battle::stack::ctx::EffectProvider;
use crate::battle::BattlerRef;
pub enum TurnEvent<P: EffectProvider + ?Sized> {
MoveUsed {
actor: BattlerRef,
move_: P::Move,
},
Missed {
actor: BattlerRef,
},
Blocked {
actor: BattlerRef,
},
Crit {
actor: BattlerRef,
},
Damaged {
target: BattlerRef,
amount: u16,
cause: Option<HpChangeCause<P>>,
},
Healed {
target: BattlerRef,
amount: u16,
cause: Option<HpChangeCause<P>>,
},
StatusInflicted {
target: BattlerRef,
status: P::Status,
},
StatusCured {
target: BattlerRef,
status: P::Status,
},
StatChanged {
target: BattlerRef,
stat: P::Stat,
delta: i8,
},
Fainted {
who: BattlerRef,
},
}
impl<P: EffectProvider + ?Sized> Clone for TurnEvent<P> {
fn clone(&self) -> Self {
match self {
Self::MoveUsed { actor, move_ } => Self::MoveUsed { actor: *actor, move_: move_.clone() },
Self::Missed { actor } => Self::Missed { actor: *actor },
Self::Blocked { actor } => Self::Blocked { actor: *actor },
Self::Crit { actor } => Self::Crit { actor: *actor },
Self::Damaged { target, amount, cause } => Self::Damaged { target: *target, amount: *amount, cause: cause.clone() },
Self::Healed { target, amount, cause } => Self::Healed { target: *target, amount: *amount, cause: cause.clone() },
Self::StatusInflicted { target, status } => {
Self::StatusInflicted { target: *target, status: status.clone() }
}
Self::StatusCured { target, status } => {
Self::StatusCured { target: *target, status: status.clone() }
}
Self::StatChanged { target, stat, delta } => {
Self::StatChanged { target: *target, stat: *stat, delta: *delta }
}
Self::Fainted { who } => Self::Fainted { who: *who },
}
}
}
impl<P: EffectProvider + ?Sized> fmt::Debug for TurnEvent<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::MoveUsed { actor, move_ } => f
.debug_struct("MoveUsed")
.field("actor", actor)
.field("move_", move_)
.finish(),
Self::Missed { actor } => f.debug_struct("Missed").field("actor", actor).finish(),
Self::Blocked { actor } => f.debug_struct("Blocked").field("actor", actor).finish(),
Self::Crit { actor } => f.debug_struct("Crit").field("actor", actor).finish(),
Self::Damaged { target, amount, cause } => f
.debug_struct("Damaged")
.field("target", target)
.field("amount", amount)
.field("cause", cause)
.finish(),
Self::Healed { target, amount, cause } => f
.debug_struct("Healed")
.field("target", target)
.field("amount", amount)
.field("cause", cause)
.finish(),
Self::StatusInflicted { target, status } => f
.debug_struct("StatusInflicted")
.field("target", target)
.field("status", status)
.finish(),
Self::StatusCured { target, status } => f
.debug_struct("StatusCured")
.field("target", target)
.field("status", status)
.finish(),
Self::StatChanged { target, stat, delta } => f
.debug_struct("StatChanged")
.field("target", target)
.field("stat", stat)
.field("delta", delta)
.finish(),
Self::Fainted { who } => f.debug_struct("Fainted").field("who", who).finish(),
}
}
}
pub enum HpChangeCause<P: EffectProvider + ?Sized> {
Status(P::Status),
Volatile(P::EffectStateKind),
}
impl<P: EffectProvider + ?Sized> Clone for HpChangeCause<P> {
fn clone(&self) -> Self {
match self {
Self::Status(s) => Self::Status(s.clone()),
Self::Volatile(k) => Self::Volatile(k.clone()),
}
}
}
impl<P: EffectProvider + ?Sized> fmt::Debug for HpChangeCause<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Status(s) => f.debug_tuple("Status").field(s).finish(),
Self::Volatile(_) => f.write_str("Volatile(..)"),
}
}
}
pub struct TurnLog<P: EffectProvider + ?Sized> {
pub events: Vec<TurnEvent<P>>,
}
impl<P: EffectProvider + ?Sized> TurnLog<P> {
pub fn new() -> Self {
Self { events: Vec::new() }
}
pub fn push(&mut self, ev: TurnEvent<P>) {
self.events.push(ev);
}
pub fn len(&self) -> usize {
self.events.len()
}
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
}
impl<P: EffectProvider + ?Sized> Default for TurnLog<P> {
fn default() -> Self {
Self::new()
}
}
impl<P: EffectProvider + ?Sized> Clone for TurnLog<P> {
fn clone(&self) -> Self {
Self { events: self.events.clone() }
}
}
impl<P: EffectProvider + ?Sized> fmt::Debug for TurnLog<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TurnLog").field("events", &self.events).finish()
}
}