Core/Spells: fixed duration clamping for haste based periodic auras and added support for rolling any tick over
* roll over remaining time until next tick over into a refreshed periodic aura's duration * this behavior is now being used for stackable spells, all HoTs and DoTs * fixed adding extra ticks when at certain tick thresholds * corrected implementation of SPELL_ATTR8_HASTE_AFFECTS_DURATION * implemented SPELL_ATTR8_MELEE_HASTE_AFFECTS_PERIODIC
This commit is contained in:
1 parent
b6f0650303
commit
b6f8a68d61
10 files changed
+72
-97
No files matched your search
@@ -3029,7 +3029,19 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
|
||||
|
||||
if (!hitInfo.HitAura)
|
||||
{
|
||||
bool const resetPeriodicTimer = (m_spellInfo->StackAmount < 2) && !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER);
|
||||
bool const resetPeriodicTimer = [&]()
|
||||
{
|
||||
// HoTs and DoTs don't reset their periodic timer and roll ther duration over
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
if (m_spellInfo->Effects[i].IsEffect() && (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE
|
||||
|| m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_HEAL))
|
||||
return false;
|
||||
|
||||
if ((m_spellInfo->StackAmount < 2) && !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER))
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}();
|
||||
uint8 const allAuraEffectMask = Aura::BuildEffectMaskForOwner(hitInfo.AuraSpellInfo, MAX_EFFECT_MASK, unit);
|
||||
int32 const* bp = hitInfo.AuraBasePoints;
|
||||
if (hitInfo.AuraSpellInfo == m_spellInfo)
|
||||
@@ -3065,23 +3077,38 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
|
||||
|
||||
if (hitInfo.AuraDuration > 0)
|
||||
{
|
||||
// Haste modifies duration of channeled spells
|
||||
if (m_spellInfo->IsChanneled())
|
||||
caster->ModSpellDurationTime(m_spellInfo, hitInfo.AuraDuration, this);
|
||||
else if (m_spellInfo->HasAttribute(SPELL_ATTR8_HASTE_AFFECTS_DURATION))
|
||||
// Haste modifies duration and periodic of spells so we have to clamp the duration accordingly
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR8_HASTE_AFFECTS_DURATION)
|
||||
|| m_spellInfo->HasAttribute(SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC)
|
||||
|| m_spellInfo->HasAttribute(SPELL_ATTR8_MELEE_HASTE_AFFECTS_PERIODIC))
|
||||
{
|
||||
// Haste based auras need their duration adapted.
|
||||
int32 origDuration = hitInfo.AuraDuration;
|
||||
hitInfo.AuraDuration = 0;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (AuraEffect const* aurEff = hitInfo.HitAura->GetEffect(effIndex))
|
||||
if (int32 period = aurEff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED
|
||||
hitInfo.AuraDuration = std::max(std::max(origDuration / period, 1) * period, hitInfo.AuraDuration);
|
||||
{
|
||||
if (int32 period = aurEff->GetPeriod())
|
||||
{
|
||||
hitInfo.AuraDuration = std::clamp(origDuration / period * period, 1, origDuration);
|
||||
|
||||
// If the duration of the aura could fit in half of a tick, round up
|
||||
if (origDuration % period >= (period / 2))
|
||||
hitInfo.AuraDuration += period;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no periodic effect
|
||||
if (!hitInfo.AuraDuration)
|
||||
hitInfo.AuraDuration = int32(origDuration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
|
||||
hitInfo.AuraDuration = origDuration;
|
||||
}
|
||||
|
||||
// Apply rolled over duration if there is any
|
||||
hitInfo.AuraDuration += hitInfo.HitAura->GetRolledOverDuration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3767,17 +3794,9 @@ void Spell::handle_immediate()
|
||||
// start channeling if applicable
|
||||
if (m_spellInfo->IsChanneled())
|
||||
{
|
||||
int32 duration = m_spellInfo->GetDuration();
|
||||
int32 duration = Aura::CalcMaxDuration(m_spellInfo, m_caster);
|
||||
if (duration > 0)
|
||||
{
|
||||
// First mod_duration then haste - see Missile Barrage
|
||||
// Apply duration mod
|
||||
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SpellModOp::Duration, duration);
|
||||
|
||||
// Apply haste mods
|
||||
m_caster->ModSpellDurationTime(m_spellInfo, duration, this);
|
||||
|
||||
m_channeledDuration = duration;
|
||||
SendChannelStart(duration);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user