aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/BattleGround.cpp4
-rw-r--r--src/game/GroupHandler.cpp26
-rw-r--r--src/game/Pet.cpp2
-rw-r--r--src/game/Pet.h9
-rw-r--r--src/game/Player.cpp59
-rw-r--r--src/game/Player.h7
-rw-r--r--src/game/SpellAuras.cpp204
-rw-r--r--src/game/SpellAuras.h19
-rw-r--r--src/game/Unit.cpp73
-rw-r--r--src/game/Unit.h34
10 files changed, 248 insertions, 189 deletions
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index 9669f638fc3..0fa7f09aa20 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -1407,7 +1407,9 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());
// aura
- pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL);
+ //TODO: Fix display here
+ //pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL);
+
//pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
//pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
//pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index 6bcc4a4d8cc..574ebd7de75 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -726,18 +726,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_AURAS)
{
- const uint64& auramask = player->GetAuraUpdateMask();
+ const uint64& auramask = player->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i)
{
if(auramask & (uint64(1) << i))
{
- uint32 updatedAura = player->GetVisibleAura(i);
- *data << uint32(updatedAura);
+ AuraSlotEntry * pAura = player->GetVisibleAura(i);
+ *data << uint32(pAura ? pAura->m_spellId : 0);
*data << uint8(1);
- //TODO: find a safe place to do this cleanup
- //if(!updatedAura)
- //player->UnsetAuraUpdateMask(i);
}
}
}
@@ -811,18 +808,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
{
if(pet)
{
- const uint64& auramask = pet->GetAuraUpdateMask();
+ const uint64& auramask = pet->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i)
{
if(auramask & (uint64(1) << i))
{
- uint32 updatedAura = pet->GetVisibleAura(i);
- *data << uint32(updatedAura);
+ AuraSlotEntry * pAura = pet->GetVisibleAura(i);
+ *data << uint32(pAura ? pAura->m_spellId : 0);
*data << uint8(1);
- //TODO: find a safe place to do this cleanup
- //if(!updatedAura)
- //pet->UnsetAuraUpdateMask(i);
}
}
}
@@ -880,10 +874,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) auramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(uint32 aura = player->GetVisibleAura(i))
+ if(AuraSlotEntry * pAura = player->GetVisibleAura(i))
{
auramask |= (uint64(1) << i);
- data << (uint32) aura;
+ data << (uint32) pAura->m_spellId;
data << (uint8) 1;
}
}
@@ -906,10 +900,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) petauramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(uint32 petaura = pet->GetVisibleAura(i))
+ if(AuraSlotEntry * pAura = pet->GetVisibleAura(i))
{
petauramask |= (uint64(1) << i);
- data << (uint32) petaura;
+ data << (uint32) pAura->m_spellId;
data << (uint8) 1;
}
}
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 8dcea866ef4..1205ed641f0 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -43,7 +43,7 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
Pet::Pet(PetType type) :
Creature(), m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0), m_bonusdamage(0),
-m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraUpdateMask(0), m_loading(false),
+m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraRaidUpdateMask(0), m_loading(false),
m_declinedname(NULL)
{
m_isPet = true;
diff --git a/src/game/Pet.h b/src/game/Pet.h
index 4425f2e06db..f863051b74d 100644
--- a/src/game/Pet.h
+++ b/src/game/Pet.h
@@ -216,10 +216,9 @@ class Pet : public Creature
time_t m_resetTalentsTime;
uint32 m_usedTalentCount;
- const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
- void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
- void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
- void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
+ const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
+ void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
+ void ResetAuraUpdateMaskForRaid() { m_auraRaidUpdateMask = 0; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
@@ -229,7 +228,7 @@ class Pet : public Creature
PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
int32 m_bonusdamage;
- uint64 m_auraUpdateMask;
+ uint64 m_auraRaidUpdateMask;
bool m_loading;
DeclinedName *m_declinedname;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 082e4bc41a7..8a2a9982d4e 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -328,7 +328,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
// group is initialized in the reference constructor
SetGroupInvite(NULL);
m_groupUpdateMask = 0;
- m_auraUpdateMask = 0;
+ m_auraRaidUpdateMask = 0;
duel = NULL;
@@ -4020,8 +4020,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
{
if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i))
{
- Aur->SetAuraDuration(delta*1000);
- Aur->SendAuraUpdate(false);
+ Aur->SetAuraDurationAndUpdate(delta*1000);
}
}
}
@@ -18699,9 +18698,9 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
group->UpdatePlayerOutOfRange(this);
m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
- m_auraUpdateMask = 0;
+ m_auraRaidUpdateMask = 0;
if(Pet *pet = GetPet())
- pet->ResetAuraUpdateMask();
+ pet->ResetAuraUpdateMaskForRaid();
}
void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)
@@ -18926,35 +18925,39 @@ void Player::SendAurasForTarget(Unit *target)
Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
{
- for(uint32 j = 0; j < 3; ++j)
+ Aura * aura=NULL;
+ for (uint8 i=0 ; i<3; i++)
{
- if(Aura *aura = target->GetAura(itr->second, j))
+ if (itr->second.m_slotAuras[i])
{
- data << uint8(aura->GetAuraSlot());
- data << uint32(aura->GetId());
+ aura=itr->second.m_slotAuras[i];
+ break;
+ }
+ }
+ if(aura)
+ {
+ data << uint8(aura->GetAuraSlot());
+ data << uint32(aura->GetId());
- if(aura->GetId())
+ if(aura->GetId())
+ {
+ // flags
+ data << itr->second.m_Flags;
+ // level
+ data << itr->second.m_Level;
+ // charges
+ data << uint8(aura->GetAuraCharges());
+
+ if(!(itr->second.m_Flags & AFLAG_NOT_CASTER))
{
- uint8 auraFlags = aura->GetAuraFlags();
- // flags
- data << uint8(auraFlags);
- // level
- data << uint8(aura->GetAuraLevel());
- // charges
- data << uint8(aura->GetAuraCharges());
-
- if(!(auraFlags & AFLAG_NOT_CASTER))
- {
- data << uint8(0); // packed GUID of someone (caster?)
- }
+ data << uint8(0); // packed GUID of someone (caster?)
+ }
- if(auraFlags & AFLAG_DURATION) // include aura duration
- {
- data << uint32(aura->GetAuraMaxDuration());
- data << uint32(aura->GetAuraDuration());
- }
+ if(itr->second.m_Flags & AFLAG_DURATION) // include aura duration
+ {
+ data << uint32(aura->GetAuraMaxDuration());
+ data << uint32(aura->GetAuraDuration());
}
- break;
}
}
}
diff --git a/src/game/Player.h b/src/game/Player.h
index eeac9ca53f0..186d0b5692c 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -2142,9 +2142,8 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 GetSubGroup() const { return m_group.getSubGroup(); }
uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; }
void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; }
- const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
- void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
- void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
+ const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
+ void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
Player* GetNextRandomRaidMember(float radius);
PartyResult CanUninviteFromGroup() const;
@@ -2390,7 +2389,7 @@ class TRINITY_DLL_SPEC Player : public Unit
GroupReference m_group;
Group *m_groupInvite;
uint32 m_groupUpdateMask;
- uint64 m_auraUpdateMask;
+ uint64 m_auraRaidUpdateMask;
// Temporarily removed pet cache
uint32 m_temporaryUnsummonedPetNumber;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index a2155e6df72..d44101cf68e 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -769,12 +769,21 @@ void Aura::_AddAura()
if(!m_target)
return;
+ Unit* caster = GetCaster();
+
+ // passive auras (except totem auras) do not get placed in the slots
+ // area auras with SPELL_AURA_NONE are not shown on target
+ // all further code applies only to active spells
+ if(!((m_spellProto->Attributes & 0x80 || !m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
+ (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster)))
+ return;
+
// Second aura if some spell
bool secondaura = false;
// Try find slot for aura
uint8 slot = NULL_AURA_SLOT;
- // Lookup for some spell auras (and get slot from it)
- for(uint8 i = 0; i < m_effIndex; i++)
+ // Lookup for auras already applied from spell
+ for(uint8 i = 0; i < 3; i++)
{
Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
@@ -791,7 +800,7 @@ void Aura::_AddAura()
break;
}
// Lookup free slot
- if (!secondaura && m_target->GetVisibleAurasCount() < MAX_AURAS)
+ if (!secondaura && m_target->GetVisibleAurasCount() < MAX_AURAS )
{
Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
for(uint8 i = 0; i < MAX_AURAS; ++i)
@@ -800,71 +809,82 @@ void Aura::_AddAura()
if(itr == visibleAuras->end())
{
slot = i;
- // update for out of range group members (on 1 slot use)
- m_target->UpdateAuraForGroup(slot);
break;
}
}
}
- Unit* caster = GetCaster();
+ if (!secondaura)
+ {
+ AuraSlotEntry t_entry;
+ t_entry.m_Flags=(IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE);
+ t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- // passive auras (except totem auras) do not get placed in the slots
- // area auras with SPELL_AURA_NONE are not shown on target
- if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
- (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
+ //init pointers-prevent unexpected behaviour
+ for(uint8 i = 0; i < 3; i++)
+ t_entry.m_slotAuras[i]=NULL;
+
+ t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ m_target->SetVisibleAura(slot, t_entry);
+ }
+
+ sLog.outError("aura::_addaura slot:%d", slot);
+
+ AuraSlotEntry * entry;
+ entry=m_target->GetVisibleAura(slot);
+
+ entry->m_Flags |= (1 << GetEffIndex());
+ entry->m_slotAuras[GetEffIndex()]=this;
+
+ SetAuraSlot( slot );
+
+ if(slot < MAX_AURAS) // slot found send data to client
{
- SetAuraSlot( slot );
- if(slot < MAX_AURAS) // slot found send data to client
- {
- SetAura(false);
- SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE));
- SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- SendAuraUpdate(false);
- }
+ // update for out of range group members (on 1 slot use)
+ m_target->UpdateAuraForGroup(slot);
+ }
- //*****************************************************
- // Update target aura state flag (at 1 aura apply)
- // TODO: Make it easer
- //*****************************************************
- if (!secondaura)
- {
- // Sitdown on apply aura req seated
- if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
- m_target->SetStandState(UNIT_STAND_STATE_SIT);
+ //*****************************************************
+ // Update target aura state flag (at 1 aura apply)
+ // TODO: Make it easer
+ //*****************************************************
+ if (!secondaura)
+ {
+ // Sitdown on apply aura req seated
+ if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
+ m_target->SetStandState(UNIT_STAND_STATE_SIT);
- // register aura diminishing on apply
- if (getDiminishGroup() != DIMINISHING_NONE )
- m_target->ApplyDiminishingAura(getDiminishGroup(),true);
+ // register aura diminishing on apply
+ if (getDiminishGroup() != DIMINISHING_NONE )
+ m_target->ApplyDiminishingAura(getDiminishGroup(),true);
- // Update Seals information
- if (IsSealSpell(m_spellProto))
- m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
+ // Update Seals information
+ if (IsSealSpell(m_spellProto))
+ m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
- // Conflagrate aura state on Immolate
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags[0] & 4)
- m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
+ // Conflagrate aura state on Immolate
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags[0] & 4)
+ m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
- // Faerie Fire (druid versions)
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x400)
- m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true);
+ // Faerie Fire (druid versions)
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x400)
+ m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true);
- // Victorious
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00040000)
- m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true);
+ // Victorious
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00040000)
+ m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true);
- // Swiftmend state on Regrowth & Rejuvenation
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x50 )
- m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
+ // Swiftmend state on Regrowth & Rejuvenation
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x50 )
+ m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
- // Deadly poison aura state
- if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x10000)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true);
+ // Deadly poison aura state
+ if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x10000)
+ m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true);
- // Enrage aura state
- if(m_spellProto->Dispel == DISPEL_ENRAGE)
- m_target->ModifyAuraState(AURA_STATE_ENRAGE, true);
- }
+ // Enrage aura state
+ if(m_spellProto->Dispel == DISPEL_ENRAGE)
+ m_target->ModifyAuraState(AURA_STATE_ENRAGE, true);
}
}
@@ -894,39 +914,31 @@ void Aura::_RemoveAura()
if(slot >= MAX_AURAS) // slot not set
return;
- if(m_target->GetVisibleAura(slot) == 0)
+ if(!m_target->GetVisibleAura(slot)) //slot already removed-shouldn't happen
return;
bool lastaura = true;
- // find other aura in same slot (current already removed from list)
- for(uint8 i = 0; i < 3; i++)
+ AuraSlotEntry * entry=m_target->GetVisibleAura(slot);
+
+ entry->m_slotAuras[GetEffIndex()]=NULL; //unregister aura
+ Aura * ptr= NULL;
+ for (uint8 i=0 ; i<3; i++) //check slot for more auras of the spell
{
- Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
- for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
+ if (entry->m_slotAuras[i])
{
- if(itr->second->GetAuraSlot()==slot)
- {
- lastaura = false;
- break;
- }
- }
- if(!lastaura)
+ ptr=entry->m_slotAuras[i];
break;
+ }
}
// only remove icon when the last aura of the spell is removed (current aura already removed from list)
- if (lastaura)
+ if(!ptr)
{
// unregister aura diminishing (and store last time)
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),false);
- SetAura(true);
- SetAuraFlags(AFLAG_NONE);
- SetAuraLevel(0);
- SendAuraUpdate(true);
-
// update for out of range group members
m_target->UpdateAuraForGroup(slot);
@@ -996,38 +1008,6 @@ void Aura::_RemoveAura()
}
}
-void Aura::SendAuraUpdate(bool remove)
-{
- WorldPacket data(SMSG_AURA_UPDATE);
- data.append(m_target->GetPackGUID());
- data << uint8(GetAuraSlot());
- data << uint32(remove ? 0 : GetId());
-
- if(remove)
- {
- m_target->SendMessageToSet(&data, true);
- return;
- }
-
- uint8 auraFlags = GetAuraFlags();
- data << uint8(auraFlags);
- data << uint8(GetAuraLevel());
- data << uint8(m_procCharges ? m_procCharges : m_stackAmount);
-
- if(!(auraFlags & AFLAG_NOT_CASTER))
- {
- data << uint8(0); // pguid
- }
-
- if(auraFlags & AFLAG_DURATION)
- {
- data << uint32(GetAuraMaxDuration());
- data << uint32(GetAuraDuration());
- }
-
- m_target->SendMessageToSet(&data, true);
-}
-
void Aura::SetStackAmount(uint8 stackAmount)
{
if (stackAmount != m_stackAmount)
@@ -1073,7 +1053,11 @@ bool Aura::modStackAmount(int32 num)
void Aura::RefreshAura()
{
m_duration = m_maxduration;
- SendAuraUpdate(false);
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ {
+ // update for out of range group members (on 1 slot use)
+ m_target->UpdateAuraForGroup(GetAuraSlot());
+ }
}
bool Aura::isAffectedOnSpell(SpellEntry const *spell) const
@@ -5780,13 +5764,13 @@ void Aura::PeriodicTick()
int32 gain = pCaster->ModifyPower(power,gain_amount);
m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
}
- // Mark of Kaz'rogal
- if(GetId() == 31447 && m_target->GetPower(power) == 0)
- {
- m_target->CastSpell(m_target, 31463, true, 0, this);
- // Remove aura
- SetAuraDuration(0);
- }
+ // Mark of Kaz'rogal
+ if(GetId() == 31447 && m_target->GetPower(power) == 0)
+ {
+ m_target->CastSpell(m_target, 31463, true, 0, this);
+ // Remove aura
+ SetAuraDuration(0);
+ }
break;
}
case SPELL_AURA_PERIODIC_ENERGIZE:
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index e3f4e6ac6b0..06bbc22af12 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -230,6 +230,12 @@ class TRINITY_DLL_SPEC Aura
void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
int32 GetAuraDuration() const { return m_duration; }
void SetAuraDuration(int32 duration) { m_duration = duration; }
+ void SetAuraDurationAndUpdate(int32 duration)
+ {
+ m_duration = duration;
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ { m_target->UpdateAuraForGroup(GetAuraSlot()); }
+ }
time_t GetAuraApplyTime() { return m_applyTime; }
SpellModifier *getAuraSpellMod() {return m_spellmod; }
@@ -249,30 +255,25 @@ class TRINITY_DLL_SPEC Aura
uint8 GetAuraSlot() const { return m_auraSlot; }
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
- uint8 GetAuraFlags() const { return m_auraFlags; }
- void SetAuraFlags(uint8 flags) { m_auraFlags = flags; }
- uint8 GetAuraLevel() const { return m_auraLevel; }
- void SetAuraLevel(uint8 level) { m_auraLevel = level; }
uint8 GetAuraCharges() const { return m_procCharges; }
void SetAuraCharges(uint8 charges)
{
if (m_procCharges == charges)
return;
m_procCharges = charges;
- SendAuraUpdate(false);
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ { m_target->UpdateAuraForGroup(GetAuraSlot()); }
}
bool DropAuraCharge() // return true if last charge dropped
{
if (m_procCharges == 0)
return false;
m_procCharges--;
- SendAuraUpdate(false);
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ { m_target->UpdateAuraForGroup(GetAuraSlot()); }
return m_procCharges == 0;
}
- void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
- void SendAuraUpdate(bool remove);
-
int8 GetStackAmount() {return m_stackAmount;}
//int32 GetModifierValuePerStack() {return m_modifier.m_amount / m_stackAmount;}
void SetStackAmount(uint8 num);
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 5fcec4dff84..5960cde6309 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -94,6 +94,7 @@ Unit::Unit()
m_state = 0;
m_form = FORM_NONE;
m_deathState = ALIVE;
+ uint64 m_auraUpdateMask;
for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
m_currentSpells[i] = NULL;
@@ -207,6 +208,18 @@ void Unit::Update( uint32 p_time )
_UpdateAura();
}else
m_AurasCheck -= p_time;*/
+ const uint64& auramask = GetAuraUpdateMask();
+ if (auramask)
+ {
+ for(uint32 i = 0; i < MAX_AURAS; ++i)
+ {
+ if(auramask & (uint64(1) << i))
+ {
+ SendAuraUpdate(i);
+ }
+ }
+ ResetAuraUpdateMask();
+ }
// WARNING! Order of execution here is important, do not change.
// Spells must be processed with event system BEFORE they go to _UpdateSpells.
@@ -4163,7 +4176,11 @@ void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime)
iter->second->SetAuraDuration(0);
else
iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime);
- iter->second->SendAuraUpdate(false);
+ if(iter->second->GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ {
+ // update for out of range group members (on 1 slot use)
+ UpdateAuraForGroup(iter->second->GetAuraSlot());
+ }
sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration());
}
}
@@ -11538,7 +11555,7 @@ void Unit::UpdateAuraForGroup(uint8 slot)
if(player->GetGroup())
{
player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS);
- player->SetAuraUpdateMask(slot);
+ player->SetAuraUpdateMaskForRaid(slot);
}
}
else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
@@ -11550,10 +11567,11 @@ void Unit::UpdateAuraForGroup(uint8 slot)
if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
{
((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS);
- pet->SetAuraUpdateMask(slot);
+ pet->SetAuraUpdateMaskForRaid(slot);
}
}
}
+ SetAuraUpdateMask(slot);
}
float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
@@ -12464,6 +12482,55 @@ void Unit::GetPartyMember(std::list<Unit*> &TagUnitMap, float radius)
}
}
+void Unit::SendAuraUpdate(uint8 slot)
+{
+ WorldPacket data(SMSG_AURA_UPDATE);
+
+ Aura * ptr=NULL;
+ VisibleAuraMap const *visibleAuras = GetVisibleAuras();
+ AuraSlotEntry * entry=GetVisibleAura(slot);
+ if (!entry)
+ return;
+
+ //Get pointer to first aura-it doesn't matter which one we use (at least it shouldn't)
+ for (uint8 i=0 ; i<3; i++)
+ {
+ if (entry->m_slotAuras[i])
+ {
+ ptr=entry->m_slotAuras[i];
+ break;
+ }
+ }
+
+ data.append(GetPackGUID());
+ data << uint8(slot);
+ data << uint32(ptr ? ptr->GetId() : 0);
+
+ if(!ptr)
+ {
+ RemoveVisibleAura(slot);
+ SendMessageToSet(&data, true);
+ return;
+ }
+
+ data << uint8(entry->m_Flags);
+ data << uint8(entry->m_Level);
+ data << uint8(ptr->GetAuraCharges()? ptr->GetAuraCharges() : ptr->GetStackAmount());
+
+ if(!(entry->m_Flags & AFLAG_NOT_CASTER))
+ {
+ data << uint8(0); // pguid
+ }
+
+ if(entry->m_Flags & AFLAG_DURATION)
+ {
+ data << uint32(ptr->GetAuraMaxDuration());
+ data << uint32(ptr->GetAuraDuration());
+ }
+
+ SendMessageToSet(&data, true);
+}
+
void Unit::AddAura(uint32 spellId, Unit* target)
{
if(!target || !target->isAlive())
diff --git a/src/game/Unit.h b/src/game/Unit.h
index bd61171de9b..181efff1571 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -806,6 +806,14 @@ enum ReactiveType
#define MAX_REACTIVE 3
#define MAX_TOTEM 4
+struct AuraSlotEntry
+{
+ uint8 m_Flags;
+ uint8 m_Level;
+ uint32 m_spellId;
+ Aura * m_slotAuras[3];
+};
+
// delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200
@@ -820,7 +828,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
typedef std::list<Aura *> AuraList;
typedef std::list<DiminishingReturn> Diminishing;
typedef std::set<uint32> ComboPointHolderSet;
- typedef std::map<uint8, uint32> VisibleAuraMap;
+
+ typedef std::map<uint8, AuraSlotEntry> VisibleAuraMap;
virtual ~Unit ( );
@@ -1332,22 +1341,22 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
- uint32 GetVisibleAura(uint8 slot)
+ VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
+ uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); }
+ AuraSlotEntry * GetVisibleAura(uint8 slot)
{
VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
if(itr != m_visibleAuras.end())
- return itr->second;
+ return &itr->second;
return 0;
}
- void SetVisibleAura(uint8 slot, uint32 spellid)
- {
- if(spellid == 0)
- m_visibleAuras.erase(slot);
- else
- m_visibleAuras[slot] = spellid;
- }
- VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
- uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); }
+ void SetVisibleAura(uint8 slot, AuraSlotEntry entry) { m_visibleAuras[slot] = entry; }
+ void RemoveVisibleAura(uint8 slot) { m_visibleAuras.erase(slot); }
+
+ const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
+ void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
+ void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
+ void SendAuraUpdate(uint8 slot);
Aura* GetAura(uint32 spellId, uint32 effindex);
Aura* GetAura(AuraType type, uint32 family, uint32 familyFlag1 = 0, uint32 familyFlag2 = 0, uint32 familyFlag3 = 0, uint64 casterGUID = 0);
@@ -1523,6 +1532,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
DeathState m_deathState;
+ uint64 m_auraUpdateMask;
AuraMap m_Auras;
typedef std::list<uint64> DynObjectGUIDs;