From b8fe68ec8b1fc322131e5c3c8f30548b17f52489 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sun, 5 Nov 2017 17:40:57 -0500 Subject: [PATCH] Add WorldEffectID to Gameobject --- .../Framework/Constants/Update/UpdateFlags.cs | 2 +- .../Database/Databases/HotfixDatabase.cs | 6 +++ Source/Game/DataStorage/CliDB.cs | 2 + Source/Game/DataStorage/Structs/W_Records.cs | 11 ++++++ Source/Game/Entities/GameObject/GameObject.cs | 16 ++++++++ .../Entities/GameObject/GameObjectData.cs | 2 + Source/Game/Entities/Object/WorldObject.cs | 22 +++++++---- Source/Game/Globals/ObjectManager.cs | 39 ++++++++++++------- 8 files changed, 78 insertions(+), 22 deletions(-) diff --git a/Source/Framework/Constants/Update/UpdateFlags.cs b/Source/Framework/Constants/Update/UpdateFlags.cs index 91d7f1942..37ed39da9 100644 --- a/Source/Framework/Constants/Update/UpdateFlags.cs +++ b/Source/Framework/Constants/Update/UpdateFlags.cs @@ -33,7 +33,7 @@ namespace Framework.Constants Rotation = 0x80, AnimKits = 0x100, Areatrigger = 0x0200, - //UPDATEFLAG_GAMEOBJECT = 0x0400, + Gameobject = 0x0400, //UPDATEFLAG_REPLACE_ACTIVE = 0x0800, //UPDATEFLAG_NO_BIRTH_ANIM = 0x1000, //UPDATEFLAG_ENABLE_PORTALS = 0x2000, diff --git a/Source/Framework/Database/Databases/HotfixDatabase.cs b/Source/Framework/Database/Databases/HotfixDatabase.cs index efcd9c9ce..348dd5fdd 100644 --- a/Source/Framework/Database/Databases/HotfixDatabase.cs +++ b/Source/Framework/Database/Databases/HotfixDatabase.cs @@ -990,6 +990,10 @@ namespace Framework.Database "UWAmbience, NameSet, SoundProviderPref, SoundProviderPrefUnderwater, Flags, ID, UWZoneMusic FROM wmo_area_table ORDER BY ID DESC"); PrepareStatement(HotfixStatements.SEL_WMO_AREA_TABLE_LOCALE, "SELECT ID, AreaName_lang FROM wmo_area_table_locale WHERE locale = ?"); + // WorldEffect.db2 + PrepareStatement(HotfixStatements.SEL_WORLD_EFFECT, "SELECT ID, TargetAsset, CombatConditionID, TargetType, WhenToDisplay, QuestFeedbackEffectID, " + + "PlayerConditionID FROM world_effect ORDER BY ID DESC"); + // WorldMapArea.db2 PrepareStatement(HotfixStatements.SEL_WORLD_MAP_AREA, "SELECT AreaName, LocLeft, LocRight, LocTop, LocBottom, MapID, AreaID, DisplayMapID, " + "DefaultDungeonFloor, ParentWorldMapID, Flags, LevelRangeMin, LevelRangeMax, BountySetID, BountyBoardLocation, ID, PlayerConditionID" + @@ -1517,6 +1521,8 @@ namespace Framework.Database SEL_WMO_AREA_TABLE, SEL_WMO_AREA_TABLE_LOCALE, + SEL_WORLD_EFFECT, + SEL_WORLD_MAP_AREA, SEL_WORLD_MAP_OVERLAY, diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 8185b6d7f..665343d2a 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -252,6 +252,7 @@ namespace Game.DataStorage VehicleStorage = DB6Reader.Read("Vehicle.db2", DB6Metas.VehicleMeta, HotfixStatements.SEL_VEHICLE); VehicleSeatStorage = DB6Reader.Read("VehicleSeat.db2", DB6Metas.VehicleSeatMeta, HotfixStatements.SEL_VEHICLE_SEAT); WMOAreaTableStorage = DB6Reader.Read("WMOAreaTable.db2", DB6Metas.WMOAreaTableMeta, HotfixStatements.SEL_WMO_AREA_TABLE, HotfixStatements.SEL_WMO_AREA_TABLE_LOCALE); + WorldEffectStorage = DB6Reader.Read("WorldEffect.db2", DB6Metas.WorldEffectMeta, HotfixStatements.SEL_WORLD_EFFECT); WorldMapAreaStorage = DB6Reader.Read("WorldMapArea.db2", DB6Metas.WorldMapAreaMeta, HotfixStatements.SEL_WORLD_MAP_AREA); WorldMapOverlayStorage = DB6Reader.Read("WorldMapOverlay.db2", DB6Metas.WorldMapOverlayMeta, HotfixStatements.SEL_WORLD_MAP_OVERLAY); WorldMapTransformsStorage = DB6Reader.Read("WorldMapTransforms.db2", DB6Metas.WorldMapTransformsMeta, HotfixStatements.SEL_WORLD_MAP_TRANSFORMS); @@ -577,6 +578,7 @@ namespace Game.DataStorage public static DB6Storage VehicleStorage; public static DB6Storage VehicleSeatStorage; public static DB6Storage WMOAreaTableStorage; + public static DB6Storage WorldEffectStorage; public static DB6Storage WorldMapAreaStorage; public static DB6Storage WorldMapOverlayStorage; public static DB6Storage WorldMapTransformsStorage; diff --git a/Source/Game/DataStorage/Structs/W_Records.cs b/Source/Game/DataStorage/Structs/W_Records.cs index cf1b4b10a..5c621fb0f 100644 --- a/Source/Game/DataStorage/Structs/W_Records.cs +++ b/Source/Game/DataStorage/Structs/W_Records.cs @@ -39,6 +39,17 @@ namespace Game.DataStorage public uint UWZoneMusic; } + public sealed class WorldEffectRecord + { + public uint ID; + public uint TargetAsset; + public ushort CombatConditionID; + public byte TargetType; + public byte WhenToDisplay; + public uint QuestFeedbackEffectID; + public uint PlayerConditionID; + } + public sealed class WorldMapAreaRecord { public string AreaName; diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index 057796d52..2d352b861 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -228,6 +228,12 @@ namespace Game.Entities { SetUInt32Value(GameObjectFields.Faction, m_goTemplateAddon.faction); SetUInt32Value(GameObjectFields.Flags, m_goTemplateAddon.flags); + + if (m_goTemplateAddon.WorldEffectID) + { + m_updateFlag |= UpdateFlag.Gameobject; + SetWorldEffectID(m_goTemplateAddon.WorldEffectID); + } } SetEntry(goinfo.entry); @@ -318,6 +324,12 @@ namespace Game.Entities m_invisibility.AddValue(gameObjectAddon.invisibilityType, gameObjectAddon.invisibilityValue); } + if (gameObjectAddon != null && gameObjectAddon.WorldEffectID) + { + m_updateFlag |= UpdateFlag.Gameobject; + SetWorldEffectID(gameObjectAddon.WorldEffectID); + } + LastUsedScriptID = GetGoInfo().ScriptId; AIM_Initialize(); @@ -2498,6 +2510,9 @@ namespace Game.Entities public override ushort GetAIAnimKitId() { return _animKitId; } + public uint GetWorldEffectID() { return _worldEffectID; } + public void SetWorldEffectID(uint worldEffectID) { _worldEffectID = worldEffectID; } + public GameObjectTemplate GetGoInfo() { return m_goInfo; } public GameObjectTemplateAddon GetTemplateAddon() { return m_goTemplateAddon; } GameObjectData GetGoData() { return m_goData; } @@ -2663,6 +2678,7 @@ namespace Game.Entities GameObjectAI m_AI; ushort _animKitId; + uint _worldEffectID; GameObjectState m_prevGoState; // What state to set whenever resetting diff --git a/Source/Game/Entities/GameObject/GameObjectData.cs b/Source/Game/Entities/GameObject/GameObjectData.cs index b4cb9a583..7ffe89232 100644 --- a/Source/Game/Entities/GameObject/GameObjectData.cs +++ b/Source/Game/Entities/GameObject/GameObjectData.cs @@ -1030,6 +1030,7 @@ namespace Game.Entities public uint flags; public uint mingold; public uint maxgold; + public uint WorldEffectID; } public class GameObjectLocale @@ -1044,6 +1045,7 @@ namespace Game.Entities public Quaternion ParentRotation; public InvisibilityType invisibilityType; public uint invisibilityValue; + public uint WorldEffectID; } public class GameObjectData diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 2bff7fe14..47eeb465e 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -325,7 +325,7 @@ namespace Game.Entities bool AnimKitCreate = flags.HasAnyFlag(UpdateFlag.AnimKits); bool Rotation = flags.HasAnyFlag(UpdateFlag.Rotation); bool HasAreaTrigger = flags.HasAnyFlag(UpdateFlag.Areatrigger); - bool HasGameObject = false; + bool HasGameObject = flags.HasAnyFlag(UpdateFlag.Gameobject); bool ThisIsYou = flags.HasAnyFlag(UpdateFlag.Self); bool SmoothPhasing = false; bool SceneObjCreate = false; @@ -653,14 +653,20 @@ namespace Game.Entities } } - //if (HasGameObject) - //{ - // *data << uint32(WorldEffectID); + if (HasGameObject) + { + bool bit8 = false; + uint Int1 = 0; - // data.WriteBit(bit8); - // if (bit8) - // *data << uint32(Int1); - //} + GameObject gameObject = ToGameObject(); + + data.WriteUInt32(gameObject.GetWorldEffectID()); + + data.WriteBit(bit8); + data.FlushBits(); + if (bit8) + data.WriteUInt32(Int1); + } //if (SmoothPhasing) //{ diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 8c52424b9..e2e213ffe 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -3803,8 +3803,8 @@ namespace Game { uint oldMSTime = Time.GetMSTime(); - // 0 1 2 3 4 - SQLResult result = DB.World.Query("SELECT entry, faction, flags, mingold, maxgold FROM gameobject_template_addon"); + // 0 1 2 3 4 5 + SQLResult result = DB.World.Query("SELECT entry, faction, flags, mingold, maxgold, WorldEffectID FROM gameobject_template_addon"); if (result.IsEmpty()) { @@ -3820,7 +3820,7 @@ namespace Game GameObjectTemplate got = Global.ObjectMgr.GetGameObjectTemplate(entry); if (got == null) { - Log.outError(LogFilter.Sql, "GameObject template (Entry: {0}) does not exist but has a record in `gameobject_template_addon`", entry); + Log.outError(LogFilter.Sql, $"GameObject template (Entry: {entry}) does not exist but has a record in `gameobject_template_addon`"); continue; } @@ -3829,10 +3829,11 @@ namespace Game gameObjectAddon.flags = result.Read(2); gameObjectAddon.mingold = result.Read(3); gameObjectAddon.maxgold = result.Read(4); + gameObjectAddon.WorldEffectID = result.Read(5); // checks if (gameObjectAddon.faction != 0 && !CliDB.FactionTemplateStorage.ContainsKey(gameObjectAddon.faction)) - Log.outError(LogFilter.Sql, "GameObject (Entry: {0}) has invalid faction ({1}) defined in `gameobject_template_addon`.", entry, gameObjectAddon.faction); + Log.outError(LogFilter.Sql, $"GameObject (Entry: {entry}) has invalid faction ({gameObjectAddon.faction}) defined in `gameobject_template_addon`."); if (gameObjectAddon.maxgold > 0) { @@ -3842,13 +3843,18 @@ namespace Game case GameObjectTypes.FishingHole: break; default: - Log.outError(LogFilter.Sql, "GameObject (Entry {0} GoType: {1}) cannot be looted but has maxgold set in `gameobject_template_addon`.", entry, got.type); + Log.outError(LogFilter.Sql, $"GameObject (Entry {entry} GoType: {got.type}) cannot be looted but has maxgold set in `gameobject_template_addon`."); break; } } - _gameObjectTemplateAddonStore[entry] = gameObjectAddon; + if (gameObjectAddon.WorldEffectID != 0 && !CliDB.WorldEffectStorage.ContainsKey(gameObjectAddon.WorldEffectID)) + { + Log.outError(LogFilter.Sql, $"GameObject (Entry: {entry}) has invalid WorldEffectID ({gameObjectAddon.WorldEffectID}) defined in `gameobject_template_addon`, set to 0."); + gameObjectAddon.WorldEffectID = 0; + } + _gameObjectTemplateAddonStore[entry] = gameObjectAddon; ++count; } while (result.NextRow()); @@ -4062,8 +4068,8 @@ namespace Game _gameObjectAddonStorage.Clear(); - // 0 1 2 3 4 5 6 - SQLResult result = DB.World.Query("SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue FROM gameobject_addon"); + // 0 1 2 3 4 5 6 7 + SQLResult result = DB.World.Query("SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue, WorldEffectID FROM gameobject_addon"); if (result.IsEmpty()) { @@ -4079,7 +4085,7 @@ namespace Game GameObjectData goData = GetGOData(guid); if (goData == null) { - Log.outError(LogFilter.Sql, "GameObject (GUID: {0}) does not exist but has a record in `gameobject_addon`", guid); + Log.outError(LogFilter.Sql, $"GameObject (GUID: {guid}) does not exist but has a record in `gameobject_addon`"); continue; } @@ -4087,32 +4093,39 @@ namespace Game gameObjectAddon.ParentRotation = new Quaternion(result.Read(1), result.Read(2), result.Read(3), result.Read(4)); gameObjectAddon.invisibilityType = (InvisibilityType)result.Read(5); gameObjectAddon.invisibilityValue = result.Read(6); + gameObjectAddon.WorldEffectID = result.Read(7); if (gameObjectAddon.invisibilityType >= InvisibilityType.Max) { - Log.outError(LogFilter.Sql, "GameObject (GUID: {0}) has invalid InvisibilityType in `gameobject_addon`, disabled invisibility", guid); + Log.outError(LogFilter.Sql, $"GameObject (GUID: {guid}) has invalid InvisibilityType in `gameobject_addon`, disabled invisibility"); gameObjectAddon.invisibilityType = InvisibilityType.General; gameObjectAddon.invisibilityValue = 0; } if (gameObjectAddon.invisibilityType != 0 && gameObjectAddon.invisibilityValue == 0) { - Log.outError(LogFilter.Sql, "GameObject (GUID: {0}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1", guid); + Log.outError(LogFilter.Sql, $"GameObject (GUID: {guid}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1"); gameObjectAddon.invisibilityValue = 1; } if (!gameObjectAddon.ParentRotation.isUnit()) { - Log.outError(LogFilter.Sql, "GameObject (GUID: {0}) has invalid parent rotation in `gameobject_addon`, set to default", guid); + Log.outError(LogFilter.Sql, $"GameObject (GUID: {guid}) has invalid parent rotation in `gameobject_addon`, set to default"); gameObjectAddon.ParentRotation = Quaternion.WAxis; } + if (gameObjectAddon.WorldEffectID != 0 && !CliDB.WorldEffectStorage.ContainsKey(gameObjectAddon.WorldEffectID)) + { + Log.outError(LogFilter.Sql, $"GameObject (GUID: {guid}) has invalid WorldEffectID ({gameObjectAddon.WorldEffectID}) in `gameobject_addon`, set to 0."); + gameObjectAddon.WorldEffectID = 0; + } + _gameObjectAddonStorage[guid] = gameObjectAddon; ++count; } while (result.NextRow()); - Log.outInfo(LogFilter.ServerLoading, "Loaded {0} gameobject addons in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); + Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} gameobject addons in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); } public void LoadGameObjectQuestItems() {