evtc\effect/
effect45.rs

1use crate::{
2    extract::{transmute_field, Extract},
3    AgentId, Event, Position, StateChange, TryExtract,
4};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9pub use super::effect51::EffectLocation;
10
11/// Effect information from an [`Event`] with [`StateChange::Effect45`].
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub struct Effect45 {
15    /// Time of registering the effect.
16    pub time: u64,
17
18    /// Id of the effect.
19    ///
20    /// Use to map to a GUID using [`StateChange::IdToGUID`] events.
21    pub effect_id: u32,
22
23    /// Source of the effect.
24    pub source: AgentId,
25
26    /// Location of the effect.
27    pub location: EffectLocation,
28
29    /// Orientation of the effect as 3 dimensional vector.
30    pub orientation: Position,
31
32    /// Duration of the effect in time or as tracking id.
33    pub duration: EffectDuration,
34}
35
36impl Effect45 {
37    /// Checks whether this is the end of an effect.
38    #[inline]
39    pub fn is_end(&self) -> bool {
40        self.effect_id == 0
41    }
42}
43
44impl Extract for Effect45 {
45    #[inline]
46    unsafe fn extract(event: &Event) -> Self {
47        let effect_id = event.skill_id;
48        let [x, y] = transmute_field!(event.affinity as [f32; 2]);
49        let z = transmute_field!(event.pad61 as f32);
50        let duration = transmute_field!(event.is_shields as u16);
51
52        Self {
53            time: event.time,
54            effect_id,
55            source: AgentId::from_src(event),
56            location: EffectLocation::extract(event),
57            orientation: [x, y, z].into(),
58            duration: if event.is_flanking != 0 || effect_id == 0 {
59                EffectDuration::TrackingId(duration)
60            } else {
61                EffectDuration::Time(duration)
62            },
63        }
64    }
65}
66
67impl TryExtract for Effect45 {
68    #[inline]
69    fn can_extract(event: &Event) -> bool {
70        event.get_statechange() == StateChange::Effect51
71    }
72}
73
74/// Duration of an effect in time or as a tracking id.
75#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77pub enum EffectDuration {
78    /// Duration as time in milliseconds.
79    Time(u16),
80
81    /// Duration as tracking id.
82    TrackingId(u16),
83}