diff options
author | ariel- <ariel-@users.noreply.github.com> | 2018-02-24 20:57:55 -0300 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2021-08-08 21:21:34 +0200 |
commit | 67a1a1d29b76acfcda505fe1a38761a335e93bc5 (patch) | |
tree | 4d74e6600201194e4fa52061efa42eeec7434263 /src | |
parent | 4c8a49302fe5d5872cae716db0c91604bc95cad4 (diff) |
Core/GameObject: implemented gameobject_overrides table to change faction and flags values on a per-spawn basis
Updates #20957
Closes #20958
(cherry picked from commit 34967e9c32b2c7e871bb93f41609a3b08ad92931)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 34 | ||||
-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, 110 insertions, 31 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f231ef6a683..821dc454323 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -318,11 +318,14 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD SetObjectScale(goInfo->size); - if (m_goTemplateAddon) + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) { - SetFaction(m_goTemplateAddon->faction); - SetFlags(GameObjectFlags(m_goTemplateAddon->flags)); + SetFaction(goOverride->Faction); + SetFlags(GameObjectFlags(goOverride->Flags)); + } + if (m_goTemplateAddon) + { if (m_goTemplateAddon->WorldEffectID) { m_updateFlag.GameObject = true; @@ -871,14 +874,14 @@ 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; } loot.clear(); - //! If this is summoned by a spell with ie. SPELL_EFFECT_SUMMON_OBJECT_WILD, with or without owner, we check respawn criteria based on spell + //! If this is summoned by a spell with ie. SPELL_EFFECT_SUMMON_OBJECT_WILD, with or without owner, we check respawn criteria based on speSendObjectDeSpawnAnim(GetGUID());ll //! The GetOwnerGUID() check is mostly for compatibility with hacky scripts - 99% of the time summoning should be done trough spells. if (GetSpellId() || !GetOwnerGUID().IsEmpty()) { @@ -894,8 +897,8 @@ void GameObject::Update(uint32 diff) { SendGameObjectDespawn(); //reset flags - if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - SetFlags(GameObjectFlags(addon->flags)); + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) + SetFlags(GameObjectFlags(goOverride->Flags)); } if (!m_respawnDelayTime) @@ -938,6 +941,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) @@ -982,8 +996,8 @@ void GameObject::Delete() SetGoState(GO_STATE_READY); - if (GameObjectTemplateAddon const* addon = GetTemplateAddon()) - SetFlags(GameObjectFlags(addon->flags)); + if (GameObjectOverride const* goOverride = GetGameObjectOverride()) + SetFlags(GameObjectFlags(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 42979d3f8ab..bb1efe37da0 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -106,6 +106,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 b2d66eaac51..89ee6f97307 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -1040,13 +1040,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; uint32 WorldEffectID; uint32 AIAnimKitID; }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index db38ba84fae..37c3b88710f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8802,7 +8802,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa 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 f2667e84a37..1d40a5dfbad 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -86,10 +86,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); - SetFlags(GameObjectFlags(m_goTemplateAddon->flags)); + SetFaction(goOverride->Faction); + SetFlags(GameObjectFlags(goOverride->Flags)); } m_goValue.Transport.PathProgress = 0; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 42ac714018d..84117d199ca 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7432,18 +7432,18 @@ 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(); gameObjectAddon.WorldEffectID = fields[5].GetUInt32(); gameObjectAddon.AIAnimKitID = fields[6].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) { @@ -7475,6 +7475,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].GetUInt64(); + GameObjectData const* goData = GetGameObjectData(spawnId); + if (!goData) + { + TC_LOG_ERROR("sql.sql", "GameObject (SpawnId: " UI64FMTD ") 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: " UI64FMTD ") 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(); @@ -9934,6 +9972,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 85ac73d7cf3..4f609eb3f95 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -505,6 +505,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; @@ -1034,6 +1035,7 @@ class TC_GAME_API ObjectMgr void LoadGameObjectTemplate(); void LoadGameObjectTemplateAddons(); + void LoadGameObjectOverrides(); CreatureTemplate const* GetCreatureTemplate(uint32 entry) const; CreatureTemplateContainer const& GetCreatureTemplates() const { return _creatureTemplateStore; } @@ -1045,6 +1047,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; } @@ -1800,6 +1803,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 06f45667e25..4cc192a5e4b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1929,7 +1929,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 9b5bc70b866..0b0d7792874 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -605,14 +605,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 = atoull(cValue); - GameObjectData const* data = sObjectMgr->GetGameObjectData(guidLow); + spawnId = atoull(cValue); + GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId); if (!data) return false; entry = data->id; @@ -672,8 +673,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()); |