wowlab_engine_combat/state/defs/
pets.rs1use wowlab_types::sim::SimTime;
4
5use super::LocalAuraIdx;
6use crate::context::HookCtx;
7
8pub(crate) type PetActionFn = fn(&mut HookCtx<'_>);
10
11#[derive(Clone, Copy, Debug, PartialEq)]
13#[must_use]
14pub struct PetStatInheritance {
15 pub(crate) attack_power: f64,
16 pub(crate) spell_power: f64,
17}
18
19impl PetStatInheritance {
20 pub const IDENTITY: Self = Self {
21 attack_power: 1.0,
22 spell_power: 1.0,
23 };
24
25 pub const fn new(attack_power: f64, spell_power: f64) -> Self {
26 Self {
27 attack_power,
28 spell_power,
29 }
30 }
31}
32
33impl Default for PetStatInheritance {
34 fn default() -> Self {
35 Self::IDENTITY
36 }
37}
38
39#[derive(Clone, Copy, Debug, PartialEq)]
41#[must_use]
42pub struct PetOwnerCoefficients {
43 pub armor: f64,
44 pub health: f64,
45 pub attack_power_from_attack_power: f64,
46 pub attack_power_from_spell_power: f64,
47 pub spell_power_from_attack_power: f64,
48 pub spell_power_from_spell_power: f64,
49}
50
51impl PetOwnerCoefficients {
52 pub const fn new() -> Self {
53 Self {
54 armor: 0.0,
55 health: 0.0,
56 attack_power_from_attack_power: 0.0,
57 attack_power_from_spell_power: 0.0,
58 spell_power_from_attack_power: 0.0,
59 spell_power_from_spell_power: 0.0,
60 }
61 }
62
63 pub const fn owner_identity() -> Self {
65 Self::new()
66 .armor(1.0)
67 .health(1.0)
68 .attack_power(1.0, 0.0)
69 .spell_power(0.0, 1.0)
70 }
71
72 pub const fn armor(mut self, coefficient: f64) -> Self {
73 self.armor = coefficient;
74
75 self
76 }
77
78 pub const fn health(mut self, coefficient: f64) -> Self {
79 self.health = coefficient;
80
81 self
82 }
83
84 pub const fn attack_power(mut self, from_attack_power: f64, from_spell_power: f64) -> Self {
85 self.attack_power_from_attack_power = from_attack_power;
86 self.attack_power_from_spell_power = from_spell_power;
87
88 self
89 }
90
91 pub const fn spell_power(mut self, from_attack_power: f64, from_spell_power: f64) -> Self {
92 self.spell_power_from_attack_power = from_attack_power;
93 self.spell_power_from_spell_power = from_spell_power;
94
95 self
96 }
97}
98
99impl Default for PetOwnerCoefficients {
100 fn default() -> Self {
101 Self::new()
102 }
103}
104
105#[derive(Clone, Copy, Debug, Default, PartialEq)]
106pub(crate) struct PetStatSnapshot {
107 pub(crate) attack_power: f64,
108 pub(crate) spell_power: f64,
109 pub(crate) armor: f64,
110 pub(crate) health: f64,
111}
112
113#[derive(Clone, Copy, Debug, Eq, PartialEq)]
115#[non_exhaustive]
116#[must_use]
117pub(crate) enum PetAbilityCondition {
118 Always,
119 OwnerAuraActive(LocalAuraIdx),
120 OwnerAuraInactive(LocalAuraIdx),
121}
122
123#[derive(Clone, Copy, Debug)]
125#[must_use]
126pub struct PetAbility {
127 pub(crate) cost: f64,
128 pub(crate) minimum_resource: f64,
129 pub(crate) gcd_ms: Option<u32>,
130 pub(crate) condition: PetAbilityCondition,
131 pub(crate) action: PetActionFn,
132}
133
134impl PetAbility {
135 pub const fn new(cost: f64, minimum_resource: f64, action: PetActionFn) -> Self {
136 Self {
137 cost,
138 minimum_resource,
139 gcd_ms: None,
140 condition: PetAbilityCondition::Always,
141 action,
142 }
143 }
144
145 pub const fn gcd_ms(mut self, gcd_ms: u32) -> Self {
147 self.gcd_ms = Some(gcd_ms);
148
149 self
150 }
151
152 pub const fn while_owner_aura_active(mut self, aura: LocalAuraIdx) -> Self {
153 self.condition = PetAbilityCondition::OwnerAuraActive(aura);
154
155 self
156 }
157
158 pub const fn while_owner_aura_inactive(mut self, aura: LocalAuraIdx) -> Self {
159 self.condition = PetAbilityCondition::OwnerAuraInactive(aura);
160
161 self
162 }
163}
164
165#[derive(Clone, Copy, Debug)]
167#[must_use]
168pub struct PetActionBar {
169 pub(crate) resource_max: f64,
170 pub(crate) resource_initial: f64,
171 pub(crate) resource_regen_per_second: f64,
172 pub(crate) gcd_ms: u32,
173 pub(crate) abilities: &'static [PetAbility],
174 pub(crate) owner_coefficients: PetOwnerCoefficients,
175}
176
177#[derive(Clone, Copy, Debug)]
179#[must_use]
180pub struct PetResourceModel {
181 max: f64,
182 initial: f64,
183 regen_per_second: f64,
184}
185
186impl PetResourceModel {
187 pub const fn new(max: f64) -> Self {
188 Self {
189 max,
190 initial: max,
191 regen_per_second: 0.0,
192 }
193 }
194
195 pub const fn initial(mut self, initial: f64) -> Self {
196 self.initial = initial;
197
198 self
199 }
200
201 pub const fn regen_per_second(mut self, regen_per_second: f64) -> Self {
202 self.regen_per_second = regen_per_second;
203
204 self
205 }
206}
207
208impl PetActionBar {
209 pub const fn new(
210 resource: PetResourceModel,
211 gcd_ms: u32,
212 abilities: &'static [PetAbility],
213 ) -> Self {
214 Self {
215 resource_max: resource.max,
216 resource_initial: resource.initial,
217 resource_regen_per_second: resource.regen_per_second,
218 gcd_ms,
219 abilities,
220 owner_coefficients: PetOwnerCoefficients::new(),
221 }
222 }
223
224 pub const fn owner_coefficients(mut self, coefficients: PetOwnerCoefficients) -> Self {
225 self.owner_coefficients = coefficients;
226
227 self
228 }
229
230 pub const fn inherit_owner_stats(self) -> Self {
231 self.owner_coefficients(PetOwnerCoefficients::owner_identity())
232 }
233}
234
235#[derive(Clone, Copy, Debug)]
236pub(crate) struct PetActionState {
237 pub(crate) resource: f64,
238 pub(crate) regen_per_second: f64,
239 pub(crate) resource_updated_at: SimTime,
240 pub(crate) gcd_ready_at: SimTime,
241 pub(crate) next_action_at: Option<SimTime>,
242 pub(crate) stat_snapshot: PetStatSnapshot,
243}