diff options
| author | Shauren <shauren.trinity@gmail.com> | 2019-06-03 20:40:34 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2019-06-08 17:06:57 +0200 |
| commit | 455959c6064af6f7863a6b4b57cb0ef1646bd8ef (patch) | |
| tree | 7d7a7cdd3a44643ee5fc7d19521ced1c8b815c66 /src/server/game/Entities/GameObject | |
| parent | 31fda79556e55375962a3c9e46f6dbdbf6e90d18 (diff) | |
Core/PacketIO: Rewrite updatefield handling
Diffstat (limited to 'src/server/game/Entities/GameObject')
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 213 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 39 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObjectData.h | 12 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/QuaternionData.h | 48 |
4 files changed, 146 insertions, 166 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 7f07e5f2930..7a9f826e885 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -40,7 +40,6 @@ #include "ScriptMgr.h" #include "SpellMgr.h" #include "Transport.h" -#include "UpdateFieldFlags.h" #include "World.h" #include <G3D/Quat.h> @@ -64,8 +63,6 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_updateFlag.Stationary = true; m_updateFlag.Rotation = true; - m_valuesCount = GAMEOBJECT_END; - _dynamicValuesCount = GAMEOBJECT_DYNAMIC_END; m_respawnTime = 0; m_respawnDelayTime = 300; m_lootState = GO_NOT_READY; @@ -128,8 +125,7 @@ void GameObject::CleanupsBeforeDelete(bool finalCleanup) { WorldObject::CleanupsBeforeDelete(finalCleanup); - if (m_uint32Values) // field array can be not exist if GameOBject not loaded - RemoveFromOwner(); + RemoveFromOwner(); } void GameObject::RemoveFromOwner() @@ -267,8 +263,8 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD if (m_goTemplateAddon) { - SetUInt32Value(GAMEOBJECT_FACTION, m_goTemplateAddon->faction); - SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags); + SetFaction(m_goTemplateAddon->faction); + SetFlags(GameObjectFlags(m_goTemplateAddon->flags)); if (m_goTemplateAddon->WorldEffectID) { @@ -286,14 +282,14 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD m_model = CreateModel(); if (m_model && m_model->isMapObject()) - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_MAP_OBJECT); + AddFlag(GO_FLAG_MAP_OBJECT); // GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3 SetGoType(GameobjectTypes(goInfo->type)); m_prevGoState = goState; SetGoState(goState); SetGoArtKit(artKit); - SetUInt32Value(GAMEOBJECT_STATE_ANIM_ID, sAnimationDataStore.GetNumRows()); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::SpawnTrackingStateAnimID), sAnimationDataStore.GetNumRows()); switch (goInfo->type) { @@ -302,12 +298,17 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD m_goValue.FishingHole.MaxOpens = urand(GetGOInfo()->fishingHole.minRestock, GetGOInfo()->fishingHole.maxRestock); break; case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING: + { // TODO: Get the values somehow, no longer in gameobject_template m_goValue.Building.Health = 20000/*goinfo->destructibleBuilding.intactNumHits + goinfo->destructibleBuilding.damagedNumHits*/; m_goValue.Building.MaxHealth = m_goValue.Building.Health; SetGoAnimProgress(255); - SetUInt32Value(GAMEOBJECT_PARENTROTATION, m_goInfo->destructibleBuilding.DestructibleModelRec); + // yes, even after the updatefield rewrite this garbage hack is still in client + QuaternionData reinterpretId; + memcpy(&reinterpretId.x, &m_goInfo->destructibleBuilding.DestructibleModelRec, sizeof(float)); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::ParentRotation), reinterpretId); break; + } case GAMEOBJECT_TYPE_TRANSPORT: { m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(goInfo->entry); @@ -344,7 +345,7 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD break; } case GAMEOBJECT_TYPE_FISHINGNODE: - SetUInt32Value(GAMEOBJECT_LEVEL, 1); + SetLevel(1); SetGoAnimProgress(255); break; case GAMEOBJECT_TYPE_TRAP: @@ -361,10 +362,11 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD } break; case GAMEOBJECT_TYPE_PHASEABLE_MO: - SetByteValue(GAMEOBJECT_FLAGS, 1, m_goInfo->phaseableMO.AreaNameSet & 0xF); + RemoveFlag(GameObjectFlags(0xF00)); + AddFlag(GameObjectFlags((m_goInfo->phaseableMO.AreaNameSet & 0xF) << 8)); break; case GAMEOBJECT_TYPE_CAPTURE_POINT: - SetUInt32Value(GAMEOBJECT_SPELL_VISUAL_ID, m_goInfo->capturePoint.SpellVisual1); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::SpellVisualID), m_goInfo->capturePoint.SpellVisual1); break; default: SetGoAnimProgress(animProgress); @@ -511,8 +513,8 @@ void GameObject::Update(uint32 diff) uint32 visualStateAfter = (m_goValue.Transport.StateUpdateTimer / 20000) & 1; if (visualStateBefore != visualStateAfter) { - ForceValuesUpdateAtIndex(GAMEOBJECT_LEVEL); - ForceValuesUpdateAtIndex(GAMEOBJECT_BYTES_1); + ForceUpdateFieldChange(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::Level)); + ForceUpdateFieldChange(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::State)); } } } @@ -528,7 +530,7 @@ void GameObject::Update(uint32 diff) if (caster && caster->GetTypeId() == TYPEID_PLAYER) { SetGoState(GO_STATE_ACTIVE); - SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); + SetFlags(GO_FLAG_NODESPAWN); UpdateData udata(caster->GetMapId()); WorldPacket packet; @@ -700,7 +702,7 @@ void GameObject::Update(uint32 diff) case GAMEOBJECT_TYPE_GOOBER: if (m_cooldownTime < time(NULL)) { - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + RemoveFlag(GO_FLAG_IN_USE); SetLootState(GO_JUST_DEACTIVATED); m_cooldownTime = 0; @@ -806,7 +808,7 @@ void GameObject::Update(uint32 diff) SendGameObjectDespawn(); //reset flags if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - SetUInt32Value(GAMEOBJECT_FLAGS, addon->flags); + SetFlags(GameObjectFlags(addon->flags)); } if (!m_respawnDelayTime) @@ -859,7 +861,7 @@ void GameObject::Delete() SetGoState(GO_STATE_READY); if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - SetUInt32Value(GAMEOBJECT_FLAGS, addon->flags); + SetFlags(GameObjectFlags(addon->flags)); uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<GameObject>(GetSpawnId()) : 0; if (poolid) @@ -1021,7 +1023,7 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, boo if (!GetGOInfo()->GetDespawnPossibility() && !GetGOInfo()->IsDespawnAtAction()) { - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); + AddFlag(GO_FLAG_NODESPAWN); m_respawnDelayTime = 0; m_respawnTime = 0; } @@ -1145,7 +1147,7 @@ bool GameObject::IsNeverVisibleFor(WorldObject const* seer) const if (GetGoType() == GAMEOBJECT_TYPE_SPELL_FOCUS && GetGOInfo()->spellFocus.serverOnly == 1) return true; - if (!GetUInt32Value(GAMEOBJECT_DISPLAYID)) + if (!GetDisplayId()) return true; return false; @@ -1206,7 +1208,7 @@ void GameObject::Respawn() } } -bool GameObject::ActivateToQuest(Player* target) const +bool GameObject::ActivateToQuest(Player const* target) const { if (target->HasQuestForGO(GetEntry())) return true; @@ -1219,7 +1221,7 @@ bool GameObject::ActivateToQuest(Player* target) const case GAMEOBJECT_TYPE_QUESTGIVER: { GameObject* go = const_cast<GameObject*>(this); - QuestGiverStatus questStatus = target->GetQuestDialogStatus(go); + QuestGiverStatus questStatus = const_cast<Player*>(target)->GetQuestDialogStatus(go); if (questStatus > DIALOG_STATUS_UNAVAILABLE) return true; break; @@ -1282,7 +1284,7 @@ void GameObject::ResetDoorOrButton() if (m_lootState == GO_READY || m_lootState == GO_JUST_DEACTIVATED) return; - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + RemoveFlag(GO_FLAG_IN_USE); SetGoState(m_prevGoState); SetLootState(GO_JUST_DEACTIVATED); @@ -1305,7 +1307,7 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f void GameObject::SetGoArtKit(uint8 kit) { - SetByteValue(GAMEOBJECT_BYTES_1, 2, kit); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::ArtKit), kit); GameObjectData* data = const_cast<GameObjectData*>(sObjectMgr->GetGOData(m_spawnId)); if (data) data->artKit = kit; @@ -1329,9 +1331,9 @@ void GameObject::SetGoArtKit(uint8 artkit, GameObject* go, ObjectGuid::LowType l void GameObject::SwitchDoorOrButton(bool activate, bool alternative /* = false */) { if (activate) - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + AddFlag(GO_FLAG_IN_USE); else - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + RemoveFlag(GO_FLAG_IN_USE); if (GetGoState() == GO_STATE_READY) //if closed -> open SetGoState(alternative ? GO_STATE_ACTIVE_ALTERNATIVE : GO_STATE_ACTIVE); @@ -1526,7 +1528,7 @@ void GameObject::Use(Unit* user) if (uint32 trapEntry = info->goober.linkedTrap) TriggeringLinkedGameObject(trapEntry, user); - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + AddFlag(GO_FLAG_IN_USE); SetLootState(GO_ACTIVATED, user); // this appear to be ok, however others exist in addition to this that should have custom (ex: 190510, 188692, 187389) @@ -2016,15 +2018,15 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge return; // remove immunity flags, to allow spell to target anything - trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC); + trigger->RemoveUnitFlag(UnitFlags(UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC)); if (Unit* owner = GetOwner()) { trigger->setFaction(owner->getFaction()); - if (owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) - trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + if (owner->HasUnitFlag(UNIT_FLAG_PVP_ATTACKABLE)) + trigger->AddUnitFlag(UNIT_FLAG_PVP_ATTACKABLE); // copy pvp state flags from owner - trigger->SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, owner->GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG)); + trigger->SetPvpFlags(owner->GetPvpFlags()); // needed for GO casts for proper target validation checks trigger->SetOwnerGUID(owner->GetGUID()); trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, owner->GetGUID()); @@ -2138,10 +2140,7 @@ void GameObject::SetWorldRotation(float qx, float qy, float qz, float qw) void GameObject::SetParentRotation(QuaternionData const& rotation) { - SetFloatValue(GAMEOBJECT_PARENTROTATION + 0, rotation.x); - SetFloatValue(GAMEOBJECT_PARENTROTATION + 1, rotation.y); - SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, rotation.z); - SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, rotation.w); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::ParentRotation), rotation); } void GameObject::SetWorldRotationAngles(float z_rot, float y_rot, float x_rot) @@ -2207,7 +2206,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* switch (state) { case GO_DESTRUCTIBLE_INTACT: - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_DESTROYED); + RemoveFlag(GameObjectFlags(GO_FLAG_DAMAGED | GO_FLAG_DESTROYED)); SetDisplayId(m_goInfo->displayId); if (setHealth) { @@ -2221,8 +2220,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* EventInform(m_goInfo->destructibleBuilding.DamagedEvent, eventInvoker); sScriptMgr->OnGameObjectDamaged(this, eventInvoker); - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); + RemoveFlag(GO_FLAG_DESTROYED); + AddFlag(GO_FLAG_DAMAGED); uint32 modelId = m_goInfo->displayId; if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec)) @@ -2249,8 +2248,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* if (Battleground* bg = eventInvoker->GetBattleground()) bg->DestroyGate(eventInvoker, this); - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); + RemoveFlag(GO_FLAG_DAMAGED); + AddFlag(GO_FLAG_DESTROYED); uint32 modelId = m_goInfo->displayId; if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec)) @@ -2269,7 +2268,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* case GO_DESTRUCTIBLE_REBUILDING: { EventInform(m_goInfo->destructibleBuilding.RebuildingEvent, eventInvoker); - RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_DESTROYED); + RemoveFlag(GameObjectFlags(GO_FLAG_DAMAGED | GO_FLAG_DESTROYED)); uint32 modelId = m_goInfo->displayId; if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec)) @@ -2316,7 +2315,7 @@ void GameObject::SetLootState(LootState state, Unit* unit) void GameObject::SetGoState(GOState state) { - SetByteValue(GAMEOBJECT_BYTES_1, 0, state); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::State), state); sScriptMgr->OnGameObjectStateChanged(this, state); if (m_model && !IsTransport()) { @@ -2367,7 +2366,7 @@ void GameObject::SetTransportState(GOState state, uint32 stopFrame /*= 0*/) void GameObject::SetDisplayId(uint32 displayid) { - SetUInt32Value(GAMEOBJECT_DISPLAYID, displayid); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::DisplayID), displayid); UpdateModel(); } @@ -2396,7 +2395,7 @@ uint8 GameObject::GetNameSetId() const case GAMEOBJECT_TYPE_GARRISON_BUILDING: case GAMEOBJECT_TYPE_GARRISON_PLOT: case GAMEOBJECT_TYPE_PHASEABLE_MO: - return GetByteValue(GAMEOBJECT_FLAGS, 1) & 0xF; + return ((*m_gameObjectData->Flags) >> 8) & 0xF; default: break; } @@ -2427,7 +2426,10 @@ void GameObject::UpdateModel() if (m_model) GetMap()->InsertGameObjectModel(*m_model); - ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_MAP_OBJECT, m_model && m_model->isMapObject()); + if (m_model && m_model->isMapObject()) + AddFlag(GO_FLAG_MAP_OBJECT); + else + RemoveFlag(GO_FLAG_MAP_OBJECT); } Player* GameObject::GetLootRecipient() const @@ -2493,106 +2495,37 @@ GameObject* GameObject::GetLinkedTrap() return ObjectAccessor::GetGameObject(*this, m_linkedTrap); } -void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void GameObject::BuildValuesCreate(ByteBuffer* data, Player const* target) const { - if (!target) - return; - - bool isStoppableTransport = GetGoType() == GAMEOBJECT_TYPE_TRANSPORT && !m_goValue.Transport.StopFrames->empty(); - bool forcedFlags = GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.usegrouplootrules && HasLootRecipient(); - bool targetIsGM = target->IsGameMaster(); + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + std::size_t sizePos = data->wpos(); + *data << uint32(0); + *data << uint8(flags); + m_objectData->WriteCreate(*data, flags, this, target); + m_gameObjectData->WriteCreate(*data, flags, this, target); + data->put<uint32>(sizePos, data->wpos() - sizePos - 4); +} - std::size_t blockCount = UpdateMask::GetBlockCount(m_valuesCount); +void GameObject::BuildValuesUpdate(ByteBuffer* data, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + std::size_t sizePos = data->wpos(); + *data << uint32(0); + *data << uint32(m_values.GetChangedObjectTypeMask()); - uint32* flags = GameObjectUpdateFieldFlags; - uint32 visibleFlag = UF_FLAG_PUBLIC; - if (GetOwnerGUID() == target->GetGUID()) - visibleFlag |= UF_FLAG_OWNER; + if (m_values.HasChanged(TYPEID_OBJECT)) + m_objectData->WriteUpdate(*data, flags, this, target); - *data << uint8(blockCount); - std::size_t maskPos = data->wpos(); - data->resize(data->size() + blockCount * sizeof(UpdateMask::BlockType)); + if (m_values.HasChanged(TYPEID_GAMEOBJECT)) + m_gameObjectData->WriteUpdate(*data, flags, this, target); - for (uint16 index = 0; index < m_valuesCount; ++index) - { - if (_fieldNotifyFlags & flags[index] || - ((updateType == UPDATETYPE_VALUES ? _changesMask[index] : m_uint32Values[index]) && (flags[index] & visibleFlag)) || - (index == GAMEOBJECT_FLAGS && forcedFlags)) - { - UpdateMask::SetUpdateBit(data->contents() + maskPos, index); - - if (index == OBJECT_DYNAMIC_FLAGS) - { - uint16 dynFlags = 0; - int16 pathProgress = -1; - switch (GetGoType()) - { - case GAMEOBJECT_TYPE_QUESTGIVER: - if (ActivateToQuest(target)) - dynFlags |= GO_DYNFLAG_LO_ACTIVATE; - break; - case GAMEOBJECT_TYPE_CHEST: - case GAMEOBJECT_TYPE_GOOBER: - if (ActivateToQuest(target)) - dynFlags |= GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE; - else if (targetIsGM) - dynFlags |= GO_DYNFLAG_LO_ACTIVATE; - break; - case GAMEOBJECT_TYPE_GENERIC: - if (ActivateToQuest(target)) - dynFlags |= GO_DYNFLAG_LO_SPARKLE; - break; - case GAMEOBJECT_TYPE_TRANSPORT: - case GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT: - { - if (uint32 transportPeriod = GetTransportPeriod()) - { - float timer = float(m_goValue.Transport.PathProgress % transportPeriod); - pathProgress = int16(timer / float(transportPeriod) * 65535.0f); - } - break; - } - default: - break; - } - - *data << uint16(dynFlags); - *data << int16(pathProgress); - } - else if (index == GAMEOBJECT_FLAGS) - { - uint32 goFlags = m_uint32Values[GAMEOBJECT_FLAGS]; - if (GetGoType() == GAMEOBJECT_TYPE_CHEST) - if (GetGOInfo()->chest.usegrouplootrules && !IsLootAllowedFor(target)) - goFlags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE; - - *data << goFlags; - } - else if (index == GAMEOBJECT_LEVEL) - { - if (isStoppableTransport) - *data << uint32(m_goValue.Transport.PathProgress); - else - *data << m_uint32Values[index]; - } - else if (index == GAMEOBJECT_BYTES_1) - { - uint32 bytes1 = m_uint32Values[index]; - if (isStoppableTransport && GetGoState() == GO_STATE_TRANSPORT_ACTIVE) - { - if ((m_goValue.Transport.StateUpdateTimer / 20000) & 1) - { - bytes1 &= 0xFFFFFF00; - bytes1 |= GO_STATE_TRANSPORT_STOPPED; - } - } + data->put<uint32>(sizePos, data->wpos() - sizePos - 4); +} - *data << bytes1; - } - else - *data << m_uint32Values[index]; // other cases - } - } +void GameObject::ClearUpdateMask(bool remove) +{ + m_values.ClearChangesMask(&GameObject::m_gameObjectData); + Object::ClearUpdateMask(remove); } void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = nullptr*/) const diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index fc53bf4d03e..a22b637f07f 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -85,7 +85,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> explicit GameObject(); ~GameObject(); - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; + void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; + void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; + void ClearUpdateMask(bool remove) override; void AddToWorld() override; void RemoveFromWorld() override; @@ -134,9 +136,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> ABORT(); } m_spawnedByDefault = false; // all object with owner is despawned after delay - SetGuidValue(GAMEOBJECT_FIELD_CREATED_BY, owner); + SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::CreatedBy), owner); } - ObjectGuid GetOwnerGUID() const { return GetGuidValue(GAMEOBJECT_FIELD_CREATED_BY); } + ObjectGuid GetOwnerGUID() const { return m_gameObjectData->CreatedBy; } Unit* GetOwner() const; void SetSpellId(uint32 id) @@ -176,16 +178,21 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SendGameObjectDespawn(); void getFishLoot(Loot* loot, Player* loot_owner); void getFishLootJunk(Loot* loot, Player* loot_owner); - GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); } - void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); } - GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); } + bool HasFlag(GameObjectFlags flags) const { return (*m_gameObjectData->Flags & flags) != 0; } + void AddFlag(GameObjectFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::Flags), flags); } + void RemoveFlag(GameObjectFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::Flags), flags); } + void SetFlags(GameObjectFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::Flags), flags); } + void SetLevel(uint32 level) { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::Level), level); } + GameobjectTypes GetGoType() const { return GameobjectTypes(*m_gameObjectData->TypeID); } + void SetGoType(GameobjectTypes type) { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::TypeID), type); } + GOState GetGoState() const { return GOState(*m_gameObjectData->State); } void SetGoState(GOState state); virtual uint32 GetTransportPeriod() const; void SetTransportState(GOState state, uint32 stopFrame = 0); - uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); } + uint8 GetGoArtKit() const { return m_gameObjectData->ArtKit; } void SetGoArtKit(uint8 artkit); - uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); } - void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); } + uint8 GetGoAnimProgress() const { return m_gameObjectData->PercentHealth; } + void SetGoAnimProgress(uint8 animprogress) { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::PercentHealth), animprogress); } static void SetGoArtKit(uint8 artkit, GameObject* go, ObjectGuid::LowType lowguid = UI64LIT(0)); void EnableCollision(bool enable); @@ -233,7 +240,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> bool hasQuest(uint32 quest_id) const override; bool hasInvolvedQuest(uint32 quest_id) const override; - bool ActivateToQuest(Player* target) const; + bool ActivateToQuest(Player const* target) const; void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = NULL); // 0 = use `gameobject`.`spawntimesecs` void ResetDoorOrButton(); @@ -258,9 +265,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker = NULL, bool setHealth = false); GameObjectDestructibleState GetDestructibleState() const { - if (HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED)) + if ((*m_gameObjectData->Flags & GO_FLAG_DESTROYED)) return GO_DESTRUCTIBLE_DESTROYED; - if (HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED)) + if ((*m_gameObjectData->Flags & GO_FLAG_DAMAGED)) return GO_DESTRUCTIBLE_DAMAGED; return GO_DESTRUCTIBLE_INTACT; } @@ -272,11 +279,11 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> std::string GetAIName() const; void SetDisplayId(uint32 displayid); - uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); } + uint32 GetDisplayId() const { return m_gameObjectData->DisplayID; } uint8 GetNameSetId() const; - uint32 GetFaction() const { return GetUInt32Value(GAMEOBJECT_FACTION); } - void SetFaction(uint32 faction) { SetUInt32Value(GAMEOBJECT_FACTION, faction); } + uint32 GetFaction() const { return m_gameObjectData->FactionTemplate; } + void SetFaction(uint32 faction) { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::FactionTemplate), faction); } GameObjectModel* m_model; void GetRespawnPosition(float &x, float &y, float &z, float* ori = NULL) const; @@ -303,6 +310,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void AIM_Destroy(); bool AIM_Initialize(); + UF::UpdateField<UF::GameObjectData, 0, TYPEID_GAMEOBJECT> m_gameObjectData; + protected: GameObjectModel* CreateModel(); void UpdateModel(); // updates model in case displayId were changed diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 5944f07654a..9f4ff342a53 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -20,6 +20,7 @@ #include "Common.h" #include "DBCEnums.h" +#include "QuaternionData.h" #include "SharedDefines.h" #include <string> #include <vector> @@ -925,17 +926,6 @@ struct GameObjectLocale std::vector<std::string> Unk1; }; -struct TC_GAME_API QuaternionData -{ - float x, y, z, w; - - QuaternionData() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {} - QuaternionData(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) {} - - bool isUnit() const; - static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X); -}; - // `gameobject_addon` table struct GameObjectAddon { diff --git a/src/server/game/Entities/GameObject/QuaternionData.h b/src/server/game/Entities/GameObject/QuaternionData.h new file mode 100644 index 00000000000..aecbac48d93 --- /dev/null +++ b/src/server/game/Entities/GameObject/QuaternionData.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2019 TrinityCore <https://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef QuaternionData_h__ +#define QuaternionData_h__ + +#include "Define.h" + +struct TC_GAME_API QuaternionData +{ + float x, y, z, w; + + QuaternionData() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) + { + } + QuaternionData(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) + { + } + + bool isUnit() const; + static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X); + + friend bool operator==(QuaternionData const& left, QuaternionData const& right) + { + return left.x == right.x && left.y == right.y && left.z == right.z && left.w == right.w; + } + + friend bool operator!=(QuaternionData const& left, QuaternionData const& right) + { + return !(left == right); + } +}; + +#endif // QuaternionData_h__ |
