Core/Quests: make the player questgiver handling a bit more flexible to allow popup quest accepting at more places in the future

This commit is contained in:
Ovahlord committed 2021-03-28 14:44:16 +02:00
1 parent 6de4fe935d
commit 4f23fb3d29
5 files changed
+55 -2

No files matched your search

@@ -425,6 +425,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{ {
if (pTarget->CanTakeQuest(q, true)) if (pTarget->CanTakeQuest(q, true))
{ {
pTarget->SetPopupQuestId(0);
pTarget->PlayerTalkClass->SendQuestGiverQuestDetails(q, pTarget->GetGUID(), true, false); pTarget->PlayerTalkClass->SendQuestGiverQuestDetails(q, pTarget->GetGUID(), true, false);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - offered quest %u", TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - offered quest %u",
pTarget->GetGUID().GetCounter(), e.action.questOffer.questID); pTarget->GetGUID().GetCounter(), e.action.questOffer.questID);
@@ -434,7 +435,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{ {
pTarget->AddQuestAndCheckCompletion(q, nullptr); pTarget->AddQuestAndCheckCompletion(q, nullptr);
if (q->IsAutoAccept()) if (q->IsAutoAccept())
{
pTarget->SetPopupQuestId(0);
pTarget->PlayerTalkClass->SendQuestGiverQuestDetails(q, pTarget->GetGUID(), true, true); pTarget->PlayerTalkClass->SendQuestGiverQuestDetails(q, pTarget->GetGUID(), true, true);
}
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - quest %u added", TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - quest %u added",
pTarget->GetGUID().GetCounter(), e.action.questOffer.questID); pTarget->GetGUID().GetCounter(), e.action.questOffer.questID);
} }
@@ -155,6 +155,7 @@ Player::Player(WorldSession* session): Unit(true)
m_ingametime = 0; m_ingametime = 0;
m_sharedQuestId = 0; m_sharedQuestId = 0;
m_popupQuestId = 0;
m_ExtraFlags = 0; m_ExtraFlags = 0;
@@ -14258,7 +14259,10 @@ void Player::SendPreparedQuest(ObjectGuid guid)
if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true); PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true);
else else
{
SetPopupQuestId(0);
PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true, false); PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true, false);
}
} }
} }
} }
@@ -23473,7 +23477,10 @@ void Player::SendInitialPacketsAfterAddToMap()
if (GetPlayerSharingQuest()) if (GetPlayerSharingQuest())
{ {
if (Quest const* quest = sObjectMgr->GetQuestTemplate(GetSharedQuestID())) if (Quest const* quest = sObjectMgr->GetQuestTemplate(GetSharedQuestID()))
{
SetPopupQuestId(0);
PlayerTalkClass->SendQuestGiverQuestDetails(quest, GetGUID(), true, false); PlayerTalkClass->SendQuestGiverQuestDetails(quest, GetGUID(), true, false);
}
else else
ClearQuestSharingInfo(); ClearQuestSharingInfo();
} }
+5
View File
@@ -1449,6 +1449,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SetQuestSharingInfo(ObjectGuid guid, uint32 id) { m_playerSharingQuest = guid; m_sharedQuestId = id; } void SetQuestSharingInfo(ObjectGuid guid, uint32 id) { m_playerSharingQuest = guid; m_sharedQuestId = id; }
void ClearQuestSharingInfo() { m_playerSharingQuest = ObjectGuid::Empty; m_sharedQuestId = 0; } void ClearQuestSharingInfo() { m_playerSharingQuest = ObjectGuid::Empty; m_sharedQuestId = 0; }
// Returns the ID of the next available quest in chain of the most recently rewarded quest that has been rewarded via UI popup
uint32 GetPopupQuestId() const { return m_popupQuestId; }
void SetPopupQuestId(uint32 questId) { m_popupQuestId = questId; }
uint32 GetInGameTime() const { return m_ingametime; } uint32 GetInGameTime() const { return m_ingametime; }
void SetInGameTime(uint32 time) { m_ingametime = time; } void SetInGameTime(uint32 time) { m_ingametime = time; }
@@ -2452,6 +2456,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
ObjectGuid m_playerSharingQuest; ObjectGuid m_playerSharingQuest;
uint32 m_sharedQuestId; uint32 m_sharedQuestId;
uint32 m_popupQuestId;
uint32 m_ingametime; uint32 m_ingametime;
/*********************************************************/ /*********************************************************/
+35 -2
View File
@@ -127,17 +127,35 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG
if (Player* playerQuestObject = object->ToPlayer()) if (Player* playerQuestObject = object->ToPlayer())
{ {
if ((!_player->GetPlayerSharingQuest().IsEmpty() && _player->GetPlayerSharingQuest() != packet.QuestGiverGUID) // Various checks for player quest givers
|| (_player != playerQuestObject && !playerQuestObject->CanShareQuest(packet.QuestID))) if ((!_player->GetPlayerSharingQuest().IsEmpty() && _player->GetPlayerSharingQuest() != packet.QuestGiverGUID) // Player tries to accept a shared quest from a different questiver
|| (_player != playerQuestObject && !playerQuestObject->CanShareQuest(packet.QuestID))) // Player tries to accept a quest that cannot be shared
{ {
CLOSE_GOSSIP_CLEAR_SHARING_INFO(); CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
} }
// Player tries to accept a quest from a player questgiver that he is not in a party/raid with
if (!_player->IsInSameRaidWith(playerQuestObject)) if (!_player->IsInSameRaidWith(playerQuestObject))
{ {
CLOSE_GOSSIP_CLEAR_SHARING_INFO(); CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
} }
// Player tries to accept a quest from himself that cannot be taken. Such quests must be provided by a quest with flag QUEST_FLAGS_AUTOCOMPLETE prior to that
if (_player->GetPopupQuestId())
{
if (_player->GetPopupQuestId() != packet.QuestID || _player->GetGUID() != packet.QuestGiverGUID)
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return;
}
}
else if (_player->GetGUID() == packet.QuestGiverGUID) // Covering all remaining poossible cheat scenarios when trying to exploit quest sharing
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return;
}
} }
else else
{ {
@@ -207,6 +225,10 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG
if (quest->GetSrcSpell() > 0) if (quest->GetSrcSpell() > 0)
_player->CastSpell(_player, quest->GetSrcSpell(), true); _player->CastSpell(_player, quest->GetSrcSpell(), true);
// A quest has been accepted, reset popup follow quest ID because the quest has either been taken or another took its place
// so the player has to take the follow quest at its corresponding creature questgiver instead.
_player->SetPopupQuestId(0);
return; return;
} }
} }
@@ -239,7 +261,10 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPackets::Quest::QuestGi
if (quest->IsAutoComplete()) if (quest->IsAutoComplete())
_player->PlayerTalkClass->SendQuestGiverRequestItems(quest, object->GetGUID(), _player->CanCompleteQuest(quest->GetQuestId()), true); _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, object->GetGUID(), _player->CanCompleteQuest(quest->GetQuestId()), true);
else else
{
_player->SetPopupQuestId(0);
_player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, object->GetGUID(), true, false); _player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, object->GetGUID(), true, false);
}
} }
} }
@@ -307,6 +332,12 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest
if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
_player->AddQuestAndCheckCompletion(nextQuest, object); _player->AddQuestAndCheckCompletion(nextQuest, object);
// Previous quest has been rewarded via popup. The player may now accept the follow quest from himself.
if (object->IsPlayer() && quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE) && !nextQuest->IsAutoAccept())
_player->SetPopupQuestId(nextQuest->GetQuestId());
else
_player->SetPopupQuestId(0);
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false);
} }
} }
@@ -327,6 +358,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest
if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true))
_player->AddQuestAndCheckCompletion(nextQuest, object); _player->AddQuestAndCheckCompletion(nextQuest, object);
_player->SetPopupQuestId(0);
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false);
} }
} }
@@ -614,6 +646,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
receiver->PlayerTalkClass->SendQuestGiverRequestItems(quest, sender->GetGUID(), receiver->CanCompleteRepeatableQuest(quest), true); receiver->PlayerTalkClass->SendQuestGiverRequestItems(quest, sender->GetGUID(), receiver->CanCompleteRepeatableQuest(quest), true);
else else
{ {
receiver->SetPopupQuestId(0);
receiver->SetQuestSharingInfo(sender->GetGUID(), questId); receiver->SetQuestSharingInfo(sender->GetGUID(), questId);
receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, receiver->GetGUID(), true, false); receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, receiver->GetGUID(), true, false);
} }
+4
View File
@@ -5136,10 +5136,14 @@ void Spell::EffectQuestStart(SpellEffIndex effIndex)
if (quest->IsAutoAccept() && player->CanAddQuest(quest, false)) if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
{ {
player->AddQuestAndCheckCompletion(quest, player); player->AddQuestAndCheckCompletion(quest, player);
player->SetPopupQuestId(0);
player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true, true); player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true, true);
} }
else else
{
player->SetPopupQuestId(quest->GetQuestId());
player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true, false); player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true, false);
}
} }
} }