diff --git a/Source/Framework/Constants/GossipConst.cs b/Source/Framework/Constants/GossipConst.cs index 4bf2e17b9..69689c56c 100644 --- a/Source/Framework/Constants/GossipConst.cs +++ b/Source/Framework/Constants/GossipConst.cs @@ -1,6 +1,8 @@ // Copyright (c) CypherCore All rights reserved. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. +using System; + namespace Framework.Constants { public enum GossipOption @@ -164,4 +166,13 @@ namespace Framework.Constants None = 0x0, QuestLabelPrepend = 0x1 } + + [Flags] + public enum ConversationFlags + { + None = 0x00, + MultipleConversationType = 0x01, // NYI purpose unknown + IsTalkingHeadConversation = 0x02, // implicitly implemented when conversation_actors.ActivePlayerObject == 0 && conversation_actors.NoActorObject == 0 && conversation_actors.ConversationActorGuid == 0 + AllowWithoutSpawnedActor = 0x04, + } } diff --git a/Source/Game/DataStorage/ConversationDataStorage.cs b/Source/Game/DataStorage/ConversationDataStorage.cs index d107e5578..956cbec74 100644 --- a/Source/Game/DataStorage/ConversationDataStorage.cs +++ b/Source/Game/DataStorage/ConversationDataStorage.cs @@ -1,11 +1,10 @@ // Copyright (c) CypherCore All rights reserved. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. +using Framework.Constants; using Framework.Database; -using System; using System.Collections.Generic; using System.Linq; -using Game.Entities; namespace Game.DataStorage { @@ -115,7 +114,7 @@ namespace Game.DataStorage return lineId; } - SQLResult templateResult = DB.World.Query("SELECT Id, FirstLineId, TextureKitId, ScriptName FROM conversation_template"); + SQLResult templateResult = DB.World.Query("SELECT Id, FirstLineId, TextureKitId, Flags, ScriptName FROM conversation_template"); if (!templateResult.IsEmpty()) { uint oldMSTime = Time.GetMSTime(); @@ -126,7 +125,8 @@ namespace Game.DataStorage conversationTemplate.Id = templateResult.Read(0); conversationTemplate.FirstLineId = templateResult.Read(1); conversationTemplate.TextureKitId = templateResult.Read(2); - conversationTemplate.ScriptId = Global.ObjectMgr.GetScriptId(templateResult.Read(3)); + conversationTemplate.Flags = (ConversationFlags)templateResult.Read(3); + conversationTemplate.ScriptId = Global.ObjectMgr.GetScriptId(templateResult.Read(4)); conversationTemplate.Actors = actorsByConversation.TryGetValue(conversationTemplate.Id, out var actors) ? actors.ToList() : new(); @@ -327,6 +327,7 @@ namespace Game.DataStorage public uint Id; public uint FirstLineId; // Link to ConversationLine.db2 public uint TextureKitId; // Background texture + public ConversationFlags Flags = ConversationFlags.None; public uint ScriptId; public List Actors = new(); diff --git a/Source/Game/Entities/Conversation.cs b/Source/Game/Entities/Conversation.cs index 079ef108a..f6daab68a 100644 --- a/Source/Game/Entities/Conversation.cs +++ b/Source/Game/Entities/Conversation.cs @@ -168,13 +168,17 @@ namespace Game.Entities public bool Start() { - foreach (ConversationLine line in m_conversationData.Lines.GetValue()) + ConversationTemplate conversationTemplate = Global.ConversationDataStorage.GetConversationTemplate(GetEntry()); // never null, already checked in ::Create / ::CreateConversation + if (!conversationTemplate.Flags.HasFlag(ConversationFlags.AllowWithoutSpawnedActor)) { - ConversationActorField actor = line.ActorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[line.ActorIndex] : null; - if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty() && actor.NoActorObject == 0)) + foreach (ConversationLine line in m_conversationData.Lines.GetValue()) { - Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {GetEntry()}) due to missing actor (Idx: {line.ActorIndex})."); - return false; + ConversationActorField actor = line.ActorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[line.ActorIndex] : null; + if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty() && actor.NoActorObject == 0)) + { + Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {GetEntry()}) due to missing actor (Idx: {line.ActorIndex})."); + return false; + } } }