AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
SpellProcChainGuardTest.cpp File Reference

Unit tests for proc chain guard and TAKEN auto-trigger logic. More...

#include "ProcChanceTestHelper.h"
#include "ProcEventInfoHelper.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Classes

class  TakenAutoTriggerTest
 
class  ProcChainGuardTest
 

Functions

 TEST_F (TakenAutoTriggerTest, TakenProcTriggerSpell_SetsTriggeredCanProc)
 
 TEST_F (TakenAutoTriggerTest, TakenProcTriggerDamage_SetsTriggeredCanProc)
 
 TEST_F (TakenAutoTriggerTest, TakenProcOtherAura_DoesNotSetTriggeredCanProc)
 
 TEST_F (TakenAutoTriggerTest, DoneProcTriggerSpell_DoesNotSetTriggeredCanProc)
 
 TEST_F (TakenAutoTriggerTest, NoProcFlags_DoesNotSetTriggeredCanProc)
 
 TEST_F (TakenAutoTriggerTest, AlwaysTriggeredAura_StaysTrue)
 
 TEST_F (TakenAutoTriggerTest, TakenDamage_WithProcTriggerSpell_SetsFlag)
 
 TEST_F (TakenAutoTriggerTest, TakenPeriodic_WithProcTriggerDamage_SetsFlag)
 
 TEST_F (TakenAutoTriggerTest, MixedDoneAndTaken_WithProcTriggerSpell_SetsFlag)
 
 TEST_F (TakenAutoTriggerTest, TakenProcModAura_DoesNotSetTriggeredCanProc)
 
 TEST_F (TakenAutoTriggerTest, Scenario_MoltenArmor_TakenAutoTrigger)
 
 TEST_F (TakenAutoTriggerTest, Scenario_Reckoning_TakenAutoTrigger)
 
 TEST_F (TakenAutoTriggerTest, Scenario_Redoubt_TakenAutoTrigger)
 
 TEST_F (TakenAutoTriggerTest, AutoGenTriggeredCanProc_AllowsTriggeredSpells)
 
 TEST_F (TakenAutoTriggerTest, WithoutAutoTrigger_TriggeredSpellsBlocked)
 
 TEST_F (ProcChainGuardTest, DisallowProcEvents_BlocksAllAuras)
 
 TEST_F (ProcChainGuardTest, DisallowProcEvents_CounterBalanced)
 
 TEST_F (ProcChainGuardTest, NoDisallowProcEvents_AllAurasCanProc)
 
 TEST_F (ProcChainGuardTest, InstantTargetProcs_BlocksDuringSpecificAura)
 
 TEST_F (ProcChainGuardTest, InstantTargetProcs_CounterBalanced)
 
 TEST_F (ProcChainGuardTest, MultipleInstantTargetProcs_EachIndependent)
 
 TEST_F (ProcChainGuardTest, Combined_DisallowAndInstantTarget_StackCorrectly)
 
 TEST_F (ProcChainGuardTest, RemovedAura_SkippedInLoop)
 
 TEST_F (ProcChainGuardTest, RemovedAuraWithInstantProcs_DoesNotAffectCounter)
 
 TEST_F (ProcChainGuardTest, EmptyContainer_NoEffect)
 
 TEST_F (ProcChainGuardTest, EmptyContainer_WithDisallowProc_StillBalanced)
 
 TEST_F (ProcChainGuardTest, Scenario_MoltenArmorVsEyeForAnEye)
 
 TEST_F (ProcChainGuardTest, Scenario_SealOfRighteousness_TriggeredDamage)
 
 TEST_F (ProcChainGuardTest, Scenario_NormalMeleeHit_AurasCanProc)
 

Detailed Description

Unit tests for proc chain guard and TAKEN auto-trigger logic.

Tests two fixes ported from TrinityCore:

  1. Proc chain guard (Unit::TriggerAurasProcOnEvent):
    • TRIGGERED_DISALLOW_PROC_EVENTS on triggering spell blocks all cascading procs during the proc event
    • SPELL_ATTR3_INSTANT_TARGET_PROCS on individual auras blocks cascading procs during that specific aura's proc trigger
    • Prevents infinite proc loops between reactive damage auras (e.g. Molten Armor <-> Eye for an Eye)
  2. TAKEN auto-trigger (SpellMgr::LoadSpellProcs auto-generation):
    • TAKEN-proc auras with SPELL_AURA_PROC_TRIGGER_SPELL or SPELL_AURA_PROC_TRIGGER_DAMAGE automatically get PROC_ATTR_TRIGGERED_CAN_PROC so they can proc from triggered spells (e.g. Mage Armor proccing from Judgement)

