diff options
| author | Shauren <shauren.trinity@gmail.com> | 2013-06-15 15:16:36 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2013-06-15 15:16:36 +0200 |
| commit | fa75fe78bd76e910ab7dfc614bc75f3ce43f9793 (patch) | |
| tree | c58fbf5ca08da0f9726b8045d42a774aaf1fc576 /src/server/game/Entities/Object | |
| parent | a8a5239aad6f0396948978bdeae0979e7a8dfa97 (diff) | |
Core/Objects
* Split BuildValuesUpdate into separate virtual methods for every object type that does something special with update fields
* Removed _SetCreateBits/_SetUpdateBits to halve the amount of checks if field needs to be sent
Diffstat (limited to 'src/server/game/Entities/Object')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 325 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 6 |
2 files changed, 21 insertions, 310 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 3076ce8b4ab..5ddc632e573 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -194,7 +194,7 @@ void Object::BuildMovementUpdateBlock(UpdateData* data, uint32 flags) const buf << uint8(UPDATETYPE_MOVEMENT); buf.append(GetPackGUID()); - _BuildMovementUpdate(&buf, flags); + BuildMovementUpdate(&buf, flags); data->AddUpdateBlock(buf); } @@ -254,12 +254,8 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c buf.append(GetPackGUID()); buf << uint8(m_objectTypeId); - _BuildMovementUpdate(&buf, flags); - - UpdateMask updateMask; - updateMask.SetCount(m_valuesCount); - _SetCreateBits(&updateMask, target); - _BuildValuesUpdate(updateType, &buf, &updateMask, target); + BuildMovementUpdate(&buf, flags); + BuildValuesUpdate(updateType, &buf, target); data->AddUpdateBlock(buf); } @@ -281,11 +277,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) c buf << uint8(UPDATETYPE_VALUES); buf.append(GetPackGUID()); - UpdateMask updateMask; - updateMask.SetCount(m_valuesCount); - - _SetUpdateBits(&updateMask, target); - _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target); + BuildValuesUpdate(UPDATETYPE_VALUES, &buf, target); data->AddUpdateBlock(buf); } @@ -358,7 +350,7 @@ uint16 Object::GetUInt16Value(uint16 index, uint8 offset) const return *(((uint16*)&m_uint32Values[index])+offset); } -void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const +void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { Unit const* unit = NULL; WorldObject const* object = NULL; @@ -510,289 +502,31 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const *data << int64(ToGameObject()->GetRotation()); } -void Object::_BuildValuesUpdate(uint8 updateType, ByteBuffer* data, UpdateMask* updateMask, Player* target) const +void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const { if (!target) return; - bool IsActivateToQuest = false; - - // Before trying to convert to each type there is a check, so safe - Unit const* unit = ToUnit(); - GameObject const* go = ToGameObject(); - - if (unit) - { - if (unit->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK)) - updateMask->SetBit(UNIT_FIELD_AURASTATE); - } - else if (go) - { - if (updateType == UPDATETYPE_CREATE_OBJECT || updateType == UPDATETYPE_CREATE_OBJECT2) - { - if (!go->IsDynTransport()) - { - if (go->ActivateToQuest(target) || target->IsGameMaster()) - IsActivateToQuest = true; - - if (go->GetGoArtKit()) - updateMask->SetBit(GAMEOBJECT_BYTES_1); - } - } - else - { - if (!go->IsTransport()) - { - if (go->ActivateToQuest(target) || target->IsGameMaster()) - IsActivateToQuest = true; - - updateMask->SetBit(GAMEOBJECT_BYTES_1); - - if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules && - go->HasLootRecipient()) - { - updateMask->SetBit(GAMEOBJECT_FLAGS); - } - } - } - } - - ASSERT(updateMask && updateMask->GetCount() == m_valuesCount); + ByteBuffer fieldBuffer; + UpdateMask updateMask; + updateMask.SetCount(m_valuesCount); - *data << uint8(updateMask->GetBlockCount()); - updateMask->AppendToPacket(data); + uint32* flags = NULL; + uint32 visibleFlag = GetUpdateFieldData(target, flags); - // 2 specialized loops for speed optimization in non-unit case - if (unit) // unit (creature/player) case + for (uint16 index = 0; index < m_valuesCount; ++index) { - Creature const* creature = ToCreature(); - for (uint16 index = 0; index < m_valuesCount; ++index) + if (_fieldNotifyFlags & flags[index] || + ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag))) { - if (updateMask->GetBit(index)) - { - if (index == UNIT_NPC_FLAGS) - { - // remove custom flag before sending - uint32 appendValue = m_uint32Values[index]; - - if (GetTypeId() == TYPEID_UNIT) - { - if (!target->CanSeeSpellClickOn(this->ToCreature())) - appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK; - } - - *data << uint32(appendValue); - } - else if (index == UNIT_FIELD_AURASTATE) - { - // Check per caster aura states to not enable using a spell in client if specified aura is not by target - *data << unit->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) - { - // convert from float to uint32 and send - *data << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]); - } - // there are some float values which may be negative or can't get negative due to other checks - else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) || - (index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6)) || - (index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6)) || - (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4)) - { - *data << uint32(m_floatValues[index]); - } - // Gamemasters should be always able to select units - remove not selectable flag - else if (index == UNIT_FIELD_FLAGS) - { - if (target->IsGameMaster()) - *data << (m_uint32Values[index] & ~UNIT_FLAG_NOT_SELECTABLE); - else - *data << m_uint32Values[index]; - } - // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures - else if (index == UNIT_FIELD_DISPLAYID) - { - if (GetTypeId() == TYPEID_UNIT) - { - CreatureTemplate const* cinfo = creature->GetCreatureTemplate(); - - // this also applies for transform auras - if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(ToUnit()->getTransForm())) - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM)) - if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue)) - { - cinfo = transformInfo; - break; - } - - if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) - { - if (target->IsGameMaster()) - { - if (cinfo->Modelid1) - *data << cinfo->Modelid1;//Modelid1 is a visible model for gms - else - *data << 17519; // world invisible trigger's model - } - else - { - if (cinfo->Modelid2) - *data << cinfo->Modelid2;//Modelid2 is an invisible model for players - else - *data << 11686; // world invisible trigger's model - } - } - else - *data << m_uint32Values[index]; - } - else - *data << m_uint32Values[index]; - } - // hide lootable animation for unallowed players - else if (index == UNIT_DYNAMIC_FLAGS) - { - uint32 dynamicFlags = m_uint32Values[index]; - - if (creature) - { - if (creature->hasLootRecipient()) - { - if (creature->isTappedBy(target)) - { - dynamicFlags |= (UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER); - } - else - { - dynamicFlags |= UNIT_DYNFLAG_TAPPED; - dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER; - } - } - else - { - dynamicFlags &= ~UNIT_DYNFLAG_TAPPED; - dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER; - } - - if (!target->isAllowedToLoot(creature)) - dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE; - } - - // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras - if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT) - if (!unit->HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID())) - dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT; - *data << dynamicFlags; - } - // FG: pretend that OTHER players in own group are friendly ("blue") - else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE) - { - if (unit->IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && unit->IsInRaidWith(target)) - { - FactionTemplateEntry const* ft1 = unit->GetFactionTemplateEntry(); - FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry(); - if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2)) - { - if (index == UNIT_FIELD_BYTES_2) - { - // Allow targetting opposite faction in party when enabled in config - *data << (m_uint32Values[index] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !! - } - else - { - // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work) - uint32 faction = target->getFaction(); - *data << uint32(faction); - } - } - else - *data << m_uint32Values[index]; - } - else - *data << m_uint32Values[index]; - } - else - { - // send in current format (float as float, uint32 as uint32) - *data << m_uint32Values[index]; - } - } + updateMask.SetBit(index); + fieldBuffer << m_uint32Values[index]; } } - else if (go) // gameobject case - { - for (uint16 index = 0; index < m_valuesCount; ++index) - { - if (updateMask->GetBit(index)) - { - // send in current format (float as float, uint32 as uint32) - if (index == GAMEOBJECT_DYNAMIC) - { - if (IsActivateToQuest) - { - switch (go->GetGoType()) - { - case GAMEOBJECT_TYPE_CHEST: - if (target->IsGameMaster()) - *data << uint16(GO_DYNFLAG_LO_ACTIVATE); - else - *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE); - *data << uint16(-1); - break; - case GAMEOBJECT_TYPE_GENERIC: - if (target->IsGameMaster()) - *data << uint16(0); - else - *data << uint16(GO_DYNFLAG_LO_SPARKLE); - *data << uint16(-1); - break; - case GAMEOBJECT_TYPE_GOOBER: - if (target->IsGameMaster()) - *data << uint16(GO_DYNFLAG_LO_ACTIVATE); - else - *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE); - *data << uint16(-1); - break; - default: - // unknown, not happen. - *data << uint16(0); - *data << uint16(-1); - break; - } - } - else - { - // disable quest object - *data << uint16(0); - *data << uint16(-1); - } - } - else if (index == GAMEOBJECT_FLAGS) - { - uint32 flags = m_uint32Values[index]; - if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST) - if (go->GetGOInfo()->chest.groupLootRules && !go->IsLootAllowedFor(target)) - flags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE; - *data << flags; - } - else - *data << m_uint32Values[index]; // other cases - } - } - } - else // other objects case (no special index checks) - { - for (uint16 index = 0; index < m_valuesCount; ++index) - { - if (updateMask->GetBit(index)) - { - // send in current format (float as float, uint32 as uint32) - *data << m_uint32Values[index]; - } - } - } + *data << uint8(updateMask.GetBlockCount()); + updateMask.AppendToPacket(data); + data->append(fieldBuffer); } void Object::ClearUpdateMask(bool remove) @@ -891,27 +625,6 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin } } -void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const -{ - uint32* flags = NULL; - uint32 visibleFlag = GetUpdateFieldData(target, flags); - - for (uint16 index = 0; index < m_valuesCount; ++index) - if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (_changesMask.GetBit(index) && (flags[index] & visibleFlag))) - updateMask->SetBit(index); -} - -void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const -{ - uint32* value = m_uint32Values; - uint32* flags = NULL; - uint32 visibleFlag = GetUpdateFieldData(target, flags); - - for (uint16 index = 0; index < m_valuesCount; ++index, ++value) - if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (*value && (flags[index] & visibleFlag))) - updateMask->SetBit(index); -} - void Object::SetInt32Value(uint16 index, int32 value) { ASSERT(index < m_valuesCount || PrintIndexError(index, true)); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index af9b6a38fc8..25f71deabe9 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -236,10 +236,8 @@ class Object uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const; - void _SetUpdateBits(UpdateMask* updateMask, Player* target) const; - void _SetCreateBits(UpdateMask* updateMask, Player* target) const; - void _BuildMovementUpdate(ByteBuffer * data, uint16 flags) const; - void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask* updateMask, Player* target) const; + void BuildMovementUpdate(ByteBuffer* data, uint16 flags) const; + virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const; uint16 m_objectType; |
