From f81a877ad3ed8cfe31b89596413c8605b450abb2 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sun, 5 Nov 2017 16:55:27 -0500 Subject: [PATCH] Added DB-support for conversation actorGuids --- Source/Framework/Logging/Log.cs | 1 + .../DataStorage/ConversationDataStorage.cs | 62 ++++++++++++++----- Source/Game/Entities/Conversation.cs | 44 ++++++++++--- 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/Source/Framework/Logging/Log.cs b/Source/Framework/Logging/Log.cs index d5a32ebd4..23e1c1c6f 100644 --- a/Source/Framework/Logging/Log.cs +++ b/Source/Framework/Logging/Log.cs @@ -394,6 +394,7 @@ public enum LogFilter Cheat, Commands, Condition, + Conversation, Garrison, Gameevent, Guild, diff --git a/Source/Game/DataStorage/ConversationDataStorage.cs b/Source/Game/DataStorage/ConversationDataStorage.cs index 481e48014..324a09bc7 100644 --- a/Source/Game/DataStorage/ConversationDataStorage.cs +++ b/Source/Game/DataStorage/ConversationDataStorage.cs @@ -19,6 +19,7 @@ using Framework.Database; using System; using System.Collections.Generic; using System.Linq; +using Game.Entities; namespace Game.DataStorage { @@ -33,6 +34,7 @@ namespace Game.DataStorage _conversationTemplateStorage.Clear(); Dictionary actorsByConversation = new Dictionary(); + Dictionary actorGuidsByConversation = new Dictionary(); SQLResult actorTemplates = DB.World.Query("SELECT Id, CreatureId, CreatureModelId FROM conversation_actor_template"); if (!actorTemplates.IsEmpty()) @@ -91,7 +93,7 @@ namespace Game.DataStorage Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Conversation line templates. DB table `conversation_line_template` is empty."); } - SQLResult actorResult = DB.World.Query("SELECT ConversationId, ConversationActorId, Idx FROM conversation_actors"); + SQLResult actorResult = DB.World.Query("SELECT ConversationId, ConversationActorId, ConversationActorGuid, Idx FROM conversation_actors"); if (!actorResult.IsEmpty()) { uint oldMSTime = Time.GetMSTime(); @@ -101,23 +103,51 @@ namespace Game.DataStorage { uint conversationId = actorResult.Read(0); uint actorId = actorResult.Read(1); - ushort idx = actorResult.Read(2); + ulong actorGuid = actorResult.Read(2); + ushort idx = actorResult.Read(3); - ConversationActorTemplate conversationActorTemplate = _conversationActorTemplateStorage.LookupByKey(actorId); - if (conversationActorTemplate != null) + if (actorId != 0 && actorGuid != 0) { - if (!actorsByConversation.ContainsKey(conversationId)) - actorsByConversation[conversationId] = new ConversationActorTemplate[idx + 1]; - - ConversationActorTemplate[] actors = actorsByConversation[conversationId]; - if (actors.Length <= idx) - Array.Resize(ref actors, idx + 1); - - actors[idx] = conversationActorTemplate; - ++count; + Log.outError(LogFilter.Sql, $"Table `conversation_actors` references both actor (ID: {actorId}) and actorGuid (GUID: {actorGuid}) for Conversation {conversationId}, skipped."); + continue; } - else - Log.outError(LogFilter.Sql, "Table `conversation_actors` references an invalid actor (ID: {0}) for Conversation {1}, skipped", actorId, conversationId); + if (actorId != 0) + { + ConversationActorTemplate conversationActorTemplate = _conversationActorTemplateStorage.LookupByKey(actorId); + if (conversationActorTemplate != null) + { + if (!actorsByConversation.ContainsKey(conversationId)) + actorsByConversation[conversationId] = new ConversationActorTemplate[idx + 1]; + + ConversationActorTemplate[] actors = actorsByConversation[conversationId]; + if (actors.Length <= idx) + Array.Resize(ref actors, idx + 1); + + actors[idx] = conversationActorTemplate; + ++count; + } + else + Log.outError(LogFilter.Sql, "Table `conversation_actors` references an invalid actor (ID: {0}) for Conversation {1}, skipped", actorId, conversationId); + } + else if (actorGuid != 0) + { + CreatureData creData = Global.ObjectMgr.GetCreatureData(actorGuid); + if (creData != null) + { + if (!actorGuidsByConversation.ContainsKey(conversationId)) + actorGuidsByConversation[conversationId] = new ulong[idx + 1]; + + var guids = actorGuidsByConversation[conversationId]; + if (guids.Length <= idx) + Array.Resize(ref guids, idx + 1); + + guids[idx] = actorGuid; + ++count; + } + else + Log.outError(LogFilter.Sql, $"Table `conversation_actors` references an invalid creature guid (GUID: {actorGuid}) for Conversation {conversationId}, skipped"); + } + } while (actorResult.NextRow()); @@ -141,6 +171,7 @@ namespace Game.DataStorage conversationTemplate.LastLineEndTime = templateResult.Read(2); conversationTemplate.Actors = actorsByConversation[conversationTemplate.Id].ToList(); + conversationTemplate.ActorGuids = actorGuidsByConversation[conversationTemplate.Id].ToList(); ConversationLineRecord currentConversationLine = CliDB.ConversationLineStorage.LookupByKey(conversationTemplate.FirstLineId); if (currentConversationLine == null) @@ -205,6 +236,7 @@ namespace Game.DataStorage public uint LastLineEndTime; // Time in ms after conversation creation the last line fades out public List Actors = new List(); + public List ActorGuids = new List(); public List Lines = new List(); } diff --git a/Source/Game/Entities/Conversation.cs b/Source/Game/Entities/Conversation.cs index 5726212c9..f99a4f01a 100644 --- a/Source/Game/Entities/Conversation.cs +++ b/Source/Game/Entities/Conversation.cs @@ -120,23 +120,48 @@ namespace Game.Entities SetUInt32Value(ConversationFields.LastLineEndTime, conversationTemplate.LastLineEndTime); _duration = conversationTemplate.LastLineEndTime; - ushort actorsIndex = 0; - foreach (ConversationActorTemplate actor in conversationTemplate.Actors) + for (ushort actorIndex = 0; actorIndex < conversationTemplate.Actors.Count; ++actorIndex) { + ConversationActorTemplate actor = conversationTemplate.Actors[actorIndex]; if (actor != null) { ConversationDynamicFieldActor actorField = new ConversationDynamicFieldActor(); actorField.ActorTemplate = actor; actorField.Type = ConversationDynamicFieldActor.ActorType.CreatureActor; - SetDynamicStructuredValue(ConversationDynamicFields.Actors, actorsIndex++, actorField); + SetDynamicStructuredValue(ConversationDynamicFields.Actors, actorIndex, actorField); } - else - ++actorsIndex; } - ushort linesIndex = 0; + for (ushort actorIndex = 0; actorIndex < conversationTemplate.ActorGuids.Count; ++actorIndex) + { + ulong actorGuid = conversationTemplate.ActorGuids[actorIndex]; + if (actorGuid == 0) + continue; + + foreach (var creature in map.GetCreatureBySpawnIdStore().LookupByKey(actorGuid)) + { + // we just need the last one, overriding is legit + AddActor(creature.GetGUID(), actorIndex); + } + } + + List actorIndices = new List(); foreach (ConversationLineTemplate line in conversationTemplate.Lines) - SetDynamicStructuredValue(ConversationDynamicFields.Lines, linesIndex++, line); + { + actorIndices.Add(line.ActorIdx); + AddDynamicStructuredValue(ConversationDynamicFields.Lines, line); + } + + // All actors need to be set + foreach (ushort actorIndex in actorIndices) + { + ConversationDynamicFieldActor actor = GetDynamicStructuredValue(ConversationDynamicFields.Actors, actorIndex); + if (actor == null || actor.IsEmpty()) + { + Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {conversationEntry}) due to missing actor (Idx: {actorIndex})."); + return false; + } + } if (!GetMap().AddToMap(this)) return false; @@ -181,6 +206,11 @@ namespace Game.Entities CreatureActor = 1 } + public bool IsEmpty() + { + return ActorGuid.IsEmpty(); // this one is good enough + } + public ObjectGuid ActorGuid; public ConversationActorTemplate ActorTemplate;