Core/GameObject: implemented gameobject_overrides table to change faction and flags values on a per-spawn basis
Port From (https://github.com/TrinityCore/TrinityCore/commit/67a1a1d29b76acfcda505fe1a38761a335e93bc5)
This commit is contained in:
@@ -150,16 +150,17 @@ namespace Game.Chat
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint entry;
|
uint entry;
|
||||||
|
ulong spawnId = 0;
|
||||||
if (param1.Equals("guid"))
|
if (param1.Equals("guid"))
|
||||||
{
|
{
|
||||||
string cValue = handler.ExtractKeyFromLink(args, "Hgameobject");
|
string cValue = handler.ExtractKeyFromLink(args, "Hgameobject");
|
||||||
if (cValue.IsEmpty())
|
if (cValue.IsEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!ulong.TryParse(cValue, out ulong guidLow))
|
if (!ulong.TryParse(cValue, out spawnId))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GameObjectData data = Global.ObjectMgr.GetGameObjectData(guidLow);
|
GameObjectData data = Global.ObjectMgr.GetGameObjectData(spawnId);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
return false;
|
return false;
|
||||||
entry = data.Id;
|
entry = data.Id;
|
||||||
@@ -216,9 +217,19 @@ namespace Game.Chat
|
|||||||
handler.SendSysMessage(CypherStrings.GoinfoName, name);
|
handler.SendSysMessage(CypherStrings.GoinfoName, name);
|
||||||
handler.SendSysMessage(CypherStrings.GoinfoSize, gameObjectInfo.size);
|
handler.SendSysMessage(CypherStrings.GoinfoSize, gameObjectInfo.size);
|
||||||
|
|
||||||
GameObjectTemplateAddon addon = Global.ObjectMgr.GetGameObjectTemplateAddon(entry);
|
GameObjectOverride goOverride = null;
|
||||||
if (addon != null)
|
if (spawnId != 0)
|
||||||
handler.SendSysMessage(CypherStrings.GoinfoAddon, addon.faction, addon.flags);
|
{
|
||||||
|
GameObjectOverride ovr = Global.ObjectMgr.GetGameObjectOverride(spawnId);
|
||||||
|
if (ovr != null)
|
||||||
|
goOverride = ovr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (goOverride == null)
|
||||||
|
goOverride = Global.ObjectMgr.GetGameObjectTemplateAddon(entry);
|
||||||
|
|
||||||
|
if (goOverride != null)
|
||||||
|
handler.SendSysMessage(CypherStrings.GoinfoAddon, goOverride.Faction, goOverride.Flags);
|
||||||
|
|
||||||
handler.SendSysMessage(CypherStrings.ObjectInfoAIInfo, gameObjectInfo.AIName, Global.ObjectMgr.GetScriptName(gameObjectInfo.ScriptId));
|
handler.SendSysMessage(CypherStrings.ObjectInfoAIInfo, gameObjectInfo.AIName, Global.ObjectMgr.GetScriptName(gameObjectInfo.ScriptId));
|
||||||
|
|
||||||
|
|||||||
@@ -254,11 +254,15 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SetObjectScale(goInfo.size);
|
SetObjectScale(goInfo.size);
|
||||||
|
|
||||||
|
GameObjectOverride goOverride = GetGameObjectOverride();
|
||||||
|
if (goOverride != null)
|
||||||
|
{
|
||||||
|
SetFaction(goOverride.Faction);
|
||||||
|
SetFlags(goOverride.Flags);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_goTemplateAddon != null)
|
if (m_goTemplateAddon != null)
|
||||||
{
|
{
|
||||||
SetFaction(m_goTemplateAddon.faction);
|
|
||||||
SetFlags((GameObjectFlags)m_goTemplateAddon.flags);
|
|
||||||
|
|
||||||
if (m_goTemplateAddon.WorldEffectID != 0)
|
if (m_goTemplateAddon.WorldEffectID != 0)
|
||||||
{
|
{
|
||||||
m_updateFlag.GameObject = true;
|
m_updateFlag.GameObject = true;
|
||||||
@@ -785,9 +789,8 @@ namespace Game.Entities
|
|||||||
SetGoState(GameObjectState.Ready);
|
SetGoState(GameObjectState.Ready);
|
||||||
|
|
||||||
//any return here in case Battleground traps
|
//any return here in case Battleground traps
|
||||||
GameObjectTemplateAddon addon = GetTemplateAddon();
|
GameObjectOverride goOverride = GetGameObjectOverride();
|
||||||
if (addon != null)
|
if (goOverride != null && goOverride.Flags.HasFlag(GameObjectFlags.NoDespawn))
|
||||||
if (addon.flags.HasAnyFlag((uint)GameObjectFlags.NoDespawn))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -809,9 +812,9 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
SendGameObjectDespawn();
|
SendGameObjectDespawn();
|
||||||
//reset flags
|
//reset flags
|
||||||
GameObjectTemplateAddon addon = GetTemplateAddon();
|
GameObjectOverride goOverride = GetGameObjectOverride();
|
||||||
if (addon != null)
|
if (goOverride != null)
|
||||||
SetFlags((GameObjectFlags)addon.flags);
|
SetFlags(goOverride.Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_respawnDelayTime == 0)
|
if (m_respawnDelayTime == 0)
|
||||||
@@ -854,6 +857,18 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GameObjectOverride GetGameObjectOverride()
|
||||||
|
{
|
||||||
|
if (m_spawnId != 0)
|
||||||
|
{
|
||||||
|
GameObjectOverride goOverride = Global.ObjectMgr.GetGameObjectOverride(m_spawnId);
|
||||||
|
if (goOverride != null)
|
||||||
|
return goOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_goTemplateAddon;
|
||||||
|
}
|
||||||
|
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
// not refresh despawned not casted GO (despawned casted GO destroyed in all cases anyway)
|
// not refresh despawned not casted GO (despawned casted GO destroyed in all cases anyway)
|
||||||
@@ -897,9 +912,9 @@ namespace Game.Entities
|
|||||||
SendGameObjectDespawn();
|
SendGameObjectDespawn();
|
||||||
|
|
||||||
SetGoState(GameObjectState.Ready);
|
SetGoState(GameObjectState.Ready);
|
||||||
GameObjectTemplateAddon addon = GetTemplateAddon();
|
GameObjectOverride goOverride = GetGameObjectOverride();
|
||||||
if (addon != null)
|
if (goOverride != null)
|
||||||
SetFlags((GameObjectFlags)addon.flags);
|
SetFlags(goOverride.Flags);
|
||||||
|
|
||||||
uint poolid = GetSpawnId() != 0 ? Global.PoolMgr.IsPartOfAPool<GameObject>(GetSpawnId()) : 0;
|
uint poolid = GetSpawnId() != 0 ? Global.PoolMgr.IsPartOfAPool<GameObject>(GetSpawnId()) : 0;
|
||||||
if (poolid != 0)
|
if (poolid != 0)
|
||||||
|
|||||||
@@ -1356,13 +1356,17 @@ namespace Game.Entities
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameObjectTemplateAddon
|
// From `gameobject_template_addon`, `gameobject_overrides`
|
||||||
|
public class GameObjectOverride
|
||||||
{
|
{
|
||||||
public uint entry;
|
public uint Faction;
|
||||||
public uint faction;
|
public GameObjectFlags Flags;
|
||||||
public uint flags;
|
}
|
||||||
public uint mingold;
|
|
||||||
public uint maxgold;
|
public class GameObjectTemplateAddon : GameObjectOverride
|
||||||
|
{
|
||||||
|
public uint Mingold;
|
||||||
|
public uint Maxgold;
|
||||||
public uint WorldEffectID;
|
public uint WorldEffectID;
|
||||||
public uint AIAnimKitID;
|
public uint AIAnimKitID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6084,7 +6084,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
GameObjectTemplateAddon addon = go.GetTemplateAddon();
|
GameObjectTemplateAddon addon = go.GetTemplateAddon();
|
||||||
if (addon != null)
|
if (addon != null)
|
||||||
loot.GenerateMoneyLoot(addon.mingold, addon.maxgold);
|
loot.GenerateMoneyLoot(addon.Mingold, addon.Maxgold);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loot_type == LootType.Fishing)
|
if (loot_type == LootType.Fishing)
|
||||||
|
|||||||
@@ -115,10 +115,11 @@ namespace Game.Entities
|
|||||||
_triggeredArrivalEvent = false;
|
_triggeredArrivalEvent = false;
|
||||||
_triggeredDepartureEvent = false;
|
_triggeredDepartureEvent = false;
|
||||||
|
|
||||||
if (m_goTemplateAddon != null)
|
GameObjectOverride goOverride = GetGameObjectOverride();
|
||||||
|
if (goOverride != null)
|
||||||
{
|
{
|
||||||
SetFaction(m_goTemplateAddon.faction);
|
SetFaction(goOverride.Faction);
|
||||||
SetFlags((GameObjectFlags)m_goTemplateAddon.flags);
|
SetFlags(goOverride.Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_goValue.Transport.PathProgress = 0;
|
m_goValue.Transport.PathProgress = 0;
|
||||||
|
|||||||
@@ -3845,18 +3845,18 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameObjectTemplateAddon gameObjectAddon = new();
|
GameObjectTemplateAddon gameObjectAddon = new();
|
||||||
gameObjectAddon.faction = result.Read<ushort>(1);
|
gameObjectAddon.Faction = result.Read<ushort>(1);
|
||||||
gameObjectAddon.flags = result.Read<uint>(2);
|
gameObjectAddon.Flags = (GameObjectFlags)result.Read<uint>(2);
|
||||||
gameObjectAddon.mingold = result.Read<uint>(3);
|
gameObjectAddon.Mingold = result.Read<uint>(3);
|
||||||
gameObjectAddon.maxgold = result.Read<uint>(4);
|
gameObjectAddon.Maxgold = result.Read<uint>(4);
|
||||||
gameObjectAddon.WorldEffectID = result.Read<uint>(5);
|
gameObjectAddon.WorldEffectID = result.Read<uint>(5);
|
||||||
gameObjectAddon.AIAnimKitID = result.Read<uint>(6);
|
gameObjectAddon.AIAnimKitID = result.Read<uint>(6);
|
||||||
|
|
||||||
// checks
|
// checks
|
||||||
if (gameObjectAddon.faction != 0 && !CliDB.FactionTemplateStorage.ContainsKey(gameObjectAddon.faction))
|
if (gameObjectAddon.Faction != 0 && !CliDB.FactionTemplateStorage.ContainsKey(gameObjectAddon.Faction))
|
||||||
Log.outError(LogFilter.Sql, $"GameObject (Entry: {entry}) has invalid faction ({gameObjectAddon.faction}) defined in `gameobject_template_addon`.");
|
Log.outError(LogFilter.Sql, $"GameObject (Entry: {entry}) has invalid faction ({gameObjectAddon.Faction}) defined in `gameobject_template_addon`.");
|
||||||
|
|
||||||
if (gameObjectAddon.maxgold > 0)
|
if (gameObjectAddon.Maxgold > 0)
|
||||||
{
|
{
|
||||||
switch (got.type)
|
switch (got.type)
|
||||||
{
|
{
|
||||||
@@ -3888,6 +3888,43 @@ namespace Game
|
|||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} game object template addons in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} game object template addons in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
|
public void LoadGameObjectOverrides()
|
||||||
|
{
|
||||||
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
|
// 0 1 2
|
||||||
|
var result = DB.World.Query("SELECT spawnId, faction, flags FROM gameobject_overrides");
|
||||||
|
if (result.IsEmpty())
|
||||||
|
{
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 gameobject faction and flags overrides. DB table `gameobject_overrides` is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ulong spawnId = result.Read<ulong>(0);
|
||||||
|
GameObjectData goData = GetGameObjectData(spawnId);
|
||||||
|
if (goData == null)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"GameObject (SpawnId: {spawnId}) does not exist but has a record in `gameobject_overrides`");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObjectOverride gameObjectOverride = new();
|
||||||
|
gameObjectOverride.Faction = result.Read<uint>(1);
|
||||||
|
gameObjectOverride.Flags = (GameObjectFlags)result.Read<uint>(2);
|
||||||
|
|
||||||
|
_gameObjectOverrideStorage[spawnId] = gameObjectOverride;
|
||||||
|
|
||||||
|
if (gameObjectOverride.Faction != 0 && !CliDB.FactionTemplateStorage.ContainsKey(gameObjectOverride.Faction))
|
||||||
|
Log.outError(LogFilter.Sql, $"GameObject (SpawnId: {spawnId}) has invalid faction ({gameObjectOverride.Faction}) defined in `gameobject_overrides`.");
|
||||||
|
|
||||||
|
++count;
|
||||||
|
} while (result.NextRow());
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} gameobject faction and flags overrides in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
|
}
|
||||||
public void LoadGameObjects()
|
public void LoadGameObjects()
|
||||||
{
|
{
|
||||||
var time = Time.GetMSTime();
|
var time = Time.GetMSTime();
|
||||||
@@ -4380,6 +4417,10 @@ namespace Game
|
|||||||
{
|
{
|
||||||
return _gameObjectTemplateAddonStorage.LookupByKey(entry);
|
return _gameObjectTemplateAddonStorage.LookupByKey(entry);
|
||||||
}
|
}
|
||||||
|
public GameObjectOverride GetGameObjectOverride(ulong spawnId)
|
||||||
|
{
|
||||||
|
return _gameObjectOverrideStorage.LookupByKey(spawnId);
|
||||||
|
}
|
||||||
public Dictionary<uint, GameObjectTemplate> GetGameObjectTemplates()
|
public Dictionary<uint, GameObjectTemplate> GetGameObjectTemplates()
|
||||||
{
|
{
|
||||||
return _gameObjectTemplateStorage;
|
return _gameObjectTemplateStorage;
|
||||||
@@ -10261,6 +10302,7 @@ namespace Game
|
|||||||
Dictionary<uint, GameObjectTemplate> _gameObjectTemplateStorage = new();
|
Dictionary<uint, GameObjectTemplate> _gameObjectTemplateStorage = new();
|
||||||
Dictionary<ulong, GameObjectData> gameObjectDataStorage = new();
|
Dictionary<ulong, GameObjectData> gameObjectDataStorage = new();
|
||||||
Dictionary<ulong, GameObjectTemplateAddon> _gameObjectTemplateAddonStorage = new();
|
Dictionary<ulong, GameObjectTemplateAddon> _gameObjectTemplateAddonStorage = new();
|
||||||
|
Dictionary<ulong, GameObjectOverride> _gameObjectOverrideStorage = new();
|
||||||
Dictionary<ulong, GameObjectAddon> _gameObjectAddonStorage = new();
|
Dictionary<ulong, GameObjectAddon> _gameObjectAddonStorage = new();
|
||||||
MultiMap<uint, uint> _gameObjectQuestItemStorage = new();
|
MultiMap<uint, uint> _gameObjectQuestItemStorage = new();
|
||||||
List<uint> _gameObjectForQuestStorage = new();
|
List<uint> _gameObjectForQuestStorage = new();
|
||||||
|
|||||||
@@ -623,7 +623,10 @@ namespace Game
|
|||||||
Global.ObjectMgr.LoadSpawnGroups();
|
Global.ObjectMgr.LoadSpawnGroups();
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading GameObject Addon Data...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading GameObject Addon Data...");
|
||||||
Global.ObjectMgr.LoadGameObjectAddons(); // must be after LoadGameObjectTemplate() and LoadGameobjects()
|
Global.ObjectMgr.LoadGameObjectAddons(); // must be after LoadGameObjects()
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loading GameObject faction and flags overrides...");
|
||||||
|
Global.ObjectMgr.LoadGameObjectOverrides(); // must be after LoadGameObjects()
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading GameObject Quest Items...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading GameObject Quest Items...");
|
||||||
Global.ObjectMgr.LoadGameObjectQuestItems();
|
Global.ObjectMgr.LoadGameObjectQuestItems();
|
||||||
|
|||||||
Reference in New Issue
Block a user