diff --git a/Source/Game/DataStorage/ConversationDataStorage.cs b/Source/Game/DataStorage/ConversationDataStorage.cs index 73c64a6e4..4bd6dcf33 100644 --- a/Source/Game/DataStorage/ConversationDataStorage.cs +++ b/Source/Game/DataStorage/ConversationDataStorage.cs @@ -29,37 +29,12 @@ namespace Game.DataStorage public void LoadConversationTemplates() { - _conversationActorTemplateStorage.Clear(); _conversationLineTemplateStorage.Clear(); _conversationTemplateStorage.Clear(); - Dictionary actorsByConversation = new(); + Dictionary actorsByConversation = new(); Dictionary actorGuidsByConversation = new(); - SQLResult actorTemplates = DB.World.Query("SELECT Id, CreatureId, CreatureModelId FROM conversation_actor_template"); - if (!actorTemplates.IsEmpty()) - { - uint oldMSTime = Time.GetMSTime(); - - do - { - uint id = actorTemplates.Read(0); - ConversationActorTemplate conversationActor = new(); - conversationActor.Id = id; - conversationActor.CreatureId = actorTemplates.Read(1); - conversationActor.CreatureModelId = actorTemplates.Read(2); - - _conversationActorTemplateStorage[id] = conversationActor; - } - while (actorTemplates.NextRow()); - - Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Conversation actor templates in {1} ms", _conversationActorTemplateStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); - } - else - { - Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Conversation actor templates. DB table `conversation_actor_template` is empty."); - } - SQLResult lineTemplates = DB.World.Query("SELECT Id, StartTime, UiCameraID, ActorIdx, Flags FROM conversation_line_template"); if (!lineTemplates.IsEmpty()) { @@ -93,7 +68,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, ConversationActorGuid, Idx FROM conversation_actors"); + SQLResult actorResult = DB.World.Query("SELECT ConversationId, ConversationActorId, ConversationActorGuid, Idx, CreatureId, CreatureDisplayInfoId FROM conversation_actors"); if (!actorResult.IsEmpty()) { uint oldMSTime = Time.GetMSTime(); @@ -105,29 +80,36 @@ namespace Game.DataStorage uint actorId = actorResult.Read(1); ulong actorGuid = actorResult.Read(2); ushort idx = actorResult.Read(3); + uint creatureId = actorResult.Read(4); + uint creatureDisplayInfoId = actorResult.Read(5); - if (actorId != 0 && actorGuid != 0) + if (creatureId != 0 && actorGuid != 0) { Log.outError(LogFilter.Sql, $"Table `conversation_actors` references both actor (ID: {actorId}) and actorGuid (GUID: {actorGuid}) for Conversation {conversationId}, skipped."); continue; } - 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 (creatureId != 0) + { + if (creatureDisplayInfoId != 0) + { + ConversationActor conversationActor = new(); + conversationActor.ActorId = actorId; + conversationActor.CreatureId = creatureId; + conversationActor.CreatureDisplayInfoId = creatureDisplayInfoId; + + if (!actorsByConversation.ContainsKey(conversationId)) + actorsByConversation[conversationId] = new ConversationActor[idx + 1]; + + ConversationActor[] actors = actorsByConversation[conversationId]; if (actors.Length <= idx) Array.Resize(ref actors, idx + 1); - actors[idx] = conversationActorTemplate; + actors[idx] = conversationActor; ++count; } else - Log.outError(LogFilter.Sql, "Table `conversation_actors` references an invalid actor (ID: {0}) for Conversation {1}, skipped", actorId, conversationId); + Log.outError(LogFilter.Sql, $"Table `conversation_actors` references an actor (CreatureId: {creatureId}) without CreatureDisplayInfoId for Conversation {conversationId}, skipped"); } else if (actorGuid != 0) { @@ -211,15 +193,14 @@ namespace Game.DataStorage } Dictionary _conversationTemplateStorage = new(); - Dictionary _conversationActorTemplateStorage = new(); Dictionary _conversationLineTemplateStorage = new(); } - public class ConversationActorTemplate + public class ConversationActor { - public uint Id; + public uint ActorId; public uint CreatureId; - public uint CreatureModelId; + public uint CreatureDisplayInfoId; } public class ConversationLineTemplate @@ -240,7 +221,7 @@ namespace Game.DataStorage public uint TextureKitId; // Background texture public uint ScriptId; - public List Actors = new(); + public List Actors = new(); public List ActorGuids = new(); public List Lines = new(); } diff --git a/Source/Game/Entities/Conversation.cs b/Source/Game/Entities/Conversation.cs index f5d27e613..0030a14ad 100644 --- a/Source/Game/Entities/Conversation.cs +++ b/Source/Game/Entities/Conversation.cs @@ -139,10 +139,10 @@ namespace Game.Entities { if (actor != null) { - ConversationActor actorField = new(); + ConversationActorField actorField = new(); actorField.CreatureID = actor.CreatureId; - actorField.CreatureDisplayInfoID = actor.CreatureModelId; - actorField.Id = (int)actor.Id; + actorField.CreatureDisplayInfoID = actor.CreatureDisplayInfoId; + actorField.Id = (int)actor.ActorId; actorField.Type = ConversationActorType.CreatureActor; AddDynamicUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors), actorField); @@ -191,7 +191,7 @@ namespace Game.Entities // All actors need to be set foreach (ushort actorIndex in actorIndices) { - ConversationActor actor = actorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[actorIndex] : null; + ConversationActorField actor = actorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[actorIndex] : null; if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty() && actor.NoActorObject == 0)) { Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {conversationEntry}) due to missing actor (Idx: {actorIndex})."); @@ -207,7 +207,7 @@ namespace Game.Entities void AddActor(ObjectGuid actorGuid, ushort actorIdx) { - ConversationActor actorField = m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors, actorIdx); + ConversationActorField actorField = m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors, actorIdx); SetUpdateFieldValue(ref actorField.ActorGUID, actorGuid); SetUpdateFieldValue(ref actorField.Type, ConversationActorType.WorldObjectActor); } diff --git a/Source/Game/Entities/Object/Update/UpdateFields.cs b/Source/Game/Entities/Object/Update/UpdateFields.cs index cfc2a1d66..3bf16c6ce 100644 --- a/Source/Game/Entities/Object/Update/UpdateFields.cs +++ b/Source/Game/Entities/Object/Update/UpdateFields.cs @@ -5631,7 +5631,7 @@ namespace Game.Entities } } - public class ConversationActor + public class ConversationActorField { public uint CreatureID; public uint CreatureDisplayInfoID; @@ -5666,7 +5666,7 @@ namespace Game.Entities public class ConversationData : BaseUpdateData { public UpdateField> Lines = new(0, 1); - public DynamicUpdateField Actors = new(0, 2); + public DynamicUpdateField Actors = new(0, 2); public UpdateField LastLineEndTime = new(0, 3); public UpdateField Progress = new(0, 4); diff --git a/sql/updates/world/master/2021_04_26_00_world.sql b/sql/updates/world/master/2021_04_26_00_world.sql new file mode 100644 index 000000000..a796650e5 --- /dev/null +++ b/sql/updates/world/master/2021_04_26_00_world.sql @@ -0,0 +1,9 @@ +ALTER TABLE `conversation_actors` + ADD COLUMN `CreatureId` int(10) unsigned NOT NULL DEFAULT '0' AFTER `Idx`, + ADD COLUMN `CreatureDisplayInfoId` int(10) unsigned NOT NULL DEFAULT '0' AFTER `CreatureId`; + +UPDATE `conversation_actors` AS ca +INNER JOIN `conversation_actor_template` AS cat ON (ca.ConversationActorId = cat.Id) +SET ca.CreatureId = cat.CreatureId, ca.CreatureDisplayInfoId = cat.CreatureModelId; + +DROP TABLE `conversation_actor_template`;