*Fix per-caster aura state based on [8218] (Author: VladimirMangos;almost nothing left from original patch):
*Fixes all per caster aurastates instead of only conflagrate *Adds a holder for aura state auras for speedup search *Save some memory space by removing m_auraStateMask from aura class. --HG-- branch : trunk
This commit is contained in:
@@ -477,6 +477,13 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
if (((GameObject*)this)->GetGoArtKit())
|
||||
updateMask->SetBit(GAMEOBJECT_BYTES_1);
|
||||
}
|
||||
else if (isType(TYPEMASK_UNIT))
|
||||
{
|
||||
if( ((Unit*)this)->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK))
|
||||
{
|
||||
updateMask->SetBit(UNIT_FIELD_AURASTATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // case UPDATETYPE_VALUES
|
||||
{
|
||||
@@ -489,6 +496,13 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
updateMask->SetBit(GAMEOBJECT_DYNAMIC);
|
||||
updateMask->SetBit(GAMEOBJECT_BYTES_1);
|
||||
}
|
||||
else if (isType(TYPEMASK_UNIT))
|
||||
{
|
||||
if( ((Unit*)this)->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK))
|
||||
{
|
||||
updateMask->SetBit(UNIT_FIELD_AURASTATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WPAssert(updateMask && updateMask->GetCount() == m_valuesCount);
|
||||
@@ -513,6 +527,11 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
|
||||
*data << uint32(appendValue);
|
||||
}
|
||||
else if (index == UNIT_FIELD_AURASTATE)
|
||||
{
|
||||
// Check per caster aura states to not enable using a pell in client if specified aura is not by target
|
||||
*data << ((Unit*)this)->BuildAuraStateUpdateForTarget(target);
|
||||
}
|
||||
// FIXME: Some values at server stored in float format but must be sent to client in uint32 format
|
||||
else if(index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
|
||||
{
|
||||
|
||||
@@ -893,6 +893,7 @@ enum SpellCastResult
|
||||
enum AuraState
|
||||
{ // (C) used in caster aura state (T) used in target aura state
|
||||
// (c) used in caster aura state-not (t) used in target aura state-not
|
||||
AURA_STATE_NONE = 0, // C |
|
||||
AURA_STATE_DEFENSE = 1, // C |
|
||||
AURA_STATE_HEALTHLESS_20_PERCENT = 2, // CcT |
|
||||
AURA_STATE_BERSERKING = 3, // C T |
|
||||
@@ -920,6 +921,9 @@ enum AuraState
|
||||
AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C |
|
||||
};
|
||||
|
||||
#define PER_CASTER_AURA_STATE_MASK ( \
|
||||
(1<<(AURA_STATE_CONFLAGRATE-1))|(1<<(AURA_STATE_SWIFTMEND-1))|(1<<(AURA_STATE_DEADLY_POISON-1)))
|
||||
|
||||
// Spell mechanics
|
||||
enum Mechanics
|
||||
{
|
||||
|
||||
+1
-78
@@ -354,7 +354,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
||||
Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, WorldObject *source, Unit *caster, Item* castItem) :
|
||||
m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
|
||||
m_timeCla(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
|
||||
m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false)
|
||||
m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1), m_updated(false), m_isRemoved(false)
|
||||
{
|
||||
assert(target);
|
||||
|
||||
@@ -369,8 +369,6 @@ m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_aura
|
||||
|
||||
m_isPassive = IsPassiveSpell(GetId());
|
||||
|
||||
m_auraStateMask = 0;
|
||||
|
||||
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
|
||||
|
||||
m_applyTime = time(NULL);
|
||||
@@ -1195,65 +1193,6 @@ void Aura::_AddAura()
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************
|
||||
// Update target aura state flag
|
||||
//*****************************************************
|
||||
|
||||
// Update Seals information
|
||||
if (IsSealSpell(m_spellProto))
|
||||
SetAuraState(AURA_STATE_JUDGEMENT);
|
||||
|
||||
// Conflagrate aura state on Immolate and Shadowflame
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK &&
|
||||
// Immolate
|
||||
((m_spellProto->SpellFamilyFlags[0] & 4) ||
|
||||
// Shadowflame
|
||||
(m_spellProto->SpellFamilyFlags[2] & 2)))
|
||||
SetAuraState(AURA_STATE_CONFLAGRATE);
|
||||
|
||||
// Faerie Fire (druid versions)
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x400)
|
||||
SetAuraState(AURA_STATE_FAERIE_FIRE);
|
||||
|
||||
// Sting (hunter's pet ability)
|
||||
if (m_spellProto->Category == 1133)
|
||||
SetAuraState(AURA_STATE_FAERIE_FIRE);
|
||||
|
||||
// Victorious
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00040000)
|
||||
SetAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH);
|
||||
|
||||
// Swiftmend state on Regrowth & Rejuvenation
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x50 )
|
||||
SetAuraState(AURA_STATE_SWIFTMEND);
|
||||
|
||||
// Deadly poison aura state
|
||||
if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x10000)
|
||||
SetAuraState(AURA_STATE_DEADLY_POISON);
|
||||
|
||||
// Enrage aura state
|
||||
if(m_spellProto->Dispel == DISPEL_ENRAGE)
|
||||
SetAuraState(AURA_STATE_ENRAGE);
|
||||
|
||||
// Bleeding aura state
|
||||
if (GetAllSpellMechanicMask(m_spellProto) & 1<<MECHANIC_BLEED)
|
||||
SetAuraState(AURA_STATE_BLEEDING);
|
||||
|
||||
if(GetSpellSchoolMask(m_spellProto) & SPELL_SCHOOL_MASK_FROST)
|
||||
{
|
||||
for (uint8 i = 0;i<MAX_SPELL_EFFECTS;++i)
|
||||
{
|
||||
if (m_spellProto->EffectApplyAuraName[i]==SPELL_AURA_MOD_STUN
|
||||
|| m_spellProto->EffectApplyAuraName[i]==SPELL_AURA_MOD_ROOT)
|
||||
{
|
||||
SetAuraState(AURA_STATE_FROZEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_target->ApplyModFlag(UNIT_FIELD_AURASTATE, GetAuraStateMask(), true);
|
||||
|
||||
HandleAuraSpecificMods(true);
|
||||
}
|
||||
|
||||
@@ -1300,22 +1239,6 @@ void Aura::_RemoveAura()
|
||||
if (getDiminishGroup() != DIMINISHING_NONE )
|
||||
m_target->ApplyDiminishingAura(getDiminishGroup(),false);
|
||||
|
||||
// Check needed only if aura applies aurastate
|
||||
if(GetAuraStateMask())
|
||||
{
|
||||
uint32 foundMask = 0;
|
||||
Unit::AuraMap& Auras = m_target->GetAuras();
|
||||
// Get mask of all aurastates from remaining auras
|
||||
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
|
||||
{
|
||||
foundMask|=(*i).second->GetAuraStateMask();
|
||||
}
|
||||
// Remove only aurastates which were not found
|
||||
foundMask = GetAuraStateMask() &~foundMask;
|
||||
if (foundMask)
|
||||
m_target->ApplyModFlag(UNIT_FIELD_AURASTATE, foundMask, false);
|
||||
}
|
||||
|
||||
// since now aura cannot apply/remove it's modifiers
|
||||
m_isRemoved = true;
|
||||
// disable client server communication for removed aura
|
||||
|
||||
@@ -84,8 +84,6 @@ class TRINITY_DLL_SPEC Aura
|
||||
int8 GetStackAmount() const {return m_stackAmount;}
|
||||
void SetStackAmount(uint8 num, bool applied = true);
|
||||
bool modStackAmount(int32 num); // return true if last charge dropped
|
||||
uint32 GetAuraStateMask(){return m_auraStateMask;}
|
||||
void SetAuraState(uint8 num){m_auraStateMask |= 1<<(num-1);} //modifies auras' aura state (not unit!)
|
||||
|
||||
void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
|
||||
uint8 GetRemoveMode() const {return m_removeMode;}
|
||||
@@ -154,7 +152,6 @@ class TRINITY_DLL_SPEC Aura
|
||||
uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount)
|
||||
uint8 m_procCharges; // Aura charges (0 for infinite)
|
||||
uint8 m_stackAmount; // Aura stack amount
|
||||
uint32 m_auraStateMask;
|
||||
AuraEffect * m_partAuras[3];
|
||||
|
||||
uint32 m_procDamage; // used in aura proc code
|
||||
|
||||
@@ -406,6 +406,63 @@ uint32 CalculatePowerCost(SpellEntry const * spellInfo, Unit const * caster, Spe
|
||||
return powerCost;
|
||||
}
|
||||
|
||||
AuraState GetSpellAuraState(SpellEntry const * spellInfo)
|
||||
{
|
||||
// Seals
|
||||
if (IsSealSpell(spellInfo))
|
||||
return (AURA_STATE_JUDGEMENT);
|
||||
|
||||
// Conflagrate aura state on Immolate and Shadowflame
|
||||
if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
|
||||
// Immolate
|
||||
((spellInfo->SpellFamilyFlags[0] & 4) ||
|
||||
// Shadowflame
|
||||
(spellInfo->SpellFamilyFlags[2] & 2)))
|
||||
return (AURA_STATE_CONFLAGRATE);
|
||||
|
||||
// Faerie Fire (druid versions)
|
||||
if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && spellInfo->SpellFamilyFlags[0] & 0x400)
|
||||
return (AURA_STATE_FAERIE_FIRE);
|
||||
|
||||
// Sting (hunter's pet ability)
|
||||
if (spellInfo->Category == 1133)
|
||||
return (AURA_STATE_FAERIE_FIRE);
|
||||
|
||||
// Victorious
|
||||
if (spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellFamilyFlags[1] & 0x00040000)
|
||||
return (AURA_STATE_WARRIOR_VICTORY_RUSH);
|
||||
|
||||
// Swiftmend state on Regrowth & Rejuvenation
|
||||
if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && spellInfo->SpellFamilyFlags[0] & 0x50 )
|
||||
return (AURA_STATE_SWIFTMEND);
|
||||
|
||||
// Deadly poison aura state
|
||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags[0] & 0x10000)
|
||||
return (AURA_STATE_DEADLY_POISON);
|
||||
|
||||
// Enrage aura state
|
||||
if(spellInfo->Dispel == DISPEL_ENRAGE)
|
||||
return (AURA_STATE_ENRAGE);
|
||||
|
||||
// Bleeding aura state
|
||||
if (GetAllSpellMechanicMask(spellInfo) & 1<<MECHANIC_BLEED)
|
||||
return (AURA_STATE_BLEEDING);
|
||||
|
||||
if(GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST)
|
||||
{
|
||||
for (uint8 i = 0;i<MAX_SPELL_EFFECTS;++i)
|
||||
{
|
||||
if (spellInfo->EffectApplyAuraName[i]==SPELL_AURA_MOD_STUN
|
||||
|| spellInfo->EffectApplyAuraName[i]==SPELL_AURA_MOD_ROOT)
|
||||
{
|
||||
return (AURA_STATE_FROZEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return AURA_STATE_NONE;
|
||||
}
|
||||
|
||||
SpellSpecific GetSpellSpecific(uint32 spellId)
|
||||
{
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
|
||||
|
||||
@@ -134,6 +134,7 @@ enum SpellLinkedType
|
||||
};
|
||||
|
||||
SpellSpecific GetSpellSpecific(uint32 spellId);
|
||||
AuraState GetSpellAuraState(SpellEntry const * spellInfo);
|
||||
|
||||
// Different spell properties
|
||||
inline float GetSpellRadiusForHostile(SpellRadiusEntry const *radius) { return (radius ? radius->radiusHostile : 0); }
|
||||
|
||||
+65
-5
@@ -3883,6 +3883,17 @@ bool Unit::AddAura(Aura *Aur, bool handleEffects)
|
||||
|
||||
// add aura, register in lists and arrays
|
||||
Aur->_AddAura();
|
||||
|
||||
//*****************************************************
|
||||
// Update target aura state flag
|
||||
//*****************************************************
|
||||
if(AuraState aState = GetSpellAuraState(Aur->GetSpellProto()))
|
||||
{
|
||||
bool found = false;
|
||||
m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, Aur));
|
||||
ModifyAuraState(aState, true);
|
||||
}
|
||||
|
||||
m_Auras.insert(AuraMap::value_type(aurId, Aur));
|
||||
|
||||
if(aurSpellInfo->AuraInterruptFlags)
|
||||
@@ -4214,6 +4225,28 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
||||
|
||||
Aur->_RemoveAura();
|
||||
|
||||
bool auraStateFound = false;
|
||||
if (AuraState auraState = GetSpellAuraState(Aur->GetSpellProto()))
|
||||
{
|
||||
bool canBreak = false;
|
||||
// Get mask of all aurastates from remaining auras
|
||||
for(AuraStateAurasMap::iterator itr = m_auraStateAuras.lower_bound(auraState); itr != m_auraStateAuras.upper_bound(auraState) || !(auraStateFound && canBreak);)
|
||||
{
|
||||
if (itr->second == Aur)
|
||||
{
|
||||
m_auraStateAuras.erase(itr);
|
||||
itr = m_auraStateAuras.lower_bound(auraState);
|
||||
canBreak = true;
|
||||
continue;
|
||||
}
|
||||
auraStateFound = true;
|
||||
++itr;
|
||||
}
|
||||
// Remove only aurastates which were not found
|
||||
if (!auraStateFound)
|
||||
ModifyAuraState(auraState, false);
|
||||
}
|
||||
|
||||
// Remove totem at next update if totem looses its aura
|
||||
if (Aur->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem()&& ((TempSummon*)this)->GetSummonerGUID()==Aur->GetCasterGUID())
|
||||
{
|
||||
@@ -8581,15 +8614,42 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Unit::BuildAuraStateUpdateForTarget(Unit * target) const
|
||||
{
|
||||
uint32 auraStates = GetUInt32Value(UNIT_FIELD_AURASTATE) &~(PER_CASTER_AURA_STATE_MASK);
|
||||
for(AuraStateAurasMap::const_iterator itr = m_auraStateAuras.begin(); itr != m_auraStateAuras.end();++itr)
|
||||
{
|
||||
if ((1<<(itr->first-1)) & PER_CASTER_AURA_STATE_MASK)
|
||||
{
|
||||
if (itr->second->GetCasterGUID() == target->GetGUID())
|
||||
auraStates |= (1<<(itr->first-1));
|
||||
}
|
||||
}
|
||||
return auraStates;
|
||||
}
|
||||
|
||||
bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit * Caster) const
|
||||
{
|
||||
if (Caster && spellProto)
|
||||
if (Caster)
|
||||
{
|
||||
AuraEffectList const& stateAuras = Caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
|
||||
for(AuraEffectList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
|
||||
if((*j)->isAffectedOnSpell(spellProto))
|
||||
return true;
|
||||
if(spellProto)
|
||||
{
|
||||
AuraEffectList const& stateAuras = Caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
|
||||
for(AuraEffectList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
|
||||
if((*j)->isAffectedOnSpell(spellProto))
|
||||
return true;
|
||||
}
|
||||
// Check per caster aura state
|
||||
// If aura with aurastate by caster not found return false
|
||||
if ((1<<(flag-1)) & PER_CASTER_AURA_STATE_MASK)
|
||||
{
|
||||
for(AuraStateAurasMap::const_iterator itr = m_auraStateAuras.lower_bound(flag); itr != m_auraStateAuras.upper_bound(flag);++itr)
|
||||
if (itr->second->GetCasterGUID() == Caster->GetGUID())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1023,6 +1023,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
typedef std::set<Unit*> ControlList;
|
||||
typedef std::pair<uint32, uint8> spellEffectPair;
|
||||
typedef std::multimap<uint32, Aura*> AuraMap;
|
||||
typedef std::multimap<AuraState, Aura*> AuraStateAurasMap;
|
||||
typedef std::list<AuraEffect *> AuraEffectList;
|
||||
typedef std::list<Aura *> AuraList;
|
||||
typedef std::list<DiminishingReturn> Diminishing;
|
||||
@@ -1658,6 +1659,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
uint32 CalculateDamage(WeaponAttackType attType, bool normalized);
|
||||
float GetAPMultiplier(WeaponAttackType attType, bool normalized);
|
||||
void ModifyAuraState(AuraState flag, bool apply);
|
||||
uint32 BuildAuraStateUpdateForTarget(Unit * target) const;
|
||||
bool HasAuraState(AuraState flag, SpellEntry const *spellProto = NULL, Unit * Caster = NULL) const ;
|
||||
void UnsummonAllTotems();
|
||||
Unit* SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo = NULL);
|
||||
@@ -1855,12 +1857,12 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
AuraList m_scAuras; // casted singlecast auras
|
||||
AuraList m_interruptableAuras;
|
||||
AuraList m_removedAuras;
|
||||
AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
|
||||
uint32 m_interruptMask;
|
||||
|
||||
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
|
||||
float m_weaponDamage[MAX_ATTACK][2];
|
||||
bool m_canModifyStats;
|
||||
//std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem
|
||||
VisibleAuraMap m_visibleAuras;
|
||||
|
||||
float m_speed_rate[MAX_MOVE_TYPE];
|
||||
|
||||
Reference in New Issue
Block a user