1use super::SemanticSupport;
2
3const COMBAT_LOG_METADATA_HANDLER: &str = "combat-log metadata has no simulation impact";
4const SPELLBOOK_METADATA_HANDLER: &str = "spellbook display metadata has no combat impact";
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8#[repr(u16)]
9#[non_exhaustive]
10pub enum SpellAttributeKind {
11 RangedAbility = 1,
12 Ability = 4,
13 Passive = 6,
14 Hidden = 7,
15 DoNotLog = 8,
16 NotShapeshifted = 16,
17 RequiresStealth = 17,
18 DoNotSheath = 18,
19 CancelsAutoAttack = 20,
20 NoActiveDefense = 21,
21 NoCombat = 22,
22 AllowWhileMounted = 24,
23 AllowWhileSitting = 27,
24 NoImmunities = 29,
25 NoAuraCancel = 31,
26 Channeled = 34,
27 NoRedirection = 35,
28 AllowWhileStealthed = 37,
29 SelfChanneled = 38,
30 NoReflection = 39,
31 InitiatesAutoAttack = 41,
32 NoThreat = 42,
33 ImmunityPurgesEffect = 47,
34 NoAutoCastAi = 49,
35 DiscountPowerOnMiss = 59,
36 NoAuraIcon = 60,
37 IgnoreLineOfSight = 66,
38 IncludeAdvancedCombatLog = 72,
39 ChainFromCaster = 76,
40 AllowWhileNotShapeshifted = 83,
41 NotAnAction = 92,
42 CannotCrit = 93,
43 FoodAura = 95,
44 DotStackingRule = 103,
45 NotAProc = 105,
46 RequiresMainHand = 106,
47 SuppressCasterProcs = 112,
48 SuppressTargetProcs = 113,
49 AlwaysHit = 114,
50 InstantTargetProcs = 115,
51 AllowAuraWhileDead = 116,
52 RequiresOffHand = 120,
53 TreatAsPeriodic = 121,
54 CanProcFromProcs = 122,
55 DoNotDisplayRange = 126,
56 NoCastLog = 128,
57 CannotBeStolen = 134,
58 AllowCastWhileCasting = 135,
59 DisableTargetMultiplier = 136,
60 NotInSpellbook = 143,
61 AllowProcWhileSitting = 147,
62 AuraNeverBounces = 148,
63 AllowEnteringArena = 149,
64 SuppressWeaponProcs = 151,
65 AllowWhileStunned = 163,
66 TickOnApplication = 169,
67 SpellHasteAffectsPeriodic = 173,
68 TreatAsAreaEffect = 175,
69 AllowWhileFleeing = 177,
70 AllowWhileConfused = 178,
71 RequiresLineOfSight = 186,
72 IgnoreTimeRate = 196,
73 NoAuraLog = 202,
74 AllowWhileRidingVehicle = 204,
75 TapsImmediately = 215,
76 VehicleImmunityCategory = 218,
77 IgnoreHealingModifiers = 219,
78 DoNotAutoSelectTarget = 220,
79 DisablePlayerMultiplier = 221,
80 AllowSpellReflection = 224,
81 DisableAuraWhileDead = 226,
82 CannotDodge = 247,
83 CannotParry = 248,
84 CannotMiss = 249,
85 CanProcFromSuppressedTarget = 254,
86 CannotBlock = 256,
87 PeriodicCanCrit = 265,
88 AuraPointsOnClient = 268,
89 NotInSpellbookUntilLearned = 269,
90 HasteAffectsDuration = 273,
91 RequiresEquippedArmorType = 276,
92 MeleeHasteAffectsPeriodic = 278,
93 MasteryAffectsPoints = 285,
94 DisplayLargeAuraIcon = 286,
95 FixedTravelTime = 292,
96 AllowCastWhileChanneling = 308,
97 SpellcastOverrideInSpellbook = 310,
98 DisablePlayerHealingMultiplier = 312,
99 DisableTargetPositiveMultiplier = 321,
100 TargetSpecificCooldown = 330,
101 ResetCooldownOnEncounterEnd = 333,
102 RollingPeriodic = 334,
103 UpdatePassivesOnApplyRemove = 344,
104 EnforceFacingPrimaryTargetOnly = 351,
105 ScalesWithCastingItemLevel = 354,
106 DoNotLogOnLearn = 355,
107 EnableProcsFromSuppressed = 384,
108 CanProcFromSuppressed = 385,
109 IgnoreCastingDisabled = 393,
110 OnlyProcFromClassAbilities = 415,
111 AllowClassAbilityProcs = 416,
112 NameplatePersonalAura = 423,
113 NameplateEnemyDebuff = 426,
114 DoNotConsumeAuraStackOnProc = 428,
115 PeriodicRefreshExtendsDuration = 436,
116 DoNotDisplayCastTime = 441,
117 AlwaysAllowNegativeHealingModifiers = 442,
118 PreventJumpingDuringPrecast = 448,
119 HidePassiveFromTooltip = 451,
120 AsynchronousStackingBuff = 490,
121 ImportantSpell = 491,
122 ExternalDefensive = 499,
123 BigDefensive = 512,
124}
125
126impl SpellAttributeKind {
127 #[must_use]
128 pub const fn block(self) -> usize {
129 self as usize / i32::BITS as usize
130 }
131
132 #[must_use]
133 pub const fn mask(self) -> i32 {
134 1_i32.wrapping_shl(self as u32 % i32::BITS)
135 }
136}
137
138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
140pub struct SpellAttributeSemantic {
141 pub kind: SpellAttributeKind,
142 pub name: &'static str,
143 pub support: SemanticSupport,
144 pub handler: &'static str,
145}
146
147const fn spell_attribute(
148 kind: SpellAttributeKind,
149 name: &'static str,
150 support: SemanticSupport,
151 handler: &'static str,
152) -> SpellAttributeSemantic {
153 SpellAttributeSemantic {
154 kind,
155 name,
156 support,
157 handler,
158 }
159}
160
161#[rustfmt::skip]
163pub const SPELL_ATTRIBUTE_SEMANTICS: &[SpellAttributeSemantic] = &[
164 spell_attribute(SpellAttributeKind::RangedAbility, "Uses Ranged Slot", SemanticSupport::Generic, "base GCD haste classification combined with passive auras 320 and 417"),
165 spell_attribute(SpellAttributeKind::Ability, "Is Ability", SemanticSupport::Generic, "base GCD haste classification combined with passive auras 320 and 417"),
166 spell_attribute(SpellAttributeKind::Passive, "Passive", SemanticSupport::Generic, "passive spell classification"),
167 spell_attribute(SpellAttributeKind::Hidden, "Do Not Display", SemanticSupport::Ignored, "display metadata has no combat impact"),
168 spell_attribute(SpellAttributeKind::DoNotLog, "Do Not Log", SemanticSupport::Ignored, COMBAT_LOG_METADATA_HANDLER),
169 spell_attribute(SpellAttributeKind::NotShapeshifted, "Not Shapeshifted", SemanticSupport::Generic, "shared player form cast gating"),
170 spell_attribute(SpellAttributeKind::RequiresStealth, "Requires Stealth", SemanticSupport::Generic, "shared cast gating against player stealth state"),
171 spell_attribute(SpellAttributeKind::DoNotSheath, "Do Not Sheath", SemanticSupport::Ignored, "animation metadata has no combat impact"),
172 spell_attribute(SpellAttributeKind::CancelsAutoAttack, "Cancels Auto Attack", SemanticSupport::Generic, "action-driven auto-attack cancellation"),
173 spell_attribute(SpellAttributeKind::NoActiveDefense, "No Active Defense", SemanticSupport::Unsupported, "active defense and attack avoidance are not modelled"),
174 spell_attribute(SpellAttributeKind::NoCombat, "Does Not Enter Combat", SemanticSupport::Unsupported, "per-action combat-state transitions are not modelled"),
175 spell_attribute(SpellAttributeKind::AllowWhileMounted, "Allow While Mounted", SemanticSupport::Unsupported, "mounted actor state and cast gating are not modelled"),
176 spell_attribute(SpellAttributeKind::AllowWhileSitting, "Allow While Sitting", SemanticSupport::Unsupported, "sitting actor state and cast gating are not modelled"),
177 spell_attribute(SpellAttributeKind::NoImmunities, "No Immunities", SemanticSupport::Unsupported, "spell-level bypass of active school and mechanic immunities is not modelled"),
178 spell_attribute(SpellAttributeKind::NoAuraCancel, "No Aura Cancel", SemanticSupport::Unsupported, "aura cancellation eligibility is not modelled"),
179 spell_attribute(SpellAttributeKind::Channeled, "Is Channelled", SemanticSupport::Generic, "channel cast-time resolution"),
180 spell_attribute(SpellAttributeKind::NoRedirection, "No Redirection", SemanticSupport::Unsupported, "spell-level bypass of active split and share damage is not modelled"),
181 spell_attribute(SpellAttributeKind::AllowWhileStealthed, "Allow While Stealthed", SemanticSupport::Generic, "stealth-break resolution"),
182 spell_attribute(SpellAttributeKind::SelfChanneled, "Is Self Channelled", SemanticSupport::Generic, "channel cast-time resolution"),
183 spell_attribute(SpellAttributeKind::NoReflection, "No Reflection", SemanticSupport::Generic, "bypasses shared target reflection and deflection resolution"),
184 spell_attribute(SpellAttributeKind::InitiatesAutoAttack, "Initiates Auto Attack", SemanticSupport::Generic, "action-driven auto-attack start scheduling"),
185 spell_attribute(SpellAttributeKind::NoThreat, "No Threat", SemanticSupport::Unsupported, "per-action threat generation is not modelled"),
186 spell_attribute(SpellAttributeKind::ImmunityPurgesEffect, "Immunity Purges Effect", SemanticSupport::Unsupported, "immunity-driven aura purging is not modelled"),
187 spell_attribute(SpellAttributeKind::NoAutoCastAi, "No AutoCast (AI)", SemanticSupport::Unsupported, "pet and creature autocast eligibility is not modelled"),
188 spell_attribute(SpellAttributeKind::DiscountPowerOnMiss, "Discount Power On Miss", SemanticSupport::Unsupported, "miss outcomes and cost refunds are not modelled"),
189 spell_attribute(SpellAttributeKind::NoAuraIcon, "No Aura Icon", SemanticSupport::Ignored, "display metadata has no combat impact"),
190 spell_attribute(SpellAttributeKind::IgnoreLineOfSight, "Ignore Line of Sight", SemanticSupport::Generic, "shared hostile range and line-of-sight cast gating"),
191 spell_attribute(SpellAttributeKind::IncludeAdvancedCombatLog, "Include In Advanced Combat Log", SemanticSupport::Ignored, COMBAT_LOG_METADATA_HANDLER),
192 spell_attribute(SpellAttributeKind::ChainFromCaster, "Chain From Caster", SemanticSupport::Generic, "shared chain targeting keeps every additional target anchored on the caster"),
193 spell_attribute(SpellAttributeKind::AllowWhileNotShapeshifted, "Allow While Not Shapeshifted", SemanticSupport::Generic, "caster-form exception to shared stance-mask gating"),
194 spell_attribute(SpellAttributeKind::NotAnAction, "Not an Action", SemanticSupport::Unsupported, "action classification is not consumed by cast or proc resolution"),
195 spell_attribute(SpellAttributeKind::CannotCrit, "Can't Crit", SemanticSupport::Generic, "direct and triggered damage critical-hit resolution"),
196 spell_attribute(SpellAttributeKind::FoodAura, "Food Aura", SemanticSupport::Unsupported, "item-cast retention semantics are not modelled"),
197 spell_attribute(SpellAttributeKind::DotStackingRule, "DoT Stacking Rule", SemanticSupport::Ignored, "legacy flag is not consumed by current SimC"),
198 spell_attribute(SpellAttributeKind::NotAProc, "Not a Proc", SemanticSupport::Partial, "proc-source provenance"),
199 spell_attribute(SpellAttributeKind::RequiresMainHand, "Requires Main-Hand Weapon", SemanticSupport::Generic, "shared equipped-weapon cast gating"),
200 spell_attribute(SpellAttributeKind::SuppressCasterProcs, "Suppress Caster Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
201 spell_attribute(SpellAttributeKind::SuppressTargetProcs, "Suppress Target Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
202 spell_attribute(SpellAttributeKind::AlwaysHit, "Always Hit", SemanticSupport::Generic, "attack-table miss override"),
203 spell_attribute(SpellAttributeKind::InstantTargetProcs, "Instant Target Procs", SemanticSupport::Unsupported, "target-proc timing is not modelled"),
204 spell_attribute(SpellAttributeKind::AllowAuraWhileDead, "Allow Aura While Dead", SemanticSupport::Unsupported, "dead actor state and aura eligibility are not modelled"),
205 spell_attribute(SpellAttributeKind::RequiresOffHand, "Requires Off-Hand Weapon", SemanticSupport::Generic, "shared equipped-weapon cast gating and off-hand AP source"),
206 spell_attribute(SpellAttributeKind::TreatAsPeriodic, "Treat As Periodic", SemanticSupport::Generic, "shared damage flags route the impact through periodic modifiers"),
207 spell_attribute(SpellAttributeKind::CanProcFromProcs, "Can Proc From Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
208 spell_attribute(SpellAttributeKind::DoNotDisplayRange, "Do Not Display Range", SemanticSupport::Ignored, "display metadata has no combat impact"),
209 spell_attribute(SpellAttributeKind::NoCastLog, "No Cast Log", SemanticSupport::Ignored, COMBAT_LOG_METADATA_HANDLER),
210 spell_attribute(SpellAttributeKind::CannotBeStolen, "Cannot Be Stolen", SemanticSupport::Unsupported, "spellsteal does not yet exclude auras carrying this attribute"),
211 spell_attribute(SpellAttributeKind::AllowCastWhileCasting, "Allow Cast While Casting", SemanticSupport::Generic, "cast concurrency gating"),
212 spell_attribute(SpellAttributeKind::DisableTargetMultiplier, "Disable Target Multipliers", SemanticSupport::Generic, "damage multiplier routing"),
213 spell_attribute(SpellAttributeKind::NotInSpellbook, "Not In Spellbook", SemanticSupport::Ignored, SPELLBOOK_METADATA_HANDLER),
214 spell_attribute(SpellAttributeKind::AllowProcWhileSitting, "Allow Proc While Sitting", SemanticSupport::Unsupported, "sitting actor state and proc eligibility are not modelled"),
215 spell_attribute(SpellAttributeKind::AuraNeverBounces, "Aura Never Bounces", SemanticSupport::Unsupported, "multi-target aura bouncing is not modelled"),
216 spell_attribute(SpellAttributeKind::AllowEnteringArena, "Allow Entering Arena", SemanticSupport::Unsupported, "arena state and aura persistence are not modelled"),
217 spell_attribute(SpellAttributeKind::SuppressWeaponProcs, "Suppress Weapon Procs", SemanticSupport::Partial, "proc-source provenance"),
218 spell_attribute(SpellAttributeKind::AllowWhileStunned, "Allow While Stunned", SemanticSupport::Unsupported, "this cast exception is not applied to the player stun gate"),
219 spell_attribute(SpellAttributeKind::TickOnApplication, "Extra Initial Period", SemanticSupport::Generic, "periodic scheduling"),
220 spell_attribute(SpellAttributeKind::SpellHasteAffectsPeriodic, "Spell Haste Affects Periodic", SemanticSupport::Generic, "periodic cadence resolution"),
221 spell_attribute(SpellAttributeKind::TreatAsAreaEffect, "Treat as Area Effect", SemanticSupport::Generic, "shared AoE target-count and damage dispatch"),
222 spell_attribute(SpellAttributeKind::AllowWhileFleeing, "Allow While Fleeing", SemanticSupport::Unsupported, "this cast exception is not applied to the player fear gate"),
223 spell_attribute(SpellAttributeKind::AllowWhileConfused, "Allow While Confused", SemanticSupport::Unsupported, "this cast exception is not applied to a confusion gate"),
224 spell_attribute(SpellAttributeKind::RequiresLineOfSight, "Requires Line of Sight", SemanticSupport::Generic, "default hostile line-of-sight target gating"),
225 spell_attribute(SpellAttributeKind::IgnoreTimeRate, "Ignore Time Rate", SemanticSupport::Unsupported, "per-aura opt-out from active time-rate modifiers is not modelled"),
226 spell_attribute(SpellAttributeKind::NoAuraLog, "No Aura Log", SemanticSupport::Ignored, COMBAT_LOG_METADATA_HANDLER),
227 spell_attribute(SpellAttributeKind::AllowWhileRidingVehicle, "Allow While Riding Vehicle", SemanticSupport::Unsupported, "vehicle actor state and cast gating are not modelled"),
228 spell_attribute(SpellAttributeKind::TapsImmediately, "Taps Immediately", SemanticSupport::Unsupported, "target tapping and ownership are not modelled"),
229 spell_attribute(SpellAttributeKind::VehicleImmunityCategory, "Vehicle Immunity Category", SemanticSupport::Unsupported, "vehicle immunity categories are not modelled"),
230 spell_attribute(SpellAttributeKind::IgnoreHealingModifiers, "Ignore Healing Modifiers", SemanticSupport::Unsupported, "spell-level bypass of the shared healing modifiers is not modelled"),
231 spell_attribute(SpellAttributeKind::DoNotAutoSelectTarget, "Do Not Auto Select Target with Initiates Combat", SemanticSupport::Unsupported, "automatic target selection across actors is not modelled"),
232 spell_attribute(SpellAttributeKind::DisablePlayerMultiplier, "Disable Player Multipliers", SemanticSupport::Generic, "damage multiplier routing"),
233 spell_attribute(SpellAttributeKind::AllowSpellReflection, "Allow Spell Reflection", SemanticSupport::Generic, "explicitly permits reflection independent of magic ability classification"),
234 spell_attribute(SpellAttributeKind::DisableAuraWhileDead, "Disable Aura While Dead", SemanticSupport::Unsupported, "dead actor state and aura disabling are not modelled"),
235 spell_attribute(SpellAttributeKind::CannotDodge, "Cannot Be Dodged", SemanticSupport::Generic, "attack-table dodge override"),
236 spell_attribute(SpellAttributeKind::CannotParry, "Cannot Be Parried", SemanticSupport::Generic, "attack-table parry override"),
237 spell_attribute(SpellAttributeKind::CannotMiss, "Cannot Miss", SemanticSupport::Generic, "attack-table miss override"),
238 spell_attribute(SpellAttributeKind::CanProcFromSuppressedTarget, "Can Proc From Suppressed Target Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
239 spell_attribute(SpellAttributeKind::CannotBlock, "Cannot Be Blocked", SemanticSupport::Generic, "attack-table block override"),
240 spell_attribute(SpellAttributeKind::PeriodicCanCrit, "Periodic Can Crit", SemanticSupport::Generic, "periodic critical-hit resolution"),
241 spell_attribute(SpellAttributeKind::AuraPointsOnClient, "Aura Points On Client", SemanticSupport::Ignored, "client aura-display metadata has no combat impact"),
242 spell_attribute(SpellAttributeKind::NotInSpellbookUntilLearned, "Not In Spellbook Until Learned", SemanticSupport::Ignored, SPELLBOOK_METADATA_HANDLER),
243 spell_attribute(SpellAttributeKind::HasteAffectsDuration, "Haste Affects Duration", SemanticSupport::Generic, "aura duration resolution"),
244 spell_attribute(SpellAttributeKind::RequiresEquippedArmorType, "Requires Equipped Armor Type", SemanticSupport::Unsupported, "equipment cast gating"),
245 spell_attribute(SpellAttributeKind::MeleeHasteAffectsPeriodic, "Melee Haste Affects Periodic", SemanticSupport::Generic, "periodic cadence resolution"),
246 spell_attribute(SpellAttributeKind::MasteryAffectsPoints, "Mastery Affects Points", SemanticSupport::Generic, "live mastery effect-point resolution"),
247 spell_attribute(SpellAttributeKind::DisplayLargeAuraIcon, "Display Large Aura Icon On Unit Frames", SemanticSupport::Ignored, "display metadata has no combat impact"),
248 spell_attribute(SpellAttributeKind::FixedTravelTime, "Missile Speed is Delay", SemanticSupport::Generic, "shared spatial travel-time resolution"),
249 spell_attribute(SpellAttributeKind::AllowCastWhileChanneling, "Allow Cast While Channeling", SemanticSupport::Generic, "cast concurrency gating"),
250 spell_attribute(SpellAttributeKind::SpellcastOverrideInSpellbook, "Spellcast Override In Spellbook", SemanticSupport::Ignored, SPELLBOOK_METADATA_HANDLER),
251 spell_attribute(SpellAttributeKind::DisablePlayerHealingMultiplier, "Disable Player Healing Multipliers", SemanticSupport::Unsupported, "spell-level suppression of source healing multipliers is not modelled"),
252 spell_attribute(SpellAttributeKind::DisableTargetPositiveMultiplier, "Disable Target Positive Multipliers", SemanticSupport::Generic, "damage multiplier routing"),
253 spell_attribute(SpellAttributeKind::TargetSpecificCooldown, "Target-Specific Cooldown", SemanticSupport::Unsupported, "per-target cooldown state is not modelled"),
254 spell_attribute(SpellAttributeKind::ResetCooldownOnEncounterEnd, "Reset Cooldown Upon Ending Encounter", SemanticSupport::Ignored, "single-encounter iteration reset clears every cooldown"),
255 spell_attribute(SpellAttributeKind::RollingPeriodic, "Rolling Periodic", SemanticSupport::Generic, "rolling periodic damage pool"),
256 spell_attribute(SpellAttributeKind::UpdatePassivesOnApplyRemove, "Update Passives On Apply/Remove", SemanticSupport::Generic, "attribute-marked passives remain active auras and recompute through apply/remove"),
257 spell_attribute(SpellAttributeKind::EnforceFacingPrimaryTargetOnly, "Enforce Facing on Primary Target Only", SemanticSupport::Generic, "caster cone and line geometry faces the explicit primary target"),
258 spell_attribute(SpellAttributeKind::ScalesWithCastingItemLevel, "Scales with Casting Item's Level", SemanticSupport::Generic, "consumable item-level scaling"),
259 spell_attribute(SpellAttributeKind::DoNotLogOnLearn, "Do Not Log On Learn", SemanticSupport::Ignored, COMBAT_LOG_METADATA_HANDLER),
260 spell_attribute(SpellAttributeKind::EnableProcsFromSuppressed, "Enable Procs from Suppressed Caster Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
261 spell_attribute(SpellAttributeKind::CanProcFromSuppressed, "Can Proc from Suppressed Caster Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
262 spell_attribute(SpellAttributeKind::IgnoreCastingDisabled, "Ignore Casting Disabled", SemanticSupport::Generic, "aura 263 casting exception"),
263 spell_attribute(SpellAttributeKind::OnlyProcFromClassAbilities, "Only Proc From Class Abilities", SemanticSupport::Generic, "central paired proc provenance policy"),
264 spell_attribute(SpellAttributeKind::AllowClassAbilityProcs, "Allow Class Ability Procs", SemanticSupport::Generic, "central paired proc provenance policy"),
265 spell_attribute(SpellAttributeKind::NameplatePersonalAura, "Nameplate Personal Buffs/Debuffs", SemanticSupport::Ignored, "nameplate display metadata has no combat impact"),
266 spell_attribute(SpellAttributeKind::NameplateEnemyDebuff, "Nameplate Enemy Debuffs", SemanticSupport::Ignored, "nameplate display metadata has no combat impact"),
267 spell_attribute(SpellAttributeKind::DoNotConsumeAuraStackOnProc, "Do Not Consume Aura Stack On Proc", SemanticSupport::Unsupported, "attribute-level exception to stacks-as-proc-charges consumption is not modelled"),
268 spell_attribute(SpellAttributeKind::PeriodicRefreshExtendsDuration, "Periodic Refresh Extends Duration", SemanticSupport::Generic, "pandemic refresh carryover"),
269 spell_attribute(SpellAttributeKind::DoNotDisplayCastTime, "Do Not Display Cast Time", SemanticSupport::Ignored, "cast-bar display metadata has no combat impact"),
270 spell_attribute(SpellAttributeKind::AlwaysAllowNegativeHealingModifiers, "Always Allow Negative Healing Percent Modifiers", SemanticSupport::Unsupported, "negative healing modifier rules are not modelled"),
271 spell_attribute(SpellAttributeKind::PreventJumpingDuringPrecast, "Prevent Jumping During Precast", SemanticSupport::Unsupported, "jump state and precast movement locks are not modelled"),
272 spell_attribute(SpellAttributeKind::HidePassiveFromTooltip, "Hide Passive From Tooltip", SemanticSupport::Ignored, "tooltip display metadata has no combat impact"),
273 spell_attribute(SpellAttributeKind::AsynchronousStackingBuff, "Asynchronous Stacking Buff", SemanticSupport::Generic, "independent aura-stack expiration"),
274 spell_attribute(SpellAttributeKind::ImportantSpell, "Important Spell", SemanticSupport::Ignored, "reporting metadata has no combat impact"),
275 spell_attribute(SpellAttributeKind::ExternalDefensive, "External Defensive", SemanticSupport::Unsupported, "defensive action classification is not modelled"),
276 spell_attribute(SpellAttributeKind::BigDefensive, "Big Defensive", SemanticSupport::Unsupported, "defensive action classification is not modelled"),
277];
278
279#[must_use]
281pub fn spell_attribute_semantic(raw: i32) -> Option<&'static SpellAttributeSemantic> {
282 SPELL_ATTRIBUTE_SEMANTICS
283 .iter()
284 .find(|entry| entry.kind as i32 == raw)
285}
286
287#[must_use]
289pub fn spell_attribute_is(attributes: &[i32], expected: SpellAttributeKind) -> bool {
290 attributes
291 .get(expected.block())
292 .is_some_and(|value| value & expected.mask() != 0)
293}
294
295#[must_use]
297pub fn spell_attribute_is_any(attributes: &[i32], expected: &[SpellAttributeKind]) -> bool {
298 expected
299 .iter()
300 .any(|kind| spell_attribute_is(attributes, *kind))
301}