1use crate::{
2 extract::{transmute_field, Extract},
3 Event, StateChange, TryExtract,
4};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub struct BuffFormula {
13 pub skill_id: u32,
14 pub formula: u32,
15 pub attr1: u32,
16 pub attr2: u32,
17 pub param1: f32,
18 pub param2: f32,
19 pub param3: f32,
20 pub trait_src: u32,
21 pub trait_self: u32,
22 pub buff_src: u32,
23 pub buff_self: u32,
24 pub content_reference: f32, pub not_npc: bool,
26 pub not_player: bool,
27 pub is_break: bool,
28 pub value_type: u8,
29 pub value: u32,
30}
31
32impl BuffFormula {
33 #[inline]
35 pub fn is_unconditional(&self) -> bool {
36 self.trait_src == 0 && self.trait_self == 0 && self.buff_src == 0 && self.buff_self == 0
37 }
38}
39
40impl Extract for BuffFormula {
41 #[inline]
42 unsafe fn extract(event: &Event) -> Self {
43 RawBuffFormula::extract(event).into()
44 }
45}
46
47impl TryExtract for BuffFormula {
48 #[inline]
49 fn can_extract(event: &Event) -> bool {
50 RawBuffFormula::can_extract(event)
51 }
52}
53
54impl From<RawBuffFormula> for BuffFormula {
55 #[inline]
56 fn from(raw: RawBuffFormula) -> Self {
57 Self {
58 skill_id: raw.skill_id,
59 formula: raw.formula as _,
60 attr1: raw.attr1 as _,
61 attr2: raw.attr2 as _,
62 param1: raw.param1,
63 param2: raw.param2,
64 param3: raw.param3,
65 trait_src: raw.trait_src as _,
66 trait_self: raw.trait_self as _,
67 buff_src: raw.buff_src as _,
68 buff_self: raw.buff_self as _,
69 content_reference: raw.content_reference,
70 not_npc: raw.not_npc != 0,
71 not_player: raw.not_player != 0,
72 is_break: raw.is_break != 0,
73 value_type: raw.value_type,
74 value: raw.value,
75 }
76 }
77}
78
79#[derive(Debug, Clone)]
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82pub struct RawBuffFormula {
83 pub skill_id: u32,
84 pub formula: f32,
85 pub attr1: f32,
86 pub attr2: f32,
87 pub param1: f32,
88 pub param2: f32,
89 pub param3: f32,
90 pub trait_src: f32,
91 pub trait_self: f32,
92 pub buff_src: f32,
93 pub buff_self: f32,
94 pub content_reference: f32,
95 pub not_npc: u8,
96 pub not_player: u8,
97 pub is_break: u8,
98 pub value_type: u8,
99 pub value: u32,
100}
101
102impl RawBuffFormula {
103 #[inline]
105 pub fn is_unconditional(&self) -> bool {
106 self.trait_src == 0.0
107 && self.trait_self == 0.0
108 && self.buff_src == 0.0
109 && self.buff_self == 0.0
110 }
111}
112
113impl Extract for RawBuffFormula {
114 #[inline]
115 unsafe fn extract(event: &Event) -> Self {
116 let [kind, attr1, attr2, param1, param2, param3, trait_src, trait_self, content_reference] =
117 transmute_field!(event.time as [f32; 9]);
118 let [buff_src, buff_self] = transmute_field!(event.src_instance_id as [f32; 2]);
119
120 Self {
121 skill_id: event.skill_id,
122 formula: kind,
123 attr1,
124 attr2,
125 param1,
126 param2,
127 param3,
128 trait_src,
129 trait_self,
130 buff_src,
131 buff_self,
132 content_reference,
133 not_npc: event.is_flanking,
134 not_player: event.is_shields,
135 is_break: event.is_offcycle,
136 value_type: event.pad61,
137 value: event.overstack_value,
138 }
139 }
140}
141
142impl TryExtract for RawBuffFormula {
143 #[inline]
144 fn can_extract(event: &Event) -> bool {
145 event.get_statechange() == StateChange::BuffFormula
146 }
147}