aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp21
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h15
-rw-r--r--src/server/game/Entities/Player/Player.cpp3
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp10
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp91
-rw-r--r--src/server/game/Globals/ObjectMgr.h3
-rw-r--r--src/server/game/World/World.cpp3
7 files changed, 120 insertions, 26 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 56e4ca80c59..6d1cfe1f716 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -55,6 +55,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(),
m_cooldownTime = 0;
m_goInfo = NULL;
m_goData = NULL;
+ m_goTemplateAddon = nullptr;
m_spawnId = UI64LIT(0);
m_rotation = 0;
@@ -223,6 +224,7 @@ bool GameObject::Create(uint32 name_id, Map* map, uint32 /*phaseMask*/, float x,
Object::_Create(guid);
m_goInfo = goinfo;
+ m_goTemplateAddon = sObjectMgr->GetGameObjectTemplateAddon(name_id);
if (goinfo->type >= MAX_GAMEOBJECT_TYPE)
{
@@ -237,8 +239,11 @@ bool GameObject::Create(uint32 name_id, Map* map, uint32 /*phaseMask*/, float x,
SetObjectScale(goinfo->size);
- SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
- SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
+ if (m_goTemplateAddon)
+ {
+ SetUInt32Value(GAMEOBJECT_FACTION, m_goTemplateAddon->faction);
+ SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags);
+ }
SetEntry(goinfo->entry);
@@ -671,8 +676,9 @@ void GameObject::Update(uint32 diff)
SetGoState(GO_STATE_READY);
//any return here in case battleground traps
- if (GetGOInfo()->flags & GO_FLAG_NODESPAWN)
- return;
+ if (GameObjectTemplateAddon const* addon = GetTemplateAddon())
+ if (addon->flags & GO_FLAG_NODESPAWN)
+ return;
}
loot.clear();
@@ -693,7 +699,8 @@ void GameObject::Update(uint32 diff)
{
SendObjectDeSpawnAnim(GetGUID());
//reset flags
- SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
+ if (GameObjectTemplateAddon const* addon = GetTemplateAddon())
+ SetUInt32Value(GAMEOBJECT_FLAGS, addon->flags);
}
if (!m_respawnDelayTime)
@@ -744,7 +751,9 @@ void GameObject::Delete()
SendObjectDeSpawnAnim(GetGUID());
SetGoState(GO_STATE_READY);
- SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
+
+ if (GameObjectTemplateAddon const* addon = GetTemplateAddon())
+ SetUInt32Value(GAMEOBJECT_FLAGS, addon->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 ae91170442c..3b3c8cadbfb 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -40,8 +40,6 @@ struct GameObjectTemplate
std::string IconName;
std::string castBarCaption;
std::string unk1;
- uint32 faction;
- uint32 flags;
float size;
int32 RequiredLevel;
union
@@ -812,8 +810,19 @@ struct GameObjectTemplate
}
};
+// From `gameobject_template_addon`
+struct GameObjectTemplateAddon
+{
+ uint32 entry;
+ uint32 faction;
+ uint32 flags;
+ uint32 mingold;
+ uint32 maxgold;
+};
+
// Benchmarked: Faster than std::map (insert/find)
typedef std::unordered_map<uint32, GameObjectTemplate> GameObjectTemplateContainer;
+typedef std::unordered_map<uint32, GameObjectTemplateAddon> GameObjectTemplateAddonContainer;
class OPvPCapturePoint;
struct TransportAnimation;
@@ -939,6 +948,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
bool Create(uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit = 0);
void Update(uint32 p_time) override;
GameObjectTemplate const* GetGOInfo() const { return m_goInfo; }
+ GameObjectTemplateAddon const* GetTemplateAddon() const { return m_goTemplateAddon; }
GameObjectData const* GetGOData() const { return m_goData; }
GameObjectValue const* GetGOValue() const { return &m_goValue; }
@@ -1158,6 +1168,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
ObjectGuid::LowType m_spawnId; ///< For new or temporary gameobjects is 0 for saved it is lowguid
GameObjectTemplate const* m_goInfo;
+ GameObjectTemplateAddon const* m_goTemplateAddon;
GameObjectData const* m_goData;
GameObjectValue m_goValue;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 491397a5a70..d40ad30dfa9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -8206,6 +8206,9 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
group->UpdateLooterGuid(go);
}
+ if (GameObjectTemplateAddon const* addon = go->GetTemplateAddon())
+ loot->generateMoneyLoot(addon->mingold, addon->maxgold);
+
if (loot_type == LOOT_FISHING)
go->getFishLoot(loot, this);
else if (loot_type == LOOT_FISHING_JUNK)
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 94c12daa7bb..1c9d125d9c4 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -56,7 +56,6 @@ bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid,
Object::_Create(ObjectGuid::Create<HighGuid::Transport>(guidlow));
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry);
-
if (!goinfo)
{
TC_LOG_ERROR("sql.sql", "Transport not created: entry in `gameobject_template` not found, guidlow: " UI64FMTD " map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang);
@@ -64,6 +63,7 @@ bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid,
}
m_goInfo = goinfo;
+ m_goTemplateAddon = sObjectMgr->GetGameObjectTemplateAddon(entry);
TransportTemplate const* tInfo = sTransportMgr->GetTransportTemplate(entry);
if (!tInfo)
@@ -80,10 +80,14 @@ bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid,
_triggeredArrivalEvent = false;
_triggeredDepartureEvent = false;
+ if (m_goTemplateAddon)
+ {
+ SetFaction(m_goTemplateAddon->faction);
+ SetUInt32Value(GAMEOBJECT_FLAGS, m_goTemplateAddon->flags);
+ }
+
m_goValue.Transport.PathProgress = 0;
SetObjectScale(goinfo->size);
- SetFaction(goinfo->faction);
- SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
SetPeriod(tInfo->pathTime);
SetEntry(goinfo->entry);
SetDisplayId(goinfo->displayId);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index a8c83c13578..e84d2d97939 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -6695,8 +6695,6 @@ void ObjectMgr::LoadGameObjectTemplate()
go.type = db2go->Type;
go.displayId = db2go->DisplayID;
go.name = db2go->Name->Str[sWorld->GetDefaultDbcLocale()];
- go.faction = 0;
- go.flags = 0;
go.size = db2go->Size;
memset(go.raw.data, 0, sizeof(go.raw.data));
memcpy(go.raw.data, db2go->Data, std::min(sizeof(db2go->Data), sizeof(go.raw.data)));
@@ -6704,13 +6702,13 @@ void ObjectMgr::LoadGameObjectTemplate()
go.ScriptId = 0;
}
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, faction, flags, size, "
- // 10 11 12 13 14 15 16 17 18 19 20 21 22
+ // 0 1 2 3 4 5 6 7
+ QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
+ // 8 9 10 11 12 13 14 15 16 17 18 19 20
"Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
- // 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
+ // 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
"Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, "
- // 39 40 41 42 43 44 45
+ // 37 38 39 40 41 42 43
"Data29, Data30, Data31, Data32, RequiredLevel, AIName, ScriptName "
"FROM gameobject_template");
@@ -6729,7 +6727,6 @@ void ObjectMgr::LoadGameObjectTemplate()
uint32 entry = fields[0].GetUInt32();
GameObjectTemplate& got = _gameObjectTemplateStore[entry];
-
got.entry = entry;
got.type = uint32(fields[1].GetUInt8());
got.displayId = fields[2].GetUInt32();
@@ -6737,16 +6734,14 @@ void ObjectMgr::LoadGameObjectTemplate()
got.IconName = fields[4].GetString();
got.castBarCaption = fields[5].GetString();
got.unk1 = fields[6].GetString();
- got.faction = uint32(fields[7].GetUInt16());
- got.flags = fields[8].GetUInt32();
- got.size = fields[9].GetFloat();
+ got.size = fields[7].GetFloat();
for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
- got.raw.data[i] = fields[10 + i].GetUInt32();
+ got.raw.data[i] = fields[8 + i].GetUInt32();
- got.RequiredLevel = fields[43].GetInt32();
- got.AIName = fields[44].GetString();
- got.ScriptId = GetScriptId(fields[45].GetString());
+ got.RequiredLevel = fields[41].GetInt32();
+ got.AIName = fields[42].GetString();
+ got.ScriptId = GetScriptId(fields[43].GetString());
// Checks
@@ -6899,6 +6894,63 @@ void ObjectMgr::LoadGameObjectTemplate()
TC_LOG_INFO("server.loading", ">> Loaded %u game object templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+void ObjectMgr::LoadGameObjectTemplateAddons()
+{
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2 3 4
+ QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold FROM gameobject_template_addon");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ GameObjectTemplate const* got = sObjectMgr->GetGameObjectTemplate(entry);
+ if (!got)
+ {
+ TC_LOG_ERROR("sql.sql", "GameObject template (Entry: %u) does not exist but has a record in `gameobject_template_addon`", entry);
+ continue;
+ }
+
+ 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();
+
+ // 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.maxgold > 0)
+ {
+ switch (got->type)
+ {
+ case GAMEOBJECT_TYPE_CHEST:
+ case GAMEOBJECT_TYPE_FISHINGHOLE:
+ break;
+ default:
+ TC_LOG_ERROR("sql.sql", "GameObject (Entry %u GoType: %u) cannot be looted but has maxgold set in `gameobject_template_addon`.", entry, got->type);
+ break;
+ }
+ }
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u game object template addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
void ObjectMgr::LoadExplorationBaseXP()
{
uint32 oldMSTime = getMSTime();
@@ -9220,6 +9272,15 @@ GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) const
return nullptr;
}
+GameObjectTemplateAddon const* ObjectMgr::GetGameObjectTemplateAddon(uint32 entry) const
+{
+ auto itr = _gameObjectTemplateAddonStore.find(entry);
+ if (itr != _gameObjectTemplateAddonStore.end())
+ return &itr->second;
+
+ return nullptr;
+}
+
CreatureTemplate const* ObjectMgr::GetCreatureTemplate(uint32 entry) const
{
CreatureTemplateContainer::const_iterator itr = _creatureTemplateStore.find(entry);
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index e0018aa9998..01b1b87ca68 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -745,6 +745,7 @@ class TC_GAME_API ObjectMgr
int LoadReferenceVendor(int32 vendor, int32 item, uint8 type, std::set<uint32> *skip_vendors);
void LoadGameObjectTemplate();
+ void LoadGameObjectTemplateAddons();
CreatureTemplate const* GetCreatureTemplate(uint32 entry) const;
CreatureTemplateContainer const* GetCreatureTemplates() const { return &_creatureTemplateStore; }
@@ -755,6 +756,7 @@ class TC_GAME_API ObjectMgr
EquipmentInfo const* GetEquipmentInfo(uint32 entry, int8& id) const;
CreatureAddon const* GetCreatureAddon(ObjectGuid::LowType lowguid) const;
GameObjectAddon const* GetGameObjectAddon(ObjectGuid::LowType lowguid) const;
+ GameObjectTemplateAddon const* GetGameObjectTemplateAddon(uint32 entry) const;
CreatureAddon const* GetCreatureTemplateAddon(uint32 entry) const;
ItemTemplate const* GetItemTemplate(uint32 entry) const;
ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; }
@@ -1530,6 +1532,7 @@ class TC_GAME_API ObjectMgr
GameObjectDataContainer _gameObjectDataStore;
GameObjectLocaleContainer _gameObjectLocaleStore;
GameObjectTemplateContainer _gameObjectTemplateStore;
+ GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore;
/// Stores temp summon data grouped by summoner's entry, summoner's type and group id
TempSummonDataContainer _tempSummonDataStore;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 419af4779f2..c75022cf8e2 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1633,6 +1633,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Game Object Templates..."); // must be after LoadPageTexts
sObjectMgr->LoadGameObjectTemplate();
+ TC_LOG_INFO("server.loading", "Loading Game Object template addons...");
+ sObjectMgr->LoadGameObjectTemplateAddons();
+
TC_LOG_INFO("server.loading", "Loading Transport templates...");
sTransportMgr->LoadTransportTemplates();