Core/Auras: reset periodic aura timers by default. Except when aura comes from triggered spell

This commit is contained in:
ariel- authored and roc13x committed 2017-05-03 23:51:47 +01:00
1 parent 8f4fd78cbf
commit a7a024d1d6
10 files changed
+62 -55

No files matched your search

+5 -5
View File
@@ -3161,7 +3161,7 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/)
Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool resetPeriodicTimer /*= true*/)
{
ASSERT(casterGUID || caster);
@@ -3184,7 +3184,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
// extremely rare case
// let's just recreate aura
if (effMask != foundAura->GetEffectMask())
return NULL;
return nullptr;
// update basepoints with new values - effect amount will be recalculated in ModStackAmount
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
@@ -3210,12 +3210,12 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
}
// try to increase stack amount
foundAura->ModStackAmount(1);
foundAura->ModStackAmount(1, AURA_REMOVE_BY_DEFAULT, resetPeriodicTimer);
return foundAura;
}
}
return NULL;
return nullptr;
}
void Unit::_AddAura(UnitAura* aura, Unit* caster)
@@ -3823,7 +3823,7 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, U
if (aura->IsSingleTarget())
aura->UnregisterSingleTarget();
if (Aura* newAura = Aura::TryRefreshStackOrCreate(aura->GetSpellInfo(), effMask, stealer, NULL, &baseDamage[0], NULL, aura->GetCasterGUID()))
if (Aura* newAura = Aura::TryRefreshStackOrCreate(aura->GetSpellInfo(), effMask, stealer, nullptr, &baseDamage[0], nullptr, aura->GetCasterGUID()))
{
// created aura must not be single target aura,, so stealer won't loose it on recast
if (newAura->IsSingleTarget())
+2 -4
View File
@@ -452,7 +452,7 @@ enum TriggerCastFlags
TRIGGERED_IGNORE_CASTER_AURASTATE = 0x00000800, //! Will ignore caster aura states including combat requirements and death state
TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE = 0x00002000, //! Will ignore mounted/on vehicle restrictions
TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements
// reuse 0x00020000
TRIGGERED_DONT_RESET_PERIODIC_TIMER = 0x00020000, //! Will allow periodic aura timers to keep ticking (instead of resetting)
TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions
TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements
TRIGGERED_IGNORE_TARGET_CHECK = 0x00100000, //! Will ignore most target checks (mostly DBC target checks)
@@ -1734,16 +1734,14 @@ class TC_GAME_API Unit : public WorldObject
bool InitTamedPet(Pet* pet, uint8 level, uint32 spell_id);
// aura apply/remove helpers - you should better not use these
Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool resetPeriodicTimer = true);
void _AddAura(UnitAura* aura, Unit* caster);
AuraApplication * _CreateAuraApplication(Aura* aura, uint8 effMask);
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
void _ApplyAura(AuraApplication * aurApp, uint8 effMask);
void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
void _UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode);
void _RemoveNoStackAuraApplicationsDueToAura(Aura* aura);
void _RemoveNoStackAurasDueToAura(Aura* aura);
bool _IsNoStackAuraDueToAura(Aura* appliedAura, Aura* existingAura) const;
void _RegisterAuraEffect(AuraEffect* aurEff, bool apply);
// m_ownedAuras container management
@@ -629,8 +629,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= tru
if (!m_isPeriodic)
return;
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
Player* modOwner = caster ? caster->GetSpellModOwner() : nullptr;
// Apply casting time mods
if (m_amplitude)
{
@@ -658,9 +657,9 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= tru
else // aura just created or reapplied
{
m_tickNumber = 0;
// reset periodic timer on aura create or on reapply when aura isn't dot
// possibly we should not reset periodic timers only when aura is triggered by proc
// or maybe there's a spell attribute somewhere
// reset periodic timer on aura create or reapply
// we don't reset periodic timers when aura is triggered by proc
if (resetPeriodicTimer)
{
m_periodicTimer = 0;
@@ -29,8 +29,8 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uin
class TC_GAME_API AuraEffect
{
friend void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
friend void Aura::_InitEffects(uint8 effMask, Unit* caster, int32* baseAmount);
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, bool resetPeriodicTimer);
friend Aura::~Aura();
private:
~AuraEffect();
+36 -27
View File
@@ -230,7 +230,7 @@ void AuraApplication::ClientUpdate(bool remove)
_target->SendMessageToSet(&data, true);
}
uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner)
uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 availableEffectMask, WorldObject* owner)
{
ASSERT(spellProto);
ASSERT(owner);
@@ -239,26 +239,28 @@ uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleE
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellProto->Effects[i].IsUnitOwnedAuraEffect())
effMask |= 1 << i;
}
break;
case TYPEID_DYNAMICOBJECT:
for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellProto->Effects[i].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
effMask |= 1 << i;
}
break;
default:
ABORT();
break;
}
return effMask & avalibleEffectMask;
return effMask & availableEffectMask;
}
Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/)
Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= nullptr*/, bool resetPeriodicTimer /*= true*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -266,25 +268,28 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMas
ASSERT(tryEffMask <= MAX_EFFECT_MASK);
if (refresh)
*refresh = false;
uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
if (!effMask)
return NULL;
if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID))
return nullptr;
if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID, resetPeriodicTimer))
{
// we've here aura, which script triggered removal after modding stack amount
// check the state here, so we won't create new Aura object
if (foundAura->IsRemoved())
return NULL;
return nullptr;
if (refresh)
*refresh = true;
return foundAura;
}
else
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
}
Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -292,7 +297,8 @@ Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject
ASSERT(tryEffMask <= MAX_EFFECT_MASK);
uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
if (!effMask)
return NULL;
return nullptr;
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
}
@@ -319,9 +325,9 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne
if (!owner->IsInWorld() || ((Unit*)owner)->IsDuringRemoveFromWorld())
// owner not in world so don't allow to own not self cast single target auras
if (casterGUID != owner->GetGUID() && spellproto->IsSingleTarget())
return NULL;
return nullptr;
Aura* aura = NULL;
Aura* aura = nullptr;
switch (owner->GetTypeId())
{
case TYPEID_UNIT:
@@ -333,11 +339,12 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne
break;
default:
ABORT();
return NULL;
return nullptr;
}
// aura can be removed in Unit::_AddAura call
if (aura->IsRemoved())
return NULL;
return nullptr;
return aura;
}
@@ -774,10 +781,9 @@ void Aura::RefreshDuration(bool withMods)
m_timeCla = 1 * IN_MILLISECONDS;
}
void Aura::RefreshTimers()
void Aura::RefreshTimers(bool resetPeriodicTimer)
{
m_maxDuration = CalcMaxDuration();
bool resetPeriodic = true;
if (m_spellInfo->HasAttribute(SPELL_ATTR8_DONT_RESET_PERIODIC_TIMER))
{
int32 minAmplitude = m_maxDuration;
@@ -790,15 +796,16 @@ void Aura::RefreshTimers()
if (GetDuration() <= minAmplitude)
{
m_maxDuration += GetDuration();
resetPeriodic = false;
resetPeriodicTimer = false;
}
}
RefreshDuration();
Unit* caster = GetCaster();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (HasEffect(i))
GetEffect(i)->CalculatePeriodic(caster, resetPeriodic, false);
if (AuraEffect* aurEff = m_effects[i])
aurEff->CalculatePeriodic(caster, resetPeriodicTimer, false);
}
void Aura::SetCharges(uint8 charges)
@@ -895,7 +902,7 @@ void Aura::SetStackAmount(uint8 stackAmount)
SetNeedClientUpdateForTargets();
}
bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode)
bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode /*= AURA_REMOVE_BY_DEFAULT*/, bool resetPeriodicTimer /*= true*/)
{
int32 stackAmount = m_stackAmount + num;
@@ -923,7 +930,7 @@ bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode)
if (refresh)
{
RefreshSpellMods();
RefreshTimers();
RefreshTimers(resetPeriodicTimer);
// reset charges
SetCharges(CalcMaxCharges());
@@ -1085,14 +1092,16 @@ void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint
m_stackAmount = stackamount;
Unit* caster = GetCaster();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (m_effects[i])
{
if (AuraEffect* aurEff = m_effects[i])
{
m_effects[i]->SetAmount(amount[i]);
m_effects[i]->SetCanBeRecalculated((recalculateMask & (1 << i)) != 0);
m_effects[i]->CalculatePeriodic(caster, false, true);
m_effects[i]->CalculateSpellMod();
m_effects[i]->RecalculateAmount(caster);
aurEff->SetAmount(amount[i]);
aurEff->SetCanBeRecalculated((recalculateMask & (1 << i)) != 0);
aurEff->CalculatePeriodic(caster, false, true);
aurEff->CalculateSpellMod();
aurEff->RecalculateAmount(caster);
}
}
}
bool Aura::HasEffectType(AuraType type) const
+6 -6
View File
@@ -84,13 +84,13 @@ class TC_GAME_API AuraApplication
class TC_GAME_API Aura
{
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, bool resetPeriodicTimer);
public:
typedef std::map<ObjectGuid, AuraApplication*> ApplicationMap;
static uint8 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner);
static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL);
static Aura* TryCreate(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
static uint8 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 availableEffectMask, WorldObject* owner);
static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = nullptr, bool resetPeriodicTimer = true);
static Aura* TryCreate(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty);
static Aura* Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
explicit Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID);
void _InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
@@ -131,7 +131,7 @@ class TC_GAME_API Aura
int32 GetDuration() const { return m_duration; }
void SetDuration(int32 duration, bool withMods = false);
void RefreshDuration(bool withMods = false);
void RefreshTimers();
void RefreshTimers(bool resetPeriodicTimer);
bool IsExpired() const { return !GetDuration() && !m_dropEvent; }
bool IsPermanent() const { return GetMaxDuration() == -1; }
@@ -146,7 +146,7 @@ class TC_GAME_API Aura
uint8 GetStackAmount() const { return m_stackAmount; }
void SetStackAmount(uint8 num);
bool ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
bool ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT, bool resetPeriodicTimer = true);
void RefreshSpellMods();
+2 -1
View File
@@ -2653,8 +2653,9 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
if (m_originalCaster)
{
bool refresh = false;
bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER);
m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit,
m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh);
m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, resetPeriodicTimer);
if (m_spellAura)
{
// Set aura stack amount to desired value
@@ -231,11 +231,7 @@ class boss_kelidan_the_breaker : public CreatureScript
Talk(SAY_NOVA);
if (SpellInfo const* nova = sSpellMgr->GetSpellInfo(SPELL_BURNING_NOVA))
{
if (Aura* aura = Aura::TryRefreshStackOrCreate(nova, MAX_EFFECT_MASK, me, me))
aura->ApplyForTargets();
}
me->AddAura(SPELL_BURNING_NOVA, me);
if (IsHeroic())
DoTeleportAll(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
@@ -748,12 +748,14 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader
Unit* caster = GetCaster();
// Refresh Shadow Word: Pain on target
if (Unit* target = GetHitUnit())
{
if (AuraEffect* aur = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, caster->GetGUID()))
{
aur->SetBonusAmount(caster->SpellDamageBonusDone(target, aur->GetSpellInfo(), 0, DOT));
aur->CalculatePeriodic(caster, false, false);
aur->GetBase()->RefreshDuration();
}
}
}
void Register() override
@@ -544,6 +544,7 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
{
// Refresh corruption on target
if (AuraEffect* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, caster->GetGUID()))
{
@@ -551,6 +552,7 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
aurEff->CalculatePeriodic(caster, false, false);
aurEff->GetBase()->RefreshDuration(true);
}
}
}
void Register() override