aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2017_11_05_10_world.sql5
-rw-r--r--src/server/game/Entities/Conversation/Conversation.cpp43
-rw-r--r--src/server/game/Entities/Conversation/Conversation.h5
-rw-r--r--src/server/game/Globals/ConversationDataStore.cpp50
-rw-r--r--src/server/game/Globals/ConversationDataStore.h1
5 files changed, 84 insertions, 20 deletions
diff --git a/sql/updates/world/master/2017_11_05_10_world.sql b/sql/updates/world/master/2017_11_05_10_world.sql
new file mode 100644
index 00000000000..e22fb5d56cf
--- /dev/null
+++ b/sql/updates/world/master/2017_11_05_10_world.sql
@@ -0,0 +1,5 @@
+ALTER TABLE `conversation_actors`
+ CHANGE COLUMN `ConversationActorId` `ConversationActorId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ ADD COLUMN `ConversationActorGuid` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0' AFTER `ConversationActorId`,
+ DROP PRIMARY KEY,
+ ADD PRIMARY KEY (`ConversationId`, `Idx`);
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;
};