Core/Quests: Fixed adding autoaccept quests many times to log when started from items
Closes #2106
This commit is contained in:
@@ -14391,37 +14391,37 @@ void Player::SendPreparedQuest(uint64 guid)
|
||||
if (questMenu.GetMenuItemCount() == 1)
|
||||
{
|
||||
// Auto open -- maybe also should verify there is no greeting
|
||||
uint32 quest_id = qmi0.QuestId;
|
||||
Quest const* pQuest = sObjectMgr->GetQuestTemplate(quest_id);
|
||||
uint32 questId = qmi0.QuestId;
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
|
||||
if (pQuest)
|
||||
if (quest)
|
||||
{
|
||||
if (icon == 4 && !GetQuestRewardStatus(quest_id))
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);
|
||||
if (icon == 4 && !GetQuestRewardStatus(questId))
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanRewardQuest(quest, false), true);
|
||||
else if (icon == 4)
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanRewardQuest(quest, false), true);
|
||||
// Send completable on repeatable and autoCompletable quest if player don't have quest
|
||||
// TODO: verify if check for !pQuest->IsDaily() is really correct (possibly not)
|
||||
else
|
||||
{
|
||||
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM);
|
||||
if (!pObject || (!pObject->hasQuest(quest_id) && !pObject->hasInvolvedQuest(quest_id)))
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM);
|
||||
if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId)))
|
||||
{
|
||||
PlayerTalkClass->SendCloseGossip();
|
||||
return;
|
||||
}
|
||||
|
||||
if (pQuest->IsAutoAccept() && CanAddQuest(pQuest, true))
|
||||
if (quest->IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true))
|
||||
{
|
||||
AddQuest(pQuest, pObject);
|
||||
if (CanCompleteQuest(quest_id))
|
||||
CompleteQuest(quest_id);
|
||||
AddQuest(quest, object);
|
||||
if (CanCompleteQuest(questId))
|
||||
CompleteQuest(questId);
|
||||
}
|
||||
|
||||
if ((pQuest->IsAutoComplete() && pQuest->IsRepeatable() && !pQuest->IsDailyOrWeekly()) || pQuest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanCompleteRepeatableQuest(pQuest), true);
|
||||
if ((quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) || quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true);
|
||||
else
|
||||
PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, guid, true);
|
||||
PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,33 +237,39 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data)
|
||||
void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 guid;
|
||||
uint32 quest;
|
||||
uint32 questId;
|
||||
uint8 unk1;
|
||||
recv_data >> guid >> quest >> unk1;
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1);
|
||||
recv_data >> guid >> questId >> unk1;
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), questId, unk1);
|
||||
|
||||
// Verify that the guid is valid and is a questgiver or involved in the requested quest
|
||||
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM);
|
||||
if (!pObject || (!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest)))
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM);
|
||||
if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId)))
|
||||
{
|
||||
_player->PlayerTalkClass->SendCloseGossip();
|
||||
return;
|
||||
}
|
||||
|
||||
Quest const* pQuest = sObjectMgr->GetQuestTemplate(quest);
|
||||
if (pQuest)
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (quest)
|
||||
{
|
||||
if (pQuest->IsAutoAccept() && _player->CanAddQuest(pQuest, true))
|
||||
// not sure here what should happen to quests with QUEST_FLAGS_AUTOCOMPLETE
|
||||
// if this breaks them, add && object->GetTypeId() == TYPEID_ITEM to this check
|
||||
// item-started quests never have that flag
|
||||
if (!_player->CanTakeQuest(quest, true))
|
||||
return;
|
||||
|
||||
if (quest->IsAutoAccept() && _player->CanAddQuest(quest, true))
|
||||
{
|
||||
_player->AddQuest(pQuest, pObject);
|
||||
if (_player->CanCompleteQuest(quest))
|
||||
_player->CompleteQuest(quest);
|
||||
_player->AddQuest(quest, object);
|
||||
if (_player->CanCompleteQuest(questId))
|
||||
_player->CompleteQuest(questId);
|
||||
}
|
||||
|
||||
if (pQuest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
|
||||
_player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, pObject->GetGUID(), _player->CanCompleteQuest(pQuest->GetQuestId()), true);
|
||||
if (quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
|
||||
_player->PlayerTalkClass->SendQuestGiverRequestItems(quest, object->GetGUID(), _player->CanCompleteQuest(quest->GetQuestId()), true);
|
||||
else
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, pObject->GetGUID(), true);
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, object->GetGUID(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,9 +291,9 @@ void WorldSession::HandleQuestQueryOpcode(WorldPacket & recv_data)
|
||||
|
||||
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint32 quest, reward;
|
||||
uint32 questId, reward;
|
||||
uint64 guid;
|
||||
recv_data >> guid >> quest >> reward;
|
||||
recv_data >> guid >> questId >> reward;
|
||||
|
||||
if (reward >= QUEST_REWARD_CHOICES_COUNT)
|
||||
{
|
||||
@@ -295,67 +301,67 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
|
||||
return;
|
||||
}
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), quest, reward);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward);
|
||||
|
||||
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
|
||||
if (!pObject || !pObject->hasInvolvedQuest(quest))
|
||||
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
|
||||
if (!object || !object->hasInvolvedQuest(questId))
|
||||
return;
|
||||
|
||||
// some kind of WPE protection
|
||||
if (!_player->CanInteractWithQuestGiver(pObject))
|
||||
if (!_player->CanInteractWithQuestGiver(object))
|
||||
return;
|
||||
|
||||
if (Quest const *pQuest = sObjectMgr->GetQuestTemplate(quest))
|
||||
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
|
||||
{
|
||||
if ((!_player->CanSeeStartQuest(pQuest) && _player->GetQuestStatus(quest) == QUEST_STATUS_NONE) ||
|
||||
(_player->GetQuestStatus(quest) != QUEST_STATUS_COMPLETE && !pQuest->IsAutoComplete()))
|
||||
if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
|
||||
(_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
|
||||
{
|
||||
sLog->outError("HACK ALERT: Player %s (guid: %u) is trying to complete quest (id: %u) but he has no right to do it!",
|
||||
_player->GetName(), _player->GetGUID(), quest);
|
||||
_player->GetName(), _player->GetGUID(), questId);
|
||||
return;
|
||||
}
|
||||
if (_player->CanRewardQuest(pQuest, reward, true))
|
||||
if (_player->CanRewardQuest(quest, reward, true))
|
||||
{
|
||||
_player->RewardQuest(pQuest, reward, pObject);
|
||||
_player->RewardQuest(quest, reward, object);
|
||||
|
||||
switch(pObject->GetTypeId())
|
||||
switch (object->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
if (!(sScriptMgr->OnQuestReward(_player, (pObject->ToCreature()), pQuest, reward)))
|
||||
if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward)))
|
||||
{
|
||||
// Send next quest
|
||||
if (Quest const* nextquest = _player->GetNextQuest(guid , pQuest))
|
||||
if (Quest const* nextQuest = _player->GetNextQuest(guid , quest))
|
||||
{
|
||||
if (nextquest->IsAutoAccept() && _player->CanAddQuest(nextquest, true))
|
||||
if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
|
||||
{
|
||||
_player->AddQuest(nextquest, pObject);
|
||||
if (_player->CanCompleteQuest(nextquest->GetQuestId()))
|
||||
_player->CompleteQuest(nextquest->GetQuestId());
|
||||
_player->AddQuest(nextQuest, object);
|
||||
if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
|
||||
_player->CompleteQuest(nextQuest->GetQuestId());
|
||||
}
|
||||
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest, guid, true);
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
|
||||
}
|
||||
|
||||
(pObject->ToCreature())->AI()->sQuestReward(_player, pQuest, reward);
|
||||
(object->ToCreature())->AI()->sQuestReward(_player, quest, reward);
|
||||
}
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)pObject), pQuest, reward))
|
||||
if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
|
||||
{
|
||||
// Send next quest
|
||||
if (Quest const* nextquest = _player->GetNextQuest(guid , pQuest))
|
||||
if (Quest const* nextQuest = _player->GetNextQuest(guid , quest))
|
||||
{
|
||||
if (nextquest->IsAutoAccept() && _player->CanAddQuest(nextquest, true))
|
||||
if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
|
||||
{
|
||||
_player->AddQuest(nextquest, pObject);
|
||||
if (_player->CanCompleteQuest(nextquest->GetQuestId()))
|
||||
_player->CompleteQuest(nextquest->GetQuestId());
|
||||
_player->AddQuest(nextQuest, object);
|
||||
if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
|
||||
_player->CompleteQuest(nextQuest->GetQuestId());
|
||||
}
|
||||
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest, guid, true);
|
||||
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
|
||||
}
|
||||
|
||||
pObject->ToGameObject()->AI()->QuestReward(_player, pQuest, reward);
|
||||
object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -363,7 +369,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
|
||||
}
|
||||
}
|
||||
else
|
||||
_player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
|
||||
_player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user