diff options
author | Shauren <shauren.trinity@gmail.com> | 2013-07-11 21:45:14 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2013-07-11 21:45:14 +0200 |
commit | 30f6efb416e12e1247dd86ab52d183853326edef (patch) | |
tree | 07217da15ba3578527cf91c34f11e4a14301af89 /src | |
parent | f5cd494acb4b0b0db0a7acf5031af4927ed6575b (diff) |
Core/Quests: Fixed quest sharing
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 80 | ||||
-rw-r--r-- | src/server/scripts/Outland/zone_shattrath_city.cpp | 2 |
5 files changed, 66 insertions, 26 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index d59015fd359..e86935f49f8 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -378,7 +378,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size data << uint64(npcGUID); - data << uint64(0); // wotlk, something todo with quest sharing? + data << uint64(_session->GetPlayer()->GetDivider()); data << uint32(quest->GetQuestId()); data << questTitle; data << questDetails; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2f584fdb5d4..859b752acc7 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16653,11 +16653,11 @@ void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver) } } -void Player::SendPushToPartyResponse(Player* player, uint32 msg) +void Player::SendPushToPartyResponse(Player* player, uint8 msg) { if (player) { - WorldPacket data(MSG_QUEST_PUSH_RESULT, (8+1)); + WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 1); data << uint64(player->GetGUID()); data << uint8(msg); // valid values: 0-8 GetSession()->SendPacket(&data); @@ -18787,7 +18787,7 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report bool Player::CheckInstanceLoginValid() { - if (!GetMap()) + if (!FindMap()) return false; if (!GetMap()->IsDungeon() || IsGameMaster()) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 2058f521f7c..7500755a101 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1431,7 +1431,7 @@ class Player : public Unit, public GridObject<Player> void SendQuestTimerFailed(uint32 quest_id); void SendCanTakeQuestResponse(uint32 msg) const; void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver); - void SendPushToPartyResponse(Player* player, uint32 msg); + void SendPushToPartyResponse(Player* player, uint8 msg); void SendQuestUpdateAddItem(Quest const* quest, uint32 item_idx, uint16 count); void SendQuestUpdateAddCreatureOrGo(Quest const* quest, uint64 guid, uint32 creatureOrGO_idx, uint16 old_count, uint16 add_count); void SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint16 add_count); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index ee130728106..6cd999bc496 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -120,15 +120,37 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) 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 || (object->GetTypeId() != TYPEID_PLAYER && !object->hasQuest(questId)) || - (object->GetTypeId() == TYPEID_PLAYER && object != _player && !object->ToPlayer()->CanShareQuest(questId))) + if (!object) { - _player->PlayerTalkClass->SendCloseGossip(); - _player->SetDivider(0); + 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; @@ -138,8 +160,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) // prevent cheating if (!GetPlayer()->CanTakeQuest(quest, true)) { - _player->PlayerTalkClass->SendCloseGossip(); - _player->SetDivider(0); + CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } @@ -188,18 +209,19 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) { case TYPEID_UNIT: sScriptMgr->OnQuestAccept(_player, (object->ToCreature()), quest); - (object->ToCreature())->AI()->sQuestAccept(_player, quest); + object->ToCreature()->AI()->sQuestAccept(_player, quest); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { - sScriptMgr->OnQuestAccept(_player, ((Item*)object), quest); + 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*)object)->GetEntry()) && (((Item*)object)->GetTemplate()->MaxCount > 0)) + if (quest->RequiredItemId[i] == item->GetEntry() && item->GetTemplate()->MaxCount > 0) { destroyItem = false; break; @@ -207,13 +229,13 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) } if (destroyItem) - _player->DestroyItem(((Item*)object)->GetBagSlot(), ((Item*)object)->GetSlot(), true); + _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); break; } case TYPEID_GAMEOBJECT: - sScriptMgr->OnQuestAccept(_player, ((GameObject*)object), quest); - (object->ToGameObject())->AI()->QuestAccept(_player, quest); + sScriptMgr->OnQuestAccept(_player, object->ToGameObject(), quest); + object->ToGameObject()->AI()->QuestAccept(_player, quest); break; default: break; @@ -228,6 +250,8 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) } _player->PlayerTalkClass->SendCloseGossip(); + +#undef CLOSE_GOSSIP_CLEAR_DIVIDER } void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket& recvData) @@ -538,6 +562,9 @@ 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)) @@ -551,8 +578,6 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) 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); @@ -583,8 +608,22 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) continue; } - player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, _player->GetGUID(), true); - player->SetDivider(_player->GetGUID()); + _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); + } } } } @@ -593,18 +632,19 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket) { uint64 guid; + uint32 questId; uint8 msg; - recvPacket >> guid >> msg; + recvPacket >> guid >> questId >> msg; TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_QUEST_PUSH_RESULT"); - if (_player->GetDivider() != 0) + if (_player->GetDivider() && _player->GetDivider() == guid) { Player* player = ObjectAccessor::FindPlayer(_player->GetDivider()); if (player) { - WorldPacket data(MSG_QUEST_PUSH_RESULT, (8+1)); - data << uint64(guid); + WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1); + data << uint64(_player->GetGUID()); data << uint8(msg); // valid values: 0-8 player->GetSession()->SendPacket(&data); _player->SetDivider(0); diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index f40ede82196..6f4694a5924 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -527,7 +527,7 @@ public: if (creature->IsQuestGiver()) player->PrepareQuestMenu(creature->GetGUID()); - if (!player->hasQuest(10211)) + if (player->GetQuestStatus(10211) != QUEST_STATUS_INCOMPLETE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); |