diff options
author | cyberbrest <cyberbrest@cyberbrest.com> | 2012-09-13 16:16:33 +0100 |
---|---|---|
committer | Nay <dnpd.dd@gmail.com> | 2012-09-13 16:16:33 +0100 |
commit | ed1ece2bb78d6e473872ff1691343295cd573309 (patch) | |
tree | 35eedf3b94562df9d6cbd7ef1902242314a73160 /src | |
parent | a447554cae9fb7839a46c804d4dd34ac9c1f978e (diff) |
Core/Quest: allow to complete quest by new auto-submit system with getting next quest in chain.
Closes #7752
(Modified)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 50 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 139 | ||||
-rwxr-xr-x | src/server/game/Quests/QuestDef.h | 5 |
3 files changed, 119 insertions, 75 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a27a1b4c64a..223278faf16 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14454,11 +14454,11 @@ void Player::PrepareQuestMenu(uint64 guid) //only for quests which cast teleport spells on player Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId()); ASSERT(_map); - GameObject* pGameObject = _map->GetGameObject(guid); - if (pGameObject) + GameObject* gameObject = _map->GetGameObject(guid); + if (gameObject) { - objectQR = sObjectMgr->GetGOQuestRelationBounds(pGameObject->GetEntry()); - objectQIR = sObjectMgr->GetGOQuestInvolvedRelationBounds(pGameObject->GetEntry()); + objectQR = sObjectMgr->GetGOQuestRelationBounds(gameObject->GetEntry()); + objectQIR = sObjectMgr->GetGOQuestInvolvedRelationBounds(gameObject->GetEntry()); } else return; @@ -14600,24 +14600,40 @@ bool Player::IsActiveQuest(uint32 quest_id) const Quest const* Player::GetNextQuest(uint64 guid, Quest const* quest) { QuestRelationBounds objectQR; + uint32 nextQuestID = quest->GetNextQuestInChain(); - Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid); - if (creature) - objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry()); - else + switch (GUID_HIPART(guid)) { - //we should obtain map pointer from GetMap() in 99% of cases. Special case - //only for quests which cast teleport spells on player - Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId()); - ASSERT(_map); - GameObject* pGameObject = _map->GetGameObject(guid); - if (pGameObject) - objectQR = sObjectMgr->GetGOQuestRelationBounds(pGameObject->GetEntry()); - else + case HIGHGUID_PLAYER: + ASSERT(quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT)); + return sObjectMgr->GetQuestTemplate(nextQuestID); + case HIGHGUID_UNIT: + case HIGHGUID_PET: + case HIGHGUID_VEHICLE: + { + if (Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid)) + objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry()); + else + return NULL; + break; + } + case HIGHGUID_GAMEOBJECT: + { + //we should obtain map pointer from GetMap() in 99% of cases. Special case + //only for quests which cast teleport spells on player + Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId()); + ASSERT(_map); + if (GameObject* gameObject = _map->GetGameObject(guid)) + objectQR = sObjectMgr->GetGOQuestRelationBounds(gameObject->GetEntry()); + else + return NULL; + break; + } + default: return NULL; } - uint32 nextQuestID = quest->GetNextQuestInChain(); + // for unit and go state for (QuestRelations::const_iterator itr = objectQR.first; itr != objectQR.second; ++itr) { if (itr->second == nextQuestID) diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 2f5c031e336..8d433ca6157 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -295,74 +295,87 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward); - Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); - if (!object || !object->hasInvolvedQuest(questId)) + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) return; - // some kind of WPE protection - if (!_player->CanInteractWithQuestGiver(object)) - return; + Object* object = _player; - if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) + if (!quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT)) { - if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) || - (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) - { - sLog->outError(LOG_FILTER_NETWORKIO, "HACK ALERT: Player %s (guid: %u) is trying to complete quest (id: %u) but he has no right to do it!", - _player->GetName(), _player->GetGUIDLow(), questId); + object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if (!object || !object->hasInvolvedQuest(questId)) return; - } - if (_player->CanRewardQuest(quest, reward, true)) - { - _player->RewardQuest(quest, reward, object); - switch (object->GetTypeId()) + // some kind of WPE protection + if (!_player->CanInteractWithQuestGiver(object)) + return; + } + + if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) || + (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) + { + sLog->outError(LOG_FILTER_NETWORKIO, "HACK ALERT: Player %s (guid: %u) is trying to complete quest (id: %u) but he has no right to do it!", + _player->GetName(), _player->GetGUIDLow(), questId); + return; + } + + if (_player->CanRewardQuest(quest, reward, true)) + { + _player->RewardQuest(quest, reward, object); + + switch (object->GetTypeId()) + { + case TYPEID_UNIT: + case TYPEID_PLAYER: { - case TYPEID_UNIT: - if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward))) + //For AutoSubmition was added plr case there as it almost same exclute AI script cases. + Creature *creatureQGiver = object->ToCreature(); + if (!creatureQGiver || !(sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, reward))) + { + // Send next quest + if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { - // Send next quest - if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) + if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) { - if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) - { - _player->AddQuest(nextQuest, object); - if (_player->CanCompleteQuest(nextQuest->GetQuestId())) - _player->CompleteQuest(nextQuest->GetQuestId()); - } - - _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); + _player->AddQuest(nextQuest, object); + if (_player->CanCompleteQuest(nextQuest->GetQuestId())) + _player->CompleteQuest(nextQuest->GetQuestId()); } - (object->ToCreature())->AI()->sQuestReward(_player, quest, reward); + _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); } - break; - case TYPEID_GAMEOBJECT: - if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward)) + + if (creatureQGiver) + creatureQGiver->AI()->sQuestReward(_player, quest, reward); + } + break; + } + case TYPEID_GAMEOBJECT: + if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward)) + { + // Send next quest + if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { - // Send next quest - if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) + if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) { - if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) - { - _player->AddQuest(nextQuest, object); - if (_player->CanCompleteQuest(nextQuest->GetQuestId())) - _player->CompleteQuest(nextQuest->GetQuestId()); - } - - _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); + _player->AddQuest(nextQuest, object); + if (_player->CanCompleteQuest(nextQuest->GetQuestId())) + _player->CompleteQuest(nextQuest->GetQuestId()); } - object->ToGameObject()->AI()->QuestReward(_player, quest, reward); + _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); } - break; - default: - break; - } + + object->ToGameObject()->AI()->QuestReward(_player, quest, reward); + } + break; + default: + break; } - else - _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); } + else + _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); } void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket & recvData) @@ -483,21 +496,31 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) { uint32 questId; uint64 playerGuid; - int8 unkByte; - recvData >> playerGuid >> questId >> unkByte; + bool autoCompleteMode; // 0 - standart complete quest mode with npc, 1 - auto-complete mode + recvData >> playerGuid >> questId >> autoCompleteMode; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, questId = %u", uint32(GUID_LOPART(playerGuid)), questId); - Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, playerGuid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); - if (!object || !object->hasInvolvedQuest(questId)) - return; + if (autoCompleteMode == 0) + { + Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, playerGuid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if (!object || !object->hasInvolvedQuest(questId)) + return; - // some kind of WPE protection - if (!_player->CanInteractWithQuestGiver(object)) - return; + // some kind of WPE protection + if (!_player->CanInteractWithQuestGiver(object)) + return; + } if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { + if (autoCompleteMode && !quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT)) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] by auto-submit flag for quest witch not suport it.", + _player->GetName(), _player->GetGUIDLow(), questId); + return; + } + if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) { sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!", @@ -522,7 +545,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) if (quest->GetReqItemsCount()) // some items required _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false); else // no items required - _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, playerGuid, true); + _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, playerGuid, !autoCompleteMode); } } } diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index c00f297a7e6..8719a710497 100755 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -148,6 +148,11 @@ enum __QuestFlags QUEST_FLAGS_SPECIAL_ITEM = 0x00020000, // has something to do with RequiredItemId and SourceItemId QUEST_FLAGS_OBJ_TEXT = 0x00040000, // use Objective text as Complete text QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future. + QUEST_FLAGS_AUTO_SUBMIT = 0x00100000, // Quests with this flag player submit automatically by special button in player gui + QUEST_FLAGS_AUTO_TAKE = 0x00200000, // Automatically suggestion of accepting quest. Not from npc. + //QUEST_FLAGS_UNK2 = 0x00400000, + //QUEST_FLAGS_UNK3 = 0x00800000, // Found in quest 14069 + //QUEST_FLAGS_UNK4 = 0x01000000, // ... 4.x added flags up to 0x80000000 - all unknown for now }; |