mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Quests: Implemented new db table quest_objectives_completion_effect
* Turn off automatic phase updates on quest objective completion * Allow more convenient conversation and spell casts on quest objective completion
This commit is contained in:
13
sql/updates/world/master/2023_06_02_00_world.sql
Normal file
13
sql/updates/world/master/2023_06_02_00_world.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
--
|
||||
-- Table structure for table `quest_objectives_completion_effect`
|
||||
--
|
||||
DROP TABLE IF EXISTS `quest_objectives_completion_effect`;
|
||||
CREATE TABLE `quest_objectives_completion_effect` (
|
||||
`ObjectiveID` int NOT NULL,
|
||||
`GameEventID` int DEFAULT NULL,
|
||||
`SpellID` int DEFAULT NULL,
|
||||
`ConversationID` int DEFAULT NULL,
|
||||
`UpdatePhaseShift` tinyint(1) DEFAULT '0',
|
||||
`UpdateZoneAuras` tinyint(1) DEFAULT '0',
|
||||
PRIMARY KEY (`ObjectiveID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@@ -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
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user