AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
SpellProcSpellTypeMaskTest.cpp File Reference
#include "AuraScriptTestFramework.h"
#include "SpellMgr.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Classes

class  SpellProcSpellTypeMaskTest
 Tests for SpellTypeMask calculation based on proc phase. More...
 

Functions

 TEST_F (SpellProcSpellTypeMaskTest, CastPhase_UsesMaskAll)
 
 TEST_F (SpellProcSpellTypeMaskTest, FinishPhase_UsesMaskAll_EvenWithNullDamageInfo)
 
 TEST_F (SpellProcSpellTypeMaskTest, HitPhase_WithDamage_UsesDamageType)
 
 TEST_F (SpellProcSpellTypeMaskTest, HitPhase_WithHeal_UsesHealType)
 
 TEST_F (SpellProcSpellTypeMaskTest, HitPhase_NoDamageNoHeal_UsesNoDmgHeal)
 
 TEST_F (SpellProcSpellTypeMaskTest, KillingMachine_FinishPhase_MatchesDamageTypeMask)
 Regression test for Killing Machine (51124) proc consumption.
 
 TEST_F (SpellProcSpellTypeMaskTest, KillingMachine_FullIntegration_ProcTriggers)
 Verify FINISH phase works with actual CanSpellTriggerProcOnEvent.
 
 TEST_F (SpellProcSpellTypeMaskTest, KillingMachine_BugScenario_NoDmgHealFails)
 Verify the bug scenario - FINISH phase with NO_DMG_HEAL fails.
 

Function Documentation

◆ TEST_F() [1/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
CastPhase_UsesMaskAll   
)
74{
75 // CAST phase should use MASK_ALL regardless of damage/heal info
76 uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_CAST, nullptr, nullptr, true);
77 EXPECT_EQ(result, PROC_SPELL_TYPE_MASK_ALL);
78}
std::uint32_t uint32
Definition Define.h:107
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:242
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:248

References PROC_SPELL_PHASE_CAST, and PROC_SPELL_TYPE_MASK_ALL.

◆ TEST_F() [2/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
FinishPhase_UsesMaskAll_EvenWithNullDamageInfo   
)
81{
82 // FINISH phase should use MASK_ALL even when damageInfo is null
83 // This is the key regression test - previously returned NO_DMG_HEAL
84 uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_FINISH, nullptr, nullptr, true);
85 EXPECT_EQ(result, PROC_SPELL_TYPE_MASK_ALL);
86
87 // Verify it includes DAMAGE type (required for procs like Killing Machine)
88 EXPECT_TRUE(result & PROC_SPELL_TYPE_DAMAGE);
89}
@ PROC_SPELL_TYPE_DAMAGE
Definition SpellMgr.h:239
@ PROC_SPELL_PHASE_FINISH
Definition SpellMgr.h:250

References PROC_SPELL_PHASE_FINISH, PROC_SPELL_TYPE_DAMAGE, and PROC_SPELL_TYPE_MASK_ALL.

◆ TEST_F() [3/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
HitPhase_NoDamageNoHeal_UsesNoDmgHeal   
)
110{
111 // HIT phase with no damage/heal info should use NO_DMG_HEAL
112 uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_HIT, nullptr, nullptr, true);
113 EXPECT_EQ(result, PROC_SPELL_TYPE_NO_DMG_HEAL);
114}
@ PROC_SPELL_TYPE_NO_DMG_HEAL
Definition SpellMgr.h:241
@ PROC_SPELL_PHASE_HIT
Definition SpellMgr.h:249

References PROC_SPELL_PHASE_HIT, and PROC_SPELL_TYPE_NO_DMG_HEAL.

◆ TEST_F() [4/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
HitPhase_WithDamage_UsesDamageType   
)
92{
93 auto* spellInfo = CreateSpellInfo(12345, 15, 0);
94 DamageInfo damageInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE);
95
96 uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_HIT, &damageInfo, nullptr, true);
97 EXPECT_EQ(result, PROC_SPELL_TYPE_DAMAGE);
98}
@ SPELL_SCHOOL_MASK_FROST
Definition SharedDefines.h:289
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:255
Definition Unit.h:336

References PROC_SPELL_PHASE_HIT, PROC_SPELL_TYPE_DAMAGE, SPELL_DIRECT_DAMAGE, and SPELL_SCHOOL_MASK_FROST.

◆ TEST_F() [5/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
HitPhase_WithHeal_UsesHealType   
)
101{
102 auto* spellInfo = CreateSpellInfo(12345, 15, 0);
103 HealInfo healInfo(nullptr, nullptr, 100, spellInfo, SPELL_SCHOOL_MASK_HOLY);
104
105 uint32 result = CalculateSpellTypeMask(PROC_SPELL_PHASE_HIT, nullptr, &healInfo, true);
106 EXPECT_EQ(result, PROC_SPELL_TYPE_HEAL);
107}
@ SPELL_SCHOOL_MASK_HOLY
Definition SharedDefines.h:286
@ PROC_SPELL_TYPE_HEAL
Definition SpellMgr.h:240
Definition Unit.h:383