Definition in file SpellProcChainGuardTest.cpp.

Function Documentation

◆ TEST_F() [1/29]

TEST_F ( ProcChainGuardTest  ,
Combined_DisallowAndInstantTarget_StackCorrectly   
)
429{
430 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
431 {.spellId = 100, .hasInstantTargetProcs = false},
432 {.spellId = 200, .hasInstantTargetProcs = true},
433 {.spellId = 300, .hasInstantTargetProcs = false},
434 };
435
436 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/true, auras);
437
438 auto const& records = _sim.GetRecords();
439 ASSERT_EQ(records.size(), 3u);
440
441 // Aura 100: disableProcs active, procDeep=1
442 EXPECT_FALSE(records[0].canProcDuringTrigger);
443 EXPECT_EQ(records[0].procDeepDuringTrigger, 1);
444
445 // Aura 200: disableProcs + INSTANT_TARGET_PROCS, procDeep=2
446 EXPECT_FALSE(records[1].canProcDuringTrigger);
447 EXPECT_EQ(records[1].procDeepDuringTrigger, 2)
448 << "DISALLOW_PROC_EVENTS + INSTANT_TARGET_PROCS should stack to 2";
449
450 // Aura 300: back to just disableProcs, procDeep=1
451 EXPECT_FALSE(records[2].canProcDuringTrigger);
452 EXPECT_EQ(records[2].procDeepDuringTrigger, 1);
453
454 EXPECT_EQ(_sim.GetProcDeep(), 0)
455 << "Counter should be balanced after combined scenario";
456}

◆ TEST_F() [2/29]

TEST_F ( ProcChainGuardTest  ,
DisallowProcEvents_BlocksAllAuras   
)
292{
293 // When triggering spell has TRIGGERED_DISALLOW_PROC_EVENTS,
294 // all auras should fire with CanProc() == false
295 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
296 {.spellId = 100, .hasInstantTargetProcs = false},
297 {.spellId = 200, .hasInstantTargetProcs = false},
298 {.spellId = 300, .hasInstantTargetProcs = false},
299 };
300
301 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/true, auras);
302
303 auto const& records = _sim.GetRecords();
304 ASSERT_EQ(records.size(), 3u);
305
306 for (auto const& rec : records)
307 {
308 EXPECT_FALSE(rec.canProcDuringTrigger)
309 << "Aura " << rec.spellId
310 << " should have CanProc()=false with DISALLOW_PROC_EVENTS";
311 EXPECT_EQ(rec.procDeepDuringTrigger, 1)
312 << "m_procDeep should be 1 for all auras";
313 }
314}

References ProcChainGuardSimulator::SimulateTriggerAurasProc().

◆ TEST_F() [3/29]

TEST_F ( ProcChainGuardTest  ,
DisallowProcEvents_CounterBalanced   
)
317{
318 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
319 {.spellId = 100},
320 };
321
322 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/true, auras);
323
324 EXPECT_EQ(_sim.GetProcDeep(), 0)
325 << "m_procDeep should return to 0 after function exits";
326 EXPECT_TRUE(_sim.CanProc())
327 << "CanProc() should be true after function exits";
328}

◆ TEST_F() [4/29]

TEST_F ( ProcChainGuardTest  ,
EmptyContainer_NoEffect   
)
502{
503 std::vector<ProcChainGuardSimulator::AuraConfig> auras;
504
505 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
506
507 EXPECT_EQ(_sim.GetRecords().size(), 0u);
508 EXPECT_EQ(_sim.GetProcDeep(), 0);
509}

◆ TEST_F() [5/29]

TEST_F ( ProcChainGuardTest  ,
EmptyContainer_WithDisallowProc_StillBalanced   
)
512{
513 std::vector<ProcChainGuardSimulator::AuraConfig> auras;
514
515 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/true, auras);
516
517 EXPECT_EQ(_sim.GetRecords().size(), 0u);
518 EXPECT_EQ(_sim.GetProcDeep(), 0)
519 << "Even with disableProcs and empty container, counter should balance";
520}

◆ TEST_F() [6/29]

