2008-10-02 16:23:55 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05:00
*
* 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
2008-10-14 11:57:03 -05:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* 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, write to the Free Software
2008-10-14 11:57:03 -05:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 "ScriptCalls.h"
#include "Group.h"
2008-11-21 19:45:49 -06:00
#include "BattleGround.h"
#include "BattleGroundAV.h"
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestgiverStatusQueryOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
recv_data >> guid ;
uint8 questStatus = DIALOG_STATUS_NONE ;
uint8 defstatus = DIALOG_STATUS_NONE ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Object * questgiver = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
if ( ! questgiver )
{
sLog . outDetail ( "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)" , GuidHigh2TypeId ( GUID_HIPART ( guid )), GUID_LOPART ( guid ));
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
switch ( questgiver -> GetTypeId ())
{
case TYPEID_UNIT :
{
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u" , uint32 ( GUID_LOPART ( guid )) );
Creature * cr_questgiver = ( Creature * ) questgiver ;
if ( ! cr_questgiver -> IsHostileTo ( _player )) // not show quest status to enemies
{
questStatus = Script -> NPCDialogStatus ( _player , cr_questgiver );
if ( questStatus > 6 )
questStatus = getDialogStatus ( _player , cr_questgiver , defstatus );
}
break ;
}
case TYPEID_GAMEOBJECT :
{
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u" , uint32 ( GUID_LOPART ( guid )) );
GameObject * go_questgiver = ( GameObject * ) questgiver ;
questStatus = Script -> GODialogStatus ( _player , go_questgiver );
if ( questStatus > 6 )
questStatus = getDialogStatus ( _player , go_questgiver , defstatus );
break ;
}
default :
sLog . outError ( "QuestGiver called for unexpected type %u" , questgiver -> GetTypeId ());
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
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestgiverHelloOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
recv_data >> guid ;
2009-10-17 15:51:44 -07:00
2008-11-10 09:04:23 -06:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u" , GUID_LOPART ( guid ));
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * pCreature = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_NONE );
2008-10-02 16:23:55 -05:00
if ( ! pCreature )
{
2008-11-10 09:04:23 -06:00
sLog . outDebug ( "WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him." ,
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
if ( GetPlayer () -> hasUnitState ( UNIT_STAT_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
pCreature -> StopMoving ();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( Script -> GossipHello ( _player , pCreature ) )
return ;
2009-10-17 15:51:44 -07:00
2008-11-05 09:22:56 -06:00
pCreature -> prepareGossipMenu ( _player );
pCreature -> sendPreparedGossip ( _player );
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 :: HandleQuestgiverAcceptQuestOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
uint32 quest ;
2009-06-11 00:45:59 -05:00
uint32 unk1 ;
recv_data >> guid >> quest >> unk1 ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( ! GetPlayer () -> isAlive ())
return ;
2009-10-17 15:51:44 -07:00
2009-06-11 00:45:59 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u" , uint32 ( GUID_LOPART ( guid )), quest , unk1 );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Object * pObject = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM | TYPEMASK_PLAYER );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// no or incorrect quest giver
if ( ! pObject
2009-10-18 18:38:46 -07:00
|| ( pObject -> GetTypeId () != TYPEID_PLAYER && ! pObject -> hasQuest ( quest ))
|| ( pObject -> GetTypeId () == TYPEID_PLAYER && ! (( Player * ) pObject ) -> CanShareQuest ( quest ))
2008-10-02 16:23:55 -05:00
)
{
_player -> PlayerTalkClass -> CloseGossip ();
_player -> SetDivider ( 0 );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Quest const * qInfo = objmgr . GetQuestTemplate ( quest );
if ( qInfo )
{
// prevent cheating
if ( ! GetPlayer () -> CanTakeQuest ( qInfo , true ) )
{
_player -> PlayerTalkClass -> CloseGossip ();
_player -> SetDivider ( 0 );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> GetDivider () != 0 )
{
Player * pPlayer = ObjectAccessor :: FindPlayer ( _player -> GetDivider () );
if ( pPlayer )
{
pPlayer -> SendPushToPartyResponse ( _player , QUEST_PARTY_MSG_ACCEPT_QUEST );
_player -> SetDivider ( 0 );
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> CanAddQuest ( qInfo , true ) )
{
_player -> AddQuest ( qInfo , pObject );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> CanCompleteQuest ( quest ) )
_player -> CompleteQuest ( quest );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
switch ( pObject -> GetTypeId ())
{
case TYPEID_UNIT :
Script -> QuestAccept ( _player , (( Creature * ) pObject ), qInfo );
break ;
case TYPEID_ITEM :
case TYPEID_CONTAINER :
{
Script -> ItemQuestAccept ( _player , (( Item * ) pObject ), qInfo );
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-10-17 16:20:24 -07:00
for ( int i = 0 ; i < QUEST_OBJECTIVES_COUNT ; ++ i )
2008-10-02 16:23:55 -05:00
{
2009-01-03 11:06:51 -06:00
if (( qInfo -> ReqItemId [ i ] == (( Item * ) pObject ) -> GetEntry ()) && ((( Item * ) pObject ) -> GetProto () -> MaxCount > 0 ))
2008-10-02 16:23:55 -05:00
{
destroyItem = false ;
break ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( destroyItem )
_player -> DestroyItem ((( Item * ) pObject ) -> GetBagSlot (),(( Item * ) pObject ) -> GetSlot (), true );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
break ;
}
case TYPEID_GAMEOBJECT :
Script -> GOQuestAccept ( _player , (( GameObject * ) pObject ), qInfo );
break ;
}
_player -> PlayerTalkClass -> CloseGossip ();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( qInfo -> GetSrcSpell () > 0 )
_player -> CastSpell ( _player , qInfo -> 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
2008-10-02 16:23:55 -05:00
_player -> PlayerTalkClass -> CloseGossip ();
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleQuestgiverQueryQuestOpcode ( WorldPacket & recv_data )
2008-10-02 16:23:55 -05:00
{
uint64 guid ;
uint32 quest ;
2009-06-11 00:45:59 -05:00
uint8 unk1 ;
recv_data >> guid >> quest >> unk1 ;
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u" , uint32 ( GUID_LOPART ( guid )), quest , 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
Object * pObject = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM );
if ( ! pObject ||! pObject -> hasQuest ( quest ) && ! pObject -> hasInvolvedQuest ( quest ))
{
_player -> PlayerTalkClass -> CloseGossip ();
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Quest const * pQuest = objmgr . GetQuestTemplate ( quest );
if ( pQuest )
{
_player -> PlayerTalkClass -> SendQuestGiverQuestDetails ( pQuest , pObject -> GetGUID (), true );
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestQueryOpcode ( WorldPacket & recv_data )
{
uint32 quest ;
recv_data >> quest ;
sLog . outDebug ( "WORLD: Received CMSG_QUEST_QUERY quest = %u" , quest );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Quest const * pQuest = objmgr . GetQuestTemplate ( quest );
if ( pQuest )
{
_player -> PlayerTalkClass -> SendQuestQueryResponse ( pQuest );
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestgiverChooseRewardOpcode ( WorldPacket & recv_data )
{
uint32 quest , reward ;
uint64 guid ;
recv_data >> guid >> quest >> reward ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( reward >= QUEST_REWARD_CHOICES_COUNT )
{
sLog . outError ( "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)" , _player -> GetName (), _player -> GetGUIDLow (), reward );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( ! GetPlayer () -> isAlive ())
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u" , uint32 ( GUID_LOPART ( guid )), quest , reward );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Object * pObject = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
if ( ! pObject )
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( ! pObject -> hasInvolvedQuest ( quest ))
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Quest const * pQuest = objmgr . GetQuestTemplate ( quest );
if ( pQuest )
{
if ( _player -> CanRewardQuest ( pQuest , reward , true ) )
{
_player -> RewardQuest ( pQuest , reward , pObject );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
switch ( pObject -> GetTypeId ())
{
case TYPEID_UNIT :
if ( ! ( Script -> ChooseReward ( _player , (( Creature * ) pObject ), pQuest , reward )) )
{
// Send next quest
if ( Quest const * nextquest = _player -> GetNextQuest ( guid , pQuest ) )
_player -> PlayerTalkClass -> SendQuestGiverQuestDetails ( nextquest , guid , true );
}
break ;
case TYPEID_GAMEOBJECT :
if ( ! Script -> GOChooseReward ( _player , (( GameObject * ) pObject ), pQuest , reward ) )
{
// Send next quest
if ( Quest const * nextquest = _player -> GetNextQuest ( guid , pQuest ) )
_player -> PlayerTalkClass -> SendQuestGiverQuestDetails ( nextquest , guid , true );
}
break ;
}
}
else
_player -> PlayerTalkClass -> SendQuestGiverOfferReward ( pQuest , guid , true );
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestgiverRequestRewardOpcode ( WorldPacket & recv_data )
{
uint32 quest ;
uint64 guid ;
recv_data >> guid >> quest ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( ! GetPlayer () -> isAlive ())
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u" , uint32 ( GUID_LOPART ( guid )), quest );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Object * pObject = ObjectAccessor :: GetObjectByTypeMask ( * _player , guid , TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT );
if ( ! pObject ||! pObject -> hasInvolvedQuest ( quest ))
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> CanCompleteQuest ( quest ) )
_player -> CompleteQuest ( quest );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> GetQuestStatus ( quest ) != QUEST_STATUS_COMPLETE )
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( Quest const * pQuest = objmgr . GetQuestTemplate ( quest ))
_player -> PlayerTalkClass -> SendQuestGiverOfferReward ( pQuest , guid , true );
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestgiverCancel ( WorldPacket & /*recv_data*/ )
{
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_CANCEL" );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
_player -> PlayerTalkClass -> CloseGossip ();
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestLogSwapQuest ( WorldPacket & recv_data )
{
uint8 slot1 , slot2 ;
recv_data >> slot1 >> slot2 ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE )
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = %u, slot 2 = %u" , slot1 , slot2 );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
GetPlayer () -> SwapQuestSlot ( slot1 , slot2 );
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void WorldSession :: HandleQuestLogRemoveQuest ( WorldPacket & recv_data )
{
uint8 slot ;
recv_data >> slot ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u" , slot );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( slot < MAX_QUEST_LOG_SIZE )
{
if ( uint32 quest = _player -> GetQuestSlotQuestId ( slot ))
{
if ( ! _player -> TakeQuestSourceItem ( quest , true ))
return ; // can't un-equip some items, reject quest cancel
2009-10-17 15:51:44 -07:00
2009-10-09 20:48:55 -07:00
if ( const Quest * pQuest = objmgr . GetQuestTemplate ( quest ))
{
if ( pQuest -> HasFlag ( QUEST_TRINITY_FLAGS_TIMED ))
_player -> RemoveTimedQuest ( quest );
}
2009-10-17 15:51:44 -07:00
2009-09-09 13:57:43 +01:00
_player -> TakeQuestSourceItem ( quest , true ); // remove quest src item from player
2009-09-09 13:04:58 -04:00
_player -> SetQuestStatus ( quest , QUEST_STATUS_NONE );
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
2009-05-05 14:49:15 -05:00
_player -> GetAchievementMgr (). UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED , 1 );
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 :: HandleQuestConfirmAccept ( WorldPacket & recv_data )
{
uint32 quest ;
recv_data >> quest ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u" , quest );
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleQuestgiverCompleteQuest ( WorldPacket & recv_data )
2008-10-02 16:23:55 -05:00
{
uint32 quest ;
uint64 guid ;
recv_data >> guid >> quest ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( ! GetPlayer () -> isAlive ())
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u" , uint32 ( GUID_LOPART ( guid )), quest );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
Quest const * pQuest = objmgr . GetQuestTemplate ( quest );
if ( pQuest )
{
2008-11-21 19:45:49 -06:00
// TODO: need a virtual function
if ( GetPlayer () -> InBattleGround ())
if ( BattleGround * bg = GetPlayer () -> GetBattleGround ())
if ( bg -> GetTypeID () == BATTLEGROUND_AV )
(( BattleGroundAV * ) bg ) -> HandleQuestComplete ( quest , GetPlayer ());
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> GetQuestStatus ( quest ) != QUEST_STATUS_COMPLETE )
{
if ( pQuest -> IsRepeatable () )
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( pQuest , guid , _player -> CanCompleteRepeatableQuest ( pQuest ), false );
else
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( pQuest , guid , _player -> CanRewardQuest ( pQuest , false ), false );
}
else
2009-06-11 00:45:59 -05:00
{
if ( pQuest -> GetReqItemsCount ()) // some items required
_player -> PlayerTalkClass -> SendQuestGiverRequestItems ( pQuest , guid , _player -> CanRewardQuest ( pQuest , false ), false );
else // no items required
_player -> PlayerTalkClass -> SendQuestGiverOfferReward ( pQuest , guid , true );
}
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
{
2009-05-31 15:56:51 -05:00
sLog . outDebug ( "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
2009-07-01 17:32:20 -05:00
sLog . outDebug ( "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u" , questId );
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( Quest const * pQuest = objmgr . GetQuestTemplate ( questId ))
2008-10-02 16:23:55 -05:00
{
2009-07-01 17:32:20 -05:00
if ( Group * pGroup = _player -> GetGroup ())
2008-10-02 16:23:55 -05:00
{
2009-10-17 16:20:24 -07:00
for ( GroupReference * itr = pGroup -> GetFirstMember (); itr != NULL ; itr = itr -> next ())
2008-10-02 16:23:55 -05:00
{
2009-07-01 17:32:20 -05:00
Player * pPlayer = itr -> getSource ();
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( ! pPlayer || pPlayer == _player ) // skip self
continue ;
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
_player -> SendPushToPartyResponse ( pPlayer , QUEST_PARTY_MSG_SHARING_QUEST );
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( ! pPlayer -> SatisfyQuestStatus ( pQuest , false ))
{
_player -> SendPushToPartyResponse ( pPlayer , QUEST_PARTY_MSG_HAVE_QUEST );
continue ;
}
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( pPlayer -> GetQuestStatus ( questId ) == QUEST_STATUS_COMPLETE )
{
_player -> SendPushToPartyResponse ( pPlayer , QUEST_PARTY_MSG_FINISH_QUEST );
continue ;
}
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( ! pPlayer -> CanTakeQuest ( pQuest , false ))
{
_player -> SendPushToPartyResponse ( pPlayer , QUEST_PARTY_MSG_CANT_TAKE_QUEST );
continue ;
}
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( ! pPlayer -> SatisfyQuestLog ( false ))
{
_player -> SendPushToPartyResponse ( pPlayer , QUEST_PARTY_MSG_LOG_FULL );
continue ;
}
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
if ( pPlayer -> GetDivider () != 0 )
{
_player -> SendPushToPartyResponse ( pPlayer , QUEST_PARTY_MSG_BUSY );
continue ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-07-01 17:32:20 -05:00
pPlayer -> PlayerTalkClass -> SendQuestGiverQuestDetails ( pQuest , _player -> GetGUID (), true );
pPlayer -> SetDivider ( _player -> GetGUID ());
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 ;
uint8 msg ;
recvPacket >> guid >> msg ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: Received MSG_QUEST_PUSH_RESULT" );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( _player -> GetDivider () != 0 )
{
Player * pPlayer = ObjectAccessor :: FindPlayer ( _player -> GetDivider () );
if ( pPlayer )
{
WorldPacket data ( MSG_QUEST_PUSH_RESULT , ( 8 + 1 ) );
data << uint64 ( guid );
data << uint8 ( msg ); // valid values: 0-8
pPlayer -> GetSession () -> SendPacket ( & data );
_player -> SetDivider ( 0 );
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 WorldSession :: getDialogStatus ( Player * pPlayer , Object * questgiver , uint32 defstatus )
{
uint32 result = defstatus ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
QuestRelations const * qir ;
QuestRelations const * qr ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
switch ( questgiver -> GetTypeId ())
{
case TYPEID_GAMEOBJECT :
{
qir = & objmgr . mGOQuestInvolvedRelations ;
qr = & objmgr . mGOQuestRelations ;
break ;
}
case TYPEID_UNIT :
{
qir = & objmgr . mCreatureQuestInvolvedRelations ;
qr = & objmgr . mCreatureQuestRelations ;
break ;
}
default :
//its imposible, but check ^)
sLog . outError ( "Warning: GetDialogStatus called for unexpected type %u" , questgiver -> GetTypeId ());
return DIALOG_STATUS_NONE ;
}
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( QuestRelations :: const_iterator i = qir -> lower_bound ( questgiver -> GetEntry ()); i != qir -> upper_bound ( questgiver -> GetEntry ()); ++ i )
2008-10-02 16:23:55 -05:00
{
uint32 result2 = 0 ;
uint32 quest_id = i -> second ;
Quest const * pQuest = objmgr . GetQuestTemplate ( quest_id );
if ( ! pQuest ) continue ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
QuestStatus status = pPlayer -> GetQuestStatus ( quest_id );
if ( ( status == QUEST_STATUS_COMPLETE && ! pPlayer -> GetQuestRewardStatus ( quest_id )) ||
( pQuest -> IsAutoComplete () && pPlayer -> CanTakeQuest ( pQuest , false )) )
{
if ( pQuest -> IsAutoComplete () && pQuest -> IsRepeatable () )
result2 = DIALOG_STATUS_REWARD_REP ;
else
result2 = DIALOG_STATUS_REWARD ;
}
else if ( status == QUEST_STATUS_INCOMPLETE )
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
2009-10-17 16:20:24 -07:00
for ( QuestRelations :: const_iterator i = qr -> lower_bound ( questgiver -> GetEntry ()); i != qr -> upper_bound ( questgiver -> GetEntry ()); ++ i )
2008-10-02 16:23:55 -05:00
{
uint32 result2 = 0 ;
uint32 quest_id = i -> second ;
Quest const * pQuest = objmgr . GetQuestTemplate ( quest_id );
if ( ! pQuest )
continue ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
QuestStatus status = pPlayer -> GetQuestStatus ( quest_id );
if ( status == QUEST_STATUS_NONE )
{
if ( pPlayer -> CanSeeStartQuest ( pQuest ) )
{
if ( pPlayer -> SatisfyQuestLevel ( pQuest , false ) )
{
if ( pQuest -> IsAutoComplete () || ( pQuest -> IsRepeatable () && pPlayer -> getQuestStatusMap ()[ quest_id ]. m_rewarded ))
result2 = DIALOG_STATUS_REWARD_REP ;
2009-11-13 17:15:59 +01:00
else if ( pPlayer -> getLevel () <= (( pPlayer -> GetQuestLevel ( pQuest ) == - 1 ) ? pPlayer -> getLevel () : pPlayer -> GetQuestLevel ( pQuest ) + sWorld . getConfig ( CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF )))
2008-10-02 16:23:55 -05:00
{
2009-06-17 21:48:19 -05:00
if ( pQuest -> IsDaily ())
2008-10-02 16:23:55 -05:00
result2 = DIALOG_STATUS_AVAILABLE_REP ;
else
result2 = DIALOG_STATUS_AVAILABLE ;
}
else
result2 = DIALOG_STATUS_CHAT ;
}
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
{
sLog . outDebug ( "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
2008-10-02 16:23:55 -05:00
WorldPacket data ( SMSG_QUESTGIVER_STATUS_MULTIPLE , 4 );
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
{
uint8 questStatus = DIALOG_STATUS_NONE ;
uint8 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
Creature * questgiver = ObjectAccessor :: GetCreatureOrPetOrVehicle ( * GetPlayer (), * itr );
2008-10-02 16:23:55 -05:00
if ( ! questgiver || questgiver -> IsHostileTo ( _player ))
continue ;
if ( ! questgiver -> HasFlag ( UNIT_NPC_FLAGS , UNIT_NPC_FLAG_QUESTGIVER ))
continue ;
questStatus = Script -> NPCDialogStatus ( _player , questgiver );
if ( questStatus > 6 )
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 ());
data << uint8 ( questStatus );
++ count ;
}
else if ( IS_GAMEOBJECT_GUID ( * itr ))
{
2009-04-20 20:28:19 -05:00
GameObject * questgiver = GetPlayer () -> GetMap () -> GetGameObject ( * itr );
2008-10-02 16:23:55 -05:00
if ( ! questgiver )
continue ;
if ( questgiver -> GetGoType () != GAMEOBJECT_TYPE_QUESTGIVER )
continue ;
questStatus = Script -> GODialogStatus ( _player , questgiver );
if ( questStatus > 6 )
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 ());
data << uint8 ( questStatus );
++ 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 );
}
2009-02-17 20:07:49 -06:00