aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/GameObject
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-06-03 20:40:34 +0200
committerShauren <shauren.trinity@gmail.com>2019-06-08 17:06:57 +0200
commit455959c6064af6f7863a6b4b57cb0ef1646bd8ef (patch)
tree7d7a7cdd3a44643ee5fc7d19521ced1c8b815c66 /src/server/game/Entities/GameObject
parent31fda79556e55375962a3c9e46f6dbdbf6e90d18 (diff)
Core/PacketIO: Rewrite updatefield handling
Diffstat (limited to 'src/server/game/Entities/GameObject')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp213
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h39
-rw-r--r--src/server/game/Entities/GameObject/GameObjectData.h12
-rw-r--r--src/server/game/Entities/GameObject/QuaternionData.h48
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__