Core/Conversations: Fix conversation data handling
Port From (https://github.com/TrinityCore/TrinityCore/commit/f4ef40d9686135088a76c90a3f9de6a6bc10e8f0)
This commit is contained in:
@@ -29,37 +29,12 @@ namespace Game.DataStorage
|
||||
|
||||
public void LoadConversationTemplates()
|
||||
{
|
||||
_conversationActorTemplateStorage.Clear();
|
||||
_conversationLineTemplateStorage.Clear();
|
||||
_conversationTemplateStorage.Clear();
|
||||
|
||||
Dictionary<uint, ConversationActorTemplate[]> actorsByConversation = new();
|
||||
Dictionary<uint, ConversationActor[]> actorsByConversation = 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");
|
||||
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<uint>(1);
|
||||
ulong actorGuid = actorResult.Read<ulong>(2);
|
||||
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.");
|
||||
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<uint, ConversationTemplate> _conversationTemplateStorage = new();
|
||||
Dictionary<uint, ConversationActorTemplate> _conversationActorTemplateStorage = new();
|
||||
Dictionary<uint, ConversationLineTemplate> _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<ConversationActorTemplate> Actors = new();
|
||||
public List<ConversationActor> Actors = new();
|
||||
public List<ulong> ActorGuids = new();
|
||||
public List<ConversationLineTemplate> Lines = new();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<Conversation>
|
||||
{
|
||||
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> 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`;
|
||||
Reference in New Issue
Block a user