diff options
author | funjoker <torti-esser@web.de> | 2017-11-05 18:23:27 +0100 |
---|---|---|
committer | joschiwald <joschiwald.trinity@gmail.com> | 2017-11-05 18:23:27 +0100 |
commit | 6b1f8f3358a3ba32ea02ab4771e8f2fa3962b982 (patch) | |
tree | 09fc9c45b976f5c2e867144b67f6a85941143963 /src | |
parent | 5f3434387eb5ff98ca9abbf9e5a309f0641e8e77 (diff) |
Core/Entities: Added DB-support for conversation actorGuids (#20757)
Diffstat (limited to 'src')
4 files changed, 79 insertions, 20 deletions
diff --git a/src/server/game/Entities/Conversation/Conversation.cpp b/src/server/game/Entities/Conversation/Conversation.cpp index 1941989bed3..9d985683d0b 100644 --- a/src/server/game/Entities/Conversation/Conversation.cpp +++ b/src/server/game/Entities/Conversation/Conversation.cpp @@ -16,6 +16,9 @@ */ #include "Conversation.h" +#include "Creature.h" +#include "IteratorPair.h" +#include "Log.h" #include "Map.h" #include "Unit.h" #include "UpdateData.h" @@ -120,23 +123,47 @@ bool Conversation::Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, SetUInt32Value(CONVERSATION_LAST_LINE_END_TIME, conversationTemplate->LastLineEndTime); _duration = conversationTemplate->LastLineEndTime; - uint16 actorsIndex = 0; - for (ConversationActorTemplate const* actor : conversationTemplate->Actors) + for (uint16 actorIndex = 0; actorIndex < conversationTemplate->Actors.size(); ++actorIndex) { - if (actor) + if (ConversationActorTemplate const* actor = conversationTemplate->Actors[actorIndex]) { ConversationDynamicFieldActor actorField; actorField.ActorTemplate = *actor; actorField.Type = ConversationDynamicFieldActor::ActorType::CreatureActor; - SetDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_ACTORS, actorsIndex++, &actorField); + SetDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_ACTORS, actorIndex, &actorField); } - else - ++actorsIndex; } - uint16 linesIndex = 0; + for (uint16 actorIndex = 0; actorIndex < conversationTemplate->ActorGuids.size(); ++actorIndex) + { + ObjectGuid::LowType const& actorGuid = conversationTemplate->ActorGuids[actorIndex]; + if (!actorGuid) + continue; + + for (auto const& pair : Trinity::Containers::MapEqualRange(map->GetCreatureBySpawnIdStore(), actorGuid)) + { + // we just need the last one, overriding is legit + AddActor(pair.second->GetGUID(), actorIndex); + } + } + + std::set<uint16> actorIndices; for (ConversationLineTemplate const* line : conversationTemplate->Lines) - SetDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_LINES, linesIndex++, line); + { + actorIndices.insert(line->ActorIdx); + AddDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_LINES, line); + } + + // All actors need to be set + for (uint16 actorIndex : actorIndices) + { + ConversationDynamicFieldActor const* actor = GetDynamicStructuredValue<ConversationDynamicFieldActor>(CONVERSATION_DYNAMIC_FIELD_ACTORS, actorIndex); + if (!actor || actor->IsEmpty()) + { + TC_LOG_ERROR("entities.conversation", "Failed to create conversation (Id: %u) due to missing actor (Idx: %u).", conversationEntry, actorIndex); + return false; + } + } if (!GetMap()->AddToMap(this)) return false; diff --git a/src/server/game/Entities/Conversation/Conversation.h b/src/server/game/Entities/Conversation/Conversation.h index e637ad942fa..780252a260a 100644 --- a/src/server/game/Entities/Conversation/Conversation.h +++ b/src/server/game/Entities/Conversation/Conversation.h @@ -33,6 +33,11 @@ struct ConversationDynamicFieldActor memset(Raw.Data, 0, sizeof(Raw.Data)); } + bool IsEmpty() const + { + return ActorGuid.IsEmpty(); // this one is good enough + } + enum ActorType { WorldObjectActor = 0, diff --git a/src/server/game/Globals/ConversationDataStore.cpp b/src/server/game/Globals/ConversationDataStore.cpp index f977a77c845..8b180d6fd60 100644 --- a/src/server/game/Globals/ConversationDataStore.cpp +++ b/src/server/game/Globals/ConversationDataStore.cpp @@ -20,6 +20,7 @@ #include "DatabaseEnv.h" #include "DB2Stores.h" #include "Log.h" +#include "ObjectMgr.h" #include "Timer.h" namespace @@ -36,6 +37,7 @@ void ConversationDataStore::LoadConversationTemplates() _conversationTemplateStore.clear(); std::unordered_map<uint32, std::vector<ConversationActorTemplate const*>> actorsByConversation; + std::unordered_map<uint32, std::vector<ObjectGuid::LowType>> actorGuidsByConversation; if (QueryResult actorTemplates = WorldDatabase.Query("SELECT Id, CreatureId, CreatureModelId FROM conversation_actor_template")) { @@ -92,7 +94,7 @@ void ConversationDataStore::LoadConversationTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 Conversation line templates. DB table `conversation_line_template` is empty."); } - if (QueryResult actors = WorldDatabase.Query("SELECT ConversationId, ConversationActorId, Idx FROM conversation_actors")) + if (QueryResult actors = WorldDatabase.Query("SELECT ConversationId, ConversationActorId, ConversationActorGuid, Idx FROM conversation_actors")) { uint32 oldMSTime = getMSTime(); uint32 count = 0; @@ -101,20 +103,43 @@ void ConversationDataStore::LoadConversationTemplates() { Field* fields = actors->Fetch(); - uint32 conversationId = fields[0].GetUInt32(); - uint32 actorId = fields[1].GetUInt32(); - uint16 idx = fields[2].GetUInt16(); + uint32 conversationId = fields[0].GetUInt32(); + uint32 actorId = fields[1].GetUInt32(); + ObjectGuid::LowType actorGuid = fields[2].GetUInt64(); + uint16 idx = fields[3].GetUInt16(); - if (ConversationActorTemplate const* conversationActorTemplate = Trinity::Containers::MapGetValuePtr(_conversationActorTemplateStore, actorId)) + if (actorId != 0 && actorGuid != 0) { - std::vector<ConversationActorTemplate const*>& actors = actorsByConversation[conversationId]; - if (actors.size() <= idx) - actors.resize(idx + 1); - actors[idx] = conversationActorTemplate; - ++count; + TC_LOG_ERROR("sql.sql", "Table `conversation_actors` references both actor (ID: %u) and actorGuid (GUID: " UI64FMTD ") for Conversation %u, skipped.", actorId, actorGuid, conversationId); + continue; + } + + if (actorId != 0) + { + if (ConversationActorTemplate const* conversationActorTemplate = Trinity::Containers::MapGetValuePtr(_conversationActorTemplateStore, actorId)) + { + std::vector<ConversationActorTemplate const*>& actors = actorsByConversation[conversationId]; + if (actors.size() <= idx) + actors.resize(idx + 1); + actors[idx] = conversationActorTemplate; + ++count; + } + else + TC_LOG_ERROR("sql.sql", "Table `conversation_actors` references an invalid actor (ID: %u) for Conversation %u, skipped", actorId, conversationId); + } + else if (actorGuid != 0) + { + if (CreatureData const* creData = sObjectMgr->GetCreatureData(actorGuid)) + { + std::vector<ObjectGuid::LowType>& guids = actorGuidsByConversation[conversationId]; + if (guids.size() <= idx) + guids.resize(idx + 1); + guids[idx] = actorGuid; + ++count; + } + else + TC_LOG_ERROR("sql.sql", "Table `conversation_actors` references an invalid creature guid (GUID: " UI64FMTD ") for Conversation %u, skipped", actorGuid, conversationId); } - else - TC_LOG_ERROR("sql.sql", "Table `conversation_actors` references an invalid actor (ID: %u) for Conversation %u, skipped", actorId, conversationId); } while (actors->NextRow()); @@ -139,6 +164,7 @@ void ConversationDataStore::LoadConversationTemplates() conversationTemplate.LastLineEndTime = fields[2].GetUInt32(); conversationTemplate.Actors = std::move(actorsByConversation[conversationTemplate.Id]); + conversationTemplate.ActorGuids = std::move(actorGuidsByConversation[conversationTemplate.Id]); ConversationLineEntry const* currentConversationLine = sConversationLineStore.LookupEntry(conversationTemplate.FirstLineId); if (!currentConversationLine) diff --git a/src/server/game/Globals/ConversationDataStore.h b/src/server/game/Globals/ConversationDataStore.h index 5e7f1a21db8..91e6c0ff61e 100644 --- a/src/server/game/Globals/ConversationDataStore.h +++ b/src/server/game/Globals/ConversationDataStore.h @@ -47,6 +47,7 @@ struct ConversationTemplate uint32 LastLineEndTime; // Time in ms after conversation creation the last line fades out std::vector<ConversationActorTemplate const*> Actors; + std::vector<ObjectGuid::LowType> ActorGuids; std::vector<ConversationLineTemplate const*> Lines; }; |