TEST_F ( ProcChainGuardTest  ,
InstantTargetProcs_BlocksDuringSpecificAura   
)
356{
357 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
358 {.spellId = 100, .hasInstantTargetProcs = false},
359 {.spellId = 200, .hasInstantTargetProcs = true}, // This one blocks
360 {.spellId = 300, .hasInstantTargetProcs = false},
361 };
362
363 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
364
365 auto const& records = _sim.GetRecords();
366 ASSERT_EQ(records.size(), 3u);
367
368 // Aura 100: normal, can proc
369 EXPECT_TRUE(records[0].canProcDuringTrigger)
370 << "First aura (no INSTANT_TARGET_PROCS) should allow procs";
371 EXPECT_EQ(records[0].procDeepDuringTrigger, 0);
372
373 // Aura 200: has INSTANT_TARGET_PROCS, blocked
374 EXPECT_FALSE(records[1].canProcDuringTrigger)
375 << "Aura with INSTANT_TARGET_PROCS should block procs during its trigger";
376 EXPECT_EQ(records[1].procDeepDuringTrigger, 1);
377
378 // Aura 300: normal again, can proc (counter was decremented)
379 EXPECT_TRUE(records[2].canProcDuringTrigger)
380 << "Next aura after INSTANT_TARGET_PROCS should allow procs again";
381 EXPECT_EQ(records[2].procDeepDuringTrigger, 0);
382}

◆ TEST_F() [7/29]

TEST_F ( ProcChainGuardTest  ,
InstantTargetProcs_CounterBalanced   
)
385{
386 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
387 {.spellId = 100, .hasInstantTargetProcs = true},
388 };
389
390 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
391
392 EXPECT_EQ(_sim.GetProcDeep(), 0)
393 << "m_procDeep should return to 0 after INSTANT_TARGET_PROCS aura";
394 EXPECT_TRUE(_sim.CanProc());
395}

◆ TEST_F() [8/29]

TEST_F ( ProcChainGuardTest  ,
MultipleInstantTargetProcs_EachIndependent   
)
398{
399 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
400 {.spellId = 100, .hasInstantTargetProcs = true},
401 {.spellId = 200, .hasInstantTargetProcs = true},
402 {.spellId = 300, .hasInstantTargetProcs = true},
403 };
404
405 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
406
407 auto const& records = _sim.GetRecords();
408 ASSERT_EQ(records.size(), 3u);
409
410 // Each aura should independently block during its own trigger
411 for (auto const& rec : records)
412 {
413 EXPECT_FALSE(rec.canProcDuringTrigger)
414 << "Aura " << rec.spellId
415 << " with INSTANT_TARGET_PROCS should block during trigger";
416 EXPECT_EQ(rec.procDeepDuringTrigger, 1)
417 << "Each aura should increment to exactly 1 (not accumulate)";
418 }
419
420 EXPECT_EQ(_sim.GetProcDeep(), 0)
421 << "Counter should be balanced after all auras processed";
422}

◆ TEST_F() [9/29]

TEST_F ( ProcChainGuardTest  ,
NoDisallowProcEvents_AllAurasCanProc   
)
331{
332 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
333 {.spellId = 100, .hasInstantTargetProcs = false},
334 {.spellId = 200, .hasInstantTargetProcs = false},
335 };
336
337 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
338
339 auto const& records = _sim.GetRecords();
340 ASSERT_EQ(records.size(), 2u);
341
342 for (auto const& rec : records)
343 {
344 EXPECT_TRUE(rec.canProcDuringTrigger)
345 << "Aura " << rec.spellId
346 << " should have CanProc()=true without DISALLOW_PROC_EVENTS";
347 EXPECT_EQ(rec.procDeepDuringTrigger, 0);
348 }
349}

◆ TEST_F() [10/29]

TEST_F ( ProcChainGuardTest  ,
RemovedAura_SkippedInLoop   
)
463{
464 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
465 {.spellId = 100, .hasInstantTargetProcs = false, .isRemoved = false},
466 {.spellId = 200, .hasInstantTargetProcs = true, .isRemoved = true},
467 {.spellId = 300, .hasInstantTargetProcs = false, .isRemoved = false},
468 };
469
470 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
471
472 auto const& records = _sim.GetRecords();
473 ASSERT_EQ(records.size(), 2u)
474 << "Removed aura should be skipped";
475
476 EXPECT_EQ(records[0].spellId, 100u);
477 EXPECT_EQ(records[1].spellId, 300u);
478
479 // The INSTANT_TARGET_PROCS aura was removed, so it shouldn't affect
480 // the counter for the next aura
481 EXPECT_TRUE(records[1].canProcDuringTrigger);
482}

◆ TEST_F() [11/29]