References PROC_SPELL_PHASE_HIT, PROC_SPELL_TYPE_HEAL, and SPELL_SCHOOL_MASK_HOLY.

◆ TEST_F() [6/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
KillingMachine_BugScenario_NoDmgHealFails   
)

Verify the bug scenario - FINISH phase with NO_DMG_HEAL fails.

This test documents the bug behavior: if FINISH phase incorrectly uses NO_DMG_HEAL spellTypeMask, Killing Machine style procs fail.

202{
203 auto procEntry = SpellProcEntryBuilder()
205 .WithSpellFamilyMask(flag96(2, 0, 0))
207 .WithSpellTypeMask(PROC_SPELL_TYPE_DAMAGE) // Requires DAMAGE
209 .Build();
210
211 auto* icyTouchSpell = CreateSpellInfo(49909, 15, 2);
212 DamageInfo damageInfo(nullptr, nullptr, 100, icyTouchSpell, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE);
213
214 // Simulate the bug: FINISH phase with NO_DMG_HEAL (the old broken behavior)
215 auto eventInfo = ProcEventInfoBuilder()
220 .WithDamageInfo(&damageInfo)
221 .Build();
222
223 // This should fail - documenting the bug behavior
224 EXPECT_FALSE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo))
225 << "With NO_DMG_HEAL spellTypeMask, DAMAGE-requiring procs should NOT trigger (this was the bug)";
226}
@ PROC_HIT_NORMAL
Definition SpellMgr.h:257
#define sSpellMgr
Definition SpellMgr.h:836
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:134
Builder class for creating ProcEventInfo test instances.
Definition ProcEventInfoHelper.h:31
ProcEventInfoBuilder & WithSpellPhaseMask(uint32 spellPhaseMask)
Definition ProcEventInfoHelper.h:69
ProcEventInfoBuilder & WithDamageInfo(DamageInfo *damageInfo)
Definition ProcEventInfoHelper.h:87
ProcEventInfoBuilder & WithTypeMask(uint32 typeMask)
Definition ProcEventInfoHelper.h:57
ProcEventInfoBuilder & WithHitMask(uint32 hitMask)
Definition ProcEventInfoHelper.h:75
ProcEventInfo Build()
Definition ProcEventInfoHelper.h:111
ProcEventInfoBuilder & WithSpellTypeMask(uint32 spellTypeMask)
Definition ProcEventInfoHelper.h:63
Builder class for creating SpellProcEntry test instances.
Definition ProcEventInfoHelper.h:141
SpellProcEntry Build() const
Definition ProcEventInfoHelper.h:226
SpellProcEntryBuilder & WithSpellFamilyMask(flag96 familyMask)
Definition ProcEventInfoHelper.h:160
SpellProcEntryBuilder & WithSpellTypeMask(uint32 spellTypeMask)
Definition ProcEventInfoHelper.h:172
SpellProcEntryBuilder & WithSpellFamilyName(uint32 familyName)
Definition ProcEventInfoHelper.h:154
SpellProcEntryBuilder & WithProcFlags(uint32 procFlags)
Definition ProcEventInfoHelper.h:166
SpellProcEntryBuilder & WithSpellPhaseMask(uint32 spellPhaseMask)
Definition ProcEventInfoHelper.h:178
Definition Util.h:442

References ProcEventInfoBuilder::Build(), SpellProcEntryBuilder::Build(), PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_HIT_NORMAL, PROC_SPELL_PHASE_FINISH, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_TYPE_NO_DMG_HEAL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FROST, sSpellMgr, ProcEventInfoBuilder::WithDamageInfo(), ProcEventInfoBuilder::WithHitMask(), SpellProcEntryBuilder::WithProcFlags(), SpellProcEntryBuilder::WithSpellFamilyMask(), SpellProcEntryBuilder::WithSpellFamilyName(), ProcEventInfoBuilder::WithSpellPhaseMask(), SpellProcEntryBuilder::WithSpellPhaseMask(), ProcEventInfoBuilder::WithSpellTypeMask(), SpellProcEntryBuilder::WithSpellTypeMask(), and ProcEventInfoBuilder::WithTypeMask().

◆ TEST_F() [7/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
KillingMachine_FinishPhase_MatchesDamageTypeMask   
)

Regression test for Killing Machine (51124) proc consumption.

Killing Machine has:

  • SpellTypeMask = 1 (PROC_SPELL_TYPE_DAMAGE)
  • SpellPhaseMask = 4 (PROC_SPELL_PHASE_FINISH)

When Icy Touch is cast, the FINISH phase event must have a spellTypeMask that includes DAMAGE for the proc to fire and consume the buff.

