aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/Object.cpp19
-rw-r--r--src/game/SharedDefines.h4
-rw-r--r--src/game/SpellAuras.cpp79
-rw-r--r--src/game/SpellAuras.h3
-rw-r--r--src/game/SpellMgr.cpp57
-rw-r--r--src/game/SpellMgr.h1
-rw-r--r--src/game/Unit.cpp70
-rw-r--r--src/game/Unit.h4
8 files changed, 150 insertions, 87 deletions
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index abf4de09275..53f98214703 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -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)
{
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 535664462a5..957ef4449a6 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -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
{
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index df55a4fc1be..6ac842128b7 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -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
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 8b780520849..637c8054524 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -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
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index ae708153142..f1f43d57821 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -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);
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 2540f141b43..f1d551298f0 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -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); }
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index f48d23bd3dd..1138da4ba28 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -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));
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 85f2ed154dd..5a09d0f8c0e 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -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];