evtc\event/
mod.rs

1//! Event bindings & utilities.
2
3mod category;
4mod common;
5mod event_kind;
6mod old;
7
8pub use self::{category::*, common::*, event_kind::*, old::*};
9
10#[allow(deprecated)]
11pub use crate::{
12    agent::{
13        AgentStatusEvent, AttackTargetEvent, BarrierUpdateEvent, BreakbarPercentEvent,
14        BreakbarStateEvent, DownContributionEvent, EnterCombatEvent, GliderEvent,
15        HealthUpdateEvent, MaxHealthEvent, StunbreakEvent, TargetableEvent, TeamChangeEvent,
16    },
17    buff::{
18        BuffApplyEvent, BuffDamageEvent, BuffFormula, BuffInfo, BuffInitialEvent, BuffRemoveEvent,
19        StackActiveEvent, StackResetEvent,
20    },
21    effect::{
22        AgentEffect, AgentEffectRemove, Effect45, Effect51, GroundEffect, GroundEffectRemove,
23    },
24    log::{ArcBuildEvent, ErrorEvent, LogEvent},
25    marker::{AgentMarkerEvent, SquadMarkerEvent},
26    missile::{MissileCreate, MissileLaunch, MissileRemove},
27    player::{GuildEvent, RewardEvent, TagEvent},
28    position::PositionEvent,
29    skill::{ActivationEvent, SkillInfo, SkillTiming},
30    strike::StrikeEvent,
31    weapon::WeaponSwapEvent,
32};
33
34use crate::{
35    buff::{BuffCycle, BuffRemove},
36    extract::Extract,
37    skill::Activation,
38    strike::Strike,
39    Affinity, StateChange, TryExtract,
40};
41
42#[cfg(feature = "serde")]
43use serde::{Deserialize, Serialize};
44
45/// ArcDPS event.
46#[derive(Debug, Clone)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48#[repr(C)]
49pub struct Event {
50    /// `timeGetTime()` at time of registering the event.
51    pub time: u64,
52
53    /// Agent that caused the event.
54    pub src_agent: u64,
55
56    /// Agent the event happened to.
57    pub dst_agent: u64,
58
59    /// Value, if relevant to the event.
60    pub value: i32,
61
62    /// Buff damage, if relevant to the event.
63    pub buff_dmg: i32,
64
65    /// Overstack value, if relevant to the event.
66    pub overstack_value: u32,
67
68    /// Skill id of the relevant skill (can be zero).
69    pub skill_id: u32,
70
71    /// Instance id of source agent as appears in game at time of event.
72    pub src_instance_id: u16,
73
74    /// Instance id of destination agent as appears in game at time of event.
75    pub dst_instance_id: u16,
76
77    /// If `src_agent` has a master (e.g. is minion), will be equal to instance id of master, zero otherwise.
78    pub src_master_instance_id: u16,
79
80    /// If `dst_agent` has a master (e.g. is minion), will be equal to instance id of master, zero otherwise.
81    pub dst_master_instance_id: u16,
82
83    /// Current affinity of `src_agent` and `dst_agent`.
84    ///
85    /// Use [`Event::get_affinity`] to obtain the value as [`Affinity`].
86    ///
87    /// *Arc calls this "iff" for if friend/foe.*
88    pub affinity: u8,
89
90    /// Buff, if relevant to the event.
91    pub buff: u8,
92
93    /// Combat result.
94    ///
95    /// For strike (direct damage) events this contains the kind of strike.
96    ///
97    /// Use [`Event::get_strike`] to obtain the value as [`Strike`].
98    pub result: u8,
99
100    /// Whether event is a kind of activation event.
101    ///
102    /// Use [`Event::get_activation`] to obtain the value as [`Activation`].
103    ///
104    /// For [`Activation::CancelFire`] and [`Activation::CancelCancel`] `value` will be the ms duration of the time spent in animation.
105    /// `buff_dmg` will be the ms duration of the scaled (as if not affected) time spent.
106    ///
107    /// For Normal or Quickness, `value` will be the ms duration at which all significant effects have happened.
108    /// `buff_dmg` will be the ms duration at which control is expected to be returned to character.
109    ///
110    /// `dst_agent` will be x/y of target of skill effect.
111    /// `overstack_value` will be z of target of skill effect.
112    pub is_activation: u8,
113
114    /// Whether event is a kind of buff remove event.
115    ///
116    /// Use [`Event::get_buffremove`] to obtain the value as [`BuffRemove`].
117    ///
118    /// `src_agent` is agent that had buff removed, `dst_agent` is the agent that removed it.
119    /// `value` will be the remaining time removed calculated as duration.
120    /// `buff_dmg` will be the remaining time removed calculated as intensity.
121    ///
122    /// For [`BuffRemove::All`] `result` will be the number of stacks removed.
123    /// For [`BuffRemove::Single`] pad61-64 (uint32) will be buff instance id of buff removed.
124    pub is_buffremove: u8,
125
126    /// Whether `src_agent` is above 90% Health.
127    pub is_ninety: u8,
128
129    /// Whether `dst_agent` is below 50% Health.
130    pub is_fifty: u8,
131
132    /// Whether `src_agent` is moving at time of event.
133    pub is_moving: u8,
134
135    /// Whether event is a kind of state change event.
136    ///
137    /// Use [Event::get_statechange] to obtain the value as [`StateChange`].
138    pub is_statechange: u8,
139
140    /// Whether `src_agent` is flanking at time of event.
141    ///
142    /// The value lies in a range of `1` to `135` degrees where `135` is rear.
143    pub is_flanking: u8,
144
145    /// Shields, if relevant to the event.
146    pub is_shields: u8,
147
148    /// For relevant events this contains when the buff cycle happened.
149    ///
150    /// Use [`Event::get_buffcycle`] to obtain the value as [`BuffCycle`].
151    pub is_offcycle: u8,
152
153    /// Padding.
154    ///
155    /// May contain information depending on the kind of event.
156    pub pad61: u8,
157
158    /// Padding.
159    ///
160    /// May contain information depending on the kind of event.
161    pub pad62: u8,
162
163    /// Padding.
164    ///
165    /// May contain information depending on the kind of event.
166    pub pad63: u8,
167
168    /// Padding.
169    ///
170    /// May contain information depending on the kind of event.
171    pub pad64: u8,
172}
173
174impl Event {
175    /// Determines the [`EventCategory`] of the event.
176    #[inline]
177    pub fn categorize(&self) -> EventCategory {
178        self.into()
179    }
180
181    /// Converts the event into its [`EventKind`] representation.
182    #[inline]
183    pub fn into_kind(self) -> EventKind {
184        self.into()
185    }
186
187    /// Returns the event `is_statechange` as [`StateChange`].
188    #[inline]
189    pub fn get_statechange(&self) -> StateChange {
190        self.is_statechange.into()
191    }
192
193    /// Returns the event `affinity` as [`Affinity`].
194    ///
195    /// This will return [`Affinity::Unknown`] if the event has no valid data in `affinity`.
196    #[inline]
197    pub fn get_affinity(&self) -> Affinity {
198        self.affinity.into()
199    }
200
201    /// Returns the event `is_activation` as [`Activation`].
202    ///
203    /// This will return [`Activation::Unknown`] if the event has no valid data in `is_activation`.
204    #[inline]
205    pub fn get_activation(&self) -> Activation {
206        self.is_activation.into()
207    }
208
209    /// Returns the event `is_buffremove` as [`BuffRemove`].
210    ///
211    /// This will return [`BuffRemove::Unknown`] if the event has no valid data in `is_buffremove`.
212    #[inline]
213    pub fn get_buffremove(&self) -> BuffRemove {
214        self.is_buffremove.into()
215    }
216
217    /// Returns the event `result` as [`Strike`].
218    ///
219    /// This will return [`Strike::Unknown`] if the event has no valid data in `result`.
220    #[inline]
221    pub fn get_strike(&self) -> Strike {
222        self.result.into()
223    }
224
225    /// Returns the event `is_offcycle` as [`BuffCycle`].
226    ///
227    /// This will return [`BuffCycle::Unknown`] if the event has no valid data in `is_offcycle`.
228    #[inline]
229    pub fn get_buffcycle(&self) -> BuffCycle {
230        self.is_offcycle.into()
231    }
232
233    /// Returns the padding as [`u32`] id/signature.
234    #[inline]
235    pub fn get_pad_id(&self) -> u32 {
236        u32::from_le_bytes([self.pad61, self.pad62, self.pad63, self.pad64])
237    }
238
239    /// Checks whether the event has a timestamp.
240    #[inline]
241    pub fn has_time(&self) -> bool {
242        self.get_statechange().has_time()
243    }
244
245    /// Retrieves the event time, if present.
246    #[inline]
247    pub fn time(&self) -> Option<u64> {
248        self.has_time().then_some(self.time)
249    }
250
251    /// Forcefully extracts a type implementing [`Extract`] from the event.
252    ///
253    /// # Safety
254    /// This is safe when the given event is a valid event to extract the type from.
255    #[inline]
256    pub unsafe fn extract<T>(&self) -> T
257    where
258        T: Extract,
259    {
260        T::extract(self)
261    }
262
263    /// Attempts to extract a type implementing [`TryExtract`] from the event.
264    #[inline]
265    pub fn try_extract<T>(&self) -> Option<T>
266    where
267        T: TryExtract,
268    {
269        T::try_extract(self)
270    }
271
272    /// Attempts to extract an [`ActivationEvent`] from the event.
273    #[inline]
274    pub fn try_to_activation(&self) -> Option<ActivationEvent> {
275        self.try_extract()
276    }
277
278    /// Attempts to extract a [`BuffRemoveEvent`] from the event.
279    #[inline]
280    pub fn try_to_buff_remove(&self) -> Option<BuffRemoveEvent> {
281        self.try_extract()
282    }
283
284    /// Attempts to extract a [`BuffApplyEvent`] from the event.
285    #[inline]
286    pub fn try_to_buff_apply(&self) -> Option<BuffApplyEvent> {
287        self.try_extract()
288    }
289
290    /// Attempts to extract a [`BuffDamageEvent`] from the event.
291    #[inline]
292    pub fn try_to_buff_damage(&self) -> Option<BuffDamageEvent> {
293        self.try_extract()
294    }
295
296    /// Attempts to extract a [`StrikeEvent`] from the event.
297    #[inline]
298    pub fn try_to_strike(&self) -> Option<StrikeEvent> {
299        self.try_extract()
300    }
301
302    /// Checks whether the event is an initial buff event.
303    #[inline]
304    pub fn is_buffinitial(&self) -> bool {
305        self.get_statechange() == StateChange::BuffInitial && self.buff == 18
306    }
307}