aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp50
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp139
-rwxr-xr-xsrc/server/game/Quests/QuestDef.h5
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
};