aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2013-07-11 21:45:14 +0200
committerShauren <shauren.trinity@gmail.com>2013-07-11 21:45:14 +0200
commit30f6efb416e12e1247dd86ab52d183853326edef (patch)
tree07217da15ba3578527cf91c34f11e4a14301af89 /src
parentf5cd494acb4b0b0db0a7acf5031af4927ed6575b (diff)
Core/Quests: Fixed quest sharing
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp6
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp80
-rw-r--r--src/server/scripts/Outland/zone_shattrath_city.cpp2
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());