evtc\event/
event_kind.rs

1use crate::{
2    agent::{
3        AgentStatusEvent, AttackTargetEvent, BarrierUpdateEvent, BreakbarPercentEvent,
4        BreakbarStateEvent, DownContributionEvent, EnterCombatEvent, GliderEvent,
5        HealthUpdateEvent, MaxHealthEvent, StunbreakEvent, TargetableEvent, TeamChangeEvent,
6    },
7    buff::{
8        BuffApplyEvent, BuffDamageEvent, BuffFormula, BuffInfo, BuffInitialEvent, BuffRemoveEvent,
9        StackActiveEvent, StackResetEvent,
10    },
11    content::ContentInfo,
12    effect::{
13        AgentEffect, AgentEffectRemove, Effect45, Effect51, GroundEffect, GroundEffectRemove,
14    },
15    log::{ArcBuildEvent, ErrorEvent, LogEvent},
16    marker::{AgentMarkerEvent, SquadMarkerEvent},
17    missile::{MissileCreate, MissileLaunch, MissileRemove},
18    player::{GuildEvent, RewardEvent},
19    position::PositionEvent,
20    ruleset::Ruleset,
21    skill::{ActivationEvent, SkillInfo, SkillTiming},
22    strike::StrikeEvent,
23    weapon::WeaponSwapEvent,
24    Event, EventCategory, Language, StateChange,
25};
26
27#[cfg(feature = "serde")]
28use serde::{Deserialize, Serialize};
29
30/// Possible [`Event`] kinds.
31#[derive(Debug, Clone)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[cfg_attr(feature = "serde", serde(tag = "kind"))]
34pub enum EventKind {
35    /// Activation (cast) event.
36    Activation(ActivationEvent),
37
38    /// Buff removed.
39    BuffRemove(BuffRemoveEvent),
40
41    /// Buff applied.
42    BuffApply(BuffApplyEvent),
43
44    /// Buff damage.
45    BuffDamage(BuffDamageEvent),
46
47    /// Direct (strike) damage.
48    Strike(StrikeEvent),
49
50    /// Agent entered combat.
51    EnterCombat(EnterCombatEvent),
52
53    /// Agent left combat.
54    ExitCombat(AgentStatusEvent),
55
56    /// Agent is now alive.
57    ChangeUp(AgentStatusEvent),
58
59    /// Agent is now dead.
60    ChangeDead(AgentStatusEvent),
61
62    /// Agent is now downed.
63    ChangeDown(AgentStatusEvent),
64
65    /// Agent is now in game tracking range.
66    Spawn(AgentStatusEvent),
67
68    /// Agent is no longer being tracked or out of game tracking range.
69    Despawn(AgentStatusEvent),
70
71    /// Agent health change.
72    HealthUpdate(HealthUpdateEvent),
73
74    /// Log started.
75    SquadCombatStart(LogEvent),
76
77    /// Log ended.
78    SquadCombatEnd(LogEvent),
79
80    /// Agent swapped weapon set.
81    WeaponSwap(WeaponSwapEvent),
82
83    /// Agent maximum health change.
84    MaxHealthUpdate(MaxHealthEvent),
85
86    /// Agent is "recording" player.
87    PointOfView(AgentStatusEvent),
88
89    /// Game text language.
90    Language {
91        time: u64,
92        language: Result<Language, u64>,
93    },
94
95    /// Game build.
96    GWBuild { time: u64, build: u64 },
97
98    /// Sever shard id.
99    ShardId { time: u64, shard: u64 },
100
101    /// Agent got a reward chest.
102    Reward(RewardEvent),
103
104    /// Appears once per buff per agent on logging start.
105    BuffInitial(BuffInitialEvent),
106
107    /// Agent position change.
108    Position(PositionEvent),
109
110    /// Agent velocity change.
111    Velocity(PositionEvent),
112
113    /// Agent facing change.
114    Facing(PositionEvent),
115
116    /// Agent team change.
117    TeamChange(TeamChangeEvent),
118
119    /// Agent is now an attack target.
120    AttackTarget(AttackTargetEvent),
121
122    /// Agent targetability change.
123    Targetable(TargetableEvent),
124
125    /// Map id.
126    MapId { time: u64, map: u64 },
127
128    /// Agent with active buff.
129    StackActive(StackActiveEvent),
130
131    /// Agent with reset buff.
132    StackReset(StackResetEvent),
133
134    /// Agent is in guild.
135    Guild(GuildEvent),
136
137    /// Buff information.
138    BuffInfo(BuffInfo),
139
140    /// Buff formula.
141    BuffFormula(BuffFormula),
142
143    /// Skill information.
144    SkillInfo(SkillInfo),
145
146    /// Skill action.
147    SkillTiming(SkillTiming),
148
149    /// Agent breakbar state change.
150    BreakbarState(BreakbarStateEvent),
151
152    /// Breakbar percentage.
153    BreakbarPercent(BreakbarPercentEvent),
154
155    /// Error.
156    Integrity(ErrorEvent),
157
158    /// Agent has marker.
159    AgentMarker(AgentMarkerEvent),
160
161    /// Agent barrier change.
162    BarrierUpdate(BarrierUpdateEvent),
163
164    /// Arc UI stats reset.
165    StatReset { time: u64, target: u64 },
166
167    /// A custom event created by an extension (addon/plugin).
168    Extension { sig: u32, event: Event },
169
170    /// Delayed combat event.
171    ApiDelayed { event: Box<EventKind> },
172
173    /// Instance started.
174    InstanceStart { time: u64, start: u64 },
175
176    /// Tick rate.
177    RateHealth { time: u64, rate: u64 },
178
179    /// Last 90% before down for downs contribution.
180    Last90BeforeDown(DownContributionEvent),
181
182    /// Effect created or ended.
183    Effect45(Effect45),
184
185    /// Content id to GUID.
186    ///
187    /// This maps a volatile content id to a stable GUID.
188    IdToGUID(ContentInfo),
189
190    /// Log NPC changed.
191    LogNPCUpdate(LogEvent),
192
193    /// A custom combat event created by an extension (addon/plugin).
194    ExtensionCombat { sig: u32, event: Event },
195
196    /// Fractal scale.
197    FractalScale { time: u64, scale: u64 },
198
199    /// Effect created or ended.
200    Effect51(Effect51),
201
202    /// Combat ruleset.
203    Ruleset(Ruleset),
204
205    /// Squad marker placed or removed.
206    SquadMarker(SquadMarkerEvent),
207
208    /// ArcDPS build information.
209    ArcBuild(ArcBuildEvent),
210
211    /// Agent gliding state changed.
212    Glider(GliderEvent),
213
214    /// Effect
215    Stunbreak(StunbreakEvent),
216
217    /// Missile created.
218    MissileCreate(MissileCreate),
219
220    /// Missile launched or relaunched.
221    MissileLaunch(MissileLaunch),
222
223    /// Missile removed or destroyed.
224    MissileRemove(MissileRemove),
225
226    /// Ground effect created.
227    EffectGroundCreate(GroundEffect),
228
229    /// Ground effect removed.
230    EffectGroundRemove(GroundEffectRemove),
231
232    /// Effect around agent created.
233    EffectAgentCreate(AgentEffect),
234
235    /// Effect around agent removed.
236    EffectAgentRemove(AgentEffectRemove),
237
238    /// Player IID (unique agent id) change.
239    IIDChange { time: u64, id: u64, previous: u64 },
240
241    /// Map change.
242    MapChange { time: u64, map: u64, previous: u64 },
243
244    /// Unknown event.
245    Unknown(Event),
246}
247
248impl From<Event> for EventKind {
249    #[inline]
250    fn from(mut event: Event) -> Self {
251        unsafe {
252            match event.categorize() {
253                EventCategory::Activation => Self::Activation(event.extract()),
254                EventCategory::BuffRemove => Self::BuffRemove(event.extract()),
255                EventCategory::BuffApply => Self::BuffApply(event.extract()),
256                EventCategory::BuffDamage => Self::BuffDamage(event.extract()),
257                EventCategory::Strike => Self::Strike(event.extract()),
258
259                EventCategory::StateChange => match event.get_statechange() {
260                    StateChange::None => unreachable!("statechange none in statechange category"),
261                    StateChange::IdleEvent | StateChange::ReplInfo => {
262                        unreachable!("illegal internal statechange")
263                    }
264                    StateChange::EnterCombat => Self::EnterCombat(event.extract()),
265                    StateChange::ExitCombat => Self::ExitCombat(event.extract()),
266                    StateChange::ChangeUp => Self::ChangeUp(event.extract()),
267                    StateChange::ChangeDead => Self::ChangeDead(event.extract()),
268                    StateChange::ChangeDown => Self::ChangeDown(event.extract()),
269                    StateChange::Spawn => Self::Spawn(event.extract()),
270                    StateChange::Despawn => Self::Despawn(event.extract()),
271                    StateChange::HealthUpdate => Self::HealthUpdate(event.extract()),
272                    StateChange::SquadCombatStart => Self::SquadCombatStart(event.extract()),
273                    StateChange::SquadCombatEnd => Self::SquadCombatEnd(event.extract()),
274                    StateChange::WeaponSwap => Self::WeaponSwap(event.extract()),
275                    StateChange::MaxHealthUpdate => Self::MaxHealthUpdate(event.extract()),
276                    StateChange::PointOfView => Self::PointOfView(event.extract()),
277                    StateChange::Language => Self::Language {
278                        time: event.time,
279                        language: Language::try_from(event.src_agent as i32)
280                            .map_err(|_| event.src_agent),
281                    },
282                    StateChange::GWBuild => Self::GWBuild {
283                        time: event.time,
284                        build: event.src_agent,
285                    },
286                    StateChange::ShardId => Self::ShardId {
287                        time: event.time,
288                        shard: event.src_agent,
289                    },
290                    StateChange::Reward => Self::Reward(event.extract()),
291                    StateChange::BuffInitial => Self::BuffInitial(event.extract()),
292                    StateChange::Position => Self::Position(event.extract()),
293                    StateChange::Velocity => Self::Velocity(event.extract()),
294                    StateChange::Facing => Self::Facing(event.extract()),
295                    StateChange::TeamChange => Self::TeamChange(event.extract()),
296                    StateChange::AttackTarget => Self::AttackTarget(event.extract()),
297                    StateChange::Targetable => Self::Targetable(event.extract()),
298                    StateChange::MapId => Self::MapId {
299                        time: event.time,
300                        map: event.src_agent,
301                    },
302                    StateChange::StackActive => Self::StackActive(event.extract()),
303                    StateChange::StackReset => Self::StackReset(event.extract()),
304                    StateChange::Guild => Self::Guild(event.extract()),
305                    StateChange::BuffInfo => Self::BuffInfo(event.extract()),
306                    StateChange::BuffFormula => Self::BuffFormula(event.extract()),
307                    StateChange::SkillInfo => Self::SkillInfo(event.extract()),
308                    StateChange::SkillTiming => Self::SkillTiming(event.extract()),
309                    StateChange::BreakbarState => Self::BreakbarState(event.extract()),
310                    StateChange::BreakbarPercent => Self::BreakbarPercent(event.extract()),
311                    StateChange::Integrity => Self::Integrity(event.extract()),
312                    StateChange::Marker => Self::AgentMarker(event.extract()),
313                    StateChange::BarrierUpdate => Self::BarrierUpdate(event.extract()),
314                    StateChange::StatReset => Self::StatReset {
315                        time: event.time,
316                        target: event.src_agent,
317                    },
318                    StateChange::Extension => Self::Extension {
319                        sig: event.get_pad_id(),
320                        event,
321                    },
322                    StateChange::ApiDelayed => {
323                        event.is_statechange = StateChange::None.into();
324                        Self::ApiDelayed {
325                            event: event.into_kind().into(),
326                        }
327                    }
328                    StateChange::InstanceStart => Self::InstanceStart {
329                        time: event.time,
330                        start: event.src_agent,
331                    },
332                    StateChange::RateHealth => Self::RateHealth {
333                        time: event.time,
334                        rate: event.src_agent,
335                    },
336                    StateChange::Last90BeforeDown => Self::Last90BeforeDown(event.extract()),
337                    StateChange::Effect45 => Self::Effect45(event.extract()),
338                    StateChange::IdToGUID => Self::IdToGUID(event.extract()),
339                    StateChange::LogNPCUpdate => Self::LogNPCUpdate(event.extract()),
340                    StateChange::ExtensionCombat => Self::ExtensionCombat {
341                        sig: event.get_pad_id(),
342                        event,
343                    },
344                    StateChange::FractalScale => Self::FractalScale {
345                        time: event.time,
346                        scale: event.src_agent,
347                    },
348                    StateChange::Effect51 => Self::Effect51(event.extract()),
349                    StateChange::Ruleset => {
350                        Self::Ruleset(Ruleset::from_bits_retain(event.src_agent))
351                    }
352                    StateChange::SquadMarker => Self::SquadMarker(event.extract()),
353                    StateChange::ArcBuild => Self::ArcBuild(event.extract()),
354                    StateChange::Glider => Self::Glider(event.extract()),
355                    StateChange::Stunbreak => Self::Stunbreak(event.extract()),
356                    StateChange::MissileCreate => Self::MissileCreate(event.extract()),
357                    StateChange::MissileLaunch => Self::MissileLaunch(event.extract()),
358                    StateChange::MissileRemove => Self::MissileRemove(event.extract()),
359                    StateChange::EffectGroundCreate => Self::EffectGroundCreate(event.extract()),
360                    StateChange::EffectGroundRemove => Self::EffectGroundRemove(event.extract()),
361                    StateChange::EffectAgentCreate => Self::EffectAgentCreate(event.extract()),
362                    StateChange::EffectAgentRemove => Self::EffectAgentRemove(event.extract()),
363                    StateChange::IIDChange => Self::IIDChange {
364                        time: event.time,
365                        id: event.dst_agent,
366                        previous: event.src_agent,
367                    },
368                    StateChange::MapChange => Self::MapChange {
369                        time: event.time,
370                        map: event.src_agent,
371                        previous: event.dst_agent,
372                    },
373                    StateChange::Unknown(_) => Self::Unknown(event),
374                },
375            }
376        }
377    }
378}