2010-10-07 15:35:36 +02:00
/*
2012-12-31 23:15:50 +01:00
* Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include "Common.h"
#include "Log.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "World.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "GossipDef.h"
#include "QuestDef.h"
#include "ObjectAccessor.h"
#include "Group.h"
2010-08-08 04:37:24 +02:00
#include "Battleground.h"
#include "BattlegroundAV.h"
2010-01-19 11:36:05 +01:00
#include "ScriptMgr.h"
2010-10-27 21:01:47 +02:00
#include "GameObjectAI.h"
2009-10-17 15:51:44 -07:00
2012-11-27 13:02:04 +01:00
void WorldSession :: HandleQuestgiverStatusQueryOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
uint64 guid ;
2012-08-05 19:40:30 -05:00
recvData >> guid ;
2011-12-22 15:00:06 +00:00
uint32 questStatus = DIALOG_STATUS_NONE ;
uint32 defstatus = DIALOG_STATUS_NONE ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
Object * questgiver = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
2010-04-07 19:14:10 +02:00
if ( ! questgiver )
2008-10-02 16:23:55 -05:00
{
2013-05-13 15:07:36 +02:00
TC_LOG_INFO ( LOG_FILTER_NETWORKIO , "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (Typeid: %u GUID: %u)" , GuidHigh2TypeId ( GUID_HIPART ( guid )), GUID_LOPART ( guid ));
2008-10-02 16:23:55 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
switch ( questgiver -> GetTypeId ())
2008-10-02 16:23:55 -05:00
{
case TYPEID_UNIT :
{
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u" , uint32 ( GUID_LOPART ( guid )));
2010-03-07 18:30:53 +01:00
Creature * cr_questgiver = questgiver -> ToCreature ();
2012-05-30 08:01:02 +02:00
if ( ! cr_questgiver -> IsHostileTo ( _player )) // do not show quest status to enemies
2008-10-02 16:23:55 -05:00
{
2010-12-22 21:25:23 +01:00
questStatus = sScriptMgr -> GetDialogStatus ( _player , cr_questgiver );
2010-04-07 22:59:46 +02:00
if ( questStatus > 6 )
2008-10-02 16:23:55 -05:00
questStatus = getDialogStatus ( _player , cr_questgiver , defstatus );
}
break ;
}
case TYPEID_GAMEOBJECT :
{
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u" , uint32 ( GUID_LOPART ( guid )));
2008-10-02 16:23:55 -05:00
GameObject * go_questgiver = ( GameObject * ) questgiver ;
2010-12-22 21:25:23 +01:00
questStatus = sScriptMgr -> GetDialogStatus ( _player , go_questgiver );
2010-04-07 22:59:46 +02:00
if ( questStatus > 6 )
2008-10-02 16:23:55 -05:00
questStatus = getDialogStatus ( _player , go_questgiver , defstatus );
break ;
}
default :
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_NETWORKIO , "QuestGiver called for unexpected type %u" , questgiver -> GetTypeId ());
2008-10-02 16:23:55 -05:00
break ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
//inform client about status of quest
_player -> PlayerTalkClass -> SendQuestGiverStatus ( questStatus , guid );
}
2009-10-17 15:51:44 -07:00
2012-08-05 21:52:36 -05:00
void WorldSession :: HandleQuestgiverHelloOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
uint64 guid ;
2012-08-05 19:40:30 -05:00
recvData >> guid ;
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u" , GUID_LOPART ( guid ));
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
Creature * creature = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_NONE );
if ( ! creature )
2008-10-02 16:23:55 -05:00
{
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him." ,
2008-11-10 09:04:23 -06:00
GUID_LOPART ( guid ));
2008-10-02 16:23:55 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// remove fake death
2012-02-03 19:12:41 +02:00
if ( GetPlayer () -> HasUnitState ( UNIT_STATE_DIED ))
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_FEIGN_DEATH );
2008-10-02 16:23:55 -05:00
// Stop the npc if moving
2011-10-07 11:08:09 -05:00
creature -> StopMoving ();
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
if ( sScriptMgr -> OnGossipHello ( _player , creature ))
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
_player -> PrepareGossipMenu ( creature , creature -> GetCreatureTemplate () -> GossipMenuId , true );
2011-10-07 11:08:09 -05:00
_player -> SendPreparedGossip ( creature );
2010-10-25 18:23:45 +02:00
2011-10-07 11:08:09 -05:00
creature -> AI () -> sGossipHello ( _player );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 21:52:36 -05:00
void WorldSession :: HandleQuestgiverAcceptQuestOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
uint64 guid ;
2012-05-30 08:01:02 +02:00
uint32 questId ;
2009-06-11 00:45:59 -05:00
uint32 unk1 ;
2012-08-05 19:40:30 -05:00
recvData >> guid >> questId >> unk1 ;
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u" , uint32 ( GUID_LOPART ( guid )), questId , unk1 );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
Object * object = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM | TYPEMASK_PLAYER );
2009-10-17 15:51:44 -07:00
2013-07-11 21:45:14 +02:00
#define CLOSE_GOSSIP_CLEAR_DIVIDER() \
do { \
_player->PlayerTalkClass->SendCloseGossip(); \
_player->SetDivider(0); \
} while (0)
2008-10-02 16:23:55 -05:00
// no or incorrect quest giver
2013-07-11 21:45:14 +02:00
if ( ! object )
2008-10-02 16:23:55 -05:00
{
2013-07-11 21:45:14 +02:00
CLOSE_GOSSIP_CLEAR_DIVIDER ();
2008-10-02 16:23:55 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2013-07-11 21:45:14 +02:00
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 ;
}
}
2011-05-30 02:59:37 +07:00
// some kind of WPE protection
2012-05-30 08:01:02 +02:00
if ( ! _player -> CanInteractWithQuestGiver ( object ))
2011-05-30 02:59:37 +07:00
return ;
2012-05-30 08:01:02 +02:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
2008-10-02 16:23:55 -05:00
{
// prevent cheating
2012-05-30 08:01:02 +02:00
if ( ! GetPlayer () -> CanTakeQuest ( quest , true ))
2008-10-02 16:23:55 -05:00
{
2013-07-11 21:45:14 +02:00
CLOSE_GOSSIP_CLEAR_DIVIDER ();
2008-10-02 16:23:55 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( _player -> GetDivider () != 0 )
2008-10-02 16:23:55 -05:00
{
2011-10-07 11:08:09 -05:00
Player * player = ObjectAccessor :: FindPlayer ( _player -> GetDivider ());
if ( player )
2008-10-02 16:23:55 -05:00
{
2011-10-07 11:08:09 -05:00
player -> SendPushToPartyResponse ( _player , QUEST_PARTY_MSG_ACCEPT_QUEST );
2010-04-07 22:59:46 +02:00
_player -> SetDivider ( 0 );
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( _player -> CanAddQuest ( quest , true ))
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
_player -> AddQuest ( quest , object );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( quest -> HasFlag ( QUEST_FLAGS_PARTY_ACCEPT ))
2009-12-19 18:08:07 +01:00
{
2011-10-07 10:54:53 -05:00
if ( Group * group = _player -> GetGroup ())
2009-12-19 18:08:07 +01:00
{
2011-10-07 10:54:53 -05:00
for ( GroupReference * itr = group -> GetFirstMember (); itr != NULL ; itr = itr -> next ())
2009-12-19 18:08:07 +01:00
{
2013-06-11 21:25:12 -02:30
Player * player = itr -> GetSource ();
2009-12-19 18:08:07 +01:00
2011-10-07 11:08:09 -05:00
if ( ! player || player == _player ) // not self
2009-12-19 18:08:07 +01:00
continue ;
2012-05-30 08:01:02 +02:00
if ( player -> CanTakeQuest ( quest , true ))
2009-12-19 18:08:07 +01:00
{
2011-10-07 11:08:09 -05:00
player -> SetDivider ( _player -> GetGUID ());
2009-12-19 18:08:07 +01:00
//need confirmation that any gossip window will close
2011-10-07 11:08:09 -05:00
player -> PlayerTalkClass -> SendCloseGossip ();
2009-12-19 18:08:07 +01:00
2012-05-30 08:01:02 +02:00
_player -> SendQuestConfirmAccept ( quest , player );
2009-12-19 18:08:07 +01:00
}
}
}
}
2012-05-30 08:01:02 +02:00
if ( _player -> CanCompleteQuest ( questId ))
_player -> CompleteQuest ( questId );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
switch ( object -> GetTypeId ())
2008-10-02 16:23:55 -05:00
{
case TYPEID_UNIT :
2012-05-30 08:01:02 +02:00
sScriptMgr -> OnQuestAccept ( _player , ( object -> ToCreature ()), quest );
2013-07-11 21:45:14 +02:00
object -> ToCreature () -> AI () -> sQuestAccept ( _player , quest );
2008-10-02 16:23:55 -05:00
break ;
case TYPEID_ITEM :
case TYPEID_CONTAINER :
{
2013-07-11 21:45:14 +02:00
Item * item = ( Item * ) object ;
sScriptMgr -> OnQuestAccept ( _player , item , quest );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// destroy not required for quest finish quest starting item
bool destroyItem = true ;
2009-12-17 12:13:33 +01:00
for ( int i = 0 ; i < QUEST_ITEM_OBJECTIVES_COUNT ; ++ i )
2008-10-02 16:23:55 -05:00
{
2013-07-11 21:45:14 +02:00
if ( quest -> RequiredItemId [ i ] == item -> GetEntry () && item -> GetTemplate () -> MaxCount > 0 )
2008-10-02 16:23:55 -05:00
{
destroyItem = false ;
break ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( destroyItem )
2013-07-11 21:45:14 +02:00
_player -> DestroyItem ( item -> GetBagSlot (), item -> GetSlot (), true );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
break ;
}
case TYPEID_GAMEOBJECT :
2013-07-11 21:45:14 +02:00
sScriptMgr -> OnQuestAccept ( _player , object -> ToGameObject (), quest );
object -> ToGameObject () -> AI () -> QuestAccept ( _player , quest );
2008-10-02 16:23:55 -05:00
break ;
2010-08-21 20:55:31 +02:00
default :
break ;
2008-10-02 16:23:55 -05:00
}
2011-05-26 23:57:17 +02:00
_player -> PlayerTalkClass -> SendCloseGossip ();
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( quest -> GetSrcSpell () > 0 )
_player -> CastSpell ( _player , quest -> GetSrcSpell (), true );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2011-05-26 23:57:17 +02:00
_player -> PlayerTalkClass -> SendCloseGossip ();
2013-07-11 21:45:14 +02:00
#undef CLOSE_GOSSIP_CLEAR_DIVIDER
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 21:52:36 -05:00
void WorldSession :: HandleQuestgiverQueryQuestOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
uint64 guid ;
2011-06-28 20:16:15 +02:00
uint32 questId ;
2009-06-11 00:45:59 -05:00
uint8 unk1 ;
2012-08-05 19:40:30 -05:00
recvData >> guid >> questId >> unk1 ;
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u" , uint32 ( GUID_LOPART ( guid )), questId , unk1 );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// Verify that the guid is valid and is a questgiver or involved in the requested quest
2011-06-28 20:16:15 +02:00
Object * object = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM );
if ( ! object || ( ! object -> hasQuest ( questId ) && ! object -> hasInvolvedQuest ( questId )))
2008-10-02 16:23:55 -05:00
{
2011-05-26 23:57:17 +02:00
_player -> PlayerTalkClass -> SendCloseGossip ();
2008-10-02 16:23:55 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
2008-10-02 16:23:55 -05:00
{
2011-06-28 20:16:15 +02:00
// not sure here what should happen to quests with QUEST_FLAGS_AUTOCOMPLETE
// if this breaks them, add && object->GetTypeId() == TYPEID_ITEM to this check
// item-started quests never have that flag
if ( ! _player -> CanTakeQuest ( quest , true ))
return ;
if ( quest -> IsAutoAccept () && _player -> CanAddQuest ( quest , true ))
2010-05-10 02:59:41 +02:00
{
2011-06-28 20:16:15 +02:00
_player -> AddQuest ( quest , object );
if ( _player -> CanCompleteQuest ( questId ))
_player -> CompleteQuest ( questId );
2010-05-10 02:59:41 +02:00
}
2010-04-25 23:52:33 +02:00
2011-06-28 20:16:15 +02:00
if ( quest -> HasFlag ( QUEST_FLAGS_AUTOCOMPLETE ))
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( quest , object -> GetGUID (), _player -> CanCompleteQuest ( quest -> GetQuestId ()), true );
2010-04-17 17:59:19 +02:00
else
2011-06-28 20:16:15 +02:00
_player -> PlayerTalkClass -> SendQuestGiverQuestDetails ( quest , object -> GetGUID (), true );
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2012-11-27 13:02:04 +01:00
void WorldSession :: HandleQuestQueryOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
2010-09-03 20:30:29 -07:00
if ( ! _player )
return ;
2012-05-30 08:01:02 +02:00
uint32 questId ;
2012-08-05 19:40:30 -05:00
recvData >> questId ;
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUEST_QUERY quest = %u" , questId );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
_player -> PlayerTalkClass -> SendQuestQueryResponse ( quest );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 21:52:36 -05:00
void WorldSession :: HandleQuestgiverChooseRewardOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
2011-06-28 20:16:15 +02:00
uint32 questId , reward ;
2008-10-02 16:23:55 -05:00
uint64 guid ;
2012-08-05 19:40:30 -05:00
recvData >> guid >> questId >> reward ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( reward >= QUEST_REWARD_CHOICES_COUNT )
2008-10-02 16:23:55 -05:00
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_NETWORKIO , "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (possible packet-hacking detected)" , _player -> GetName (). c_str (), _player -> GetGUIDLow (), reward );
2008-10-02 16:23:55 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u" , uint32 ( GUID_LOPART ( guid )), questId , reward );
2009-10-17 15:51:44 -07:00
2012-09-13 16:16:33 +01:00
Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId );
if ( ! quest )
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-09-13 16:16:33 +01:00
Object * object = _player ;
2009-10-17 15:51:44 -07:00
2012-09-13 16:16:33 +01:00
if ( ! quest -> HasFlag ( QUEST_FLAGS_AUTO_SUBMIT ))
2008-10-02 16:23:55 -05:00
{
2012-09-13 16:16:33 +01:00
object = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
if ( ! object || ! object -> hasInvolvedQuest ( questId ))
2011-06-03 11:54:44 +06:00
return ;
2009-10-17 15:51:44 -07:00
2012-09-13 16:16:33 +01:00
// 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 ()))
{
2013-05-21 09:55:09 +02:00
TC_LOG_ERROR ( LOG_FILTER_NETWORKIO , "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)" ,
2012-10-30 10:30:05 +01:00
_player -> GetName (). c_str (), _player -> GetGUIDLow (), questId );
2012-09-13 16:16:33 +01:00
return ;
}
if ( _player -> CanRewardQuest ( quest , reward , true ))
{
_player -> RewardQuest ( quest , reward , object );
switch ( object -> GetTypeId ())
{
case TYPEID_UNIT :
case TYPEID_PLAYER :
2008-10-02 16:23:55 -05:00
{
2012-09-13 16:16:33 +01:00
//For AutoSubmition was added plr case there as it almost same exclute AI script cases.
2013-01-14 11:12:58 +01:00
Creature * creatureQGiver = object -> ToCreature ();
2012-09-13 16:16:33 +01:00
if ( ! creatureQGiver || ! ( sScriptMgr -> OnQuestReward ( _player , creatureQGiver , quest , reward )))
{
// Send next quest
if ( Quest const * nextQuest = _player -> GetNextQuest ( guid , quest ))
2008-10-02 16:23:55 -05:00
{
2012-09-13 16:16:33 +01:00
if ( nextQuest -> IsAutoAccept () && _player -> CanAddQuest ( nextQuest , true ) && _player -> CanTakeQuest ( nextQuest , true ))
2011-06-18 17:15:52 +02:00
{
2012-09-13 16:16:33 +01:00
_player -> AddQuest ( nextQuest , object );
if ( _player -> CanCompleteQuest ( nextQuest -> GetQuestId ()))
_player -> CompleteQuest ( nextQuest -> GetQuestId ());
2011-06-18 17:15:52 +02:00
}
2010-10-25 18:23:45 +02:00
2012-09-13 16:16:33 +01:00
_player -> PlayerTalkClass -> SendQuestGiverQuestDetails ( nextQuest , guid , true );
2008-10-02 16:23:55 -05:00
}
2012-09-13 16:16:33 +01:00
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 ))
2008-10-02 16:23:55 -05:00
{
2012-09-13 16:16:33 +01:00
if ( nextQuest -> IsAutoAccept () && _player -> CanAddQuest ( nextQuest , true ) && _player -> CanTakeQuest ( nextQuest , true ))
2011-06-18 17:15:52 +02:00
{
2012-09-13 16:16:33 +01:00
_player -> AddQuest ( nextQuest , object );
if ( _player -> CanCompleteQuest ( nextQuest -> GetQuestId ()))
_player -> CompleteQuest ( nextQuest -> GetQuestId ());
2011-06-18 17:15:52 +02:00
}
2012-09-13 16:16:33 +01:00
_player -> PlayerTalkClass -> SendQuestGiverQuestDetails ( nextQuest , guid , true );
2008-10-02 16:23:55 -05:00
}
2012-09-13 16:16:33 +01:00
object -> ToGameObject () -> AI () -> QuestReward ( _player , quest , reward );
}
break ;
default :
break ;
2008-10-02 16:23:55 -05:00
}
}
2012-09-13 16:16:33 +01:00
else
_player -> PlayerTalkClass -> SendQuestGiverOfferReward ( quest , guid , true );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-27 13:02:04 +01:00
void WorldSession :: HandleQuestgiverRequestRewardOpcode ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
uint32 questId ;
2008-10-02 16:23:55 -05:00
uint64 guid ;
2012-08-05 19:40:30 -05:00
recvData >> guid >> questId ;
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u" , uint32 ( GUID_LOPART ( guid )), questId );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
Object * object = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
if ( ! object || ! object -> hasInvolvedQuest ( questId ))
2011-05-30 02:59:37 +07:00
return ;
// some kind of WPE protection
2012-05-30 08:01:02 +02:00
if ( ! _player -> CanInteractWithQuestGiver ( object ))
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( _player -> CanCompleteQuest ( questId ))
_player -> CompleteQuest ( questId );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( _player -> GetQuestStatus ( questId ) != QUEST_STATUS_COMPLETE )
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
_player -> PlayerTalkClass -> SendQuestGiverOfferReward ( quest , guid , true );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 19:40:30 -05:00
void WorldSession :: HandleQuestgiverCancel ( WorldPacket & /*recvData*/ )
2008-10-02 16:23:55 -05:00
{
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_CANCEL" );
2009-10-17 15:51:44 -07:00
2011-05-26 23:57:17 +02:00
_player -> PlayerTalkClass -> SendCloseGossip ();
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 19:40:30 -05:00
void WorldSession :: HandleQuestLogSwapQuest ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
uint8 slot1 , slot2 ;
2012-08-05 19:40:30 -05:00
recvData >> slot1 >> slot2 ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE )
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = %u, slot 2 = %u" , slot1 , slot2 );
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
GetPlayer () -> SwapQuestSlot ( slot1 , slot2 );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 19:40:30 -05:00
void WorldSession :: HandleQuestLogRemoveQuest ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
uint8 slot ;
2012-08-05 19:40:30 -05:00
recvData >> slot ;
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u" , slot );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( slot < MAX_QUEST_LOG_SIZE )
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( uint32 questId = _player -> GetQuestSlotQuestId ( slot ))
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( ! _player -> TakeQuestSourceItem ( questId , true ))
2008-10-02 16:23:55 -05:00
return ; // can't un-equip some items, reject quest cancel
2009-10-17 15:51:44 -07:00
2013-02-26 16:57:11 +01:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
2009-10-09 20:48:55 -07:00
{
2012-08-18 21:08:21 +01:00
if ( quest -> HasSpecialFlag ( QUEST_SPECIAL_FLAGS_TIMED ))
2012-05-30 08:01:02 +02:00
_player -> RemoveTimedQuest ( questId );
2013-02-26 17:14:13 +01:00
if ( quest -> HasFlag ( QUEST_FLAGS_FLAGS_PVP ))
{
_player -> pvpInfo . IsHostile = _player -> pvpInfo . IsInHostileArea || _player -> HasPvPForcingQuest ();
_player -> UpdatePvPState ();
}
2009-10-09 20:48:55 -07:00
}
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
_player -> TakeQuestSourceItem ( questId , true ); // remove quest src item from player
_player -> RemoveActiveQuest ( questId );
2012-09-18 14:29:53 +02:00
_player -> RemoveTimedAchievement ( ACHIEVEMENT_TIMED_TYPE_QUEST , questId );
2010-12-26 21:23:05 +01:00
2013-05-13 15:07:36 +02:00
TC_LOG_INFO ( LOG_FILTER_NETWORKIO , "Player %u abandoned quest %u" , _player -> GetGUIDLow (), questId );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
_player -> SetQuestSlot ( slot , 0 );
2009-10-17 15:51:44 -07:00
2012-07-09 11:08:33 +02:00
_player -> UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED , 1 );
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-12-22 04:34:26 +00:00
void WorldSession :: HandleQuestConfirmAccept ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
2011-12-22 04:34:26 +00:00
uint32 questId ;
2012-01-14 19:27:14 +00:00
recvData >> questId ;
2009-10-17 15:51:44 -07:00
2013-05-21 09:55:09 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT questId = %u" , questId );
2011-12-22 04:34:26 +00:00
if ( const Quest * quest = sObjectMgr -> GetQuestTemplate ( questId ))
2009-12-19 18:08:07 +01:00
{
2011-12-22 04:34:26 +00:00
if ( ! quest -> HasFlag ( QUEST_FLAGS_PARTY_ACCEPT ))
2009-12-19 18:08:07 +01:00
return ;
Player * pOriginalPlayer = ObjectAccessor :: FindPlayer ( _player -> GetDivider ());
if ( ! pOriginalPlayer )
return ;
2012-12-24 19:53:28 +01:00
if ( ! _player -> IsInSameRaidWith ( pOriginalPlayer ))
return ;
2009-12-19 18:08:07 +01:00
2011-12-22 04:34:26 +00:00
if ( _player -> CanAddQuest ( quest , true ))
_player -> AddQuest ( quest , NULL ); // NULL, this prevent DB script from duplicate running
2009-12-19 18:08:07 +01:00
_player -> SetDivider ( 0 );
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-05 19:40:30 -05:00
void WorldSession :: HandleQuestgiverCompleteQuest ( WorldPacket & recvData )
2008-10-02 16:23:55 -05:00
{
2011-12-22 04:08:48 +00:00
uint32 questId ;
uint64 playerGuid ;
2012-09-13 16:16:33 +01:00
bool autoCompleteMode ; // 0 - standart complete quest mode with npc, 1 - auto-complete mode
recvData >> playerGuid >> questId >> autoCompleteMode ;
2009-10-17 15:51:44 -07:00
2013-05-21 09:55:09 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, questId = %u" , uint32 ( GUID_LOPART ( playerGuid )), questId );
2011-05-30 02:59:37 +07:00
2013-06-11 22:07:11 +02:00
Object * object = ObjectAccessor :: GetObjectByTypeMask ( * _player , playerGuid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
2012-03-09 13:42:52 +01:00
if ( ! object || ! object -> hasInvolvedQuest ( questId ))
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-09-13 16:16:33 +01:00
if ( autoCompleteMode == 0 )
{
// some kind of WPE protection
if ( ! _player -> CanInteractWithQuestGiver ( object ))
return ;
}
2009-10-17 15:51:44 -07:00
2012-03-09 13:42:52 +01:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
2008-10-02 16:23:55 -05:00
{
2012-09-13 16:16:33 +01:00
if ( autoCompleteMode && ! quest -> HasFlag ( QUEST_FLAGS_AUTO_SUBMIT ))
{
2013-05-21 09:55:09 +02:00
TC_LOG_ERROR ( 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." ,
2012-10-30 10:30:05 +01:00
_player -> GetName (). c_str (), _player -> GetGUIDLow (), questId );
2012-09-13 16:16:33 +01:00
return ;
}
2012-03-09 13:42:52 +01:00
if ( ! _player -> CanSeeStartQuest ( quest ) && _player -> GetQuestStatus ( questId ) == QUEST_STATUS_NONE )
2010-12-18 15:29:11 +01:00
{
2013-05-21 09:55:09 +02:00
TC_LOG_ERROR ( LOG_FILTER_NETWORKIO , "Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!" ,
2012-10-24 13:29:34 +02:00
_player -> GetName (). c_str (), _player -> GetGUIDLow (), questId );
2010-12-18 15:29:11 +01:00
return ;
}
2013-03-08 21:41:30 +01:00
/// @todo need a virtual function
2010-12-18 15:29:11 +01:00
if ( _player -> InBattleground ())
if ( Battleground * bg = _player -> GetBattleground ())
2010-04-07 19:14:10 +02:00
if ( bg -> GetTypeID () == BATTLEGROUND_AV )
2011-12-22 04:08:48 +00:00
(( BattlegroundAV * ) bg ) -> HandleQuestComplete ( questId , _player );
2009-10-17 15:51:44 -07:00
2011-12-22 04:08:48 +00:00
if ( _player -> GetQuestStatus ( questId ) != QUEST_STATUS_COMPLETE )
2008-10-02 16:23:55 -05:00
{
2011-12-22 04:08:48 +00:00
if ( quest -> IsRepeatable ())
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( quest , playerGuid , _player -> CanCompleteRepeatableQuest ( quest ), false );
2008-10-02 16:23:55 -05:00
else
2011-12-22 04:08:48 +00:00
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( quest , playerGuid , _player -> CanRewardQuest ( quest , false ), false );
2008-10-02 16:23:55 -05:00
}
else
2009-06-11 00:45:59 -05:00
{
2011-12-22 04:08:48 +00:00
if ( quest -> GetReqItemsCount ()) // some items required
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( quest , playerGuid , _player -> CanRewardQuest ( quest , false ), false );
2009-06-11 00:45:59 -05:00
else // no items required
2012-09-13 16:16:33 +01:00
_player -> PlayerTalkClass -> SendQuestGiverOfferReward ( quest , playerGuid , ! autoCompleteMode );
2009-06-11 00:45:59 -05:00
}
2013-06-08 00:14:14 +03:00
if ( Creature * creature = object -> ToCreature ())
sScriptMgr -> OnQuestComplete ( _player , creature , quest );
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleQuestgiverQuestAutoLaunch ( WorldPacket & /*recvPacket*/ )
2008-10-02 16:23:55 -05:00
{
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_QUEST_AUTOLAUNCH" );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
void WorldSession :: HandlePushQuestToParty ( WorldPacket & recvPacket )
2008-10-02 16:23:55 -05:00
{
2009-07-01 17:32:20 -05:00
uint32 questId ;
recvPacket >> questId ;
2009-10-17 15:51:44 -07:00
2013-07-11 21:45:14 +02:00
if ( ! _player -> CanShareQuest ( questId ))
return ;
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u" , questId );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( Quest const * quest = sObjectMgr -> GetQuestTemplate ( questId ))
2008-10-02 16:23:55 -05:00
{
2011-10-07 10:54:53 -05:00
if ( Group * group = _player -> GetGroup ())
2008-10-02 16:23:55 -05:00
{
2011-10-07 10:54:53 -05:00
for ( GroupReference * itr = group -> GetFirstMember (); itr != NULL ; itr = itr -> next ())
2008-10-02 16:23:55 -05:00
{
2013-06-11 21:25:12 -02:30
Player * player = itr -> GetSource ();
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
if ( ! player || player == _player ) // skip self
2009-07-01 17:32:20 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( ! player -> SatisfyQuestStatus ( quest , false ))
2009-07-01 17:32:20 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendPushToPartyResponse ( player , QUEST_PARTY_MSG_HAVE_QUEST );
2009-07-01 17:32:20 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
if ( player -> GetQuestStatus ( questId ) == QUEST_STATUS_COMPLETE )
2009-07-01 17:32:20 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendPushToPartyResponse ( player , QUEST_PARTY_MSG_FINISH_QUEST );
2009-07-01 17:32:20 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( ! player -> CanTakeQuest ( quest , false ))
2009-07-01 17:32:20 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendPushToPartyResponse ( player , QUEST_PARTY_MSG_CANT_TAKE_QUEST );
2009-07-01 17:32:20 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
if ( ! player -> SatisfyQuestLog ( false ))
2009-07-01 17:32:20 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendPushToPartyResponse ( player , QUEST_PARTY_MSG_LOG_FULL );
2009-07-01 17:32:20 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
if ( player -> GetDivider () != 0 )
2009-07-01 17:32:20 -05:00
{
2011-10-07 11:08:09 -05:00
_player -> SendPushToPartyResponse ( player , QUEST_PARTY_MSG_BUSY );
2009-07-01 17:32:20 -05:00
continue ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2013-07-11 21:45:14 +02:00
_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 );
}
2008-10-02 16:23:55 -05:00
}
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestPushResult ( WorldPacket & recvPacket )
{
uint64 guid ;
2013-07-11 21:45:14 +02:00
uint32 questId ;
2008-10-02 16:23:55 -05:00
uint8 msg ;
2013-07-11 21:45:14 +02:00
recvPacket >> guid >> questId >> msg ;
2009-10-17 15:51:44 -07:00
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received MSG_QUEST_PUSH_RESULT" );
2009-10-17 15:51:44 -07:00
2013-07-11 21:45:14 +02:00
if ( _player -> GetDivider () && _player -> GetDivider () == guid )
2008-10-02 16:23:55 -05:00
{
2011-10-07 11:08:09 -05:00
Player * player = ObjectAccessor :: FindPlayer ( _player -> GetDivider ());
if ( player )
2008-10-02 16:23:55 -05:00
{
2013-07-11 21:45:14 +02:00
WorldPacket data ( MSG_QUEST_PUSH_RESULT , 8 + 4 + 1 );
data << uint64 ( _player -> GetGUID ());
2008-10-02 16:23:55 -05:00
data << uint8 ( msg ); // valid values: 0-8
2011-10-07 11:08:09 -05:00
player -> GetSession () -> SendPacket ( & data );
2010-04-07 22:59:46 +02:00
_player -> SetDivider ( 0 );
2008-10-02 16:23:55 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2011-10-07 11:08:09 -05:00
uint32 WorldSession :: getDialogStatus ( Player * player , Object * questgiver , uint32 defstatus )
2008-10-02 16:23:55 -05:00
{
uint32 result = defstatus ;
2009-10-17 15:51:44 -07:00
2010-09-13 13:18:27 +02:00
QuestRelationBounds qr ;
QuestRelationBounds qir ;
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
switch ( questgiver -> GetTypeId ())
2008-10-02 16:23:55 -05:00
{
case TYPEID_GAMEOBJECT :
{
2010-12-22 21:25:23 +01:00
qr = sObjectMgr -> GetGOQuestRelationBounds ( questgiver -> GetEntry ());
qir = sObjectMgr -> GetGOQuestInvolvedRelationBounds ( questgiver -> GetEntry ());
2008-10-02 16:23:55 -05:00
break ;
}
case TYPEID_UNIT :
{
2010-12-22 21:25:23 +01:00
qr = sObjectMgr -> GetCreatureQuestRelationBounds ( questgiver -> GetEntry ());
qir = sObjectMgr -> GetCreatureQuestInvolvedRelationBounds ( questgiver -> GetEntry ());
2008-10-02 16:23:55 -05:00
break ;
}
default :
//its imposible, but check ^)
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_NETWORKIO , "Warning: GetDialogStatus called for unexpected type %u" , questgiver -> GetTypeId ());
2008-10-02 16:23:55 -05:00
return DIALOG_STATUS_NONE ;
}
2009-10-17 15:51:44 -07:00
2010-09-13 13:18:27 +02:00
for ( QuestRelations :: const_iterator i = qir . first ; i != qir . second ; ++ i )
2008-10-02 16:23:55 -05:00
{
uint32 result2 = 0 ;
uint32 quest_id = i -> second ;
2012-05-30 08:01:02 +02:00
Quest const * quest = sObjectMgr -> GetQuestTemplate ( quest_id );
if ( ! quest )
continue ;
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
ConditionList conditions = sConditionMgr -> GetConditionsForNotGroupedEntry ( CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK , quest -> GetQuestId ());
2012-02-10 14:18:59 +01:00
if ( ! sConditionMgr -> IsObjectMeetToConditions ( player , conditions ))
2010-09-20 10:19:20 +02:00
continue ;
2011-10-07 11:08:09 -05:00
QuestStatus status = player -> GetQuestStatus ( quest_id );
if (( status == QUEST_STATUS_COMPLETE && ! player -> GetQuestRewardStatus ( quest_id )) ||
2012-05-30 08:01:02 +02:00
( quest -> IsAutoComplete () && player -> CanTakeQuest ( quest , false )))
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( quest -> IsAutoComplete () && quest -> IsRepeatable ())
2008-10-02 16:23:55 -05:00
result2 = DIALOG_STATUS_REWARD_REP ;
else
result2 = DIALOG_STATUS_REWARD ;
}
2010-04-07 22:59:46 +02:00
else if ( status == QUEST_STATUS_INCOMPLETE )
2008-10-02 16:23:55 -05:00
result2 = DIALOG_STATUS_INCOMPLETE ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( result2 > result )
result = result2 ;
}
2009-10-17 15:51:44 -07:00
2010-09-13 13:18:27 +02:00
for ( QuestRelations :: const_iterator i = qr . first ; i != qr . second ; ++ i )
2008-10-02 16:23:55 -05:00
{
uint32 result2 = 0 ;
uint32 quest_id = i -> second ;
2012-05-30 08:01:02 +02:00
Quest const * quest = sObjectMgr -> GetQuestTemplate ( quest_id );
if ( ! quest )
2008-10-02 16:23:55 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
ConditionList conditions = sConditionMgr -> GetConditionsForNotGroupedEntry ( CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK , quest -> GetQuestId ());
2012-02-10 14:18:59 +01:00
if ( ! sConditionMgr -> IsObjectMeetToConditions ( player , conditions ))
2010-09-20 10:19:20 +02:00
continue ;
2011-10-07 11:08:09 -05:00
QuestStatus status = player -> GetQuestStatus ( quest_id );
2010-04-07 22:59:46 +02:00
if ( status == QUEST_STATUS_NONE )
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( player -> CanSeeStartQuest ( quest ))
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( player -> SatisfyQuestLevel ( quest , false ))
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( quest -> IsAutoComplete () || ( quest -> IsRepeatable () && player -> IsQuestRewarded ( quest_id )))
2008-10-02 16:23:55 -05:00
result2 = DIALOG_STATUS_REWARD_REP ;
2012-05-30 08:01:02 +02:00
else if ( player -> getLevel () <= (( player -> GetQuestLevel ( quest ) == - 1 ) ? player -> getLevel () : player -> GetQuestLevel ( quest ) + sWorld -> getIntConfig ( CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF )))
2008-10-02 16:23:55 -05:00
{
2012-05-30 08:01:02 +02:00
if ( quest -> HasFlag ( QUEST_FLAGS_DAILY ) || quest -> HasFlag ( QUEST_FLAGS_WEEKLY ))
2008-10-02 16:23:55 -05:00
result2 = DIALOG_STATUS_AVAILABLE_REP ;
else
result2 = DIALOG_STATUS_AVAILABLE ;
}
else
2010-04-11 11:16:42 +04:00
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE ;
2008-10-02 16:23:55 -05:00
}
else
result2 = DIALOG_STATUS_UNAVAILABLE ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( result2 > result )
result = result2 ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return result ;
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleQuestgiverStatusMultipleQuery ( WorldPacket & /*recvPacket*/ )
2008-10-02 16:23:55 -05:00
{
2013-05-13 15:07:36 +02:00
TC_LOG_DEBUG ( LOG_FILTER_NETWORKIO , "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY" );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2011-12-22 15:00:06 +00:00
WorldPacket data ( SMSG_QUESTGIVER_STATUS_MULTIPLE , 4 + 8 + 4 );
2008-10-02 16:23:55 -05:00
data << uint32 ( count ); // placeholder
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( Player :: ClientGUIDs :: const_iterator itr = _player -> m_clientGUIDs . begin (); itr != _player -> m_clientGUIDs . end (); ++ itr )
2008-10-02 16:23:55 -05:00
{
2011-12-22 15:00:06 +00:00
uint32 questStatus = DIALOG_STATUS_NONE ;
uint32 defstatus = DIALOG_STATUS_NONE ;
2009-10-17 15:51:44 -07:00
2009-08-23 22:09:43 -05:00
if ( IS_CRE_OR_VEH_OR_PET_GUID ( * itr ))
2008-10-02 16:23:55 -05:00
{
2009-05-04 17:26:24 -05:00
// need also pet quests case support
2011-09-15 14:08:17 +02:00
Creature * questgiver = ObjectAccessor :: GetCreatureOrPetOrVehicle ( * GetPlayer (), * itr );
2010-04-07 19:14:10 +02:00
if ( ! questgiver || questgiver -> IsHostileTo ( _player ))
2008-10-02 16:23:55 -05:00
continue ;
2010-04-07 19:14:10 +02:00
if ( ! questgiver -> HasFlag ( UNIT_NPC_FLAGS , UNIT_NPC_FLAG_QUESTGIVER ))
2008-10-02 16:23:55 -05:00
continue ;
2010-12-22 21:25:23 +01:00
questStatus = sScriptMgr -> GetDialogStatus ( _player , questgiver );
2010-04-07 22:59:46 +02:00
if ( questStatus > 6 )
2008-10-02 16:23:55 -05:00
questStatus = getDialogStatus ( _player , questgiver , defstatus );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
data << uint64 ( questgiver -> GetGUID ());
2011-12-22 15:00:06 +00:00
data << uint32 ( questStatus );
2008-10-02 16:23:55 -05:00
++ count ;
}
2010-04-07 19:14:10 +02:00
else if ( IS_GAMEOBJECT_GUID ( * itr ))
2008-10-02 16:23:55 -05:00
{
2011-09-15 14:08:17 +02:00
GameObject * questgiver = GetPlayer () -> GetMap () -> GetGameObject ( * itr );
2010-04-07 19:14:10 +02:00
if ( ! questgiver )
2008-10-02 16:23:55 -05:00
continue ;
2010-04-07 19:14:10 +02:00
if ( questgiver -> GetGoType () != GAMEOBJECT_TYPE_QUESTGIVER )
2008-10-02 16:23:55 -05:00
continue ;
2010-12-22 21:25:23 +01:00
questStatus = sScriptMgr -> GetDialogStatus ( _player , questgiver );
2010-04-07 22:59:46 +02:00
if ( questStatus > 6 )
2008-10-02 16:23:55 -05:00
questStatus = getDialogStatus ( _player , questgiver , defstatus );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
data << uint64 ( questgiver -> GetGUID ());
2011-12-22 15:00:06 +00:00
data << uint32 ( questStatus );
2008-10-02 16:23:55 -05:00
++ count ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
data . put < uint32 > ( 0 , count ); // write real count
SendPacket ( & data );
}
2010-02-14 19:13:14 -07:00
2012-08-05 21:52:36 -05:00
void WorldSession :: HandleQueryQuestsCompleted ( WorldPacket & /*recvData*/ )
2010-02-14 19:13:14 -07:00
{
2011-07-08 10:54:46 +02:00
size_t rew_count = _player -> GetRewardedQuestCount ();
2010-02-14 19:13:14 -07:00
2011-07-08 10:54:46 +02:00
WorldPacket data ( SMSG_QUERY_QUESTS_COMPLETED_RESPONSE , 4 + 4 * rew_count );
data << uint32 ( rew_count );
const RewardedQuestSet & rewQuests = _player -> getRewardedQuests ();
for ( RewardedQuestSet :: const_iterator itr = rewQuests . begin (); itr != rewQuests . end (); ++ itr )
2010-12-26 04:16:18 +01:00
data << uint32 ( * itr );
2010-02-14 19:13:14 -07:00
SendPacket ( & data );
}