Core/Conversations: Fix conversation data handling

Port From (https://github.com/TrinityCore/TrinityCore/commit/f4ef40d9686135088a76c90a3f9de6a6bc10e8f0)
This commit is contained in:
hondacrx
2021-04-28 10:44:30 -04:00
parent ad94721b7c
commit 4f650d6e90
4 changed files with 40 additions and 50 deletions
@@ -29,37 +29,12 @@ namespace Game.DataStorage
public void LoadConversationTemplates() public void LoadConversationTemplates()
{ {
_conversationActorTemplateStorage.Clear();
_conversationLineTemplateStorage.Clear(); _conversationLineTemplateStorage.Clear();
_conversationTemplateStorage.Clear(); _conversationTemplateStorage.Clear();
Dictionary<uint, ConversationActorTemplate[]> actorsByConversation = new(); Dictionary<uint, ConversationActor[]> actorsByConversation = new();
Dictionary<uint, ulong[]> actorGuidsByConversation = new(); Dictionary<uint, ulong[]> 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<uint>(0);
ConversationActorTemplate conversationActor = new();
conversationActor.Id = id;
conversationActor.CreatureId = actorTemplates.Read<uint>(1);
conversationActor.CreatureModelId = actorTemplates.Read<uint>(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"); SQLResult lineTemplates = DB.World.Query("SELECT Id, StartTime, UiCameraID, ActorIdx, Flags FROM conversation_line_template");
if (!lineTemplates.IsEmpty()) 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."); 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()) if (!actorResult.IsEmpty())
{ {
uint oldMSTime = Time.GetMSTime(); uint oldMSTime = Time.GetMSTime();
@@ -105,29 +80,36 @@ namespace Game.DataStorage
uint actorId = actorResult.Read<uint>(1); uint actorId = actorResult.Read<uint>(1);
ulong actorGuid = actorResult.Read<ulong>(2); ulong actorGuid = actorResult.Read<ulong>(2);
ushort idx = actorResult.Read<ushort>(3); ushort idx = actorResult.Read<ushort>(3);
uint creatureId = actorResult.Read<uint>(4);
uint creatureDisplayInfoId = actorResult.Read<uint>(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."); Log.outError(LogFilter.Sql, $"Table `conversation_actors` references both actor (ID: {actorId}) and actorGuid (GUID: {actorGuid}) for Conversation {conversationId}, skipped.");
continue; 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) if (actors.Length <= idx)
Array.Resize(ref actors, idx + 1); Array.Resize(ref actors, idx + 1);
actors[idx] = conversationActorTemplate; actors[idx] = conversationActor;
++count; ++count;
} }
else 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) else if (actorGuid != 0)
{ {
@@ -211,15 +193,14 @@ namespace Game.DataStorage
} }
Dictionary<uint, ConversationTemplate> _conversationTemplateStorage = new(); Dictionary<uint, ConversationTemplate> _conversationTemplateStorage = new();
Dictionary<uint, ConversationActorTemplate> _conversationActorTemplateStorage = new();
Dictionary<uint, ConversationLineTemplate> _conversationLineTemplateStorage = new(); Dictionary<uint, ConversationLineTemplate> _conversationLineTemplateStorage = new();
} }
public class ConversationActorTemplate public class ConversationActor
{ {
public uint Id; public uint ActorId;
public uint CreatureId; public uint CreatureId;
public uint CreatureModelId; public uint CreatureDisplayInfoId;
} }
public class ConversationLineTemplate public class ConversationLineTemplate
@@ -240,7 +221,7 @@ namespace Game.DataStorage
public uint TextureKitId; // Background texture public uint TextureKitId; // Background texture
public uint ScriptId; public uint ScriptId;
public List<ConversationActorTemplate> Actors = new(); public List<ConversationActor> Actors = new();
public List<ulong> ActorGuids = new(); public List<ulong> ActorGuids = new();
public List<ConversationLineTemplate> Lines = new(); public List<ConversationLineTemplate> Lines = new();
} }
+5 -5
View File
@@ -139,10 +139,10 @@ namespace Game.Entities
{ {
if (actor != null) if (actor != null)
{ {
ConversationActor actorField = new(); ConversationActorField actorField = new();
actorField.CreatureID = actor.CreatureId; actorField.CreatureID = actor.CreatureId;
actorField.CreatureDisplayInfoID = actor.CreatureModelId; actorField.CreatureDisplayInfoID = actor.CreatureDisplayInfoId;
actorField.Id = (int)actor.Id; actorField.Id = (int)actor.ActorId;
actorField.Type = ConversationActorType.CreatureActor; actorField.Type = ConversationActorType.CreatureActor;
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors), actorField); AddDynamicUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors), actorField);
@@ -191,7 +191,7 @@ namespace Game.Entities
// All actors need to be set // All actors need to be set
foreach (ushort actorIndex in actorIndices) 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)) 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})."); 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) 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.ActorGUID, actorGuid);
SetUpdateFieldValue(ref actorField.Type, ConversationActorType.WorldObjectActor); SetUpdateFieldValue(ref actorField.Type, ConversationActorType.WorldObjectActor);
} }
@@ -5631,7 +5631,7 @@ namespace Game.Entities
} }
} }
public class ConversationActor public class ConversationActorField
{ {
public uint CreatureID; public uint CreatureID;
public uint CreatureDisplayInfoID; public uint CreatureDisplayInfoID;
@@ -5666,7 +5666,7 @@ namespace Game.Entities
public class ConversationData : BaseUpdateData<Conversation> public class ConversationData : BaseUpdateData<Conversation>
{ {
public UpdateField<List<ConversationLine>> Lines = new(0, 1); public UpdateField<List<ConversationLine>> Lines = new(0, 1);
public DynamicUpdateField<ConversationActor> Actors = new(0, 2); public DynamicUpdateField<ConversationActorField> Actors = new(0, 2);
public UpdateField<uint> LastLineEndTime = new(0, 3); public UpdateField<uint> LastLineEndTime = new(0, 3);
public UpdateField<uint> Progress = new(0, 4); public UpdateField<uint> Progress = new(0, 4);
@@ -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`;