mirror of
https://github.com/mangosfour/server.git
synced 2025-12-27 10:37:02 +00:00
[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:
parent
5833d74963
commit
4687fa8cb4
19 changed files with 388 additions and 379 deletions
|
|
@ -1243,7 +1243,7 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
{
|
||||
RemoveAllAuras();
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
|
||||
|
||||
if(result)
|
||||
{
|
||||
|
|
@ -1255,16 +1255,18 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
uint32 spellid = fields[2].GetUInt32();
|
||||
uint32 stackcount = fields[3].GetUInt32();
|
||||
uint32 remaincharges = fields[4].GetUInt32();
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
uint32 periodicTime[MAX_EFFECT_INDEX];
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = fields[i+5].GetInt32();
|
||||
maxduration[i] = fields[i+8].GetInt32();
|
||||
remaintime[i] = fields[i+11].GetInt32();
|
||||
periodicTime[i] = fields[i+8].GetUInt32();
|
||||
}
|
||||
uint32 effIndexMask = fields[14].GetUInt32();
|
||||
|
||||
int32 maxduration = fields[11].GetInt32();
|
||||
int32 remaintime = fields[12].GetInt32();
|
||||
uint32 effIndexMask = fields[13].GetUInt32();
|
||||
|
||||
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
||||
if (!spellproto)
|
||||
|
|
@ -1277,6 +1279,14 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
||||
continue;
|
||||
|
||||
if (remaintime != -1 && !IsPositiveSpell(spellproto))
|
||||
{
|
||||
if (remaintime/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
// prevent wrong values of remaincharges
|
||||
uint32 procCharges = spellproto->procCharges;
|
||||
if (procCharges)
|
||||
|
|
@ -1294,34 +1304,24 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
else if (!stackcount)
|
||||
stackcount = 1;
|
||||
|
||||
|
||||
SpellAuraHolder *holder = CreateSpellAuraHolder(spellproto, this, NULL);
|
||||
holder->SetLoadedState(caster_guid, ObjectGuid(HIGHGUID_ITEM, item_lowguid), stackcount, remaincharges, maxduration, remaintime);
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if ((effIndexMask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
if (remaintime[i] != -1 && !IsPositiveEffect(spellproto, SpellEffectIndex(i)))
|
||||
{
|
||||
if (remaintime[i]/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime[i] -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
Aura* aura = CreateAura(spellproto, SpellEffectIndex(i), NULL, holder, this);
|
||||
if (!damage[i])
|
||||
damage[i] = aura->GetModifier()->m_amount;
|
||||
|
||||
aura->SetLoadedState(damage[i], maxduration[i], remaintime[i]);
|
||||
aura->SetLoadedState(damage[i], periodicTime[i]);
|
||||
holder->AddAura(aura, SpellEffectIndex(i));
|
||||
}
|
||||
|
||||
if (!holder->IsEmptyHolder())
|
||||
{
|
||||
holder->SetLoadedState(caster_guid, ObjectGuid(HIGHGUID_ITEM, item_lowguid), stackcount, remaincharges);
|
||||
AddSpellAuraHolder(holder);
|
||||
}
|
||||
else
|
||||
delete holder;
|
||||
}
|
||||
|
|
@ -1344,6 +1344,10 @@ void Pet::_SaveAuras()
|
|||
if (auraHolders.empty())
|
||||
return;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insAuras, "INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, "
|
||||
"basepoints0, basepoints1, basepoints2, periodictime0, periodictime1, periodictime2, maxduration, remaintime, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr)
|
||||
{
|
||||
SpellAuraHolder *holder = itr->second;
|
||||
|
|
@ -1365,16 +1369,14 @@ void Pet::_SaveAuras()
|
|||
//do not save single target holders (unless they were cast by the player)
|
||||
if (save && !holder->IsPassive() && !IsChanneledSpell(holder->GetSpellProto()) && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget()))
|
||||
{
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
uint32 periodicTime[MAX_EFFECT_INDEX];
|
||||
uint32 effIndexMask = 0;
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = 0;
|
||||
remaintime[i] = 0;
|
||||
maxduration[i] = 0;
|
||||
periodicTime[i] = 0;
|
||||
|
||||
if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
|
|
@ -1383,8 +1385,7 @@ void Pet::_SaveAuras()
|
|||
continue;
|
||||
|
||||
damage[i] = aur->GetModifier()->m_amount;
|
||||
remaintime[i] = aur->GetAuraDuration();
|
||||
maxduration[i] = aur->GetAuraMaxDuration();
|
||||
periodicTime[i] = aur->GetModifier()->periodictime;
|
||||
effIndexMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
|
@ -1392,9 +1393,6 @@ void Pet::_SaveAuras()
|
|||
if (!effIndexMask)
|
||||
continue;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insAuras, "INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
stmt.addUInt32(m_charmInfo->GetPetNumber());
|
||||
stmt.addUInt64(holder->GetCasterGuid().GetRawValue());
|
||||
stmt.addUInt32(holder->GetCastItemGuid().GetCounter());
|
||||
|
|
@ -1402,15 +1400,14 @@ void Pet::_SaveAuras()
|
|||
stmt.addUInt32(holder->GetStackAmount());
|
||||
stmt.addUInt8(holder->GetAuraCharges());
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
stmt.addInt32(damage[i]);
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(maxduration[i]);
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(remaintime[i]);
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
stmt.addUInt32(periodicTime[i]);
|
||||
|
||||
stmt.addInt32(holder->GetAuraMaxDuration());
|
||||
stmt.addInt32(holder->GetAuraDuration());
|
||||
stmt.addUInt32(effIndexMask);
|
||||
stmt.Execute();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue