[9090] Implement tick counting in periodic auras.

This can be used for some tick number dependent aura effects.
Also in some cases impossible claculate tickes count pass,
for example for infinity duration auras.
This commit is contained in:
VladimirMangos 2009-12-31 17:14:20 +03:00
parent 9a6c248dec
commit e5dfeea31e
4 changed files with 18 additions and 12 deletions

View file

@ -363,7 +363,7 @@ static AuraType const frozenAuraTypes[] = { SPELL_AURA_MOD_ROOT, SPELL_AURA_MOD_
Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
m_spellmod(NULL), m_caster_guid(0), m_target(target), m_castItemGuid(castItem?castItem->GetGUID():0),
m_timeCla(1000), m_periodicTimer(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
m_timeCla(1000), m_periodicTimer(0), m_periodicTick(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
m_effIndex(eff), m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),
m_positive(false), m_permanent(false), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false),
m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false)
@ -652,6 +652,7 @@ void Aura::Update(uint32 diff)
{
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
m_periodicTimer += m_modifier.periodictime;
++m_periodicTick; // for some infinity auras in some cases can overflow and reset
PeriodicTick();
}
}
@ -4539,7 +4540,7 @@ void Aura::HandlePeriodicEnergize(bool apply, bool Real)
case 54833: // Glyph of Innervate (value%/2 of casters base mana)
{
if (Unit* caster = GetCaster())
m_modifier.m_amount = int32(caster->GetCreateMana() * GetBasePoints() / (200 * m_maxduration / m_periodicTimer));
m_modifier.m_amount = int32(caster->GetCreateMana() * GetBasePoints() / (200 * GetAuraMaxTicks()));
break;
}
@ -4551,7 +4552,7 @@ void Aura::HandlePeriodicEnergize(bool apply, bool Real)
if (caster->HasAura(54832))
caster->CastSpell(caster,54833,true,NULL,this);
m_modifier.m_amount = int32(caster->GetCreateMana() * GetBasePoints() / (100 * m_maxduration / m_periodicTimer));
m_modifier.m_amount = int32(caster->GetCreateMana() * GetBasePoints() / (100 * GetAuraMaxTicks()));
}
break;
}
@ -6612,10 +6613,10 @@ void Aura::PeriodicTick()
if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && GetSpellProto()->SpellIconID==544)
{
// 1..4 ticks, 1/2 from normal tick damage
if (m_duration >= ((m_maxduration-m_modifier.periodictime) * 2 / 3))
if (GetAuraTicks() <= 4)
pdamage = pdamage/2;
// 9..12 ticks, 3/2 from normal tick damage
else if(m_duration < ((m_maxduration-m_modifier.periodictime) / 3))
else if(GetAuraTicks() >= 9)
pdamage += (pdamage + 1) / 2; // +1 prevent 0.5 damage possible lost at 1..4 ticks
// 5..8 ticks have normal tick damage
}
@ -6756,8 +6757,8 @@ void Aura::PeriodicTick()
// Wild Growth (1/7 - 6 + 2*ramainTicks) %
if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellIconID == 2864)
{
int32 ticks = m_maxduration/m_modifier.periodictime;
int32 remainingTicks = int32(float(m_duration) / m_modifier.periodictime + 0.5);
int32 ticks = GetAuraMaxTicks();
int32 remainingTicks = ticks - GetAuraTicks();
pdamage = int32(pdamage) + int32(amount)*ticks*(-6+2*remainingTicks)/100;
}
}

View file

@ -234,7 +234,9 @@ class MANGOS_DLL_SPEC Aura
void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
int32 GetAuraDuration() const { return m_duration; }
void SetAuraDuration(int32 duration) { m_duration = duration; }
time_t GetAuraApplyTime() { return m_applyTime; }
time_t GetAuraApplyTime() const { return m_applyTime; }
uint32 GetAuraTicks() const { return m_periodicTick; }
uint32 GetAuraMaxTicks() const { return m_maxduration > 0 && m_modifier.periodictime > 0 ? m_maxduration / m_modifier.periodictime : 0; }
SpellModifier *getAuraSpellMod() {return m_spellmod; }
@ -249,6 +251,9 @@ class MANGOS_DLL_SPEC Aura
m_maxduration = maxduration;
m_duration = duration;
m_procCharges = charges;
if(uint32 maxticks = GetAuraMaxTicks())
m_periodicTick = maxticks - m_duration / m_modifier.periodictime;
}
uint8 GetAuraSlot() const { return m_auraSlot; }
@ -368,6 +373,7 @@ class MANGOS_DLL_SPEC Aura
int32 m_duration; // Current time
int32 m_timeCla; // Timer for power per sec calcultion
int32 m_periodicTimer; // Timer for periodic auras
uint32 m_periodicTick; // Tick count pass (including current if use in tick code) from aura apply, used for some tick count dependent aura effects
AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
DiminishingGroup m_AuraDRGroup:8; // Diminishing

View file

@ -3621,11 +3621,10 @@ bool Unit::AddAura(Aura *Aur)
// Carry over removed Aura's remaining damage if Aura still has ticks remaining
else if (aur2->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_STACK_DOT_MODIFIER && aurName == SPELL_AURA_PERIODIC_DAMAGE && aur2->GetAuraDuration() > 0)
{
int32 remainingTicks = 1 + (aur2->GetAuraDuration() / aur2->GetModifier()->periodictime);
int32 remainingTicks = aur2->GetAuraMaxTicks() - aur2->GetAuraTicks();
int32 remainingDamage = aur2->GetModifier()->m_amount * remainingTicks;
int32 maxTicks = Aur->GetAuraMaxDuration() / Aur->GetModifier()->periodictime;
Aur->GetModifier()->m_amount += int32(remainingDamage / maxTicks);
Aur->GetModifier()->m_amount += int32(remainingDamage / Aur->GetAuraMaxTicks());
}
// can be only single (this check done at _each_ aura add
RemoveAura(i2,AURA_REMOVE_BY_STACK);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9089"
#define REVISION_NR "9090"
#endif // __REVISION_NR_H__