mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[10156] Add shared object for auras of same spell and move spell proc code to its own file, also spread procs by auras and effect indexes.
This commit is contained in:
parent
abe6776358
commit
a32b3063a2
32 changed files with 7507 additions and 6076 deletions
|
|
@ -4505,13 +4505,13 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
|||
{
|
||||
int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE;
|
||||
|
||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
if (SpellAuraHolder* holder = GetSpellAuraHolder(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS))
|
||||
{
|
||||
if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,SpellEffectIndex(i)))
|
||||
{
|
||||
Aur->SetAuraDuration(delta*IN_MILLISECONDS);
|
||||
Aur->SendAuraUpdate(false);
|
||||
}
|
||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
if(Aura* Aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
Aur->SetAuraDuration(delta*IN_MILLISECONDS);
|
||||
|
||||
holder->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6811,8 +6811,8 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||
|
||||
/* remove auras */
|
||||
std::vector<uint32> auras2remove;
|
||||
AuraMap const& vAuras = duel->opponent->GetAuras();
|
||||
for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i)
|
||||
SpellAuraHolderMap const& vAuras = duel->opponent->GetSpellAuraHolderMap();
|
||||
for (SpellAuraHolderMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i)
|
||||
{
|
||||
if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
|
||||
auras2remove.push_back(i->second->GetId());
|
||||
|
|
@ -6822,8 +6822,8 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||
duel->opponent->RemoveAurasDueToSpell(auras2remove[i]);
|
||||
|
||||
auras2remove.clear();
|
||||
AuraMap const& auras = GetAuras();
|
||||
for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
|
||||
SpellAuraHolderMap const& auras = GetSpellAuraHolderMap();
|
||||
for (SpellAuraHolderMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
|
||||
{
|
||||
if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
|
||||
auras2remove.push_back(i->second->GetId());
|
||||
|
|
@ -7302,8 +7302,8 @@ void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply
|
|||
bool found = false;
|
||||
for (int k=0; k < MAX_EFFECT_INDEX; ++k)
|
||||
{
|
||||
spellEffectPair spair = spellEffectPair(spellInfo->Id, SpellEffectIndex(k));
|
||||
for (AuraMap::const_iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter)
|
||||
SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellInfo->Id);
|
||||
for (SpellAuraHolderMap::const_iterator iter = spair.first; iter != spair.second; ++iter)
|
||||
{
|
||||
if(!item || iter->second->GetCastItemGUID() == item->GetGUID())
|
||||
{
|
||||
|
|
@ -15604,7 +15604,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
{
|
||||
//RemoveAllAuras(); -- some spells casted before aura load, for example in LoadSkills, aura list explcitly cleaned early
|
||||
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||
|
||||
if(result)
|
||||
{
|
||||
|
|
@ -15613,67 +15613,79 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
Field *fields = result->Fetch();
|
||||
uint64 caster_guid = fields[0].GetUInt64();
|
||||
uint32 spellid = fields[1].GetUInt32();
|
||||
SpellEffectIndex effindex = SpellEffectIndex(fields[2].GetUInt32());
|
||||
uint32 stackcount = fields[3].GetUInt32();
|
||||
int32 damage = fields[4].GetInt32();
|
||||
int32 maxduration = fields[5].GetInt32();
|
||||
int32 remaintime = fields[6].GetInt32();
|
||||
int32 remaincharges = fields[7].GetInt32();
|
||||
uint32 stackcount = fields[2].GetUInt32();
|
||||
int32 remaincharges = (int32)fields[3].GetUInt32();
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = (int32)fields[i+4].GetUInt32();
|
||||
maxduration[i] = (int32)fields[i+7].GetUInt32();
|
||||
remaintime[i] = (int32)fields[i+10].GetUInt32();
|
||||
}
|
||||
uint32 effIndexMask = (int32)fields[13].GetUInt32();
|
||||
|
||||
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
||||
if (!spellproto)
|
||||
if(!spellproto)
|
||||
{
|
||||
sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex);
|
||||
sLog.outError("Unknown spell (spellid %u), ignore.",spellid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (effindex >= MAX_EFFECT_INDEX)
|
||||
{
|
||||
sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// negative effects should continue counting down after logout
|
||||
if (remaintime != -1 && !IsPositiveEffect(spellid, effindex))
|
||||
{
|
||||
if (remaintime/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
// prevent wrong values of remaincharges
|
||||
if (spellproto->procCharges)
|
||||
if(spellproto->procCharges)
|
||||
{
|
||||
if (remaincharges <= 0 || remaincharges > (int32)spellproto->procCharges)
|
||||
if(remaincharges <= 0 || remaincharges > (int32)spellproto->procCharges)
|
||||
remaincharges = spellproto->procCharges;
|
||||
}
|
||||
else
|
||||
remaincharges = 0;
|
||||
|
||||
if (spellproto->StackAmount < stackcount)
|
||||
stackcount = spellproto->StackAmount;
|
||||
|
||||
for(uint32 i = 0; i < stackcount; ++i)
|
||||
SpellAuraHolder *holder = CreateSpellAuraHolder(spellproto, this, NULL);
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
|
||||
if (!damage)
|
||||
damage = aura->GetModifier()->m_amount;
|
||||
if ((effIndexMask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
// reset stolen single target auras
|
||||
if (caster_guid != GetGUID() && aura->IsSingleTarget())
|
||||
aura->SetIsSingleTarget(false);
|
||||
if (remaintime[i] != -1 && !IsPositiveEffect(spellid, SpellEffectIndex(i)))
|
||||
{
|
||||
if (remaintime[i]/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
||||
AddAura(aura);
|
||||
DETAIL_LOG("Added aura spellid %u, effect %u", spellproto->Id, effindex);
|
||||
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]);
|
||||
holder->AddAura(aura, SpellEffectIndex(i));
|
||||
}
|
||||
|
||||
if (!holder->IsEmptyHolder())
|
||||
{
|
||||
// reset stolen single target auras
|
||||
if (caster_guid != GetGUID() && holder->IsSingleTarget())
|
||||
holder->SetIsSingleTarget(false);
|
||||
|
||||
holder->SetLoadedState(caster_guid, stackcount, remaincharges);
|
||||
AddSpellAuraHolder(holder);
|
||||
DETAIL_LOG("Added auras from spellid %u, effect %u", spellproto->Id);
|
||||
}
|
||||
else
|
||||
delete holder;
|
||||
}
|
||||
while( result->NextRow() );
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
if(getClass() == CLASS_WARRIOR && !HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
|
||||
CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);
|
||||
CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);
|
||||
}
|
||||
|
||||
void Player::_LoadGlyphs(QueryResult *result)
|
||||
|
|
@ -16867,61 +16879,50 @@ void Player::_SaveAuras()
|
|||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||
|
||||
AuraMap const& auras = GetAuras();
|
||||
SpellAuraHolderMap const& auraHolders = GetSpellAuraHolderMap();
|
||||
|
||||
if (auras.empty())
|
||||
if (auraHolders.empty())
|
||||
return;
|
||||
|
||||
spellEffectPair lastEffectPair = auras.begin()->first;
|
||||
uint32 stackCounter = 1;
|
||||
|
||||
/* copied following sql-code partly from achievementmgr */
|
||||
bool first_round = true;
|
||||
std::ostringstream ss;
|
||||
for(AuraMap::const_iterator itr = auras.begin(); ; ++itr)
|
||||
|
||||
for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr)
|
||||
{
|
||||
if(itr == auras.end() || lastEffectPair != itr->first)
|
||||
SpellAuraHolder *holder = itr->second;
|
||||
//skip all holders from spells that are passive
|
||||
//do not save single target holders (unless they were cast by the player)
|
||||
if (!holder->IsPassive() && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget()))
|
||||
{
|
||||
AuraMap::const_iterator itr2 = itr;
|
||||
// save previous spellEffectPair to db
|
||||
itr2--;
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
uint32 effIndexMask = 0;
|
||||
|
||||
//skip all auras from spells that are passive
|
||||
//do not save single target auras (unless they were cast by the player)
|
||||
if (!itr2->second->IsPassive() && (itr2->second->GetCasterGUID() == GetGUID() || !itr2->second->IsSingleTarget()))
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (first_round)
|
||||
damage[i] = 0;
|
||||
remaintime[i] = 0;
|
||||
maxduration[i] = 0;
|
||||
|
||||
if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
ss << "INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges)VALUES ";
|
||||
first_round = false;
|
||||
// don't save not own area auras
|
||||
if (aur->IsAreaAura() && holder->GetCasterGUID() != GetGUID())
|
||||
continue;
|
||||
|
||||
damage[i] = aur->GetModifier()->m_amount;
|
||||
remaintime[i] = aur->GetAuraDuration();
|
||||
maxduration[i] = aur->GetAuraMaxDuration();
|
||||
effIndexMask |= (1 << i);
|
||||
}
|
||||
// next new/changed record prefix
|
||||
else
|
||||
ss << ", ";
|
||||
|
||||
ss << "("<< GetGUIDLow() << "," << itr2->second->GetCasterGUID() << ","
|
||||
<< (uint32)itr2->second->GetId() << "," << (uint32)itr2->second->GetEffIndex() << ","
|
||||
<< stackCounter << "," << itr2->second->GetModifier()->m_amount << ","
|
||||
<<int(itr2->second->GetAuraMaxDuration()) << "," << int(itr2->second->GetAuraDuration()) << ","
|
||||
<< int(itr2->second->GetAuraCharges()) << ")";
|
||||
}
|
||||
|
||||
if (!effIndexMask)
|
||||
continue;
|
||||
|
||||
if(itr == auras.end())
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastEffectPair == itr->first)
|
||||
stackCounter++;
|
||||
else
|
||||
{
|
||||
lastEffectPair = itr->first;
|
||||
stackCounter = 1;
|
||||
CharacterDatabase.PExecute("INSERT INTO character_aura (guid, caster_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", GetGUIDLow(), holder->GetCasterGUID(), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], effIndexMask);
|
||||
}
|
||||
}
|
||||
|
||||
// if something changed execute
|
||||
if (!first_round)
|
||||
CharacterDatabase.Execute( ss.str().c_str() );
|
||||
}
|
||||
|
||||
void Player::_SaveGlyphs()
|
||||
|
|
@ -19750,38 +19751,51 @@ void Player::SendAurasForTarget(Unit *target)
|
|||
Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
|
||||
for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
|
||||
{
|
||||
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
|
||||
SpellAuraHolderBounds bounds = target->GetSpellAuraHolderBounds(itr->second);
|
||||
for (SpellAuraHolderMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
||||
{
|
||||
if(Aura *aura = target->GetAura(itr->second, SpellEffectIndex(j)))
|
||||
SpellAuraHolder *holder = iter->second;
|
||||
data << uint8(holder->GetAuraSlot());
|
||||
data << uint32(holder->GetId());
|
||||
|
||||
if(holder->GetId())
|
||||
{
|
||||
data << uint8(aura->GetAuraSlot());
|
||||
data << uint32(aura->GetId());
|
||||
uint8 auraFlags = holder->GetAuraFlags();
|
||||
// flags
|
||||
data << uint8(auraFlags);
|
||||
// level
|
||||
data << uint8(holder->GetAuraLevel());
|
||||
// charges
|
||||
if (holder->GetAuraCharges())
|
||||
data << uint8(holder->GetAuraCharges() * holder->GetStackAmount());
|
||||
else
|
||||
data << uint8(holder->GetStackAmount());
|
||||
|
||||
if(aura->GetId())
|
||||
if(!(auraFlags & AFLAG_NOT_CASTER)) // packed GUID of caster
|
||||
{
|
||||
uint8 auraFlags = aura->GetAuraFlags();
|
||||
// flags
|
||||
data << uint8(auraFlags);
|
||||
// level
|
||||
data << uint8(aura->GetAuraLevel());
|
||||
// charges
|
||||
if (aura->GetAuraCharges())
|
||||
data << uint8(aura->GetAuraCharges() * aura->GetStackAmount());
|
||||
else
|
||||
data << uint8(aura->GetStackAmount());
|
||||
|
||||
if(!(auraFlags & AFLAG_NOT_CASTER)) // packed GUID of caster
|
||||
{
|
||||
data.appendPackGUID(aura->GetCasterGUID());
|
||||
}
|
||||
|
||||
if(auraFlags & AFLAG_DURATION) // include aura duration
|
||||
{
|
||||
data << uint32(aura->GetAuraMaxDuration());
|
||||
data << uint32(aura->GetAuraDuration());
|
||||
}
|
||||
data.appendPackGUID(holder->GetCasterGUID());
|
||||
}
|
||||
|
||||
if(auraFlags & AFLAG_DURATION) // include aura duration
|
||||
{
|
||||
// take highest - to display icon even if stun fades
|
||||
uint32 max_duration = 0;
|
||||
uint32 duration = 0;
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (Aura *aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
if (uint32(aura->GetAuraMaxDuration()) > max_duration)
|
||||
{
|
||||
max_duration = aura->GetAuraMaxDuration();
|
||||
duration = aura->GetAuraDuration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data << uint32(max_duration);
|
||||
data << uint32(duration);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20121,14 +20135,14 @@ bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const
|
|||
|
||||
void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
|
||||
{
|
||||
AuraMap& auras = GetAuras();
|
||||
for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); )
|
||||
SpellAuraHolderMap& auras = GetSpellAuraHolderMap();
|
||||
for(SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); )
|
||||
{
|
||||
Aura* aura = itr->second;
|
||||
SpellAuraHolder* holder = itr->second;
|
||||
|
||||
// skip passive (passive item dependent spells work in another way) and not self applied auras
|
||||
SpellEntry const* spellInfo = aura->GetSpellProto();
|
||||
if(aura->IsPassive() || aura->GetCasterGUID()!=GetGUID())
|
||||
SpellEntry const* spellInfo = holder->GetSpellProto();
|
||||
if(holder->IsPassive() || holder->GetCasterGUID()!=GetGUID())
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -20142,7 +20156,7 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
|
|||
}
|
||||
|
||||
// no alt item, remove aura, restart check
|
||||
RemoveAurasDueToSpell(aura->GetId());
|
||||
RemoveAurasDueToSpell(holder->GetId());
|
||||
itr = auras.begin();
|
||||
}
|
||||
|
||||
|
|
@ -20369,11 +20383,14 @@ void Player::UpdateZoneDependentAuras( uint32 newZone )
|
|||
void Player::UpdateAreaDependentAuras( uint32 newArea )
|
||||
{
|
||||
// remove auras from spells with area limitations
|
||||
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
|
||||
for(SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();)
|
||||
{
|
||||
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
|
||||
if(sSpellMgr.GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,this) != SPELL_CAST_OK)
|
||||
RemoveAura(iter);
|
||||
{
|
||||
RemoveSpellAuraHolder(iter->second);
|
||||
iter = m_spellAuraHolders.begin();
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue