Core/Quests: Fixed adding autoaccept quests many times to log when started from items

Closes #2106
This commit is contained in:
Shauren
2011-06-28 20:16:15 +02:00
parent c42db7af8c
commit 1eff27f57c
2 changed files with 65 additions and 59 deletions
+15 -15
View File
@@ -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);
}
}