[11299] Handle aura durations in SpellAuraHolder

- Unit::CalculateSpellDuration split into two functions
    - CalculateSpellDuration taking into account combo points and caster-side spell mods
    - Unit::CalculateAuraDuration taking into account target-side spell mods
- Diminishing is now applied before duration reduction mods
- Implement saving per-effect periodic timers to DB (required for auras affected by haste)
This commit is contained in:
zergtmn 2011-03-30 23:29:01 +06:00
parent 5833d74963
commit 4687fa8cb4
19 changed files with 388 additions and 379 deletions

View file

@ -1150,7 +1150,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo);
}
void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
void Spell::DoSpellHitOnUnit(Unit *unit, uint32 effectMask)
{
if (!unit || !effectMask)
return;
@ -1264,9 +1264,12 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
CastPreCastSpells(unit);
if (IsSpellAppliesAura(m_spellInfo, effectMask))
spellAuraHolder = CreateSpellAuraHolder(m_spellInfo, unit, realCaster, m_CastItem);
{
m_spellAuraHolder = CreateSpellAuraHolder(m_spellInfo, unit, realCaster, m_CastItem);
m_spellAuraHolder->setDiminishGroup(m_diminishGroup);
}
else
spellAuraHolder = NULL;
m_spellAuraHolder = NULL;
for(int effectNumber = 0; effectNumber < MAX_EFFECT_INDEX; ++effectNumber)
{
@ -1287,13 +1290,39 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
}
// now apply all created auras
if (spellAuraHolder)
if (m_spellAuraHolder)
{
// normally shouldn't happen
if (!spellAuraHolder->IsEmptyHolder())
unit->AddSpellAuraHolder(spellAuraHolder);
if (!m_spellAuraHolder->IsEmptyHolder())
{
int32 duration = m_spellAuraHolder->GetAuraMaxDuration();
int32 originalDuration = duration;
if (duration > 0)
{
int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, m_spellInfo);
unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel, limitduration);
// Fully diminished
if (duration == 0)
{
delete m_spellAuraHolder;
return;
}
}
duration = unit->CalculateAuraDuration(m_spellInfo, effectMask, duration, m_caster);
if (duration != originalDuration)
{
m_spellAuraHolder->SetAuraMaxDuration(duration);
m_spellAuraHolder->SetAuraDuration(duration);
}
unit->AddSpellAuraHolder(m_spellAuraHolder);
}
else
delete spellAuraHolder;
delete m_spellAuraHolder;
}
}
@ -2771,7 +2800,7 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
if(triggeredByAura)
{
SendChannelUpdate(0);
triggeredByAura->SetAuraDuration(0);
triggeredByAura->GetHolder()->SetAuraDuration(0);
}
SendCastResult(result);
finish(false);
@ -3126,12 +3155,10 @@ void Spell::handle_immediate()
// start channeling if applicable
if(IsChanneledSpell(m_spellInfo))
{
int32 duration = GetSpellDuration(m_spellInfo);
if (duration)
int32 duration = CalculateSpellDuration(m_spellInfo, m_caster);
if (duration > 0)
{
// Apply duration mod
if(Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
m_spellState = SPELL_STATE_CASTING;
SendChannelStart(duration);
}
@ -5694,7 +5721,7 @@ SpellCastResult Spell::CheckCasterAuras() const
{
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
{
if (GetSpellMechanicMask(itr->second->GetSpellProto(), i) & mechanic_immune)
if (GetSpellMechanicMask(itr->second->GetSpellProto(), 1 << i) & mechanic_immune)
continue;
if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune)
continue;