*Fix aura sending to 303 client.

--HG--
branch : trunk
This commit is contained in:
QAston
2009-02-06 19:42:03 +01:00
parent 59cce00301
commit 4c5f0fd6a5
10 changed files with 252 additions and 193 deletions
+3 -1
View File
@@ -1407,7 +1407,9 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID()); pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());
// aura // 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_AURAFLAGS, 0x00000009);
//pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); //pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
//pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF); //pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
+10 -16
View File
@@ -726,18 +726,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_AURAS) if (mask & GROUP_UPDATE_FLAG_AURAS)
{ {
const uint64& auramask = player->GetAuraUpdateMask(); const uint64& auramask = player->GetAuraUpdateMaskForRaid();
*data << uint64(auramask); *data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i) for(uint32 i = 0; i < MAX_AURAS; ++i)
{ {
if(auramask & (uint64(1) << i)) if(auramask & (uint64(1) << i))
{ {
uint32 updatedAura = player->GetVisibleAura(i); AuraSlotEntry * pAura = player->GetVisibleAura(i);
*data << uint32(updatedAura); *data << uint32(pAura ? pAura->m_spellId : 0);
*data << uint8(1); *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) if(pet)
{ {
const uint64& auramask = pet->GetAuraUpdateMask(); const uint64& auramask = pet->GetAuraUpdateMaskForRaid();
*data << uint64(auramask); *data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i) for(uint32 i = 0; i < MAX_AURAS; ++i)
{ {
if(auramask & (uint64(1) << i)) if(auramask & (uint64(1) << i))
{ {
uint32 updatedAura = pet->GetVisibleAura(i); AuraSlotEntry * pAura = pet->GetVisibleAura(i);
*data << uint32(updatedAura); *data << uint32(pAura ? pAura->m_spellId : 0);
*data << uint8(1); *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 data << (uint64) auramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i) for(uint8 i = 0; i < MAX_AURAS; ++i)
{ {
if(uint32 aura = player->GetVisibleAura(i)) if(AuraSlotEntry * pAura = player->GetVisibleAura(i))
{ {
auramask |= (uint64(1) << i); auramask |= (uint64(1) << i);
data << (uint32) aura; data << (uint32) pAura->m_spellId;
data << (uint8) 1; data << (uint8) 1;
} }
} }
@@ -906,10 +900,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) petauramask; // placeholder data << (uint64) petauramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i) for(uint8 i = 0; i < MAX_AURAS; ++i)
{ {
if(uint32 petaura = pet->GetVisibleAura(i)) if(AuraSlotEntry * pAura = pet->GetVisibleAura(i))
{ {
petauramask |= (uint64(1) << i); petauramask |= (uint64(1) << i);
data << (uint32) petaura; data << (uint32) pAura->m_spellId;
data << (uint8) 1; data << (uint8) 1;
} }
} }
+1 -1
View File
@@ -43,7 +43,7 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
Pet::Pet(PetType type) : Pet::Pet(PetType type) :
Creature(), m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0), m_bonusdamage(0), 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_declinedname(NULL)
{ {
m_isPet = true; m_isPet = true;
+4 -5
View File
@@ -216,10 +216,9 @@ class Pet : public Creature
time_t m_resetTalentsTime; time_t m_resetTalentsTime;
uint32 m_usedTalentCount; uint32 m_usedTalentCount;
const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; } const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); } void ResetAuraUpdateMaskForRaid() { m_auraRaidUpdateMask = 0; }
void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; } DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
@@ -229,7 +228,7 @@ class Pet : public Creature
PetType m_petType; PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
int32 m_bonusdamage; int32 m_bonusdamage;
uint64 m_auraUpdateMask; uint64 m_auraRaidUpdateMask;
bool m_loading; bool m_loading;
DeclinedName *m_declinedname; DeclinedName *m_declinedname;
+17 -14
View File
@@ -328,7 +328,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
// group is initialized in the reference constructor // group is initialized in the reference constructor
SetGroupInvite(NULL); SetGroupInvite(NULL);
m_groupUpdateMask = 0; m_groupUpdateMask = 0;
m_auraUpdateMask = 0; m_auraRaidUpdateMask = 0;
duel = NULL; duel = NULL;
@@ -4020,8 +4020,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
{ {
if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i)) if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i))
{ {
Aur->SetAuraDuration(delta*1000); Aur->SetAuraDurationAndUpdate(delta*1000);
Aur->SendAuraUpdate(false);
} }
} }
} }
@@ -18699,9 +18698,9 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
group->UpdatePlayerOutOfRange(this); group->UpdatePlayerOutOfRange(this);
m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE; m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
m_auraUpdateMask = 0; m_auraRaidUpdateMask = 0;
if(Pet *pet = GetPet()) if(Pet *pet = GetPet())
pet->ResetAuraUpdateMask(); pet->ResetAuraUpdateMaskForRaid();
} }
void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg) void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)
@@ -18926,36 +18925,40 @@ void Player::SendAurasForTarget(Unit *target)
Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras(); Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) 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])
{
aura=itr->second.m_slotAuras[i];
break;
}
}
if(aura)
{ {
data << uint8(aura->GetAuraSlot()); data << uint8(aura->GetAuraSlot());
data << uint32(aura->GetId()); data << uint32(aura->GetId());
if(aura->GetId()) if(aura->GetId())
{ {
uint8 auraFlags = aura->GetAuraFlags();
// flags // flags
data << uint8(auraFlags); data << itr->second.m_Flags;
// level // level
data << uint8(aura->GetAuraLevel()); data << itr->second.m_Level;
// charges // charges
data << uint8(aura->GetAuraCharges()); data << uint8(aura->GetAuraCharges());
if(!(auraFlags & AFLAG_NOT_CASTER)) if(!(itr->second.m_Flags & 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 if(itr->second.m_Flags & AFLAG_DURATION) // include aura duration
{ {
data << uint32(aura->GetAuraMaxDuration()); data << uint32(aura->GetAuraMaxDuration());
data << uint32(aura->GetAuraDuration()); data << uint32(aura->GetAuraDuration());
} }
} }
break;
}
} }
} }
+3 -4
View File
@@ -2142,9 +2142,8 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 GetSubGroup() const { return m_group.getSubGroup(); } uint8 GetSubGroup() const { return m_group.getSubGroup(); }
uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; }
void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; }
const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; } const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
Player* GetNextRandomRaidMember(float radius); Player* GetNextRandomRaidMember(float radius);
PartyResult CanUninviteFromGroup() const; PartyResult CanUninviteFromGroup() const;
@@ -2390,7 +2389,7 @@ class TRINITY_DLL_SPEC Player : public Unit
GroupReference m_group; GroupReference m_group;
Group *m_groupInvite; Group *m_groupInvite;
uint32 m_groupUpdateMask; uint32 m_groupUpdateMask;
uint64 m_auraUpdateMask; uint64 m_auraRaidUpdateMask;
// Temporarily removed pet cache // Temporarily removed pet cache
uint32 m_temporaryUnsummonedPetNumber; uint32 m_temporaryUnsummonedPetNumber;
+49 -65
View File
@@ -769,12 +769,21 @@ void Aura::_AddAura()
if(!m_target) if(!m_target)
return; 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 // Second aura if some spell
bool secondaura = false; bool secondaura = false;
// Try find slot for aura // Try find slot for aura
uint8 slot = NULL_AURA_SLOT; uint8 slot = NULL_AURA_SLOT;
// Lookup for some spell auras (and get slot from it) // Lookup for auras already applied from spell
for(uint8 i = 0; i < m_effIndex; i++) for(uint8 i = 0; i < 3; i++)
{ {
Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), 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) for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
@@ -800,27 +809,39 @@ void Aura::_AddAura()
if(itr == visibleAuras->end()) if(itr == visibleAuras->end())
{ {
slot = i; slot = i;
// update for out of range group members (on 1 slot use)
m_target->UpdateAuraForGroup(slot);
break; break;
} }
} }
} }
Unit* caster = GetCaster(); if (!secondaura)
// 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))
{ {
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));
//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 ); SetAuraSlot( slot );
if(slot < MAX_AURAS) // slot found send data to client if(slot < MAX_AURAS) // slot found send data to client
{ {
SetAura(false); // update for out of range group members (on 1 slot use)
SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE)); m_target->UpdateAuraForGroup(slot);
SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
SendAuraUpdate(false);
} }
//***************************************************** //*****************************************************
@@ -866,7 +887,6 @@ void Aura::_AddAura()
m_target->ModifyAuraState(AURA_STATE_ENRAGE, true); m_target->ModifyAuraState(AURA_STATE_ENRAGE, true);
} }
} }
}
void Aura::_RemoveAura() void Aura::_RemoveAura()
{ {
@@ -894,39 +914,31 @@ void Aura::_RemoveAura()
if(slot >= MAX_AURAS) // slot not set if(slot >= MAX_AURAS) // slot not set
return; return;
if(m_target->GetVisibleAura(slot) == 0) if(!m_target->GetVisibleAura(slot)) //slot already removed-shouldn't happen
return; return;
bool lastaura = true; bool lastaura = true;
// find other aura in same slot (current already removed from list) AuraSlotEntry * entry=m_target->GetVisibleAura(slot);
for(uint8 i = 0; i < 3; i++)
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); if (entry->m_slotAuras[i])
for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
{ {
if(itr->second->GetAuraSlot()==slot) ptr=entry->m_slotAuras[i];
{
lastaura = false;
break; break;
} }
} }
if(!lastaura)
break;
}
// only remove icon when the last aura of the spell is removed (current aura already removed from list) // 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) // unregister aura diminishing (and store last time)
if (getDiminishGroup() != DIMINISHING_NONE ) if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),false); m_target->ApplyDiminishingAura(getDiminishGroup(),false);
SetAura(true);
SetAuraFlags(AFLAG_NONE);
SetAuraLevel(0);
SendAuraUpdate(true);
// update for out of range group members // update for out of range group members
m_target->UpdateAuraForGroup(slot); 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) void Aura::SetStackAmount(uint8 stackAmount)
{ {
if (stackAmount != m_stackAmount) if (stackAmount != m_stackAmount)
@@ -1073,7 +1053,11 @@ bool Aura::modStackAmount(int32 num)
void Aura::RefreshAura() void Aura::RefreshAura()
{ {
m_duration = m_maxduration; 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 bool Aura::isAffectedOnSpell(SpellEntry const *spell) const
+10 -9
View File
@@ -230,6 +230,12 @@ class TRINITY_DLL_SPEC Aura
void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; } void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
int32 GetAuraDuration() const { return m_duration; } int32 GetAuraDuration() const { return m_duration; }
void SetAuraDuration(int32 duration) { m_duration = 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; } time_t GetAuraApplyTime() { return m_applyTime; }
SpellModifier *getAuraSpellMod() {return m_spellmod; } SpellModifier *getAuraSpellMod() {return m_spellmod; }
@@ -249,30 +255,25 @@ class TRINITY_DLL_SPEC Aura
uint8 GetAuraSlot() const { return m_auraSlot; } uint8 GetAuraSlot() const { return m_auraSlot; }
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; } 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; } uint8 GetAuraCharges() const { return m_procCharges; }
void SetAuraCharges(uint8 charges) void SetAuraCharges(uint8 charges)
{ {
if (m_procCharges == charges) if (m_procCharges == charges)
return; return;
m_procCharges = charges; 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 bool DropAuraCharge() // return true if last charge dropped
{ {
if (m_procCharges == 0) if (m_procCharges == 0)
return false; return false;
m_procCharges--; m_procCharges--;
SendAuraUpdate(false); if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
{ m_target->UpdateAuraForGroup(GetAuraSlot()); }
return m_procCharges == 0; 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;} int8 GetStackAmount() {return m_stackAmount;}
//int32 GetModifierValuePerStack() {return m_modifier.m_amount / m_stackAmount;} //int32 GetModifierValuePerStack() {return m_modifier.m_amount / m_stackAmount;}
void SetStackAmount(uint8 num); void SetStackAmount(uint8 num);
+70 -3
View File
@@ -94,6 +94,7 @@ Unit::Unit()
m_state = 0; m_state = 0;
m_form = FORM_NONE; m_form = FORM_NONE;
m_deathState = ALIVE; m_deathState = ALIVE;
uint64 m_auraUpdateMask;
for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
m_currentSpells[i] = NULL; m_currentSpells[i] = NULL;
@@ -207,6 +208,18 @@ void Unit::Update( uint32 p_time )
_UpdateAura(); _UpdateAura();
}else }else
m_AurasCheck -= p_time;*/ 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. // WARNING! Order of execution here is important, do not change.
// Spells must be processed with event system BEFORE they go to _UpdateSpells. // 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); iter->second->SetAuraDuration(0);
else else
iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime); 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()); 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()) if(player->GetGroup())
{ {
player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS); player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS);
player->SetAuraUpdateMask(slot); player->SetAuraUpdateMaskForRaid(slot);
} }
} }
else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) 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()) if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
{ {
((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS); ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS);
pet->SetAuraUpdateMask(slot); pet->SetAuraUpdateMaskForRaid(slot);
} }
} }
} }
SetAuraUpdateMask(slot);
} }
float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) 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) void Unit::AddAura(uint32 spellId, Unit* target)
{ {
if(!target || !target->isAlive()) if(!target || !target->isAlive())
+22 -12
View File
@@ -806,6 +806,14 @@ enum ReactiveType
#define MAX_REACTIVE 3 #define MAX_REACTIVE 3
#define MAX_TOTEM 4 #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 // delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200 #define ATTACK_DISPLAY_DELAY 200
@@ -820,7 +828,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
typedef std::list<Aura *> AuraList; typedef std::list<Aura *> AuraList;
typedef std::list<DiminishingReturn> Diminishing; typedef std::list<DiminishingReturn> Diminishing;
typedef std::set<uint32> ComboPointHolderSet; typedef std::set<uint32> ComboPointHolderSet;
typedef std::map<uint8, uint32> VisibleAuraMap;
typedef std::map<uint8, AuraSlotEntry> VisibleAuraMap;
virtual ~Unit ( ); virtual ~Unit ( );
@@ -1332,22 +1341,22 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ } void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
HostilRefManager& getHostilRefManager() { return m_HostilRefManager; } 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); VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
if(itr != m_visibleAuras.end()) if(itr != m_visibleAuras.end())
return itr->second; return &itr->second;
return 0; return 0;
} }
void SetVisibleAura(uint8 slot, uint32 spellid) void SetVisibleAura(uint8 slot, AuraSlotEntry entry) { m_visibleAuras[slot] = entry; }
{ void RemoveVisibleAura(uint8 slot) { m_visibleAuras.erase(slot); }
if(spellid == 0)
m_visibleAuras.erase(slot); const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
else void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
m_visibleAuras[slot] = spellid; void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
} void SendAuraUpdate(uint8 slot);
VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); }
Aura* GetAura(uint32 spellId, uint32 effindex); Aura* GetAura(uint32 spellId, uint32 effindex);
Aura* GetAura(AuraType type, uint32 family, uint32 familyFlag1 = 0, uint32 familyFlag2 = 0, uint32 familyFlag3 = 0, uint64 casterGUID = 0); 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; DeathState m_deathState;
uint64 m_auraUpdateMask;
AuraMap m_Auras; AuraMap m_Auras;
typedef std::list<uint64> DynObjectGUIDs; typedef std::list<uint64> DynObjectGUIDs;