void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { if (Group* group = _player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->getSource(); if (!player || player == _player) // skip self continue; _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_SHARING_QUEST); if (!player->SatisfyQuestStatus(quest, false)) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!player->CanTakeQuest(quest, false)) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!player->SatisfyQuestLog(false)) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_LOG_FULL); continue; } if (player->GetDivider() != 0) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_BUSY); continue; } player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, _player->GetGUID(), true); player->SetDivider(_player->GetGUID()); } } } }
void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; DEBUG_LOG("WORLD: Received opcode CMSG_PUSHQUESTTOPARTY quest = %u", questId); if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(questId)) { if (Group* pGroup = _player->GetGroup()) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // skip self continue; _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); if (_player->GetDistance(pPlayer) > 10) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_TOO_FAR); continue; } if (!pPlayer->SatisfyQuestStatus(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (pPlayer->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!pPlayer->CanTakeQuest(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!pPlayer->SatisfyQuestLog(false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_LOG_FULL); continue; } if (pPlayer->GetDividerGuid()) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_BUSY); continue; } #ifndef BUILD_PLAYERBOT pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetObjectGuid(), true); #endif pPlayer->SetDividerGuid(_player->GetObjectGuid()); #ifdef BUILD_PLAYERBOT if (pPlayer->GetPlayerbotAI()) pPlayer->GetPlayerbotAI()->AcceptQuest(pQuest, _player); else { pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetObjectGuid(), true); pPlayer->SetDividerGuid(_player->GetObjectGuid()); } #endif } } } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recv_data) { ObjectGuid guid; uint32 quest; recv_data >> guid >> quest; if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_ACCEPT_QUEST")) return; DEBUG_LOG("WORLD: Received opcode CMSG_QUESTGIVER_ACCEPT_QUEST - for %s to %s, quest = %u", _player->GetGuidStr().c_str(), guid.GetString().c_str(), quest); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM); // no or incorrect quest giver if (!pObject || (pObject->GetTypeId() != TYPEID_PLAYER && !pObject->HasQuest(quest)) || (pObject->GetTypeId() == TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) ) { _player->PlayerTalkClass->CloseGossip(); _player->ClearDividerGuid(); return; } Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if (qInfo) { // prevent cheating if (!GetPlayer()->CanTakeQuest(qInfo, true)) { _player->PlayerTalkClass->CloseGossip(); _player->ClearDividerGuid(); return; } if (Player* pPlayer = ObjectAccessor::FindPlayer(_player->GetDividerGuid())) { pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->ClearDividerGuid(); } if (_player->CanAddQuest(qInfo, true)) { _player->AddQuest(qInfo, pObject); // pObject (if it item) can be destroyed at call if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDividerGuid(_player->GetObjectGuid()); // need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if (_player->CanCompleteQuest(quest)) _player->CompleteQuest(quest); _player->PlayerTalkClass->CloseGossip(); if (qInfo->GetSrcSpell() > 0) _player->CastSpell(_player, qInfo->GetSrcSpell(), TRIGGERED_OLD_TRIGGERED); return; } } _player->PlayerTalkClass->CloseGossip(); }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestGiverAcceptQuest& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST %s, quest = %u, startcheat = %u", packet.QuestGiverGUID.ToString().c_str(), packet.QuestID, packet.StartCheat); Object* object; if (!packet.QuestGiverGUID.IsPlayer()) object = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM); else object = ObjectAccessor::FindPlayer(packet.QuestGiverGUID); #define CLOSE_GOSSIP_CLEAR_DIVIDER() \ do { \ _player->PlayerTalkClass->SendCloseGossip(); \ _player->SetDivider(ObjectGuid::Empty); \ } while (0) // no or incorrect quest giver if (!object) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (Player* playerQuestObject = object->ToPlayer()) { if ((_player->GetDivider().IsEmpty() && _player->GetDivider() != packet.QuestGiverGUID) || !playerQuestObject->CanShareQuest(packet.QuestID)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (!_player->IsInSameRaidWith(playerQuestObject)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } else { if (!object->hasQuest(packet.QuestID)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID)) { // prevent cheating if (!GetPlayer()->CanTakeQuest(quest, true)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (!_player->GetDivider().IsEmpty()) { Player* player = ObjectAccessor::FindPlayer(_player->GetDivider()); if (player) { player->SendPushToPartyResponse(_player, QUEST_PUSH_ACCEPTED); _player->SetDivider(ObjectGuid::Empty); } } if (_player->CanAddQuest(quest, true)) { _player->AddQuestAndCheckCompletion(quest, object); if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* group = _player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || player == _player) // not self continue; if (player->CanTakeQuest(quest, true)) { player->SetDivider(_player->GetGUID()); // need confirmation that any gossip window will close player->PlayerTalkClass->SendCloseGossip(); _player->SendQuestConfirmAccept(quest, player); } } } } _player->PlayerTalkClass->SendCloseGossip(); if (quest->GetSrcSpell() > 0) _player->CastSpell(_player, quest->GetSrcSpell(), true); return; } } CLOSE_GOSSIP_CLEAR_DIVIDER(); #undef CLOSE_GOSSIP_CLEAR_DIVIDER }
void WorldSession::HandlePushQuestToParty(WorldPackets::Quest::PushQuestToParty& packet) { if (!_player->CanShareQuest(packet.QuestID)) return; Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); if (!quest) return; Player * const sender = GetPlayer(); Group* group = sender->GetGroup(); if (!group) return; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* receiver = itr->GetSource(); if (!receiver || receiver == sender) continue; if (!receiver->SatisfyQuestStatus(quest, false)) { sender->SendPushToPartyResponse(receiver, QUEST_PUSH_ONQUEST); continue; } if (receiver->GetQuestStatus(packet.QuestID) == QUEST_STATUS_COMPLETE) { sender->SendPushToPartyResponse(receiver, QUEST_PUSH_ALREADY_DONE); continue; } if (!receiver->CanTakeQuest(quest, false)) { sender->SendPushToPartyResponse(receiver, QUEST_PUSH_INVALID); continue; } if (!receiver->SatisfyQuestLog(false)) { sender->SendPushToPartyResponse(receiver, QUEST_PUSH_LOG_FULL); continue; } if (!receiver->GetDivider().IsEmpty()) { sender->SendPushToPartyResponse(receiver, QUEST_PUSH_BUSY); continue; } sender->SendPushToPartyResponse(receiver, QUEST_PUSH_SUCCESS); if (quest->IsAutoAccept() && receiver->CanAddQuest(quest, true) && receiver->CanTakeQuest(quest, true)) receiver->AddQuestAndCheckCompletion(quest, sender); if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) receiver->PlayerTalkClass->SendQuestGiverRequestItems(quest, sender->GetGUID(), receiver->CanCompleteRepeatableQuest(quest), true); else { receiver->SetDivider(sender->GetGUID()); receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, receiver->GetGUID(), true); } } }
void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; if (!_player->CanShareQuest(questId)) return; TC_LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY questId = %u", questId); Quest const* quest = sObjectMgr->GetQuestTemplate(questId); if (!quest) return; Player * const sender = GetPlayer(); Group* group = sender->GetGroup(); if (!group) return; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* receiver = itr->GetSource(); if (!receiver || receiver == sender) continue; if (!receiver->SatisfyQuestStatus(quest, false)) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (receiver->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!receiver->CanTakeQuest(quest, false)) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!receiver->SatisfyQuestLog(false)) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_LOG_FULL); continue; } if (receiver->GetDivider() != 0) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_BUSY); continue; } sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_SHARING_QUEST); if (quest->IsAutoAccept() && receiver->CanAddQuest(quest, true) && receiver->CanTakeQuest(quest, true)) receiver->AddQuestAndCheckCompletion(quest, sender); if ((quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) || quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE)) receiver->PlayerTalkClass->SendQuestGiverRequestItems(quest, sender->GetGUID(), receiver->CanCompleteRepeatableQuest(quest), true); else { receiver->SetDivider(sender->GetGUID()); receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, sender->GetGUID(), true); } } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) { uint64 guid; uint32 questId; uint32 unk1; recvData >> guid >> questId >> unk1; TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), questId, unk1); Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); #define CLOSE_GOSSIP_CLEAR_DIVIDER() \ do { \ _player->PlayerTalkClass->SendCloseGossip(); \ _player->SetDivider(0); \ } while (0) // no or incorrect quest giver if (!object) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (Player* playerQuestObject = object->ToPlayer()) { if ((_player->GetDivider() && _player->GetDivider() != guid) || ((object != _player && !playerQuestObject->CanShareQuest(questId)))) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } else { if (!object->hasQuest(questId)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) return; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { // prevent cheating if (!GetPlayer()->CanTakeQuest(quest, true)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (_player->GetDivider() != 0) { Player* player = ObjectAccessor::FindPlayer(_player->GetDivider()); if (player) { player->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->SetDivider(0); } } if (_player->CanAddQuest(quest, true)) { _player->AddQuestAndCheckCompletion(quest, object); if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* group = _player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || player == _player) // not self continue; if (player->CanTakeQuest(quest, true)) { player->SetDivider(_player->GetGUID()); // need confirmation that any gossip window will close player->PlayerTalkClass->SendCloseGossip(); _player->SendQuestConfirmAccept(quest, player); } } } } _player->PlayerTalkClass->SendCloseGossip(); if (quest->GetSrcSpell() > 0) _player->CastSpell(_player, quest->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->SendCloseGossip(); #undef CLOSE_GOSSIP_CLEAR_DIVIDER }
void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket) { CHECK_PACKET_SIZE(recvPacket,4); uint32 quest; recvPacket >> quest; sLog.outDebug("WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", quest); Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest); if (pQuest) { if (_player->GetGroup()) { Group *pGroup = _player->GetGroup(); if (pGroup) { for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // skip self continue; _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); if (_player->GetDistance(pPlayer) > 10) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_TOO_FAR); continue; } if (!pPlayer->SatisfyQuestStatus(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (pPlayer->GetQuestStatus(quest) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!pPlayer->CanTakeQuest(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!pPlayer->SatisfyQuestLog(false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_LOG_FULL); continue; } if (pPlayer->GetDivider() != 0 ) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_BUSY); continue; } pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetGUID(), true); pPlayer->SetDivider(_player->GetGUID()); } } } } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data,8+4); uint64 guid; uint32 quest; recv_data >> guid >> quest; if (!GetPlayer()->isAlive()) return; sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest); Object* pObject = _player->GetMap()->GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); // no or incorrect quest giver if (!pObject || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest)) || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) ) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider(0); return; } Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if (qInfo) { // prevent cheating if (!GetPlayer()->CanTakeQuest(qInfo,true)) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider(0); return; } if (_player->GetDivider() != 0) { Player *pPlayer = ObjectAccessor::FindPlayer(_player->GetDivider()); if (pPlayer) { pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->SetDivider(0); } } if (_player->CanAddQuest(qInfo, true)) { _player->AddQuest(qInfo, pObject); if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDivider(_player->GetGUID()); //need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if (_player->CanCompleteQuest(quest)) _player->CompleteQuest(quest); switch (pObject->GetTypeId()) { case TYPEID_UNIT: sScriptMgr.OnQuestAccept(_player, ((Creature*)pObject), qInfo); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { sScriptMgr.OnQuestAccept(_player, ((Item*)pObject), qInfo); // destroy not required for quest finish quest starting item bool destroyItem = true; for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) { if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0)) { destroyItem = false; break; } } if (destroyItem) _player->DestroyItem(((Item*)pObject)->GetBagSlot(),((Item*)pObject)->GetSlot(),true); break; } case TYPEID_GAMEOBJECT: sScriptMgr.OnQuestAccept(_player, ((GameObject*)pObject), qInfo); break; } _player->PlayerTalkClass->CloseGossip(); if (qInfo->GetSrcSpell() > 0) _player->CastSpell(_player, qInfo->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->CloseGossip(); }
void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; if (!_player->CanShareQuest(questId)) return; TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { if (Group* group = _player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || player == _player) // skip self continue; if (!player->SatisfyQuestStatus(quest, false)) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!player->CanTakeQuest(quest, false)) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!player->SatisfyQuestLog(false)) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_LOG_FULL); continue; } if (player->GetDivider() != 0) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_BUSY); continue; } _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_SHARING_QUEST); if (quest->IsAutoAccept() && player->CanAddQuest(quest, true) && player->CanTakeQuest(quest, true)) { player->AddQuest(quest, _player); if (player->CanCompleteQuest(questId)) player->CompleteQuest(questId); } if ((quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) || quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE)) player->PlayerTalkClass->SendQuestGiverRequestItems(quest, _player->GetGUID(), player->CanCompleteRepeatableQuest(quest), true); else { player->SetDivider(_player->GetGUID()); player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, _player->GetGUID(), true); } } } } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) { uint64 guid; uint32 questId; uint32 unk1; recvData >> guid >> questId >> unk1; TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), questId, unk1); Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); #define CLOSE_GOSSIP_CLEAR_DIVIDER() \ do { \ _player->PlayerTalkClass->SendCloseGossip(); \ _player->SetDivider(0); \ } while (0) // no or incorrect quest giver if (!object) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (Player* playerQuestObject = object->ToPlayer()) { if ((_player->GetDivider() && _player->GetDivider() != guid) || ((object != _player && !playerQuestObject->CanShareQuest(questId)))) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } else { if (!object->hasQuest(questId)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) return; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { // prevent cheating if (!GetPlayer()->CanTakeQuest(quest, true)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (_player->GetDivider() != 0) { Player* player = ObjectAccessor::FindPlayer(_player->GetDivider()); if (player) { player->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->SetDivider(0); } } if (_player->CanAddQuest(quest, true)) { _player->AddQuest(quest, object); if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* group = _player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || player == _player) // not self continue; if (player->CanTakeQuest(quest, true)) { player->SetDivider(_player->GetGUID()); //need confirmation that any gossip window will close player->PlayerTalkClass->SendCloseGossip(); _player->SendQuestConfirmAccept(quest, player); } } } } if (_player->CanCompleteQuest(questId)) _player->CompleteQuest(questId); switch (object->GetTypeId()) { case TYPEID_UNIT: sScriptMgr->OnQuestAccept(_player, (object->ToCreature()), quest); object->ToCreature()->AI()->sQuestAccept(_player, quest); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { Item* item = (Item*)object; sScriptMgr->OnQuestAccept(_player, item, quest); // destroy not required for quest finish quest starting item bool destroyItem = true; for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (quest->RequiredItemId[i] == item->GetEntry() && item->GetTemplate()->MaxCount > 0) { destroyItem = false; break; } } if (destroyItem) _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); break; } case TYPEID_GAMEOBJECT: sScriptMgr->OnQuestAccept(_player, object->ToGameObject(), quest); object->ToGameObject()->AI()->QuestAccept(_player, quest); break; default: break; } _player->PlayerTalkClass->SendCloseGossip(); if (quest->GetSrcSpell() > 0) _player->CastSpell(_player, quest->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->SendCloseGossip(); #undef CLOSE_GOSSIP_CLEAR_DIVIDER }
void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; sLog.outDebug("WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(questId)) { if (Group* pGroup = _player->GetGroup()) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // skip self continue; _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); // 2.4.3: can only share quests within 10 yards if (_player->GetDistance(pPlayer) > 10) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_TOO_FAR); continue; } //player already has quest if (!pPlayer->SatisfyQuestStatus(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_HAVE_QUEST); continue; } //player already completed quest if (pPlayer->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_FINISH_QUEST); continue; } //player is ineligible for the quest if (!pPlayer->CanTakeQuest(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } //player has full quest log if (!pPlayer->SatisfyQuestLog(false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_LOG_FULL); continue; } if (pPlayer->GetDivider() != 0) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_BUSY); continue; } pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetGUID(), true); pPlayer->SetDivider(_player->GetGUID()); } } } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) { ObjectGuid guid; uint32 quest; uint32 unk1; recv_data >> guid >> quest >> unk1; if (!GetPlayer()->isAlive()) return; DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1 ); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM); // no or incorrect quest giver if(!pObject || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->HasQuest(quest)) || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) ) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider( 0 ); return; } Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if ( qInfo ) { // prevent cheating if(!GetPlayer()->CanTakeQuest(qInfo,true) ) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider( 0 ); return; } if( _player->GetDivider() != 0 ) { Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() ); if( pPlayer ) { pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST ); _player->SetDivider( 0 ); } } if( _player->CanAddQuest( qInfo, true ) ) { _player->AddQuest( qInfo, pObject ); if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDivider(_player->GetGUID()); //need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if ( _player->CanCompleteQuest( quest ) ) _player->CompleteQuest( quest ); _player->GetAchievementMgr().StartTimedAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest); switch(pObject->GetTypeId()) { case TYPEID_UNIT: sScriptMgr.OnQuestAccept(_player, (Creature*)pObject, qInfo); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { sScriptMgr.OnQuestAccept(_player, (Item*)pObject, qInfo); // destroy not required for quest finish quest starting item bool destroyItem = true; for(int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0)) { destroyItem = false; break; } } if(destroyItem) _player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true); break; } case TYPEID_GAMEOBJECT: sScriptMgr.OnQuestAccept(_player, (GameObject*)pObject, qInfo); break; } _player->PlayerTalkClass->CloseGossip(); if( qInfo->GetSrcSpell() > 0 ) _player->CastSpell( _player, qInfo->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->CloseGossip(); }
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) { ObjectGuid guid; uint32 quest; uint32 unk1; recv_data >> guid >> quest >> unk1; if (!GetPlayer()->isAlive()) { if (Unit * pQuestNPC = GetPlayer()->GetMap()->GetUnit(guid)) if (!pQuestNPC->isInvisibleForAlive()) return; } DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1 ); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM); // no or incorrect quest giver if(!pObject || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->HasQuest(quest)) || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) ) { _player->PlayerTalkClass->CloseGossip(); _player->ClearDividerGuid(); return; } Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if ( qInfo ) { // prevent cheating if(!GetPlayer()->CanTakeQuest(qInfo,true) ) { _player->PlayerTalkClass->CloseGossip(); _player->ClearDividerGuid(); return; } if (Player *pPlayer = ObjectAccessor::FindPlayer(_player->GetDividerGuid())) { pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->ClearDividerGuid(); } if( _player->CanAddQuest( qInfo, true ) ) { _player->AddQuest( qInfo, pObject ); // pObject (if it item) can be destroyed at call if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDividerGuid(_player->GetObjectGuid()); //need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if ( _player->CanCompleteQuest( quest ) ) _player->CompleteQuest( quest ); _player->GetAchievementMgr().StartTimedAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest); _player->PlayerTalkClass->CloseGossip(); if( qInfo->GetSrcSpell() > 0 ) _player->CastSpell( _player, qInfo->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->CloseGossip(); }