aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-06-10 20:31:33 +0200
committerShauren <shauren.trinity@gmail.com>2023-06-10 20:31:33 +0200
commit4d4c7e68935df9ca40bd5539d602ac4e779f53d5 (patch)
treecba70a6e20bb52a33815204d40d929220ac4ab0c /src/server/game/Entities
parent39bebe6a653bdd65160aa7f9fef6501d43884079 (diff)
Core/Quests: Quest flag fixups
* Update flag names * Implemented QUEST_FLAGS_COMPLETION_NO_DEATH and QUEST_FLAGS_FAIL_ON_LOGOUT * Started using QUEST_FLAGS_COMPLETION_EVENT and QUEST_FLAGS_COMPLETION_AREA_TRIGGER instead of a custom SpeclalFlag * Renamed Quest::IsAutoComplete to Quest::IsTurnIn to better describe what it means (a quest that can be turned in without accepting it to quest log) * Implemented QUEST_FLAGS_UPDATE_PHASESHIFT and removed forced phaseshift updates on every quest status change * Implemented QUEST_FLAGS_LAUNCH_GOSSIP_ACCEPT - reopens gossip menu with questgiver
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp141
-rw-r--r--src/server/game/Entities/Player/Player.h3
3 files changed, 86 insertions, 62 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 574d016eb06..632fb3f366a 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -283,7 +283,7 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
text.QuestType = item.QuestIcon;
text.QuestFlags[0] = quest->GetFlags();
text.QuestFlags[1] = quest->GetFlagsEx();
- text.Repeatable = quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
+ text.Repeatable = quest->IsTurnIn() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
text.QuestTitle = quest->GetLogTitle();
LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex();
@@ -410,7 +410,7 @@ void PlayerMenu::SendQuestGiverQuestListMessage(Object* questgiver)
text.QuestType = questMenuItem.QuestIcon;
text.QuestFlags[0] = quest->GetFlags();
text.QuestFlags[1] = quest->GetFlagsEx();
- text.Repeatable = quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
+ text.Repeatable = quest->IsTurnIn() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
text.QuestTitle = quest->GetLogTitle();
LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex();
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 67fcd09e365..d24aae288ed 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1264,6 +1264,8 @@ void Player::setDeathState(DeathState s)
InitializeSelfResurrectionSpells();
+ FailQuestsWithFlag(QUEST_FLAGS_COMPLETION_NO_DEATH);
+
UpdateCriteria(CriteriaType::DieOnMap, 1);
UpdateCriteria(CriteriaType::DieAnywhere, 1);
UpdateCriteria(CriteriaType::DieInInstance, 1);
@@ -14419,9 +14421,9 @@ void Player::PrepareQuestMenu(ObjectGuid guid)
if (!CanTakeQuest(quest, false))
continue;
- if (quest->IsAutoComplete() && (!quest->IsRepeatable() || quest->IsDaily() || quest->IsWeekly() || quest->IsMonthly()))
+ if (quest->IsTurnIn() && (!quest->IsRepeatable() || quest->IsDaily() || quest->IsWeekly() || quest->IsMonthly()))
qm.AddMenuItem(quest_id, 0);
- else if (quest->IsAutoComplete())
+ else if (quest->IsTurnIn())
qm.AddMenuItem(quest_id, 4);
else if (GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
qm.AddMenuItem(quest_id, 2);
@@ -14454,9 +14456,9 @@ void Player::SendPreparedQuest(WorldObject* source)
if (quest->IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true))
AddQuestAndCheckCompletion(quest, source);
- if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
+ if (quest->IsTurnIn() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
PlayerTalkClass->SendQuestGiverRequestItems(quest, source->GetGUID(), CanCompleteRepeatableQuest(quest), true);
- else if (quest->IsAutoComplete() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
+ else if (quest->IsTurnIn() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
PlayerTalkClass->SendQuestGiverRequestItems(quest, source->GetGUID(), CanRewardQuest(quest, false), true);
else
PlayerTalkClass->SendQuestGiverQuestDetails(quest, source->GetGUID(), true, false);
@@ -14482,7 +14484,9 @@ Quest const* Player::GetNextQuest(Object const* questGiver, Quest const* quest)
if (questGiver == this)
{
- ASSERT(quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE));
+ if (!quest->HasFlag(QUEST_FLAGS_AUTO_COMPLETE))
+ return nullptr;
+
return sObjectMgr->GetQuestTemplate(nextQuestID);
}
@@ -14560,7 +14564,7 @@ bool Player::CanCompleteQuest(uint32 quest_id, uint32 ignoredQuestObjectiveId /*
return false; // not allow re-complete quest
// auto complete quest
- if (qInfo->IsAutoComplete() && CanTakeQuest(qInfo, false))
+ if (qInfo->IsTurnIn() && CanTakeQuest(qInfo, false))
return true;
QuestStatusMap::iterator itr = m_QuestStatus.find(quest_id);
@@ -14583,7 +14587,7 @@ bool Player::CanCompleteQuest(uint32 quest_id, uint32 ignoredQuestObjectiveId /*
}
}
- if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT) && !q_status.Explored)
+ if ((qInfo->HasFlag(QUEST_FLAGS_COMPLETION_EVENT) || qInfo->HasFlag(QUEST_FLAGS_COMPLETION_AREA_TRIGGER)) && !q_status.Explored)
return false;
if (qInfo->GetLimitTime() && q_status.Timer == 0)
@@ -14621,7 +14625,7 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg) const
return false;
// not auto complete quest and not completed quest (only cheating case, then ignore without message)
- if (!quest->IsDFQuest() && !quest->IsAutoComplete() && GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_COMPLETE)
+ if (!quest->IsDFQuest() && !quest->IsTurnIn() && GetQuestStatus(quest->GetQuestId()) != QUEST_STATUS_COMPLETE)
return false;
// daily quest can't be rewarded (25 daily quest already completed)
@@ -14893,7 +14897,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetSrcSpell(), GetMap()->GetDifficultyID());
Unit* caster = this;
- if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_ACCEPT) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER) && !spellInfo->HasTargetType(TARGET_DEST_CASTER_SUMMON))
+ if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ACCEPT) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER) && !spellInfo->HasTargetType(TARGET_DEST_CASTER_SUMMON))
if (Unit* unit = questGiver->ToUnit())
caster = unit;
@@ -14936,7 +14940,7 @@ void Player::CompleteQuest(uint32 quest_id)
SetQuestSlotState(questStatus->Slot, QUEST_STATE_COMPLETE);
if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id))
- if (qInfo->HasFlag(QUEST_FLAGS_TRACKING))
+ if (qInfo->HasFlag(QUEST_FLAGS_TRACKING_EVENT))
RewardQuest(qInfo, LootItemType::Item, 0, this, false);
}
@@ -15069,23 +15073,29 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
switch (obj.Type)
{
case QUEST_OBJECTIVE_ITEM:
- if (!(quest->GetFlagsEx() & QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS))
- DestroyItemCount(obj.ObjectID, obj.Amount, true);
+ {
+ int32 amountToDestroy = obj.Amount;
+ if (quest->HasFlag(QUEST_FLAGS_REMOVE_SURPLUS_ITEMS))
+ amountToDestroy = std::numeric_limits<uint32>::max();
+ DestroyItemCount(obj.ObjectID, amountToDestroy, true);
break;
+ }
case QUEST_OBJECTIVE_CURRENCY:
RemoveCurrency(obj.ObjectID, obj.Amount, CurrencyDestroyReason::QuestTurnin);
break;
}
}
- if (!(quest->GetFlagsEx() & QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS))
+ if (!quest->HasFlagEx(QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS))
{
for (uint8 i = 0; i < QUEST_ITEM_DROP_COUNT; ++i)
{
if (quest->ItemDrop[i])
{
uint32 count = quest->ItemDropQuantity[i];
- DestroyItemCount(quest->ItemDrop[i], count ? count : 9999, true);
+ if (!count)
+ count = std::numeric_limits<uint32>::max();
+ DestroyItemCount(quest->ItemDrop[i], count, true);
}
}
}
@@ -15246,7 +15256,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
{
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(quest->GetRewSpell(), GetMap()->GetDifficultyID());
Unit* caster = this;
- if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
+ if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
if (Unit* unit = questGiver->ToUnit())
caster = unit;
@@ -15262,7 +15272,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(displaySpell.SpellId, GetMap()->GetDifficultyID());
Unit* caster = this;
- if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
+ if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
if (Unit* unit = questGiver->ToUnit())
caster = unit;
@@ -15290,66 +15300,66 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
SendQuestGiverStatusMultiple();
- bool conditionChanged = SendQuestUpdate(quest_id, false);
+ SendQuestUpdate(quest_id);
+
+ bool updateVisibility = false;
+ if (quest->HasFlag(QUEST_FLAGS_UPDATE_PHASESHIFT))
+ updateVisibility = PhasingHandler::OnConditionChange(this, false);
//lets remove flag for delayed teleports
SetCanDelayTeleport(false);
- bool canHaveNextQuest = !quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE) ? questGiver && !questGiver->IsPlayer() : true;
- if (canHaveNextQuest)
+ switch (questGiver->GetTypeId())
{
- switch (questGiver->GetTypeId())
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
{
- case TYPEID_UNIT:
- case TYPEID_PLAYER:
+ //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
+ // Send next quest
+ if (Quest const* nextQuest = GetNextQuest(questGiver, quest))
{
- //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
- // Send next quest
- if (Quest const* nextQuest = GetNextQuest(questGiver, quest))
+ // Only send the quest to the player if the conditions are met
+ if (CanTakeQuest(nextQuest, false))
{
- // Only send the quest to the player if the conditions are met
- if (CanTakeQuest(nextQuest, false))
- {
- if (nextQuest->IsAutoAccept() && CanAddQuest(nextQuest, true))
- AddQuestAndCheckCompletion(nextQuest, questGiver);
+ if (nextQuest->IsAutoAccept() && CanAddQuest(nextQuest, true))
+ AddQuestAndCheckCompletion(nextQuest, questGiver);
- PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, questGiver->GetGUID(), true, false);
- }
+ PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, questGiver->GetGUID(), true, false);
}
-
- PlayerTalkClass->ClearMenus();
- if (Creature* creatureQGiver = questGiver->ToCreature())
- creatureQGiver->AI()->OnQuestReward(this, quest, rewardType, rewardId);
- break;
}
- case TYPEID_GAMEOBJECT:
+
+ PlayerTalkClass->ClearMenus();
+ if (Creature* creatureQGiver = questGiver->ToCreature())
+ creatureQGiver->AI()->OnQuestReward(this, quest, rewardType, rewardId);
+ break;
+ }
+ case TYPEID_GAMEOBJECT:
+ {
+ // Send next quest
+ if (Quest const* nextQuest = GetNextQuest(questGiver, quest))
{
- // Send next quest
- if (Quest const* nextQuest = GetNextQuest(questGiver, quest))
+ // Only send the quest to the player if the conditions are met
+ if (CanTakeQuest(nextQuest, false))
{
- // Only send the quest to the player if the conditions are met
- if (CanTakeQuest(nextQuest, false))
- {
- if (nextQuest->IsAutoAccept() && CanAddQuest(nextQuest, true))
- AddQuestAndCheckCompletion(nextQuest, questGiver);
+ if (nextQuest->IsAutoAccept() && CanAddQuest(nextQuest, true))
+ AddQuestAndCheckCompletion(nextQuest, questGiver);
- PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, questGiver->GetGUID(), true, false);
- }
+ PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, questGiver->GetGUID(), true, false);
}
-
- PlayerTalkClass->ClearMenus();
- questGiver->ToGameObject()->AI()->OnQuestReward(this, quest, rewardType, rewardId);
- break;
}
- default:
- break;
+
+ PlayerTalkClass->ClearMenus();
+ questGiver->ToGameObject()->AI()->OnQuestReward(this, quest, rewardType, rewardId);
+ break;
}
+ default:
+ break;
}
sScriptMgr->OnQuestStatusChange(this, quest_id);
sScriptMgr->OnQuestStatusChange(this, quest, oldStatus, QUEST_STATUS_REWARDED);
- if (conditionChanged)
+ if (updateVisibility)
UpdateObjectVisibility();
}
@@ -15407,6 +15417,20 @@ void Player::FailQuest(uint32 questId)
}
}
+void Player::FailQuestsWithFlag(QuestFlags flag)
+{
+ for (uint16 slot = 0; MAX_QUEST_LOG_SIZE; ++slot)
+ {
+ uint32 questId = GetQuestSlotQuestId(slot);
+ if (!questId)
+ continue;
+
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
+ if (quest->HasFlag(flag))
+ FailQuest(questId);
+ }
+}
+
void Player::AbandonQuest(uint32 questId)
{
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
@@ -15981,7 +16005,7 @@ void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*=
QuestStatus oldStatus = m_QuestStatus[questId].Status;
m_QuestStatus[questId].Status = status;
- if (!quest->IsAutoComplete())
+ if (!quest->IsTurnIn())
m_QuestStatusSave[questId] = QUEST_DEFAULT_SAVE_TYPE;
sScriptMgr->OnQuestStatusChange(this, questId);
@@ -16041,7 +16065,7 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/)
SendQuestUpdate(questId);
}
-bool Player::SendQuestUpdate(uint32 questId, bool updateVisiblity /*= true*/)
+void Player::SendQuestUpdate(uint32 questId)
{
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(questId);
@@ -16090,7 +16114,6 @@ bool Player::SendQuestUpdate(uint32 questId, bool updateVisiblity /*= true*/)
}
UpdateVisibleGameobjectsOrSpellClicks();
- return PhasingHandler::OnConditionChange(this, updateVisiblity);
}
QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const
@@ -16152,7 +16175,7 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const
break;
}
- if (quest->IsAutoComplete() && CanTakeQuest(quest, false) && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
+ if (quest->IsTurnIn() && CanTakeQuest(quest, false) && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
{
if (GetLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
result |= QuestGiverStatus::RepeatableTurnin;
@@ -16951,7 +16974,7 @@ void Player::SendQuestReward(Quest const* quest, Creature const* questGiver, uin
if (questGiver->IsQuestGiver())
packet.LaunchQuest = (GetQuestDialogStatus(questGiver) & ~QuestGiverStatus::Future) != QuestGiverStatus::None;
- if (!quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
+ if (!quest->HasFlag(QUEST_FLAGS_AUTO_COMPLETE))
if (Quest const* rewardQuest = GetNextQuest(questGiver, quest))
packet.UseQuestReward = CanTakeQuest(rewardQuest, false);
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index e52f4d4bd29..71b00fe46d9 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1589,6 +1589,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rewardId, Object* questGiver, bool announce = true);
void SetRewardedQuest(uint32 quest_id);
void FailQuest(uint32 quest_id);
+ void FailQuestsWithFlag(QuestFlags flag);
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
bool SatisfyQuestLevel(Quest const* qInfo, bool msg) const;
bool SatisfyQuestMinLevel(Quest const* qInfo, bool msg) const;
@@ -1618,7 +1619,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SetQuestStatus(uint32 questId, QuestStatus status, bool update = true);
void RemoveActiveQuest(uint32 questId, bool update = true);
void RemoveRewardedQuest(uint32 questId, bool update = true);
- bool SendQuestUpdate(uint32 questId, bool updateVisiblity = true);
+ void SendQuestUpdate(uint32 questId);
QuestGiverStatus GetQuestDialogStatus(Object const* questGiver) const;
void SetDailyQuestStatus(uint32 quest_id);