TEST_F ( ProcChainGuardTest  ,
RemovedAuraWithInstantProcs_DoesNotAffectCounter   
)
485{
486 std::vector<ProcChainGuardSimulator::AuraConfig> auras = {
487 {.spellId = 100, .hasInstantTargetProcs = true, .isRemoved = true},
488 };
489
490 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, auras);
491
492 EXPECT_EQ(_sim.GetRecords().size(), 0u);
493 EXPECT_EQ(_sim.GetProcDeep(), 0)
494 << "Removed aura should not touch the proc deep counter";
495}

◆ TEST_F() [12/29]

TEST_F ( ProcChainGuardTest  ,
Scenario_MoltenArmorVsEyeForAnEye   
)
527{
528 // Molten Armor (43046) has SPELL_ATTR3_INSTANT_TARGET_PROCS
529 // When Molten Armor deals fire damage to an attacker, that damage
530 // should not trigger the attacker's reactive procs (Eye for an Eye)
531 // back on the mage, preventing infinite ping-pong
532
533 // Mage's perspective: paladin hits mage, mage's auras proc
534 std::vector<ProcChainGuardSimulator::AuraConfig> mageAuras = {
535 {.spellId = 43046, .hasInstantTargetProcs = true}, // Molten Armor
536 };
537
538 // The paladin's melee hit is NOT TRIGGERED_DISALLOW_PROC_EVENTS
539 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, mageAuras);
540
541 auto const& records = _sim.GetRecords();
542 ASSERT_EQ(records.size(), 1u);
543
544 // During Molten Armor's proc trigger, CanProc() is false
545 // This means the fire damage it deals cannot trigger further procs
546 EXPECT_FALSE(records[0].canProcDuringTrigger)
547 << "Molten Armor proc should block cascading procs (prevents EfaE loop)";
548
549 EXPECT_EQ(_sim.GetProcDeep(), 0)
550 << "Counter balanced after Molten Armor scenario";
551}

◆ TEST_F() [13/29]

TEST_F ( ProcChainGuardTest  ,
Scenario_NormalMeleeHit_AurasCanProc   
)
578{
579 // A normal melee swing should allow all auras to proc normally
580 // (no DISALLOW_PROC_EVENTS, no INSTANT_TARGET_PROCS)
581
582 std::vector<ProcChainGuardSimulator::AuraConfig> targetAuras = {
583 {.spellId = 20177, .hasInstantTargetProcs = false}, // Reckoning
584 {.spellId = 20127, .hasInstantTargetProcs = false}, // Redoubt
585 {.spellId = 16958, .hasInstantTargetProcs = false}, // Blood Craze
586 };
587
588 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/false, targetAuras);
589
590 auto const& records = _sim.GetRecords();
591 ASSERT_EQ(records.size(), 3u);
592
593 for (auto const& rec : records)
594 {
595 EXPECT_TRUE(rec.canProcDuringTrigger)
596 << "Aura " << rec.spellId
597 << " should proc normally from a regular melee hit";
598 EXPECT_EQ(rec.procDeepDuringTrigger, 0);
599 }
600}

◆ TEST_F() [14/29]

TEST_F ( ProcChainGuardTest  ,
Scenario_SealOfRighteousness_TriggeredDamage   
)
554{
555 // SoR bonus damage is triggered with TRIGGERED_DISALLOW_PROC_EVENTS
556 // It should not trigger the target's reactive damage auras back
557
558 std::vector<ProcChainGuardSimulator::AuraConfig> targetAuras = {
559 {.spellId = 43046, .hasInstantTargetProcs = true}, // Molten Armor
560 {.spellId = 12345, .hasInstantTargetProcs = false}, // Some other aura
561 };
562
563 _sim.SimulateTriggerAurasProc(/*disallowProcEvents=*/true, targetAuras);
564
565 auto const& records = _sim.GetRecords();
566 ASSERT_EQ(records.size(), 2u);
567
568 // All auras should see CanProc() = false
569 for (auto const& rec : records)
570 {
571 EXPECT_FALSE(rec.canProcDuringTrigger)
572 << "All target auras should be blocked when SoR damage"
573 << " has DISALLOW_PROC_EVENTS";
574 }
575}

◆ TEST_F() [15/29]

