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::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::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 }