evtc\effect/
ground.rs

1use crate::extract::transmute_field;
2use crate::{extract::Extract, Event, StateChange, TryExtract};
3use crate::{AgentId, Position};
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8/// Effect information from an [`Event`] with [`StateChange::EffectGroundCreate`].
9#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub struct GroundEffect {
12    /// Time of registering the effect.
13    pub time: u64,
14
15    /// Source of the effect.
16    pub source: AgentId,
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    /// Location of the effect.
24    pub location: Position,
25
26    /// Effect orientation.
27    pub orientation: Position,
28
29    /// Duration of the effect in milliseconds.
30    pub duration: u32,
31
32    /// Effect flags.
33    pub flags: u8,
34
35    /// Whether the effect is on a moving platform.
36    pub moving_platform: u8,
37
38    /// Effect scale.
39    pub scale: f32,
40
41    /// Trackable id for effect remove.
42    pub tracking_id: u32,
43}
44
45impl Extract for GroundEffect {
46    #[inline]
47    unsafe fn extract(event: &Event) -> Self {
48        let [pos_x, pos_y, pos_z, orient_x, orient_y, orient_z] =
49            transmute_field!(event.dst_agent as [i16; 6]);
50        let effect_id = event.skill_id;
51        let duration = transmute_field!(event.affinity as u32);
52        let flags = event.is_buffremove;
53        let moving_platform = event.is_flanking;
54        let scale = transmute_field!(event.is_shields as i16);
55
56        Self {
57            time: event.time,
58            source: AgentId::from_src(event),
59            effect_id,
60            location: Position::from_scaled_i16s(pos_x, pos_y, pos_z, 10.0),
61            orientation: Position::from_scaled_i16s(orient_x, orient_y, orient_z, 1.0 / 1000.0),
62            duration,
63            flags,
64            moving_platform,
65            scale: scale as f32 / 1000.0,
66            tracking_id: event.get_pad_id(),
67        }
68    }
69}
70
71impl TryExtract for GroundEffect {
72    #[inline]
73    fn can_extract(event: &Event) -> bool {
74        event.get_statechange() == StateChange::EffectGroundCreate
75    }
76}
77
78/// Effect information from an [`Event`] with [`StateChange::EffectGroundRemove`].
79#[derive(Debug, Clone)]
80#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
81pub struct GroundEffectRemove {
82    /// Time of registering the effect.
83    pub time: u64,
84
85    /// Trackable id for effect remove.
86    pub tracking_id: u32,
87}
88
89impl Extract for GroundEffectRemove {
90    #[inline]
91    unsafe fn extract(event: &Event) -> Self {
92        Self {
93            time: event.time,
94            tracking_id: event.get_pad_id(),
95        }
96    }
97}
98
99impl TryExtract for GroundEffectRemove {
100    #[inline]
101    fn can_extract(event: &Event) -> bool {
102        event.get_statechange() == StateChange::EffectGroundRemove
103    }
104}