TEST_F ( TakenAutoTriggerTest  ,
AlwaysTriggeredAura_StaysTrue   
)
112{
114 config.procFlags = 0; // No TAKEN flags
115 config.auraName = SPELL_AURA_DUMMY;
116 config.isAlwaysTriggeredAura = true;
117
119 << "isAlwaysTriggeredAura should keep addTriggerFlag = true";
120}
@ SPELL_AURA_DUMMY
Definition SpellAuraDefines.h:67
static bool ShouldAutoAddTriggeredCanProc(TakenAutoTriggerConfig const &config)
Simulate the TAKEN auto-trigger logic from SpellMgr::LoadSpellProcs()
Definition ProcChanceTestHelper.h:555
Configuration for simulating the TAKEN auto-trigger logic from SpellMgr::LoadSpellProcs() auto-genera...
Definition ProcChanceTestHelper.h:539
bool isAlwaysTriggeredAura
Definition ProcChanceTestHelper.h:542
uint32 auraName
Definition ProcChanceTestHelper.h:541
uint32 procFlags
Definition ProcChanceTestHelper.h:540

References ProcChanceTestHelper::TakenAutoTriggerConfig::auraName, ProcChanceTestHelper::TakenAutoTriggerConfig::isAlwaysTriggeredAura, ProcChanceTestHelper::TakenAutoTriggerConfig::procFlags, ProcChanceTestHelper::ShouldAutoAddTriggeredCanProc(), and SPELL_AURA_DUMMY.

◆ TEST_F() [16/29]

TEST_F ( TakenAutoTriggerTest  ,
AutoGenTriggeredCanProc_AllowsTriggeredSpells   
)
218{
219 // Verify that when TAKEN auto-trigger sets addTriggerFlag,
220 // the resulting proc entry with PROC_ATTR_TRIGGERED_CAN_PROC
221 // allows triggered spells through the filter
222
223 // Step 1: Auto-trigger logic says yes
228
229 // Step 2: Build proc entry with the auto-added attribute
230 auto procEntry = SpellProcEntryBuilder()
233 .WithChance(100.0f)
234 .Build();
235
236 // Step 3: Verify triggered spells pass through the filter
238 trigConfig.isTriggered = true; // e.g. Judgement damage is triggered
239 trigConfig.auraHasCanProcFromProcs = false;
240 trigConfig.spellHasNotAProc = false;
241
243 trigConfig, procEntry, PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK))
244 << "Auto-generated TRIGGERED_CAN_PROC should allow triggered spells";
245}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition SpellAuraDefines.h:105
@ PROC_ATTR_TRIGGERED_CAN_PROC
Definition SpellMgr.h:277
@ PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK
Definition SpellMgr.h:114
static bool ShouldBlockTriggeredSpell(TriggeredSpellConfig const &config, SpellProcEntry const &procEntry, uint32 eventTypeMask)
Simulate triggered spell filtering Implements the self-loop prevention and triggered spell blocking f...
Definition ProcChanceTestHelper.h:256
Builder class for creating SpellProcEntry test instances.
Definition ProcEventInfoHelper.h:141
SpellProcEntry Build() const
Definition ProcEventInfoHelper.h:226
SpellProcEntryBuilder & WithChance(float chance)
Definition ProcEventInfoHelper.h:208
SpellProcEntryBuilder & WithAttributesMask(uint32 attributesMask)
Definition ProcEventInfoHelper.h:190
SpellProcEntryBuilder & WithProcFlags(uint32 procFlags)
Definition ProcEventInfoHelper.h:166
Configuration for simulating triggered spell filtering.
Definition ProcChanceTestHelper.h:239
bool isTriggered
Definition ProcChanceTestHelper.h:240
bool spellHasNotAProc
Definition ProcChanceTestHelper.h:242
bool auraHasCanProcFromProcs
Definition ProcChanceTestHelper.h:241

References ProcChanceTestHelper::TriggeredSpellConfig::auraHasCanProcFromProcs, ProcChanceTestHelper::TakenAutoTriggerConfig::auraName, SpellProcEntryBuilder::Build(), ProcChanceTestHelper::TriggeredSpellConfig::isTriggered, PROC_ATTR_TRIGGERED_CAN_PROC, PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK, ProcChanceTestHelper::TakenAutoTriggerConfig::procFlags, ProcChanceTestHelper::ShouldAutoAddTriggeredCanProc(), ProcChanceTestHelper::ShouldBlockTriggeredSpell(), SPELL_AURA_PROC_TRIGGER_SPELL, ProcChanceTestHelper::TriggeredSpellConfig::spellHasNotAProc, SpellProcEntryBuilder::WithAttributesMask(), SpellProcEntryBuilder::WithChance(), and SpellProcEntryBuilder::WithProcFlags().

◆ TEST_F() [17/29]

