diff options
author | ariel- <ariel-@users.noreply.github.com> | 2018-02-24 20:57:55 -0300 |
---|---|---|
committer | ariel- <ariel-@users.noreply.github.com> | 2018-02-24 20:57:55 -0300 |
commit | 34967e9c32b2c7e871bb93f41609a3b08ad92931 (patch) | |
tree | 575a6bd4c3b83c33b82975b9b0ae2e3ce7b9a943 /src | |
parent | 02739c2cbb1c6956e26a21120ddef42d017923c2 (diff) |
Core/GameObject: implemented gameobject_overrides table to change faction and flags values on a per-spawn basis
Updates #20957
Closes #20958
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 29 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObjectData.h | 15 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Transport/Transport.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 57 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 4 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 5 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_gobject.cpp | 17 |
9 files changed, 106 insertions, 30 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index a7ce1810c0e..5d8bd04e0ba 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -308,10 +308,10 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u SetObjectScale(goinfo->size); - if (m_goTemplateAddon) + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) { - SetFaction(m_goTemplateAddon->faction); - SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags); + SetFaction(goOverride->Faction); + SetUInt32Value(GAMEOBJECT_FLAGS, goOverride->Flags); } SetEntry(goinfo->entry); @@ -744,8 +744,8 @@ void GameObject::Update(uint32 diff) SetGoState(GO_STATE_READY); //any return here in case battleground traps - if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - if (addon->flags & GO_FLAG_NODESPAWN) + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) + if (goOverride->Flags & GO_FLAG_NODESPAWN) return; } @@ -767,8 +767,8 @@ void GameObject::Update(uint32 diff) { SendObjectDeSpawnAnim(GetGUID()); //reset flags - if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - SetUInt32Value(GAMEOBJECT_FLAGS, addon->flags); + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) + SetUInt32Value(GAMEOBJECT_FLAGS, goOverride->Flags); } if (!m_respawnDelayTime) @@ -810,6 +810,17 @@ void GameObject::Update(uint32 diff) } } +GameObjectOverride const* GameObject::GetGameObjectOverride() const +{ + if (m_spawnId) + { + if (GameObjectOverride const* goOverride = sObjectMgr->GetGameObjectOverride(m_spawnId)) + return goOverride; + } + + return m_goTemplateAddon; +} + void GameObject::Refresh() { // Do not refresh despawned GO from spellcast (GO's from spellcast are destroyed after despawn) @@ -854,8 +865,8 @@ void GameObject::Delete() SetGoState(GO_STATE_READY); - if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - SetUInt32Value(GAMEOBJECT_FLAGS, addon->flags); + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) + SetUInt32Value(GAMEOBJECT_FLAGS, goOverride->Flags); uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<GameObject>(GetSpawnId()) : 0; if (poolid) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index e28f8973535..18c66ec1f39 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -93,6 +93,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void Update(uint32 p_time) override; GameObjectTemplate const* GetGOInfo() const { return m_goInfo; } GameObjectTemplateAddon const* GetTemplateAddon() const { return m_goTemplateAddon; } + GameObjectOverride const* GetGameObjectOverride() const; GameObjectData const* GetGameObjectData() const { return m_goData; } GameObjectValue const* GetGOValue() const { return &m_goValue; } diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 70bd2316471..35bb6ec6aa2 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -562,13 +562,18 @@ struct GameObjectTemplate WorldPacket BuildQueryData(LocaleConstant loc) const; }; +// From `gameobject_template_addon`, `gameobject_overrides` +struct GameObjectOverride +{ + uint32 Faction; + uint32 Flags; +}; + // From `gameobject_template_addon` -struct GameObjectTemplateAddon +struct GameObjectTemplateAddon : public GameObjectOverride { - uint32 faction; - uint32 flags; - uint32 mingold; - uint32 maxgold; + uint32 Mingold; + uint32 Maxgold; }; struct GameObjectLocale diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d46f735713e..83b0c22823c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8403,7 +8403,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type) if (go->GetLootMode() > 0) if (GameObjectTemplateAddon const* addon = go->GetTemplateAddon()) - loot->generateMoneyLoot(addon->mingold, addon->maxgold); + loot->generateMoneyLoot(addon->Mingold, addon->Maxgold); if (loot_type == LOOT_FISHING) go->getFishLoot(loot, this); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index b629dfe5f1f..b8880564155 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -85,10 +85,10 @@ bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, _triggeredArrivalEvent = false; _triggeredDepartureEvent = false; - if (m_goTemplateAddon) + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) { - SetFaction(m_goTemplateAddon->faction); - SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags); + SetFaction(goOverride->Faction); + SetUInt32Value(GAMEOBJECT_FLAGS, goOverride->Flags); } m_goValue.Transport.PathProgress = 0; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index eb6f0b77a08..06752a1d261 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7176,16 +7176,16 @@ void ObjectMgr::LoadGameObjectTemplateAddons() } GameObjectTemplateAddon& gameObjectAddon = _gameObjectTemplateAddonStore[entry]; - gameObjectAddon.faction = uint32(fields[1].GetUInt16()); - gameObjectAddon.flags = fields[2].GetUInt32(); - gameObjectAddon.mingold = fields[3].GetUInt32(); - gameObjectAddon.maxgold = fields[4].GetUInt32(); + gameObjectAddon.Faction = uint32(fields[1].GetUInt16()); + gameObjectAddon.Flags = fields[2].GetUInt32(); + gameObjectAddon.Mingold = fields[3].GetUInt32(); + gameObjectAddon.Maxgold = fields[4].GetUInt32(); // checks - if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction)) - TC_LOG_ERROR("sql.sql", "GameObject (Entry: %u) has invalid faction (%u) defined in `gameobject_template_addon`.", entry, gameObjectAddon.faction); + if (gameObjectAddon.Faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.Faction)) + TC_LOG_ERROR("sql.sql", "GameObject (Entry: %u) has invalid faction (%u) defined in `gameobject_template_addon`.", entry, gameObjectAddon.Faction); - if (gameObjectAddon.maxgold > 0) + if (gameObjectAddon.Maxgold > 0) { switch (got->type) { @@ -7205,6 +7205,44 @@ void ObjectMgr::LoadGameObjectTemplateAddons() TC_LOG_INFO("server.loading", ">> Loaded %u game object template addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadGameObjectOverrides() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT spawnId, faction, flags FROM gameobject_overrides"); + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 gameobject faction and flags overrides. DB table `gameobject_overrides` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + ObjectGuid::LowType spawnId = fields[0].GetUInt32(); + GameObjectData const* goData = GetGameObjectData(spawnId); + if (!goData) + { + TC_LOG_ERROR("sql.sql", "GameObject (SpawnId: %u) does not exist but has a record in `gameobject_overrides`", spawnId); + continue; + } + + GameObjectOverride& gameObjectOverride = _gameObjectOverrideStore[spawnId]; + gameObjectOverride.Faction = fields[1].GetUInt32(); + gameObjectOverride.Flags = fields[2].GetUInt32(); + + if (gameObjectOverride.Faction && !sFactionTemplateStore.LookupEntry(gameObjectOverride.Faction)) + TC_LOG_ERROR("sql.sql", "GameObject (SpawnId: %u) has invalid faction (%u) defined in `gameobject_overrides`.", spawnId, gameObjectOverride.Faction); + + ++count; + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u gameobject faction and flags overrides in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadExplorationBaseXP() { uint32 oldMSTime = getMSTime(); @@ -9487,6 +9525,11 @@ GameObjectTemplateAddon const* ObjectMgr::GetGameObjectTemplateAddon(uint32 entr return nullptr; } +GameObjectOverride const* ObjectMgr::GetGameObjectOverride(ObjectGuid::LowType spawnId) const +{ + return Trinity::Containers::MapGetValuePtr(_gameObjectOverrideStore, spawnId); +} + CreatureTemplate const* ObjectMgr::GetCreatureTemplate(uint32 entry) const { return Trinity::Containers::MapGetValuePtr(_creatureTemplateStore, entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 1090fca529f..70610ed67a1 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -548,6 +548,7 @@ typedef std::unordered_map<uint32, CreatureModelInfo> CreatureModelContainer; typedef std::unordered_map<uint32, std::vector<uint32>> CreatureQuestItemMap; typedef std::unordered_map<uint32, GameObjectTemplate> GameObjectTemplateContainer; typedef std::unordered_map<uint32, GameObjectTemplateAddon> GameObjectTemplateAddonContainer; +typedef std::unordered_map<ObjectGuid::LowType, GameObjectOverride> GameObjectOverrideContainer; typedef std::unordered_map<ObjectGuid::LowType, GameObjectData> GameObjectDataContainer; typedef std::unordered_map<ObjectGuid::LowType, GameObjectAddon> GameObjectAddonContainer; typedef std::unordered_map<uint32, std::vector<uint32>> GameObjectQuestItemMap; @@ -928,6 +929,7 @@ class TC_GAME_API ObjectMgr void LoadGameObjectTemplate(); void LoadGameObjectTemplateAddons(); + void LoadGameObjectOverrides(); CreatureTemplate const* GetCreatureTemplate(uint32 entry) const; CreatureTemplateContainer const& GetCreatureTemplates() const { return _creatureTemplateStore; } @@ -939,6 +941,7 @@ class TC_GAME_API ObjectMgr CreatureAddon const* GetCreatureAddon(ObjectGuid::LowType lowguid) const; GameObjectAddon const* GetGameObjectAddon(ObjectGuid::LowType lowguid) const; GameObjectTemplateAddon const* GetGameObjectTemplateAddon(uint32 entry) const; + GameObjectOverride const* GetGameObjectOverride(ObjectGuid::LowType spawnId) const; CreatureAddon const* GetCreatureTemplateAddon(uint32 entry) const; ItemTemplate const* GetItemTemplate(uint32 entry) const; ItemTemplateContainer const& GetItemTemplateStore() const { return _itemTemplateStore; } @@ -1635,6 +1638,7 @@ class TC_GAME_API ObjectMgr GameObjectLocaleContainer _gameObjectLocaleStore; GameObjectTemplateContainer _gameObjectTemplateStore; GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore; + GameObjectOverrideContainer _gameObjectOverrideStore; SpawnGroupDataContainer _spawnGroupDataStore; SpawnGroupLinkContainer _spawnGroupMapStore; InstanceSpawnGroupContainer _instanceSpawnGroupStore; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a7f8ba4def7..376a430d28a 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1748,7 +1748,10 @@ void World::SetInitialWorldSettings() sObjectMgr->LoadSpawnGroups(); TC_LOG_INFO("server.loading", "Loading GameObject Addon Data..."); - sObjectMgr->LoadGameObjectAddons(); // must be after LoadGameObjectTemplate() and LoadGameObjects() + sObjectMgr->LoadGameObjectAddons(); // must be after LoadGameObjects() + + TC_LOG_INFO("server.loading", "Loading GameObject faction and flags overrides..."); + sObjectMgr->LoadGameObjectOverrides(); // must be after LoadGameObjects() TC_LOG_INFO("server.loading", "Loading GameObject Quest Items..."); sObjectMgr->LoadGameObjectQuestItems(); diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 75259a81ef1..45a816a6a77 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -614,14 +614,15 @@ public: if (!param1) return false; + ObjectGuid::LowType spawnId = 0; if (strcmp(param1, "guid") == 0) { char* tail = strtok(nullptr, ""); char* cValue = handler->extractKeyFromLink(tail, "Hgameobject"); if (!cValue) return false; - ObjectGuid::LowType guidLow = atoul(cValue); - GameObjectData const* data = sObjectMgr->GetGameObjectData(guidLow); + spawnId = atoul(cValue); + GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId); if (!data) return false; entry = data->id; @@ -684,8 +685,16 @@ public: handler->PSendSysMessage(LANG_GOINFO_NAME, name.c_str()); handler->PSendSysMessage(LANG_GOINFO_SIZE, gameObjectInfo->size); - if (GameObjectTemplateAddon const* addon = sObjectMgr->GetGameObjectTemplateAddon(entry)) - handler->PSendSysMessage(LANG_GOINFO_ADDON, addon->faction, addon->flags); + GameObjectOverride const* goOverride = nullptr; + if (spawnId) + if (GameObjectOverride const* ovr = sObjectMgr->GetGameObjectOverride(spawnId)) + goOverride = ovr; + + if (!goOverride) + goOverride = sObjectMgr->GetGameObjectTemplateAddon(entry); + + if (goOverride) + handler->PSendSysMessage(LANG_GOINFO_ADDON, goOverride->Faction, goOverride->Flags); handler->PSendSysMessage(LANG_OBJECTINFO_AIINFO, gameObjectInfo->AIName.c_str(), sObjectMgr->GetScriptName(gameObjectInfo->ScriptId).c_str()); |