The bug was: FINISH phase calculated spellTypeMask as NO_DMG_HEAL (4) because damageInfo was null, causing the proc check to fail.

134{
135 // Killing Machine spell_proc entry
136 auto procEntry = SpellProcEntryBuilder()
137 .WithSpellFamilyName(15) // SPELLFAMILY_DEATHKNIGHT
138 .WithSpellFamilyMask(flag96(2, 6, 0)) // Icy Touch, Frost Strike, Howling Blast
143 .WithCharges(1)
144 .Build();
145
146 // Calculate what spellTypeMask FINISH phase would produce
147 // (simulating Spell.cpp calling ProcSkillsAndAuras with nullptr damageInfo)
148 uint32 finishPhaseSpellTypeMask = CalculateSpellTypeMask(PROC_SPELL_PHASE_FINISH, nullptr, nullptr, true);
149
150 // Verify the calculated mask includes DAMAGE type
151 EXPECT_TRUE(finishPhaseSpellTypeMask & PROC_SPELL_TYPE_DAMAGE)
152 << "FINISH phase spellTypeMask must include PROC_SPELL_TYPE_DAMAGE for Killing Machine to work";
153
154 // Verify that the proc entry's SpellTypeMask requirement is satisfied
155 EXPECT_TRUE(finishPhaseSpellTypeMask & procEntry.SpellTypeMask)
156 << "FINISH phase spellTypeMask (" << finishPhaseSpellTypeMask
157 << ") must match Killing Machine's SpellTypeMask requirement (" << procEntry.SpellTypeMask << ")";
158}
@ PROC_ATTR_REQ_SPELLMOD
Definition SpellMgr.h:279
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:116
SpellProcEntryBuilder & WithCharges(uint32 charges)
Definition ProcEventInfoHelper.h:220
SpellProcEntryBuilder & WithAttributesMask(uint32 attributesMask)
Definition ProcEventInfoHelper.h:190

References SpellProcEntryBuilder::Build(), PROC_ATTR_REQ_SPELLMOD, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_SPELL_PHASE_FINISH, PROC_SPELL_TYPE_DAMAGE, SpellProcEntryBuilder::WithAttributesMask(), SpellProcEntryBuilder::WithCharges(), SpellProcEntryBuilder::WithProcFlags(), SpellProcEntryBuilder::WithSpellFamilyMask(), SpellProcEntryBuilder::WithSpellFamilyName(), SpellProcEntryBuilder::WithSpellPhaseMask(), and SpellProcEntryBuilder::WithSpellTypeMask().

◆ TEST_F() [8/8]

TEST_F ( SpellProcSpellTypeMaskTest  ,
KillingMachine_FullIntegration_ProcTriggers   
)

Verify FINISH phase works with actual CanSpellTriggerProcOnEvent.

This test verifies the full integration: when we pass the correctly calculated spellTypeMask to CanSpellTriggerProcOnEvent, Killing Machine style procs should work.

168{
169 // Killing Machine spell_proc entry
170 auto procEntry = SpellProcEntryBuilder()
171 .WithSpellFamilyName(15) // SPELLFAMILY_DEATHKNIGHT
172 .WithSpellFamilyMask(flag96(2, 0, 0)) // Icy Touch
176 .Build();
177
178 // Create Icy Touch spell info (SpellFamilyFlags = [2, 0, 0])
179 auto* icyTouchSpell = CreateSpellInfo(49909, 15, 2); // DK family, mask0=2
180 DamageInfo damageInfo(nullptr, nullptr, 100, icyTouchSpell, SPELL_SCHOOL_MASK_FROST, SPELL_DIRECT_DAMAGE);
181
182 // Create event with FINISH phase and MASK_ALL (as the fix provides)
183 auto eventInfo = ProcEventInfoBuilder()
188 .WithDamageInfo(&damageInfo)
189 .Build();
190
191 EXPECT_TRUE(sSpellMgr->CanSpellTriggerProcOnEvent(procEntry, eventInfo))
192 << "Killing Machine style proc should trigger on FINISH phase with MASK_ALL spellTypeMask";
193}

References ProcEventInfoBuilder::Build(), SpellProcEntryBuilder::Build(), PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_HIT_NORMAL, PROC_SPELL_PHASE_FINISH, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_TYPE_MASK_ALL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_FROST, sSpellMgr, ProcEventInfoBuilder::WithDamageInfo(), ProcEventInfoBuilder::WithHitMask(), SpellProcEntryBuilder::WithProcFlags(), SpellProcEntryBuilder::WithSpellFamilyMask(), SpellProcEntryBuilder::WithSpellFamilyName(), ProcEventInfoBuilder::WithSpellPhaseMask(), SpellProcEntryBuilder::WithSpellPhaseMask(), ProcEventInfoBuilder::WithSpellTypeMask(), SpellProcEntryBuilder::WithSpellTypeMask(), and ProcEventInfoBuilder::WithTypeMask().