aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-05-20 21:09:03 +0200
committerShauren <shauren.trinity@gmail.com>2016-05-20 21:09:03 +0200
commit1e1fcd6847619629f4b6642faaccb81c4cf3755e (patch)
tree6f9db0c018ffb3f15033d3461818379cc342250a
parentd8cc656ff404217819d618e601cc502b0af08c56 (diff)
Core/Auras: Fixed cooldowns for procs calling PreventDefaultAction() in aura proc script
* This also fixes proc cooldows unneccessarily being sent to client * Also removes the need for cooldown hacks when the proc trigger is selected randomly like for Deathbringer's Will
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp135
-rw-r--r--src/server/game/Entities/Unit/Unit.h8
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp24
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h10
4 files changed, 64 insertions, 113 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index bc20dc5e658..09658b3d9df 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -5299,7 +5299,7 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType
}
//victim may be NULL
-bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
+bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, Milliseconds& cooldown)
{
SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo();
uint32 effIndex = triggeredByAura->GetEffIndex();
@@ -5309,8 +5309,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
- uint32 cooldown_spell_id = 0; // for random trigger, will be one of the triggered spell to avoid repeatable triggers
- // otherwise, it's the triggered_spell_id by default
Unit* target = victim;
int32 basepoints0 = 0;
ObjectGuid originalCaster;
@@ -5386,24 +5384,20 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
case CLASS_PALADIN: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409
case CLASS_DRUID: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409
triggered_spell_id = RAND(39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409);
- cooldown_spell_id = 39511;
break;
case CLASS_ROGUE: // 39511, 40997, 40998, 41002, 41005, 41011
case CLASS_WARRIOR: // 39511, 40997, 40998, 41002, 41005, 41011
case CLASS_DEATH_KNIGHT:
triggered_spell_id = RAND(39511, 40997, 40998, 41002, 41005, 41011);
- cooldown_spell_id = 39511;
break;
case CLASS_PRIEST: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
case CLASS_SHAMAN: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
case CLASS_MAGE: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
case CLASS_WARLOCK: // 40999, 41002, 41005, 41009, 41011, 41406, 41409
triggered_spell_id = RAND(40999, 41002, 41005, 41009, 41011, 41406, 41409);
- cooldown_spell_id = 40999;
break;
case CLASS_HUNTER: // 40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409
triggered_spell_id = RAND(40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409);
- cooldown_spell_id = 40997;
break;
default:
return false;
@@ -5633,11 +5627,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
uint8 rand_spell = urand(0, (RandomSpells.size() - 1));
CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
- for (std::vector<uint32>::iterator itr = RandomSpells.begin(); itr != RandomSpells.end(); ++itr)
- {
- if (!GetSpellHistory()->HasCooldown(*itr))
- GetSpellHistory()->AddCooldown(*itr, 0, std::chrono::seconds(cooldown));
- }
break;
}
case 71562: // Deathbringer's Will Heroic
@@ -5679,11 +5668,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
uint8 rand_spell = urand(0, (RandomSpells.size() - 1));
CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
- for (std::vector<uint32>::iterator itr = RandomSpells.begin(); itr != RandomSpells.end(); ++itr)
- {
- if (!GetSpellHistory()->HasCooldown(*itr))
- GetSpellHistory()->AddCooldown(*itr, 0, std::chrono::seconds(cooldown));
- }
break;
}
case 65032: // Boom aura (321 Boombot)
@@ -6519,7 +6503,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// Item - Paladin T8 Holy 4P Bonus
if (Unit* caster = triggeredByAura->GetCaster())
if (AuraEffect const* aurEff = caster->GetAuraEffect(64895, 0))
- cooldown = aurEff->GetAmount();
+ cooldown = Milliseconds(aurEff->GetAmount());
target = this;
break;
@@ -6834,10 +6818,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (!player || !castItem || !castItem->IsEquipped() || !victim || !victim->IsAlive())
return false;
- // custom cooldown processing case
- if (cooldown && GetSpellHistory()->HasCooldown(dummySpell->Id))
- return false;
-
if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID())
return false;
@@ -6900,8 +6880,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 33750;
// apply cooldown before cast to prevent processing itself
- if (cooldown)
- player->GetSpellHistory()->AddCooldown(dummySpell->Id, 0, std::chrono::seconds(cooldown));
+ triggeredByAura->GetBase()->AddProcCooldown(std::chrono::steady_clock::now() + cooldown);
+ cooldown = Milliseconds::zero();
// Attack Twice
for (uint32 i = 0; i < 2; ++i)
@@ -7144,10 +7124,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (!procSpell || GetTypeId() != TYPEID_PLAYER || !victim)
return false;
- // custom cooldown processing case
- if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(dummySpell->Id))
- return false;
-
uint32 spellId = 0;
// Every Lightning Bolt and Chain Lightning spell have duplicate vs half damage and zero cost
switch (procSpell->Id)
@@ -7193,10 +7169,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
CastSpell(victim, spellId, true, castItem, triggeredByAura);
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- GetSpellHistory()->AddCooldown(dummySpell->Id, 0, std::chrono::seconds(cooldown));
-
return true;
}
// Static Shock
@@ -7498,26 +7470,17 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
}
- if (cooldown_spell_id == 0)
- cooldown_spell_id = triggered_spell_id;
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(cooldown_spell_id))
- return false;
-
if (basepoints0)
CastCustomSpell(target, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura, originalCaster);
else
CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster);
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- GetSpellHistory()->AddCooldown(cooldown_spell_id, 0, std::chrono::seconds(cooldown));
-
return true;
}
// Used in case when access to whole aura is needed
// All procs should be handled like this...
-bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 /*procFlag*/, uint32 procEx, uint32 cooldown, bool * handled)
+bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 /*procFlag*/, uint32 procEx, bool* handled)
{
SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo();
@@ -7729,12 +7692,6 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
case 49222:
{
*handled = true;
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- {
- if (GetSpellHistory()->HasCooldown(100000))
- return false;
- GetSpellHistory()->AddCooldown(100000, 0, std::chrono::seconds(cooldown));
- }
return true;
}
// Hungering Cold aura drop
@@ -7777,7 +7734,7 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
return false;
}
-bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown)
+bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx)
{
// Get triggered aura spell info
SpellInfo const* auraSpellInfo = triggeredByAura->GetSpellInfo();
@@ -7858,7 +7815,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
float averageDmg = 0;
// now compute approximate weapon damage by formula from wowwiki.com
- if (procFlags & PROC_FLAG_DONE_OFFHAND_ATTACK)
+ if (procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
averageDmg = (GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)) / 2.f;
else
averageDmg = (GetFloatValue(UNIT_FIELD_MINDAMAGE) + GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2.f;
@@ -8020,13 +7977,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
if (!target)
return false;
- if (cooldown && target->GetTypeId() == TYPEID_PLAYER && target->GetSpellHistory()->HasCooldown(trigger_spell_id))
- return false;
-
target->CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- GetSpellHistory()->AddCooldown(trigger_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
// Cast positive spell on enemy target
@@ -8157,7 +8108,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
case 56453:
{
// Proc only from Frost/Freezing trap activation or from Freezing Arrow (the periodic dmg proc handled elsewhere)
- if (!(procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION) || !procSpell || !(procSpell->SchoolMask & SPELL_SCHOOL_MASK_FROST) || !roll_chance_i(triggerAmount))
+ if (!(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION) || !procSpell || !(procSpell->SchoolMask & SPELL_SCHOOL_MASK_FROST) || !roll_chance_i(triggerAmount))
return false;
break;
}
@@ -8204,29 +8155,23 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
}
- if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(trigger_spell_id))
- return false;
-
// extra attack should hit same target
if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
target = victim;
// try detect target manually if not set
if (target == NULL)
- target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry->IsPositive() ? this : victim;
+ target = !(procFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry->IsPositive() ? this : victim;
if (basepoints0)
CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
else
CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- GetSpellHistory()->AddCooldown(trigger_spell_id, 0, std::chrono::seconds(cooldown));
-
return true;
}
-bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown)
+bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* procSpell)
{
int32 scriptId = triggeredByAura->GetMiscValue();
@@ -8317,14 +8262,7 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, Au
return false;
}
- if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(triggered_spell_id))
- return false;
-
CastSpell(victim, triggered_spell_id, true, castItem, triggeredByAura);
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- GetSpellHistory()->AddCooldown(triggered_spell_id, 0, std::chrono::seconds(cooldown));
-
return true;
}
@@ -13858,6 +13796,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
HealInfo healInfo = HealInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL);
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, nullptr, &damageInfo, &healInfo);
+ std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
ProcTriggeredList procTriggered;
// Fill procTriggered list
for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr!= GetAppliedAuras().end(); ++itr)
@@ -13865,6 +13804,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
// Do not allow auras to proc from effect triggered by itself
if (procAura && procAura->Id == itr->first)
continue;
+
+ if (itr->second->GetBase()->IsProcOnCooldown(now))
+ continue;
+
ProcTriggeredData triggerData(itr->second->GetBase());
// Defensive procs are active on absorbs (so absorption effects are not a hindrance)
bool active = damage || (procExtra & PROC_EX_BLOCK && isVictim);
@@ -13946,9 +13889,9 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo);
// For players set spell cooldown if need
- uint32 cooldown = 0;
+ Milliseconds cooldown = Milliseconds::zero();
if (prepare && GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
- cooldown = i->spellProcEvent->cooldown;
+ cooldown = Seconds(i->spellProcEvent->cooldown);
// Note: must SetCantProc(false) before return
if (spellInfo->HasAttribute(SPELL_ATTR3_DISABLE_PROC))
@@ -13957,9 +13900,9 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
bool handled = i->aura->CallScriptProcHandlers(aurApp, eventInfo);
// "handled" is needed as long as proc can be handled in multiple places
- if (!handled && HandleAuraProc(target, damage, i->aura, procSpell, procFlag, procExtra, cooldown, &handled))
+ if (!handled && HandleAuraProc(target, damage, i->aura, procSpell, procFlag, procExtra, &handled))
{
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), Id);
+ TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), Id);
takeCharges = true;
}
@@ -13967,7 +13910,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
{
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
- if (!(i->effMask & (1<<effIndex)))
+ if (!(i->effMask & (1 << effIndex)))
continue;
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
@@ -13984,9 +13927,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
{
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)",
+ spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
// Don`t drop charge or add cooldown for not started trigger
- if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra))
takeCharges = true;
break;
}
@@ -14003,7 +13947,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
case SPELL_AURA_MANA_SHIELD:
case SPELL_AURA_DUMMY:
{
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)",
+ spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
@@ -14012,20 +13957,22 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
case SPELL_AURA_MOD_MELEE_HASTE:
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, isVictim ? "a victim's" : "an attacker's", triggeredByAura->GetId());
+ TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)",
+ spellInfo->Id, isVictim ? "a victim's" : "an attacker's", triggeredByAura->GetId());
takeCharges = true;
break;
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
{
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
+ TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)",
+ spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
+ if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell))
takeCharges = true;
break;
}
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
{
TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
takeCharges = true;
@@ -14034,7 +13981,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
case SPELL_AURA_RAID_PROC_FROM_CHARGE:
{
TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
HandleAuraRaidProcFromCharge(triggeredByAura);
takeCharges = true;
@@ -14042,9 +13989,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
}
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
{
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)",
+ spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
- if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra))
takeCharges = true;
break;
}
@@ -14129,6 +14077,9 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
} // for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
} // if (!handled)
+ if (prepare && takeCharges && cooldown != Milliseconds::zero())
+ i->aura->AddProcCooldown(now + cooldown);
+
// Remove charge (aura can be removed by triggers)
if (prepare && useCharges && takeCharges)
{
@@ -14157,6 +14108,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo)
{
+ std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
+
// use provided list of auras which can proc
if (procAuras)
{
@@ -14164,9 +14117,9 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTrigge
{
ASSERT((*itr)->GetTarget() == this);
if (!(*itr)->GetRemoveMode())
- if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo))
+ if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo, now))
{
- (*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo);
+ (*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo, now);
aurasTriggeringProc.push_back(*itr);
}
}
@@ -14176,9 +14129,9 @@ void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTrigge
{
for (AuraApplicationMap::iterator itr = GetAppliedAuras().begin(); itr!= GetAppliedAuras().end(); ++itr)
{
- if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo))
+ if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo, now))
{
- itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo);
+ itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo, now);
aurasTriggeringProc.push_back(itr->second);
}
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 190f581d4b8..30ef6eb394f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -2257,10 +2257,10 @@ class TC_GAME_API Unit : public WorldObject
private:
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent);
bool RollProcResult(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, SpellProcEventEntry const* spellProcEvent);
- bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
- bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled);
- bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
- bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown);
+ bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, Milliseconds& cooldown);
+ bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, bool* handled);
+ bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx);
+ bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell);
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);
bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 74a94a63594..3d35e4039ba 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -337,7 +337,8 @@ m_spellInfo(spellproto), m_casterGuid(casterGUID ? casterGUID : caster->GetGUID(
m_castItemGuid(castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_applyTime(time(NULL)),
m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0),
m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1),
-m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr)
+m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr),
+m_procCooldown(std::chrono::steady_clock::time_point::min())
{
if (m_spellInfo->ManaPerSecond || m_spellInfo->ManaPerSecondPerLevel)
m_timeCla = 1 * IN_MILLISECONDS;
@@ -1851,22 +1852,17 @@ bool Aura::CanStackWith(Aura const* existingAura) const
return true;
}
-bool Aura::IsProcOnCooldown() const
+bool Aura::IsProcOnCooldown(std::chrono::steady_clock::time_point now) const
{
- /*if (m_procCooldown)
- {
- if (m_procCooldown > time(NULL))
- return true;
- }*/
- return false;
+ return m_procCooldown > now;
}
-void Aura::AddProcCooldown(Milliseconds /*msec*/)
+void Aura::AddProcCooldown(std::chrono::steady_clock::time_point cooldownEnd)
{
- //m_procCooldown = std::chrono::steady_clock::now() + msec;
+ m_procCooldown = cooldownEnd;
}
-void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo)
+void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now)
{
bool prepare = CallScriptPrepareProcHandlers(aurApp, eventInfo);
if (!prepare)
@@ -1884,10 +1880,10 @@ void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInf
ASSERT(procEntry);
// cooldowns should be added to the whole aura (see 51698 area aura)
- AddProcCooldown(procEntry->Cooldown);
+ AddProcCooldown(now + procEntry->Cooldown);
}
-bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const
+bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now) const
{
SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId());
// only auras with spell proc entry can trigger proc
@@ -1899,7 +1895,7 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
return false;
// check proc cooldown
- if (IsProcOnCooldown())
+ if (IsProcOnCooldown(now))
return false;
/// @todo
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index f792581c86d..a147957f258 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -203,12 +203,12 @@ class TC_GAME_API Aura
// this subsystem is not yet in use - the core of it is functional, but still some research has to be done
// and some dependant problems fixed before it can replace old proc system (for example cooldown handling)
// currently proc system functionality is implemented in Unit::ProcDamageAndSpell
- bool IsProcOnCooldown() const;
- void AddProcCooldown(Milliseconds msec);
+ bool IsProcOnCooldown(std::chrono::steady_clock::time_point now) const;
+ void AddProcCooldown(std::chrono::steady_clock::time_point cooldownEnd);
bool IsUsingCharges() const { return m_isUsingCharges; }
void SetUsingCharges(bool val) { m_isUsingCharges = val; }
- void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo);
- bool IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const;
+ void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now);
+ bool IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now) const;
float CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const;
void TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo);
@@ -269,6 +269,8 @@ class TC_GAME_API Aura
ChargeDropEvent* m_dropEvent;
+ std::chrono::steady_clock::time_point m_procCooldown;
+
private:
Unit::AuraApplicationList m_removedApplications;
};