◆ TEST_F() [18/29]

◆ TEST_F() [19/29]

◆ TEST_F() [20/29]

TEST_F ( TakenAutoTriggerTest  ,
Scenario_MoltenArmor_TakenAutoTrigger   
)
175{
176 // Molten Armor (30482): TAKEN_MELEE_AUTO_ATTACK + PROC_TRIGGER_DAMAGE
177 // Note: Molten Armor has an explicit spell_proc entry so auto-gen
178 // is skipped, but the logic should still apply if it didn't
183 config.isAlwaysTriggeredAura = false;
184
186 << "Molten Armor-like aura should auto-add TRIGGERED_CAN_PROC";
187}
@ SPELL_AURA_PROC_TRIGGER_DAMAGE
Definition SpellAuraDefines.h:106
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:117

References ProcChanceTestHelper::TakenAutoTriggerConfig::auraName, ProcChanceTestHelper::TakenAutoTriggerConfig::isAlwaysTriggeredAura, PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, ProcChanceTestHelper::TakenAutoTriggerConfig::procFlags, ProcChanceTestHelper::ShouldAutoAddTriggeredCanProc(), and SPELL_AURA_PROC_TRIGGER_DAMAGE.

◆ TEST_F() [21/29]

◆ TEST_F() [22/29]

◆ TEST_F() [23/29]

TEST_F ( TakenAutoTriggerTest  ,
TakenDamage_WithProcTriggerSpell_SetsFlag   
)

◆ TEST_F() [24/29]

◆ TEST_F() [25/29]

TEST_F ( TakenAutoTriggerTest  ,
TakenProcModAura_DoesNotSetTriggeredCanProc   
)
159{
160 // SPELL_AURA_ADD_FLAT_MODIFIER is not PROC_TRIGGER_SPELL/DAMAGE
164 config.isAlwaysTriggeredAura = false;
165
167 << "TAKEN proc + modifier aura should NOT auto-add TRIGGERED_CAN_PROC";
168}
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition SpellAuraDefines.h:170

References ProcChanceTestHelper::TakenAutoTriggerConfig::auraName, ProcChanceTestHelper::TakenAutoTriggerConfig::isAlwaysTriggeredAura, PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK, ProcChanceTestHelper::TakenAutoTriggerConfig::procFlags, ProcChanceTestHelper::ShouldAutoAddTriggeredCanProc(), and SPELL_AURA_ADD_FLAT_MODIFIER.

◆ TEST_F() [26/29]

◆ TEST_F() [27/29]

◆ TEST_F() [28/29]

◆ TEST_F() [29/29]

TEST_F ( TakenAutoTriggerTest  ,
WithoutAutoTrigger_TriggeredSpellsBlocked   
)
248{
249 // Without the TAKEN auto-trigger, DONE-only proc auras would block
250 // triggered spells (no TRIGGERED_CAN_PROC set)
251
253 autoConfig.procFlags = PROC_FLAG_DONE_MELEE_AUTO_ATTACK; // DONE only
256
257 // Build proc entry WITHOUT TRIGGERED_CAN_PROC
258 auto procEntry = SpellProcEntryBuilder()
260 .WithAttributesMask(0) // No TRIGGERED_CAN_PROC
261 .WithChance(100.0f)
262 .Build();
263
264 // Triggered spells should be blocked
266 trigConfig.isTriggered = true;
267 trigConfig.auraHasCanProcFromProcs = false;
268 trigConfig.spellHasNotAProc = false;
269
271 trigConfig, procEntry, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG))
272 << "Without TRIGGERED_CAN_PROC, triggered spells should be blocked";
273}
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:134

References ProcChanceTestHelper::TriggeredSpellConfig::auraHasCanProcFromProcs, ProcChanceTestHelper::TakenAutoTriggerConfig::auraName, SpellProcEntryBuilder::Build(), ProcChanceTestHelper::TriggeredSpellConfig::isTriggered, PROC_FLAG_DONE_MELEE_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, ProcChanceTestHelper::TakenAutoTriggerConfig::procFlags, ProcChanceTestHelper::ShouldAutoAddTriggeredCanProc(), ProcChanceTestHelper::ShouldBlockTriggeredSpell(), SPELL_AURA_PROC_TRIGGER_SPELL, ProcChanceTestHelper::TriggeredSpellConfig::spellHasNotAProc, SpellProcEntryBuilder::WithAttributesMask(), SpellProcEntryBuilder::WithChance(), and SpellProcEntryBuilder::WithProcFlags().