aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Entities/Player/Player.cpp26
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp6
-rw-r--r--src/server/game/Quests/QuestDef.cpp25
-rw-r--r--src/server/game/Quests/QuestDef.h11
4 files changed, 63 insertions, 5 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 6d28af5cd21..cb269842145 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -55,6 +55,7 @@
#include "EquipmentSetPackets.h"
#include "Formulas.h"
#include "GameEventMgr.h"
+#include "GameEventSender.h"
#include "GameObjectAI.h"
#include "Garrison.h"
#include "GarrisonMgr.h"
@@ -16544,6 +16545,8 @@ void Player::CurrencyChanged(uint32 currencyId, int32 change)
void Player::UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int32 objectId, int64 addCount, ObjectGuid victimGuid)
{
bool anyObjectiveChangedCompletionState = false;
+ bool updatePhaseShift = false;
+ bool updateZoneAuras = false;
for (QuestObjectiveStatusMap::value_type const& objectiveItr : Trinity::Containers::MapEqualRange(m_questObjectiveStatus, { objectiveType, objectId }))
{
@@ -16648,6 +16651,20 @@ void Player::UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int3
if (objectiveWasComplete != objectiveIsNowComplete)
anyObjectiveChangedCompletionState = true;
+ if (objectiveIsNowComplete && objective.CompletionEffect)
+ {
+ if (objective.CompletionEffect->GameEventId)
+ GameEvents::Trigger(*objective.CompletionEffect->GameEventId, this, nullptr);
+ if (objective.CompletionEffect->SpellId)
+ CastSpell(this, *objective.CompletionEffect->SpellId, true);
+ if (objective.CompletionEffect->ConversationId)
+ Conversation::CreateConversation(*objective.CompletionEffect->ConversationId, this, GetPosition(), GetGUID());
+ if (objective.CompletionEffect->UpdatePhaseShift)
+ updatePhaseShift = true;
+ if (objective.CompletionEffect->UpdateZoneAuras)
+ updateZoneAuras = true;
+ }
+
if (objectiveIsNowComplete && CanCompleteQuest(questId, objective.ID))
CompleteQuest(questId);
else if (objectiveItr.second.QuestStatusItr->second.Status == QUEST_STATUS_COMPLETE)
@@ -16658,7 +16675,14 @@ void Player::UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int3
if (anyObjectiveChangedCompletionState)
UpdateVisibleGameobjectsOrSpellClicks();
- PhasingHandler::OnConditionChange(this);
+ if (updatePhaseShift)
+ PhasingHandler::OnConditionChange(this);
+
+ if (updateZoneAuras)
+ {
+ UpdateZoneDependentAuras(GetZoneId());
+ UpdateAreaDependentAuras(GetAreaId());
+ }
}
bool Player::HasQuestForItem(uint32 itemid) const
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 60ab1dfa41b..94f0b5cd966 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4554,8 +4554,10 @@ void ObjectMgr::LoadQuests()
// 0 1
{ "QuestId, RewardMailSenderEntry", "quest_mail_sender", "", "mail sender entries", &Quest::LoadQuestMailSender },
- // 0 1 2 3 4 5 6 7 8 9
- { "QuestID, ID, Type, StorageIndex, ObjectID, Amount, Flags, Flags2, ProgressBarWeight, Description", "quest_objectives", "ORDER BY `Order` ASC, StorageIndex ASC", "quest objectives", &Quest::LoadQuestObjective },
+ // 0 1 2 3 4 5 6 7 8 9
+ { "qo.QuestID, qo.ID, qo.Type, qo.StorageIndex, qo.ObjectID, qo.Amount, qo.Flags, qo.Flags2, qo.ProgressBarWeight, qo.Description, "
+ // 10 11 12 13 14
+ "qoce.GameEventID, qoce.SpellID, qoce.ConversationID, qoce.UpdatePhaseShift, qoce.UpdateZoneAuras", "quest_objectives qo", "LEFT JOIN quest_objectives_completion_effect qoce ON qo.ID = qoce.ObjectiveID ORDER BY `Order` ASC, StorageIndex ASC", "quest objectives", &Quest::LoadQuestObjective },
// 0 1 2 3 4
{ "QuestId, PlayerConditionId, QuestgiverCreatureId, Text, locale", "quest_description_conditional", "ORDER BY OrderIndex", "conditional details", &Quest::LoadConditionalConditionalQuestDescription },
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index b4e18f2ed97..e3d39cef7a9 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -131,6 +131,12 @@ Quest::Quest(Field* questRecord)
_questCompletionLog = questRecord[115].GetString();
}
+Quest::~Quest()
+{
+ for (QuestObjective& objective : Objectives)
+ delete objective.CompletionEffect;
+}
+
void Quest::LoadRewardDisplaySpell(Field* fields)
{
uint32 spellId = fields[1].GetUInt32();
@@ -248,7 +254,7 @@ void Quest::LoadQuestMailSender(Field* fields)
void Quest::LoadQuestObjective(Field* fields)
{
- QuestObjective obj;
+ QuestObjective& obj = Objectives.emplace_back();
obj.QuestID = fields[0].GetUInt32();
obj.ID = fields[1].GetUInt32();
obj.Type = fields[2].GetUInt8();
@@ -260,7 +266,22 @@ void Quest::LoadQuestObjective(Field* fields)
obj.ProgressBarWeight = fields[8].GetFloat();
obj.Description = fields[9].GetString();
- Objectives.push_back(obj);
+ bool hasCompletionEffect = std::any_of(fields + 10, fields + 15, [](Field const& f) { return !f.IsNull(); });
+ if (hasCompletionEffect)
+ {
+ obj.CompletionEffect = new QuestObjectiveAction();
+ if (!fields[10].IsNull())
+ obj.CompletionEffect->GameEventId = fields[10].GetUInt32();
+ if (!fields[11].IsNull())
+ obj.CompletionEffect->SpellId = fields[11].GetUInt32();
+ if (!fields[12].IsNull())
+ obj.CompletionEffect->ConversationId = fields[12].GetUInt32();
+ if (!fields[13].IsNull())
+ obj.CompletionEffect->UpdatePhaseShift = fields[13].GetBool();
+ if (!fields[14].IsNull())
+ obj.CompletionEffect->UpdateZoneAuras = fields[14].GetBool();
+ }
+
_usedQuestObjectiveTypes[obj.Type] = true;
}
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 3660d2da57f..016ec2dc958 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -403,6 +403,15 @@ struct QuestOfferRewardLocale
std::vector<std::string> RewardText;
};
+struct QuestObjectiveAction
+{
+ Optional<uint32> GameEventId;
+ Optional<uint32> SpellId;
+ Optional<uint32> ConversationId;
+ bool UpdatePhaseShift = false;
+ bool UpdateZoneAuras = false;
+};
+
struct QuestObjective
{
uint32 ID = 0;
@@ -416,6 +425,7 @@ struct QuestObjective
float ProgressBarWeight = 0.0f;
std::string Description;
std::vector<int32> VisualEffects;
+ QuestObjectiveAction* CompletionEffect = nullptr;
bool IsStoringValue() const
{
@@ -504,6 +514,7 @@ class TC_GAME_API Quest
public:
// Loading data. All queries are in ObjectMgr::LoadQuests()
explicit Quest(Field* questRecord);
+ ~Quest();
void LoadRewardDisplaySpell(Field* fields);
void LoadRewardChoiceItems(Field* fields);
void LoadQuestDetails(Field* fields);