34 _conversationLineTemplateStore.clear();
35 _conversationTemplateStore.clear();
37 std::unordered_map<uint32, std::vector<ConversationActorTemplate>> actorsByConversation;
39 if (
QueryResult lineTemplates =
WorldDatabase.Query(
"SELECT Id, UiCameraID, ActorIdx, Flags, ChatType FROM conversation_line_template"))
45 Field* fields = lineTemplates->Fetch();
51 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_line_template` has template for non existing ConversationLine (ID: {}), skipped",
id);
56 conversationLine.
Id = id;
62 while (lineTemplates->NextRow());
64 TC_LOG_INFO(
"server.loading",
">> Loaded {} Conversation line templates in {} ms", _conversationLineTemplateStore.size(),
GetMSTimeDiffToNow(oldMSTime));
68 TC_LOG_INFO(
"server.loading",
">> Loaded 0 Conversation line templates. DB table `conversation_line_template` is empty.");
71 if (
QueryResult actors =
WorldDatabase.Query(
"SELECT ConversationId, ConversationActorId, ConversationActorGuid, Idx, CreatureId, CreatureDisplayInfoId, NoActorObject, ActivePlayerObject FROM conversation_actors"))
76 struct ConversationActorDbRow
83 uint32 CreatureDisplayInfoId = 0;
89 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` references an invalid creature guid (GUID: {}) for Conversation {} and Idx {}, skipped.", SpawnId, ConversationId, ActorIndex);
94 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with ConversationActorGuid cannot have CreatureId ({}). Conversation {} and Idx {}.",
CreatureId, ConversationId, ActorIndex);
96 if (CreatureDisplayInfoId)
97 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with ConversationActorGuid cannot have CreatureDisplayInfoId ({}). Conversation {} and Idx {}.", CreatureDisplayInfoId, ConversationId, ActorIndex);
107 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` references an invalid creature id ({}) for Conversation {} and Idx {}, skipped.",
CreatureId, ConversationId, ActorIndex);
113 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` references an invalid creature display id ({}) for Conversation {} and Idx {}, skipped.", CreatureDisplayInfoId, ConversationId, ActorIndex);
118 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with NoActorObject cannot have ConversationActorGuid ({}). Conversation {} and Idx {}.", SpawnId, ConversationId, ActorIndex);
128 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with ActivePlayerObject cannot have ConversationActorGuid ({}). Conversation {} and Idx {}.", SpawnId, ConversationId, ActorIndex);
131 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with ActivePlayerObject cannot have CreatureId ({}). Conversation {} and Idx {}.",
CreatureId, ConversationId, ActorIndex);
133 if (CreatureDisplayInfoId)
134 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with ActivePlayerObject cannot have CreatureDisplayInfoId ({}). Conversation {} and Idx {}.", CreatureDisplayInfoId, ConversationId, ActorIndex);
143 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` references an invalid creature id ({}) for Conversation {} and Idx {}, skipped.",
CreatureId, ConversationId, ActorIndex);
149 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` references an invalid creature display id ({}) for Conversation {} and Idx {}, skipped.", CreatureDisplayInfoId, ConversationId, ActorIndex);
154 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_actors` with TalkingHead cannot have ConversationActorGuid ({}). Conversation {} and Idx {}.", SpawnId, ConversationId, ActorIndex);
164 Field* fields = actors->Fetch();
166 ConversationActorDbRow data;
168 data.ConversationId = fields[0].
GetUInt32();
173 data.CreatureDisplayInfoId = fields[5].
GetUInt32();
174 bool noActorObject = fields[6].
GetUInt8() == 1;
175 bool activePlayerObject = fields[7].
GetUInt8() == 1;
177 if (activePlayerObject)
179 else if (noActorObject)
181 else if (data.SpawnId || !data.CreatureId)
186 bool valid = std::visit(data, actor.
Data);
190 actorsByConversation[data.ConversationId].push_back(actor);
192 }
while (actors->NextRow());
198 TC_LOG_INFO(
"server.loading",
">> Loaded 0 Conversation actors. DB table `conversation_actors` is empty.");
204 if (conversationLine && conversationLine->NextConversationLineID)
206 static constexpr uint32 FirstLineId = 60000;
208 if (conversationLine->ID > FirstLineId && conversationLine->NextConversationLineID < (
sConversationLineStore.GetNumRows() - USHRT_MAX - 1))
209 return (
uint32)(USHRT_MAX + conversationLine->NextConversationLineID + 1);
211 return (
uint32)conversationLine->NextConversationLineID;
218 std::unordered_map<uint32, uint32> prevConversationLineIds;
220 if (
uint32 nextConversationLineId = getNextConversationLineId(conversationLine))
221 prevConversationLineIds[nextConversationLineId] = conversationLine->ID;
223 auto getFirstLineIdFromAnyLineId = [&](
uint32 lineId)
226 lineId = *prevLineId;
231 if (
QueryResult templates =
WorldDatabase.Query(
"SELECT Id, FirstLineId, TextureKitId, Flags, ScriptName FROM conversation_template"))
237 Field* fields = templates->Fetch();
246 conversationTemplate.
Actors = std::move(actorsByConversation[conversationTemplate.
Id]);
248 uint32 correctedFirstLineId = getFirstLineIdFromAnyLineId(conversationTemplate.
FirstLineId);
249 if (conversationTemplate.
FirstLineId != correctedFirstLineId)
251 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_template` has incorrect FirstLineId {}, it should be {} for Conversation {}, corrected",
252 conversationTemplate.
FirstLineId, correctedFirstLineId, conversationTemplate.
Id);
253 conversationTemplate.
FirstLineId = correctedFirstLineId;
257 if (!currentConversationLine)
258 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_template` references an invalid line (ID: {}) for Conversation {}, skipped", conversationTemplate.
FirstLineId, conversationTemplate.
Id);
260 while (currentConversationLine !=
nullptr)
263 conversationTemplate.
Lines.push_back(conversationLineTemplate);
265 TC_LOG_ERROR(
"sql.sql",
"Table `conversation_line_template` has missing template for line (ID: {}) in Conversation {}, skipped", currentConversationLine->
ID, conversationTemplate.
Id);
267 uint32 nextConversationLineId = getNextConversationLineId(currentConversationLine);
268 if (!nextConversationLineId)
274 _conversationTemplateStore[conversationTemplate.
Id] = std::move(conversationTemplate);
276 while (templates->NextRow());
278 TC_LOG_INFO(
"server.loading",
">> Loaded {} Conversation templates in {} ms", _conversationTemplateStore.size(),
GetMSTimeDiffToNow(oldMSTime));
282 TC_LOG_INFO(
"server.loading",
">> Loaded 0 Conversation templates. DB table `conversation_template` is empty.");