Core/Quests: Fixed questgiver icons

Closes #25702
This commit is contained in:
Shauren
2020-12-11 22:19:19 +01:00
parent a50f671afd
commit 5f3a2d2abf
19 changed files with 217 additions and 56 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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,

View File

@@ -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) { }

View File

@@ -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

View File

@@ -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()

View File

@@ -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*/) { }

View File

@@ -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()

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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();

View File

@@ -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
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,
// Custom value meaning that script call did not return any valid quest status
DIALOG_STATUS_SCRIPTED_NO_STATUS = 0x1000
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; }

View File

@@ -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