use crate::{
agent::{
AgentStatusEvent, AttackTargetEvent, BarrierUpdateEvent, BreakbarPercentEvent,
BreakbarStateEvent, DownContributionEvent, EnterCombatEvent, HealthUpdateEvent,
MaxHealthEvent, TargetableEvent, TeamChangeEvent,
},
buff::{
BuffApplyEvent, BuffDamageEvent, BuffFormula, BuffInfo, BuffInitialEvent, BuffRemoveEvent,
StackActiveEvent, StackResetEvent,
},
effect::{Effect, EffectOld},
guid::ContentGUID,
log::{ErrorEvent, LogEvent},
marker::{AgentMarkerEvent, SquadMarkerEvent},
player::{GuildEvent, RewardEvent},
position::PositionEvent,
ruleset::Ruleset,
skill::{ActivationEvent, SkillInfo, SkillTiming},
strike::StrikeEvent,
weapon::WeaponSwapEvent,
Event, EventCategory, Language, StateChange,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "kind"))]
pub enum EventKind {
EnterCombat(EnterCombatEvent),
ExitCombat(AgentStatusEvent),
ChangeUp(AgentStatusEvent),
ChangeDead(AgentStatusEvent),
ChangeDown(AgentStatusEvent),
Spawn(AgentStatusEvent),
Despawn(AgentStatusEvent),
HealthUpdate(HealthUpdateEvent),
LogStart(LogEvent),
LogEnd(LogEvent),
WeaponSwap(WeaponSwapEvent),
MaxHealthUpdate(MaxHealthEvent),
PointOfView(AgentStatusEvent),
Language {
time: u64,
language: Result<Language, u64>,
},
GWBuild { time: u64, build: u64 },
ShardId { time: u64, shard: u64 },
Reward(RewardEvent),
BuffInitial(BuffInitialEvent),
Position(PositionEvent),
Velocity(PositionEvent),
Facing(PositionEvent),
TeamChange(TeamChangeEvent),
AttackTarget(AttackTargetEvent),
Targetable(TargetableEvent),
MapId { time: u64, map: u64 },
StackActive(StackActiveEvent),
StackReset(StackResetEvent),
Guild(GuildEvent),
BuffInfo(BuffInfo),
BuffFormula(BuffFormula),
SkillInfo(SkillInfo),
SkillTiming(SkillTiming),
BreakbarState(BreakbarStateEvent),
BreakbarPercent(BreakbarPercentEvent),
Error(ErrorEvent),
AgentMarker(AgentMarkerEvent),
BarrierUpdate(BarrierUpdateEvent),
StatReset { time: u64, target: u64 },
Extension { sig: u32, event: Event },
ApiDelayed { event: Box<EventKind> },
InstanceStart { time: u64, start: u64 },
Tickrate { time: u64, rate: u64 },
Last90BeforeDown(DownContributionEvent),
EffectOld(EffectOld),
IdToGUID(ContentGUID),
LogNPCUpdate(LogEvent),
ExtensionCombat { sig: u32, event: Event },
FractalScale { time: u64, scale: u64 },
Effect(Effect),
Ruleset(Ruleset),
Activation(ActivationEvent),
BuffRemove(BuffRemoveEvent),
BuffApply(BuffApplyEvent),
BuffDamage(BuffDamageEvent),
Strike(StrikeEvent),
SquadMarker(SquadMarkerEvent),
Unknown(Event),
}
impl From<Event> for EventKind {
#[inline]
fn from(mut event: Event) -> Self {
unsafe {
match event.categorize() {
EventCategory::StateChange => match event.get_statechange() {
StateChange::None => unreachable!("statechange none in statechange category"),
StateChange::IdleEvent | StateChange::ReplInfo => {
unreachable!("illegal internal statechange")
}
StateChange::EnterCombat => Self::EnterCombat(event.extract()),
StateChange::ExitCombat => Self::ExitCombat(event.extract()),
StateChange::ChangeUp => Self::ChangeUp(event.extract()),
StateChange::ChangeDead => Self::ChangeDead(event.extract()),
StateChange::ChangeDown => Self::ChangeDown(event.extract()),
StateChange::Spawn => Self::Spawn(event.extract()),
StateChange::Despawn => Self::Despawn(event.extract()),
StateChange::HealthUpdate => Self::HealthUpdate(event.extract()),
StateChange::LogStart => Self::LogStart(event.extract()),
StateChange::LogEnd => Self::LogEnd(event.extract()),
StateChange::WeaponSwap => Self::WeaponSwap(event.extract()),
StateChange::MaxHealthUpdate => Self::MaxHealthUpdate(event.extract()),
StateChange::PointOfView => Self::PointOfView(event.extract()),
StateChange::Language => Self::Language {
time: event.time,
language: Language::try_from(event.src_agent as i32)
.map_err(|_| event.src_agent),
},
StateChange::GWBuild => Self::GWBuild {
time: event.time,
build: event.src_agent,
},
StateChange::ShardId => Self::ShardId {
time: event.time,
shard: event.src_agent,
},
StateChange::Reward => Self::Reward(event.extract()),
StateChange::BuffInitial => Self::BuffInitial(event.extract()),
StateChange::Position => Self::Position(event.extract()),
StateChange::Velocity => Self::Velocity(event.extract()),
StateChange::Facing => Self::Facing(event.extract()),
StateChange::TeamChange => Self::TeamChange(event.extract()),
StateChange::AttackTarget => Self::AttackTarget(event.extract()),
StateChange::Targetable => Self::Targetable(event.extract()),
StateChange::MapId => Self::MapId {
time: event.time,
map: event.src_agent,
},
StateChange::StackActive => Self::StackActive(event.extract()),
StateChange::StackReset => Self::StackReset(event.extract()),
StateChange::Guild => Self::Guild(event.extract()),
StateChange::BuffInfo => Self::BuffInfo(event.extract()),
StateChange::BuffFormula => Self::BuffFormula(event.extract()),
StateChange::SkillInfo => Self::SkillInfo(event.extract()),
StateChange::SkillTiming => Self::SkillTiming(event.extract()),
StateChange::BreakbarState => Self::BreakbarState(event.extract()),
StateChange::BreakbarPercent => Self::BreakbarPercent(event.extract()),
StateChange::Error => Self::Error(event.extract()),
StateChange::Marker => Self::AgentMarker(event.extract()),
StateChange::BarrierUpdate => Self::BarrierUpdate(event.extract()),
StateChange::StatReset => Self::StatReset {
time: event.time,
target: event.src_agent,
},
StateChange::Extension => Self::Extension {
sig: event.get_pad_id(),
event,
},
StateChange::ApiDelayed => {
event.is_statechange = StateChange::None.into();
Self::ApiDelayed {
event: event.into_kind().into(),
}
}
StateChange::InstanceStart => Self::InstanceStart {
time: event.time,
start: event.src_agent,
},
StateChange::Tickrate => Self::Tickrate {
time: event.time,
rate: event.src_agent,
},
StateChange::Last90BeforeDown => Self::Last90BeforeDown(event.extract()),
StateChange::EffectOld => Self::EffectOld(event.extract()),
StateChange::IdToGUID => Self::IdToGUID(event.extract()),
StateChange::LogNPCUpdate => Self::LogNPCUpdate(event.extract()),
StateChange::ExtensionCombat => Self::ExtensionCombat {
sig: event.get_pad_id(),
event,
},
StateChange::FractalScale => Self::FractalScale {
time: event.time,
scale: event.src_agent,
},
StateChange::Effect => Self::Effect(event.extract()),
StateChange::Ruleset => {
Self::Ruleset(Ruleset::from_bits_retain(event.src_agent))
}
StateChange::SquadMarker => Self::SquadMarker(event.extract()),
StateChange::Unknown(_) => Self::Unknown(event),
},
EventCategory::Activation => Self::Activation(event.extract()),
EventCategory::BuffRemove => Self::BuffRemove(event.extract()),
EventCategory::BuffApply => Self::BuffApply(event.extract()),
EventCategory::BuffDamage => Self::BuffDamage(event.extract()),
EventCategory::Strike => Self::Strike(event.extract()),
}
}
}
}