evtc\buff/
apply.rs

1use crate::{
2    event::{impl_common, CommonEvent},
3    extract::Extract,
4    Event, EventCategory, TryExtract,
5};
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[cfg(feature = "strum")]
11use strum::{Display, EnumCount, EnumIter, IntoStaticStr, VariantNames};
12
13/// Buff apply event.
14#[derive(Debug, Clone)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16pub struct BuffApplyEvent {
17    /// Common combat event information.
18    #[cfg_attr(feature = "serde", serde(flatten))]
19    pub common: CommonEvent,
20
21    /// Kind of buff application/extension.
22    pub apply: BuffApplyKind,
23
24    /// Stack active status.
25    pub stack_active: u8,
26
27    /// Buff stack (instance) id.
28    pub stack_id: u32,
29}
30
31impl_common!(BuffApplyEvent);
32
33impl Extract for BuffApplyEvent {
34    #[inline]
35    unsafe fn extract(event: &Event) -> Self {
36        Self {
37            common: event.into(),
38            apply: BuffApplyKind::extract(event),
39            stack_active: event.is_shields,
40            stack_id: event.get_pad_id(),
41        }
42    }
43}
44
45impl TryExtract for BuffApplyEvent {
46    #[inline]
47    fn can_extract(event: &Event) -> bool {
48        event.categorize() == EventCategory::BuffApply
49    }
50}
51
52/// Buff apply behavior.
53#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
54#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
55#[cfg_attr(feature = "serde", serde(tag = "kind"))]
56#[cfg_attr(
57    feature = "strum",
58    derive(Display, EnumCount, EnumIter, IntoStaticStr, VariantNames)
59)]
60#[repr(u8)]
61pub enum BuffApplyKind {
62    /// New stack applied or existing stack replaced.
63    Apply {
64        /// Applied duration.
65        duration: i32,
66
67        /// Duration of removed stack, if any.
68        removed_duration: u32,
69    },
70
71    /// Existing stack extended.
72    Extend {
73        /// New stack duration.
74        new_duration: u32,
75
76        /// Duration change.
77        duration_change: i32,
78    },
79}
80
81impl Extract for BuffApplyKind {
82    #[inline]
83    unsafe fn extract(event: &Event) -> Self {
84        if event.is_offcycle == 0 {
85            Self::Apply {
86                duration: event.value,
87                removed_duration: event.overstack_value,
88            }
89        } else {
90            Self::Extend {
91                new_duration: event.overstack_value,
92                duration_change: event.value,
93            }
94        }
95    }
96}