diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 135 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 8 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 10 |
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; }; |