aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/hotfixes/master/2020_12_11_00_hotfixes.sql62
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp5
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h4
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.cpp4
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h3
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp4
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h3
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h17
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp2
-rw-r--r--src/server/game/DataStores/DB2Stores.h1
-rw-r--r--src/server/game/DataStores/DB2Structure.h9
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp5
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp70
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp2
-rw-r--r--src/server/game/Quests/QuestDef.cpp8
-rw-r--r--src/server/game/Quests/QuestDef.h67
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h4
19 files changed, 218 insertions, 57 deletions
diff --git a/sql/updates/hotfixes/master/2020_12_11_00_hotfixes.sql b/sql/updates/hotfixes/master/2020_12_11_00_hotfixes.sql
new file mode 100644
index 00000000000..8fb38de49d1
--- /dev/null
+++ b/sql/updates/hotfixes/master/2020_12_11_00_hotfixes.sql
@@ -0,0 +1,62 @@
+--
+-- Table structure for table `quest_info`
+--
+
+DROP TABLE IF EXISTS `quest_info`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `quest_info` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `InfoName` text,
+ `Type` tinyint(4) NOT NULL DEFAULT '0',
+ `Modifiers` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `Profession` smallint(5) unsigned NOT NULL DEFAULT '0',
+ `VerifiedBuild` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`,`VerifiedBuild`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `quest_info`
+--
+
+LOCK TABLES `quest_info` WRITE;
+/*!40000 ALTER TABLE `quest_info` DISABLE KEYS */;
+/*!40000 ALTER TABLE `quest_info` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `quest_info_locale`
+--
+
+DROP TABLE IF EXISTS `quest_info_locale`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `quest_info_locale` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `locale` varchar(4) NOT NULL,
+ `InfoName_lang` text,
+ `VerifiedBuild` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`,`locale`,`VerifiedBuild`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
+/*!50500 PARTITION BY LIST COLUMNS(locale)
+(PARTITION deDE VALUES IN ('deDE') ENGINE = InnoDB,
+ PARTITION esES VALUES IN ('esES') ENGINE = InnoDB,
+ PARTITION esMX VALUES IN ('esMX') ENGINE = InnoDB,
+ PARTITION frFR VALUES IN ('frFR') ENGINE = InnoDB,
+ PARTITION itIT VALUES IN ('itIT') ENGINE = InnoDB,
+ PARTITION koKR VALUES IN ('koKR') ENGINE = InnoDB,
+ PARTITION ptBR VALUES IN ('ptBR') ENGINE = InnoDB,
+ PARTITION ruRU VALUES IN ('ruRU') ENGINE = InnoDB,
+ PARTITION zhCN VALUES IN ('zhCN') ENGINE = InnoDB,
+ PARTITION zhTW VALUES IN ('zhTW') ENGINE = InnoDB) */;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `quest_info_locale`
+--
+
+LOCK TABLES `quest_info_locale` WRITE;
+/*!40000 ALTER TABLE `quest_info_locale` DISABLE KEYS */;
+/*!40000 ALTER TABLE `quest_info_locale` ENABLE KEYS */;
+UNLOCK TABLES;
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index 8f4930262cc..89cb1191e4c 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -1067,6 +1067,11 @@ void HotfixDatabaseConnection::DoPrepareStatements()
"Difficulty7, Difficulty8, Difficulty9, Difficulty10 FROM quest_faction_reward WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_QUEST_FACTION_REWARD, "SELECT MAX(ID) + 1 FROM quest_faction_reward", CONNECTION_SYNCH);
+ // QuestInfo.db2
+ PrepareStatement(HOTFIX_SEL_QUEST_INFO, "SELECT ID, InfoName, Type, Modifiers, Profession FROM quest_info WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
+ PREPARE_MAX_ID_STMT(HOTFIX_SEL_QUEST_INFO, "SELECT MAX(ID) + 1 FROM quest_info", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_QUEST_INFO, "SELECT ID, InfoName_lang FROM quest_info_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?", CONNECTION_SYNCH);
+
// QuestMoneyReward.db2
PrepareStatement(HOTFIX_SEL_QUEST_MONEY_REWARD, "SELECT ID, Difficulty1, Difficulty2, Difficulty3, Difficulty4, Difficulty5, Difficulty6, "
"Difficulty7, Difficulty8, Difficulty9, Difficulty10 FROM quest_money_reward WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index 37b6dc165c7..820b11720f5 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -615,6 +615,10 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_QUEST_FACTION_REWARD,
HOTFIX_SEL_QUEST_FACTION_REWARD_MAX_ID,
+ HOTFIX_SEL_QUEST_INFO,
+ HOTFIX_SEL_QUEST_INFO_MAX_ID,
+ HOTFIX_SEL_QUEST_INFO_LOCALE,
+
HOTFIX_SEL_QUEST_MONEY_REWARD,
HOTFIX_SEL_QUEST_MONEY_REWARD_MAX_ID,
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.cpp b/src/server/game/AI/CoreAI/GameObjectAI.cpp
index e9ac3f67e6b..f65be59edbc 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.cpp
+++ b/src/server/game/AI/CoreAI/GameObjectAI.cpp
@@ -31,9 +31,9 @@ void GameObjectAI::QuestReward(Player* player, Quest const* quest, uint32 opt)
QuestReward(player, quest, LootItemType::Item, opt);
}
-uint32 GameObjectAI::GetDialogStatus(Player* /*player*/)
+QuestGiverStatus GameObjectAI::GetDialogStatus(Player* /*player*/)
{
- return DIALOG_STATUS_SCRIPTED_NO_STATUS;
+ return QuestGiverStatus::ScriptedDefault;
}
NullGameObjectAI::NullGameObjectAI(GameObject* g) : GameObjectAI(g) { }
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index 3299e0d66d7..fa2c83fdb43 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -27,6 +27,7 @@ class Quest;
class SpellInfo;
class Unit;
enum class LootItemType : uint8;
+enum class QuestGiverStatus : uint32;
class TC_GAME_API GameObjectAI
{
@@ -66,7 +67,7 @@ class TC_GAME_API GameObjectAI
virtual void QuestReward(Player* /*player*/, Quest const* /*quest*/, LootItemType /*type*/, uint32 /*opt*/) { }
// Called when the dialog status between a player and the gameobject is requested.
- virtual uint32 GetDialogStatus(Player* player);
+ virtual QuestGiverStatus GetDialogStatus(Player* player);
// Called when a Player clicks a GameObject, before GossipHello
// prevents achievement tracking if returning true
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index a7204104e9f..318c7c29583 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -318,9 +318,9 @@ void UnitAI::QuestReward(Player* player, Quest const* quest, uint32 opt)
QuestReward(player, quest, LootItemType::Item, opt);
}
-uint32 UnitAI::GetDialogStatus(Player* /*player*/)
+QuestGiverStatus UnitAI::GetDialogStatus(Player* /*player*/)
{
- return DIALOG_STATUS_SCRIPTED_NO_STATUS;
+ return QuestGiverStatus::ScriptedDefault;
}
ThreatManager& UnitAI::GetThreatManager()
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 870b460f662..498fd736a41 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -45,6 +45,7 @@ enum DamageEffectType : uint8;
enum Difficulty : uint8;
enum SpellEffIndex : uint8;
enum class LootItemType : uint8;
+enum class QuestGiverStatus : uint32;
//Selection method used by SelectTarget
enum SelectAggroTarget
@@ -330,7 +331,7 @@ class TC_GAME_API UnitAI
virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) { }
// Called when the dialog status between a player and the creature is requested.
- virtual uint32 GetDialogStatus(Player* player);
+ virtual QuestGiverStatus GetDialogStatus(Player* player);
virtual void WaypointStarted(uint32 /*nodeId*/, uint32 /*pathId*/) { }
virtual void WaypointReached(uint32 /*nodeId*/, uint32 /*pathId*/) { }
diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h
index dde5b4fa2ba..d50b7548174 100644
--- a/src/server/game/DataStores/DB2LoadInfo.h
+++ b/src/server/game/DataStores/DB2LoadInfo.h
@@ -4133,6 +4133,23 @@ struct QuestFactionRewardLoadInfo
}
};
+struct QuestInfoLoadInfo
+{
+ static DB2LoadInfo const* Instance()
+ {
+ static DB2FieldMeta const fields[] =
+ {
+ { false, FT_INT, "ID" },
+ { false, FT_STRING, "InfoName" },
+ { true, FT_BYTE, "Type" },
+ { false, FT_BYTE, "Modifiers" },
+ { false, FT_SHORT, "Profession" },
+ };
+ static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, QuestInfoMeta::Instance(), HOTFIX_SEL_QUEST_INFO);
+ return &loadInfo;
+ }
+};
+
struct QuestMoneyRewardLoadInfo
{
static DB2LoadInfo const* Instance()
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 90ec65c3b30..70d54661a19 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -220,6 +220,7 @@ DB2Storage<PvpTalentEntry> sPvpTalentStore("PvpTalent.db2",
DB2Storage<PvpTalentCategoryEntry> sPvpTalentCategoryStore("PvpTalentCategory.db2", PvpTalentCategoryLoadInfo::Instance());
DB2Storage<PvpTalentSlotUnlockEntry> sPvpTalentSlotUnlockStore("PvpTalentSlotUnlock.db2", PvpTalentSlotUnlockLoadInfo::Instance());
DB2Storage<QuestFactionRewardEntry> sQuestFactionRewardStore("QuestFactionReward.db2", QuestFactionRewardLoadInfo::Instance());
+DB2Storage<QuestInfoEntry> sQuestInfoStore("QuestInfo.db2", QuestInfoLoadInfo::Instance());
DB2Storage<QuestMoneyRewardEntry> sQuestMoneyRewardStore("QuestMoneyReward.db2", QuestMoneyRewardLoadInfo::Instance());
DB2Storage<QuestPackageItemEntry> sQuestPackageItemStore("QuestPackageItem.db2", QuestPackageItemLoadInfo::Instance());
DB2Storage<QuestSortEntry> sQuestSortStore("QuestSort.db2", QuestSortLoadInfo::Instance());
@@ -745,6 +746,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sPvpTalentCategoryStore);
LOAD_DB2(sPvpTalentSlotUnlockStore);
LOAD_DB2(sQuestFactionRewardStore);
+ LOAD_DB2(sQuestInfoStore);
LOAD_DB2(sQuestMoneyRewardStore);
LOAD_DB2(sQuestPackageItemStore);
LOAD_DB2(sQuestSortStore);
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index b0dfb56f9cc..d20c58b9dd1 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -162,6 +162,7 @@ TC_GAME_API extern DB2Storage<PvpTalentEntry> sPvpTalentSt
TC_GAME_API extern DB2Storage<PvpTalentCategoryEntry> sPvpTalentCategoryStore;
TC_GAME_API extern DB2Storage<PvpTalentSlotUnlockEntry> sPvpTalentSlotUnlockStore;
TC_GAME_API extern DB2Storage<QuestFactionRewardEntry> sQuestFactionRewardStore;
+TC_GAME_API extern DB2Storage<QuestInfoEntry> sQuestInfoStore;
TC_GAME_API extern DB2Storage<QuestMoneyRewardEntry> sQuestMoneyRewardStore;
TC_GAME_API extern DB2Storage<QuestSortEntry> sQuestSortStore;
TC_GAME_API extern DB2Storage<QuestXPEntry> sQuestXPStore;
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 36f315edb80..8cb0995e121 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -2526,6 +2526,15 @@ struct QuestFactionRewardEntry
int16 Difficulty[10];
};
+struct QuestInfoEntry
+{
+ uint32 ID;
+ LocalizedString InfoName;
+ int8 Type;
+ uint8 Modifiers;
+ uint16 Profession;
+};
+
struct QuestMoneyRewardEntry
{
uint32 ID;
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 0fd96f36f82..12926a2dbc1 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -27,6 +27,7 @@
#include "QuestPackets.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include "Util.h"
#include "World.h"
#include "WorldSession.h"
@@ -387,14 +388,14 @@ void PlayerMenu::SendQuestGiverQuestListMessage(Object* questgiver)
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE NPC=%s", guid.ToString().c_str());
}
-void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const
+void PlayerMenu::SendQuestGiverStatus(QuestGiverStatus questStatus, ObjectGuid npcGUID) const
{
WorldPackets::Quest::QuestGiverStatus packet;
packet.QuestGiver.Guid = npcGUID;
packet.QuestGiver.Status = questStatus;
_session->SendPacket(packet.Write());
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC=%s, status=%u", npcGUID.ToString().c_str(), questStatus);
+ TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC=%s, status=%u", npcGUID.ToString().c_str(), AsUnderlyingType(questStatus));
}
void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup) const
diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h
index cd4ec97ae76..96209804af7 100644
--- a/src/server/game/Entities/Creature/GossipDef.h
+++ b/src/server/game/Entities/Creature/GossipDef.h
@@ -26,6 +26,7 @@
class Object;
class Quest;
class WorldSession;
+enum class QuestGiverStatus : uint32;
#define GOSSIP_MAX_MENU_ITEMS 32
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
@@ -288,7 +289,7 @@ class TC_GAME_API PlayerMenu
/*********************************************************/
/*** QUEST SYSTEM ***/
/*********************************************************/
- void SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const;
+ void SendQuestGiverStatus(QuestGiverStatus questStatus, ObjectGuid npcGUID) const;
void SendQuestGiverQuestListMessage(Object* questgiver);
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 9247c0eb731..4f2a19a2d72 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1333,7 +1333,7 @@ bool GameObject::ActivateToQuest(Player const* target) const
{
GameObject* go = const_cast<GameObject*>(this);
QuestGiverStatus questStatus = const_cast<Player*>(target)->GetQuestDialogStatus(go);
- if (questStatus > DIALOG_STATUS_UNAVAILABLE)
+ if (questStatus != QuestGiverStatus::None && questStatus != QuestGiverStatus::Future)
return true;
break;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 2fd5fefc983..860933b7c39 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -16575,8 +16575,8 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
{
case TYPEID_GAMEOBJECT:
{
- QuestGiverStatus questStatus = QuestGiverStatus(questgiver->ToGameObject()->AI()->GetDialogStatus(this));
- if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS)
+ QuestGiverStatus questStatus = questgiver->ToGameObject()->AI()->GetDialogStatus(this);
+ if (questStatus != QuestGiverStatus::ScriptedDefault)
return questStatus;
qr = sObjectMgr->GetGOQuestRelationBounds(questgiver->GetEntry());
qir = sObjectMgr->GetGOQuestInvolvedRelationBounds(questgiver->GetEntry());
@@ -16584,8 +16584,8 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
}
case TYPEID_UNIT:
{
- QuestGiverStatus questStatus = QuestGiverStatus(questgiver->ToCreature()->AI()->GetDialogStatus(this));
- if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS)
+ QuestGiverStatus questStatus = questgiver->ToCreature()->AI()->GetDialogStatus(this);
+ if (questStatus != QuestGiverStatus::ScriptedDefault)
return questStatus;
qr = sObjectMgr->GetCreatureQuestRelationBounds(questgiver->GetEntry());
qir = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(questgiver->GetEntry());
@@ -16595,35 +16595,49 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
// it's impossible, but check
TC_LOG_ERROR("entities.player.quest", "Player::GetQuestDialogStatus: Called with unexpected type (Entry: %u, Type: %u) by player '%s' (%s)",
questgiver->GetEntry(), questgiver->GetTypeId(), GetName().c_str(), GetGUID().ToString().c_str());
- return DIALOG_STATUS_NONE;
+ return QuestGiverStatus::None;
}
- QuestGiverStatus result = DIALOG_STATUS_NONE;
+ QuestGiverStatus result = QuestGiverStatus::None;
for (QuestRelations::const_iterator i = qir.first; i != qir.second; ++i)
{
- QuestGiverStatus result2 = DIALOG_STATUS_NONE;
uint32 questId = i->second;
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
if (!quest)
continue;
- QuestStatus status = GetQuestStatus(questId);
- if (status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(questId))
- result2 = DIALOG_STATUS_REWARD;
- else if (status == QUEST_STATUS_INCOMPLETE)
- result2 = DIALOG_STATUS_INCOMPLETE;
+ switch (GetQuestStatus(questId))
+ {
+ case QUEST_STATUS_COMPLETE:
+ if (quest->GetQuestTag() == QuestTagType::CovenantCalling)
+ result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::CovenantCallingRewardCompleteNoPOI : QuestGiverStatus::CovenantCallingRewardCompletePOI;
+ else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY_QUEST))
+ result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::LegendaryRewardCompleteNoPOI : QuestGiverStatus::LegendaryRewardCompletePOI;
+ else
+ result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::RewardCompleteNoPOI : QuestGiverStatus::RewardCompletePOI;
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ if (quest->GetQuestTag() == QuestTagType::CovenantCalling)
+ result |= QuestGiverStatus::CovenantCallingReward;
+ else
+ result |= QuestGiverStatus::Reward;
+ break;
+ default:
+ break;
+ }
if (quest->IsAutoComplete() && CanTakeQuest(quest, false) && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
- result2 = DIALOG_STATUS_REWARD_REP;
-
- if (result2 > result)
- result = result2;
+ {
+ if (getLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
+ result |= QuestGiverStatus::RepeatableTurnin;
+ else
+ result |= QuestGiverStatus::TrivialRepeatableTurnin;
+ }
}
for (QuestRelations::const_iterator i = qr.first; i != qr.second; ++i)
{
- QuestGiverStatus result2 = DIALOG_STATUS_NONE;
uint32 questId = i->second;
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
if (!quest)
@@ -16632,8 +16646,7 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_QUEST_AVAILABLE, quest->GetQuestId(), this))
continue;
- QuestStatus status = GetQuestStatus(questId);
- if (status == QUEST_STATUS_NONE)
+ if (GetQuestStatus(questId) == QUEST_STATUS_NONE)
{
if (CanSeeStartQuest(quest))
{
@@ -16641,21 +16654,24 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
{
if (getLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
{
- if (quest->IsDaily())
- result2 = DIALOG_STATUS_AVAILABLE_REP;
+ if (quest->GetQuestTag() == QuestTagType::CovenantCalling)
+ result |= QuestGiverStatus::CovenantCallingQuest;
+ else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY_QUEST))
+ result |= QuestGiverStatus::LegendaryQuest;
+ else if (quest->IsDaily())
+ result |= QuestGiverStatus::DailyQuest;
else
- result2 = DIALOG_STATUS_AVAILABLE;
+ result |= QuestGiverStatus::Quest;
}
+ else if (quest->IsDaily())
+ result |= QuestGiverStatus::TrivialDailyQuest;
else
- result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
+ result |= QuestGiverStatus::Trivial;
}
else
- result2 = DIALOG_STATUS_UNAVAILABLE;
+ result |= QuestGiverStatus::Future;
}
}
-
- if (result2 > result)
- result = result2;
}
return result;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index c26aa694795..417abf4cb98 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -39,7 +39,7 @@
void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet)
{
- uint32 questStatus = DIALOG_STATUS_NONE;
+ QuestGiverStatus questStatus = QuestGiverStatus::None;
Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
if (!questGiver)
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index a1d8520c8dd..5caea515380 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -314,6 +314,14 @@ uint32 Quest::MoneyValue(Player const* player) const
return 0;
}
+Optional<QuestTagType> Quest::GetQuestTag() const
+{
+ if (QuestInfoEntry const* questInfo = sQuestInfoStore.LookupEntry(GetQuestInfoID()))
+ return static_cast<QuestTagType>(questInfo->Type);
+
+ return {};
+}
+
void Quest::BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const
{
rewards.ChoiceItemCount = GetRewChoiceItemsCount();
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 1a2e5fe6c50..f08513881a7 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -21,6 +21,7 @@
#include "Common.h"
#include "DBCEnums.h"
#include "DatabaseEnvFwd.h"
+#include "Optional.h"
#include "RaceMask.h"
#include "SharedDefines.h"
#include "WorldPacket.h"
@@ -115,25 +116,36 @@ enum QuestStatus : uint8
MAX_QUEST_STATUS
};
-enum QuestGiverStatus
+enum class QuestGiverStatus : uint32
{
- DIALOG_STATUS_NONE = 0x000,
- DIALOG_STATUS_UNK = 0x001,
- DIALOG_STATUS_UNAVAILABLE = 0x002,
- DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 0x004,
- DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 0x008,
- DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 0x010,
- DIALOG_STATUS_INCOMPLETE = 0x020,
- DIALOG_STATUS_REWARD_REP = 0x040,
- DIALOG_STATUS_AVAILABLE_REP = 0x080,
- DIALOG_STATUS_AVAILABLE = 0x100,
- DIALOG_STATUS_REWARD2 = 0x200, // no yellow dot on minimap
- DIALOG_STATUS_REWARD = 0x400, // yellow dot on minimap
-
- // Custom value meaning that script call did not return any valid quest status
- DIALOG_STATUS_SCRIPTED_NO_STATUS = 0x1000
+ None = 0x000000,
+ Future = 0x000002,
+ Trivial = 0x000004,
+ TrivialRepeatableTurnin = 0x000008,
+ TrivialDailyQuest = 0x000010,
+ Reward = 0x000020,
+ JourneyReward = 0x000040,
+ CovenantCallingReward = 0x000080,
+ RepeatableTurnin = 0x000100,
+ DailyQuest = 0x000200,
+ Quest = 0x000400,
+ RewardCompleteNoPOI = 0x000800,
+ RewardCompletePOI = 0x001000,
+ LegendaryQuest = 0x002000,
+ LegendaryRewardCompleteNoPOI = 0x004000,
+ LegendaryRewardCompletePOI = 0x008000,
+ JourneyQuest = 0x010000,
+ JourneyRewardCompleteNoPOI = 0x020000,
+ JourneyRewardCompletePOI = 0x040000,
+ CovenantCallingQuest = 0x080000,
+ CovenantCallingRewardCompleteNoPOI = 0x100000,
+ CovenantCallingRewardCompletePOI = 0x200000,
+
+ ScriptedDefault = 0x80000000
};
+DEFINE_ENUM_FLAG(QuestGiverStatus)
+
enum QuestFlags : uint32
{
QUEST_FLAGS_NONE = 0x00000000,
@@ -251,6 +263,26 @@ enum QuestSpecialFlags
QUEST_SPECIAL_FLAGS_COMPLETED_AT_START = 0x1000 // Internal flag computed only
};
+enum class QuestTagType
+{
+ Tag,
+ Profession,
+ Normal,
+ Pvp,
+ PetBattle,
+ Bounty,
+ Dungeon,
+ Invasion,
+ Raid,
+ Contribution,
+ RatedRreward,
+ InvasionWrapper,
+ FactionAssault,
+ Islands,
+ Threat,
+ CovenantCalling
+};
+
enum QuestObjectiveType
{
QUEST_OBJECTIVE_MONSTER = 0,
@@ -362,7 +394,7 @@ struct QuestObjective
}
};
-typedef std::vector<QuestObjective> QuestObjectives;
+using QuestObjectives = std::vector<QuestObjective>;
struct QuestRewardDisplaySpell
{
@@ -396,6 +428,7 @@ class TC_GAME_API Quest
uint32 XPValue(Player const* player) const;
uint32 MoneyValue(Player const* player) const;
+ Optional<QuestTagType> GetQuestTag() const;
bool HasFlag(QuestFlags flag) const { return (_flags & uint32(flag)) != 0; }
bool HasFlagEx(QuestFlagsEx flag) const { return (_flagsEx & uint32(flag)) != 0; }
diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h
index 8c738fdcebe..84a4f7f3b79 100644
--- a/src/server/game/Server/Packets/QuestPackets.h
+++ b/src/server/game/Server/Packets/QuestPackets.h
@@ -53,11 +53,11 @@ namespace WorldPackets
struct QuestGiverInfo
{
QuestGiverInfo() { }
- QuestGiverInfo(ObjectGuid const& guid, uint32 status)
+ QuestGiverInfo(ObjectGuid const& guid, ::QuestGiverStatus status)
: Guid(guid), Status(status) { }
ObjectGuid Guid;
- uint32 Status = DIALOG_STATUS_NONE;
+ ::QuestGiverStatus Status = ::QuestGiverStatus::None;
};
class QuestGiverStatus final : public ServerPacket