2008-10-11 14:16:25 -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
*
2010-01-16 20:19:18 +03:00
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
2008-10-11 14:16:25 -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-11-10 17:19:35 -06:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-11 14:16:25 -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-11-10 17:19:35 -06:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
#include "QuestDef.h"
#include "GossipDef.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "WorldPacket.h"
#include "WorldSession.h"
2008-10-22 07:02:05 -05:00
#include "Formulas.h"
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GossipMenu :: GossipMenu ()
{
m_gItems . reserve ( 16 ); // can be set for max from most often sizes to speedup push_back and less memory use
2009-12-20 13:35:08 +02:00
m_gMenuId = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GossipMenu ::~ GossipMenu ()
{
ClearMenu ();
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
void GossipMenu :: AddMenuItem ( uint8 Icon , const std :: string & Message , uint32 dtSender , uint32 dtAction , const std :: string & BoxMessage , uint32 BoxMoney , bool Coded )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
ASSERT ( m_gItems . size () <= GOSSIP_MAX_MENU_ITEMS );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GossipMenuItem gItem ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
gItem . m_gIcon = Icon ;
gItem . m_gMessage = Message ;
gItem . m_gCoded = Coded ;
gItem . m_gSender = dtSender ;
2009-12-20 13:35:08 +02:00
gItem . m_gOptionId = dtAction ;
2008-10-11 14:16:25 -05:00
gItem . m_gBoxMessage = BoxMessage ;
gItem . m_gBoxMoney = BoxMoney ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_gItems . push_back ( gItem );
}
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
void GossipMenu :: AddGossipMenuItemData ( uint32 action_menu , uint32 action_poi , uint32 action_script )
{
GossipMenuItemData pItemData ;
pItemData . m_gAction_menu = action_menu ;
pItemData . m_gAction_poi = action_poi ;
pItemData . m_gAction_script = action_script ;
m_gItemsData . push_back ( pItemData );
}
2008-12-12 11:21:28 -06:00
void GossipMenu :: AddMenuItem ( uint8 Icon , const std :: string & Message , bool Coded )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
AddMenuItem ( Icon , Message , 0 , 0 , "" , 0 , Coded );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void GossipMenu :: AddMenuItem ( uint8 Icon , char const * Message , bool Coded )
{
AddMenuItem ( Icon , std :: string ( Message ? Message : "" ), Coded );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void GossipMenu :: AddMenuItem ( uint8 Icon , char const * Message , uint32 dtSender , uint32 dtAction , char const * BoxMessage , uint32 BoxMoney , bool Coded )
{
AddMenuItem ( Icon , std :: string ( Message ? Message : "" ), dtSender , dtAction , std :: string ( BoxMessage ? BoxMessage : "" ), BoxMoney , Coded );
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint32 GossipMenu :: MenuItemSender ( unsigned int ItemId )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ItemId >= m_gItems . size ()) return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return m_gItems [ ItemId ]. m_gSender ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint32 GossipMenu :: MenuItemAction ( unsigned int ItemId )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ItemId >= m_gItems . size ()) return 0 ;
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
return m_gItems [ ItemId ]. m_gOptionId ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
bool GossipMenu :: MenuItemCoded ( unsigned int ItemId )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ItemId >= m_gItems . size ()) return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return m_gItems [ ItemId ]. m_gCoded ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void GossipMenu :: ClearMenu ()
{
m_gItems . clear ();
2009-12-20 13:35:08 +02:00
m_gItemsData . clear ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
PlayerMenu :: PlayerMenu ( WorldSession * session ) : pSession ( session )
2008-10-11 14:16:25 -05:00
{
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerMenu ::~ PlayerMenu ()
{
ClearMenus ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void PlayerMenu :: ClearMenus ()
{
mGossipMenu . ClearMenu ();
mQuestMenu . ClearMenu ();
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint32 PlayerMenu :: GossipOptionSender ( unsigned int Selection )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
return mGossipMenu . MenuItemSender ( Selection );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint32 PlayerMenu :: GossipOptionAction ( unsigned int Selection )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
return mGossipMenu . MenuItemAction ( Selection );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
bool PlayerMenu :: GossipOptionCoded ( unsigned int Selection )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
return mGossipMenu . MenuItemCoded ( Selection );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
void PlayerMenu :: SendGossipMenu ( uint32 TitleTextId , uint64 objectGUID )
2008-10-11 14:16:25 -05:00
{
2009-12-20 13:35:08 +02:00
WorldPacket data ( SMSG_GOSSIP_MESSAGE , ( 100 )); // guess size
data << uint64 ( objectGUID );
data << uint32 ( mGossipMenu . GetMenuId ()); // new 2.4.0
data << uint32 ( TitleTextId );
data << uint32 ( mGossipMenu . MenuItemCount ()); // max count 0x10
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint32 iI = 0 ; iI < mGossipMenu . MenuItemCount (); ++ iI )
2008-10-11 14:16:25 -05:00
{
GossipMenuItem const & gItem = mGossipMenu . GetItem ( iI );
2010-04-07 22:59:46 +02:00
data << uint32 ( iI );
data << uint8 ( gItem . m_gIcon );
data << uint8 ( gItem . m_gCoded ); // makes pop up box password
2008-10-11 14:16:25 -05:00
data << uint32 ( gItem . m_gBoxMoney ); // money required to open menu, 2.0.3
data << gItem . m_gMessage ; // text for gossip item
data << gItem . m_gBoxMessage ; // accept text (related to money) pop up box, 2.0.3
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
data << uint32 ( mQuestMenu . MenuItemCount ()); // max count 0x20
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint32 iI = 0 ; iI < mQuestMenu . MenuItemCount (); ++ iI )
2008-10-11 14:16:25 -05:00
{
QuestMenuItem const & qItem = mQuestMenu . GetItem ( iI );
uint32 questID = qItem . m_qId ;
Quest const * pQuest = objmgr . GetQuestTemplate ( questID );
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
data << uint32 ( questID );
2009-05-31 15:56:51 -05:00
data << uint32 ( qItem . m_qIcon );
2009-02-27 12:25:10 -06:00
data << uint32 ( pSession -> GetPlayer () -> GetQuestLevel ( pQuest ));
2010-04-11 20:20:38 +02:00
data << uint32 ( pQuest -> GetFlags ()); // 3.3.3 quest flags
data << uint8 ( 0 ); // 3.3.3 changes icon: blue question or yellow exclamation
2008-10-11 14:16:25 -05:00
std :: string Title = pQuest -> GetTitle ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
2010-04-11 11:13:08 +04:00
if ( QuestLocale const * ql = objmgr . GetQuestLocale ( questID ))
2008-10-11 14:16:25 -05:00
if ( ql -> Title . size () > loc_idx && ! ql -> Title [ loc_idx ]. empty ())
2010-04-11 20:20:38 +02:00
Title = ql -> Title [ loc_idx ];
2010-04-11 11:13:08 +04:00
data << Title ; // max 0x200
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void PlayerMenu :: CloseGossip ()
{
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_GOSSIP_COMPLETE , 0 );
pSession -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
// Outdated
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendPointOfInterest ( float X , float Y , uint32 Icon , uint32 Flags , uint32 Data , char const * locName )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_GOSSIP_POI , ( 4 + 4 + 4 + 4 + 4 + 10 )); // guess size
2010-04-11 20:20:38 +02:00
data << uint32 ( Flags );
data << float ( X );
2010-04-11 11:13:08 +04:00
data << float ( Y );
2008-10-11 14:16:25 -05:00
data << uint32 ( Icon );
data << uint32 ( Data );
data << locName ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
//sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI");
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendPointOfInterest ( uint32 poi_id )
2009-02-17 17:40:03 -06:00
{
PointOfInterest const * poi = objmgr . GetPointOfInterest ( poi_id );
2010-04-07 19:14:10 +02:00
if ( ! poi )
2009-02-17 17:40:03 -06:00
{
2009-02-24 11:14:28 -06:00
sLog . outErrorDb ( "Requested send not existed POI (Id: %u), ignore." , poi_id );
2009-02-17 17:40:03 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
std :: string icon_name = poi -> icon_name ;
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
PointOfInterestLocale const * pl = objmgr . GetPointOfInterestLocale ( poi_id );
if ( pl )
{
if ( pl -> IconName . size () > size_t ( loc_idx ) && ! pl -> IconName [ loc_idx ]. empty ())
icon_name = pl -> IconName [ loc_idx ];
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_GOSSIP_POI , ( 4 + 4 + 4 + 4 + 4 + 10 )); // guess size
2009-02-17 17:40:03 -06:00
data << uint32 ( poi -> flags );
data << float ( poi -> x );
data << float ( poi -> y );
data << uint32 ( poi -> icon );
data << uint32 ( poi -> data );
data << icon_name ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2009-02-17 17:40:03 -06:00
//sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI");
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendTalking ( uint32 textID )
2008-10-11 14:16:25 -05:00
{
2009-02-16 20:12:55 -06:00
GossipText const * pGossip = objmgr . GetGossipText ( textID );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_NPC_TEXT_UPDATE , 100 ); // guess size
2008-10-11 14:16:25 -05:00
data << textID ; // can be < 0
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! pGossip )
{
2009-10-17 16:20:24 -07:00
for ( uint32 i = 0 ; i < 8 ; ++ i )
2008-10-11 14:16:25 -05:00
{
data << float ( 0 );
data << "Greetings $N" ;
data << "Greetings $N" ;
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
}
}
else
{
std :: string Text_0 [ 8 ], Text_1 [ 8 ];
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < 8 ; ++ i )
2008-10-11 14:16:25 -05:00
{
Text_0 [ i ] = pGossip -> Options [ i ]. Text_0 ;
Text_1 [ i ] = pGossip -> Options [ i ]. Text_1 ;
}
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
NpcTextLocale const * nl = objmgr . GetNpcTextLocale ( textID );
if ( nl )
{
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < 8 ; ++ i )
2008-10-11 14:16:25 -05:00
{
if ( nl -> Text_0 [ i ]. size () > loc_idx && ! nl -> Text_0 [ i ][ loc_idx ]. empty ())
Text_0 [ i ] = nl -> Text_0 [ i ][ loc_idx ];
if ( nl -> Text_1 [ i ]. size () > loc_idx && ! nl -> Text_1 [ i ][ loc_idx ]. empty ())
Text_1 [ i ] = nl -> Text_1 [ i ][ loc_idx ];
}
}
}
2009-04-29 00:26:07 -05:00
for ( int i = 0 ; i < 8 ; ++ i )
2008-10-11 14:16:25 -05:00
{
data << pGossip -> Options [ i ]. Probability ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( Text_0 [ i ]. empty ())
2008-10-11 14:16:25 -05:00
data << Text_1 [ i ];
else
data << Text_0 [ i ];
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( Text_1 [ i ]. empty ())
2008-10-11 14:16:25 -05:00
data << Text_0 [ i ];
else
data << Text_1 [ i ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << pGossip -> Options [ i ]. Language ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( int j = 0 ; j < 3 ; ++ j )
2009-02-16 20:12:55 -06:00
{
data << pGossip -> Options [ i ]. Emotes [ j ]. _Delay ;
data << pGossip -> Options [ i ]. Emotes [ j ]. _Emote ;
}
2008-10-11 14:16:25 -05:00
}
}
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
sLog . outDebug ( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendTalking ( char const * title , char const * text )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_NPC_TEXT_UPDATE , 50 ); // guess size
2008-10-11 14:16:25 -05:00
data << uint32 ( 0 );
2009-10-17 16:20:24 -07:00
for ( uint32 i = 0 ; i < 8 ; ++ i )
2008-10-11 14:16:25 -05:00
{
data << float ( 0 );
data << title ;
data << text ;
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
sLog . outDebug ( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
/*********************************************************/
/*** QUEST SYSTEM ***/
/*********************************************************/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
QuestMenu :: QuestMenu ()
{
m_qItems . reserve ( 16 ); // can be set for max from most often sizes to speedup push_back and less memory use
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
QuestMenu ::~ QuestMenu ()
{
ClearMenu ();
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void QuestMenu :: AddMenuItem ( uint32 QuestId , uint8 Icon )
2008-10-11 14:16:25 -05:00
{
Quest const * qinfo = objmgr . GetQuestTemplate ( QuestId );
if ( ! qinfo ) return ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
ASSERT ( m_qItems . size () <= GOSSIP_MAX_MENU_ITEMS );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
QuestMenuItem qItem ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
qItem . m_qId = QuestId ;
qItem . m_qIcon = Icon ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_qItems . push_back ( qItem );
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
bool QuestMenu :: HasItem ( uint32 questid )
2008-10-11 14:16:25 -05:00
{
2009-04-29 00:26:07 -05:00
for ( QuestMenuItemList :: const_iterator i = m_qItems . begin (); i != m_qItems . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 23:25:02 +02:00
if ( i -> m_qId == questid )
2008-10-11 14:16:25 -05:00
{
return true ;
}
}
return false ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void QuestMenu :: ClearMenu ()
{
m_qItems . clear ();
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendQuestGiverQuestList ( QEmote eEmote , const std :: string & Title , uint64 npcGUID )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_QUESTGIVER_QUEST_LIST , 100 ); // guess size
2008-10-11 14:16:25 -05:00
data << uint64 ( npcGUID );
data << Title ;
2010-04-07 22:59:46 +02:00
data << uint32 ( eEmote . _Delay ); // player emote
data << uint32 ( eEmote . _Emote ); // NPC emote
data << uint8 ( mQuestMenu . MenuItemCount ());
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint32 iI = 0 ; iI < mQuestMenu . MenuItemCount (); ++ iI )
2008-10-11 14:16:25 -05:00
{
QuestMenuItem const & qmi = mQuestMenu . GetItem ( iI );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 questID = qmi . m_qId ;
Quest const * pQuest = objmgr . GetQuestTemplate ( questID );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: string title = pQuest ? pQuest -> GetTitle () : "" ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
2010-04-07 19:14:10 +02:00
if ( QuestLocale const * ql = objmgr . GetQuestLocale ( questID ))
2008-10-11 14:16:25 -05:00
{
if ( ql -> Title . size () > loc_idx && ! ql -> Title [ loc_idx ]. empty ())
title = ql -> Title [ loc_idx ];
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( questID );
data << uint32 ( qmi . m_qIcon );
2009-02-27 12:25:10 -06:00
data << uint32 ( pSession -> GetPlayer () -> GetQuestLevel ( pQuest ));
2010-04-11 20:20:38 +02:00
data << uint32 ( pQuest -> GetFlags ()); // 3.3.3 quest flags
data << uint8 ( 0 ); // 3.3.3 changes icon: blue question or yellow exclamation
2008-10-11 14:16:25 -05:00
data << title ;
}
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2008-12-12 11:21:28 -06:00
sLog . outDebug ( "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u" , GUID_LOPART ( npcGUID ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendQuestGiverStatus ( uint8 questStatus , uint64 npcGUID )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_QUESTGIVER_STATUS , 9 );
2008-10-11 14:16:25 -05:00
data << uint64 ( npcGUID );
data << uint8 ( questStatus );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u" , GUID_LOPART ( npcGUID ), questStatus );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendQuestGiverQuestDetails ( Quest const * pQuest , uint64 npcGUID , bool ActivateAccept )
2008-10-11 14:16:25 -05:00
{
std :: string Title = pQuest -> GetTitle ();
std :: string Details = pQuest -> GetDetails ();
std :: string Objectives = pQuest -> GetObjectives ();
std :: string EndText = pQuest -> GetEndText ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
QuestLocale const * ql = objmgr . GetQuestLocale ( pQuest -> GetQuestId ());
if ( ql )
{
if ( ql -> Title . size () > loc_idx && ! ql -> Title [ loc_idx ]. empty ())
Title = ql -> Title [ loc_idx ];
if ( ql -> Details . size () > loc_idx && ! ql -> Details [ loc_idx ]. empty ())
Details = ql -> Details [ loc_idx ];
if ( ql -> Objectives . size () > loc_idx && ! ql -> Objectives [ loc_idx ]. empty ())
Objectives = ql -> Objectives [ loc_idx ];
if ( ql -> EndText . size () > loc_idx && ! ql -> EndText [ loc_idx ]. empty ())
EndText = ql -> EndText [ loc_idx ];
}
}
2009-10-17 15:51:44 -07:00
2010-02-14 19:13:14 -07:00
WorldPacket data ( SMSG_QUESTGIVER_QUEST_DETAILS , 100 ); // guess size
2008-10-11 14:16:25 -05:00
data << uint64 ( npcGUID );
2008-12-24 09:58:26 -06:00
data << uint64 ( 0 ); // wotlk, something todo with quest sharing?
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetQuestId ());
2008-12-24 09:58:26 -06:00
data << Title ;
data << Details ;
data << Objectives ;
2010-04-11 11:13:08 +04:00
data << uint8 ( ActivateAccept ? 1 : 0 ); // auto finish
data << uint32 ( pQuest -> GetFlags ()); // 3.3.3 questFlags
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetSuggestedPlayers ());
2010-04-11 11:13:08 +04:00
data << uint8 ( 0 ); // IsFinished, value is sent back to server in quest accept packet
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( pQuest -> HasFlag ( QUEST_FLAGS_HIDDEN_REWARDS ))
{
data << uint32 ( 0 ); // Rewarded chosen items hidden
data << uint32 ( 0 ); // Rewarded items hidden
data << uint32 ( 0 ); // Rewarded money hidden
}
else
{
ItemPrototype const * IProto ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewChoiceItemsCount ());
2009-04-29 00:26:07 -05:00
for ( uint32 i = 0 ; i < QUEST_REWARD_CHOICES_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ! pQuest -> RewChoiceItemId [ i ]) continue ;
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> RewChoiceItemId [ i ]);
data << uint32 ( pQuest -> RewChoiceItemCount [ i ]);
IProto = objmgr . GetItemPrototype ( pQuest -> RewChoiceItemId [ i ]);
2010-04-07 22:59:46 +02:00
if ( IProto )
2008-10-11 14:16:25 -05:00
data << uint32 ( IProto -> DisplayInfoID );
else
2010-04-07 22:59:46 +02:00
data << uint32 ( 0x00 );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewItemsCount ());
2009-04-29 00:26:07 -05:00
for ( uint32 i = 0 ; i < QUEST_REWARDS_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ! pQuest -> RewItemId [ i ]) continue ;
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> RewItemId [ i ]);
data << uint32 ( pQuest -> RewItemCount [ i ]);
IProto = objmgr . GetItemPrototype ( pQuest -> RewItemId [ i ]);
2010-04-07 22:59:46 +02:00
if ( IProto )
2008-10-11 14:16:25 -05:00
data << uint32 ( IProto -> DisplayInfoID );
else
data << uint32 ( 0 );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewOrReqMoney ());
}
2009-10-17 15:51:44 -07:00
2010-02-14 19:13:14 -07:00
data << uint32 ( 0 );
2008-10-22 08:43:09 -05:00
// rewarded honor points. Multiply with 10 to satisfy client
2008-10-22 07:02:05 -05:00
data << uint32 ( 10 * Trinity :: Honor :: hk_honor_at_level ( pSession -> GetPlayer () -> getLevel (), pQuest -> GetRewHonorableKills ()));
2010-03-27 15:10:26 +01:00
data << float ( 0 ); // new 3.3.0, honor multiplier?
2010-04-07 23:25:02 +02:00
data << uint32 ( pQuest -> GetRewSpell ()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
2009-12-21 14:48:30 -07:00
data << int32 ( pQuest -> GetRewSpellCast ()); // casted spell
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetCharTitleId ()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
2008-12-24 09:58:26 -06:00
data << uint32 ( pQuest -> GetBonusTalents ()); // bonus talents
2010-03-27 15:10:26 +01:00
data << uint32 ( pQuest -> GetRewArenaPoints ()); // reward arena points
data << uint32 ( 0 ); // unk
2010-02-14 19:13:14 -07:00
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i )
2010-02-14 19:13:14 -07:00
data << uint32 ( pQuest -> RewRepFaction [ i ]);
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i )
2010-02-14 19:13:14 -07:00
data << int32 ( pQuest -> RewRepValueId [ i ]);
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i )
2010-02-14 19:13:14 -07:00
data << int32 ( pQuest -> RewRepValue [ i ]);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( QUEST_EMOTE_COUNT );
2009-04-29 00:26:07 -05:00
for ( uint32 i = 0 ; i < QUEST_EMOTE_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
{
data << uint32 ( pQuest -> DetailsEmote [ i ]);
2009-06-03 19:23:49 -05:00
data << uint32 ( pQuest -> DetailsEmoteDelay [ i ]); // DetailsEmoteDelay (in ms)
2008-10-11 14:16:25 -05:00
}
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
sLog . outDebug ( "WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u" , GUID_LOPART ( npcGUID ), pQuest -> GetQuestId ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendQuestQueryResponse ( Quest const * pQuest )
2008-10-11 14:16:25 -05:00
{
2010-03-02 09:59:59 -07:00
std :: string Title , Details , Objectives , EndText , CompletedText ;
2008-10-11 14:16:25 -05:00
std :: string ObjectiveText [ QUEST_OBJECTIVES_COUNT ];
Title = pQuest -> GetTitle ();
Details = pQuest -> GetDetails ();
Objectives = pQuest -> GetObjectives ();
EndText = pQuest -> GetEndText ();
2010-03-02 09:59:59 -07:00
CompletedText = pQuest -> GetCompletedText ();
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < QUEST_OBJECTIVES_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
ObjectiveText [ i ] = pQuest -> ObjectiveText [ i ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
QuestLocale const * ql = objmgr . GetQuestLocale ( pQuest -> GetQuestId ());
if ( ql )
{
if ( ql -> Title . size () > loc_idx && ! ql -> Title [ loc_idx ]. empty ())
Title = ql -> Title [ loc_idx ];
if ( ql -> Details . size () > loc_idx && ! ql -> Details [ loc_idx ]. empty ())
Details = ql -> Details [ loc_idx ];
if ( ql -> Objectives . size () > loc_idx && ! ql -> Objectives [ loc_idx ]. empty ())
Objectives = ql -> Objectives [ loc_idx ];
if ( ql -> EndText . size () > loc_idx && ! ql -> EndText [ loc_idx ]. empty ())
EndText = ql -> EndText [ loc_idx ];
2010-03-02 09:59:59 -07:00
if ( ql -> CompletedText . size () > ( size_t ) loc_idx && ! ql -> CompletedText [ loc_idx ]. empty ())
CompletedText = ql -> CompletedText [ loc_idx ];
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( int i = 0 ; i < QUEST_OBJECTIVES_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
if ( ql -> ObjectiveText [ i ]. size () > loc_idx && ! ql -> ObjectiveText [ i ][ loc_idx ]. empty ())
ObjectiveText [ i ] = ql -> ObjectiveText [ i ][ loc_idx ];
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_QUEST_QUERY_RESPONSE , 100 ); // guess size
2009-10-17 15:51:44 -07:00
2009-12-17 11:11:54 +01:00
data << uint32 ( pQuest -> GetQuestId ()); // quest id
2010-04-07 23:25:02 +02:00
data << uint32 ( pQuest -> GetQuestMethod ()); // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
2009-11-26 23:44:33 +01:00
data << uint32 ( pQuest -> GetQuestLevel ()); // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client)
2010-02-14 19:13:14 -07:00
data << uint32 ( pQuest -> GetMinLevel ()); // min level
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetZoneOrSort ()); // zone or sort to display in quest log
2009-10-17 15:51:44 -07:00
2009-12-17 11:11:54 +01:00
data << uint32 ( pQuest -> GetType ()); // quest type
data << uint32 ( pQuest -> GetSuggestedPlayers ()); // suggested players count
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRepObjectiveFaction ()); // shown in quest log as part of quest objective
data << uint32 ( pQuest -> GetRepObjectiveValue ()); // shown in quest log as part of quest objective
2009-10-17 15:51:44 -07:00
2009-12-20 16:51:41 -07:00
data << uint32 ( pQuest -> GetRepObjectiveFaction2 ()); // shown in quest log as part of quest objective OPOSITE faction
data << uint32 ( pQuest -> GetRepObjectiveValue2 ()); // shown in quest log as part of quest objective OPPOSITE faction
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetNextQuestInChain ()); // client will request this quest from NPC, if not 0
2010-02-14 19:13:14 -07:00
data << uint32 ( 0 ); // unk 3.3.0
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( pQuest -> HasFlag ( QUEST_FLAGS_HIDDEN_REWARDS ))
data << uint32 ( 0 ); // Hide money rewarded
else
2009-12-17 11:11:54 +01:00
data << uint32 ( pQuest -> GetRewOrReqMoney ()); // reward money (below max lvl)
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewMoneyMaxLevel ()); // used in XP calculation at client
2010-04-07 23:25:02 +02:00
data << uint32 ( pQuest -> GetRewSpell ()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
2009-12-21 14:48:30 -07:00
data << int32 ( pQuest -> GetRewSpellCast ()); // casted spell
2009-10-17 15:51:44 -07:00
2008-10-22 07:02:05 -05:00
// rewarded honor points
data << uint32 ( Trinity :: Honor :: hk_honor_at_level ( pSession -> GetPlayer () -> getLevel (), pQuest -> GetRewHonorableKills ()));
2010-02-14 19:13:14 -07:00
data << float ( 0 ); // new reward honor (multipled by ~62 at client side)
2009-12-17 11:11:54 +01:00
data << uint32 ( pQuest -> GetSrcItemId ()); // source item id
data << uint32 ( pQuest -> GetFlags () & 0xFFFF ); // quest flags
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetCharTitleId ()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
2008-12-24 09:58:26 -06:00
data << uint32 ( pQuest -> GetPlayersSlain ()); // players slain
data << uint32 ( pQuest -> GetBonusTalents ()); // bonus talents
2010-03-27 15:10:26 +01:00
data << uint32 ( pQuest -> GetRewArenaPoints ()); // bonus arena points
2010-02-14 19:13:14 -07:00
data << uint32 ( 0 ); // unknown
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int iI ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( pQuest -> HasFlag ( QUEST_FLAGS_HIDDEN_REWARDS ))
{
2009-04-29 00:26:07 -05:00
for ( iI = 0 ; iI < QUEST_REWARDS_COUNT ; ++ iI )
2008-10-11 14:16:25 -05:00
data << uint32 ( 0 ) << uint32 ( 0 );
2009-04-29 00:26:07 -05:00
for ( iI = 0 ; iI < QUEST_REWARD_CHOICES_COUNT ; ++ iI )
2008-10-11 14:16:25 -05:00
data << uint32 ( 0 ) << uint32 ( 0 );
}
else
{
2009-04-29 00:26:07 -05:00
for ( iI = 0 ; iI < QUEST_REWARDS_COUNT ; ++ iI )
2008-10-11 14:16:25 -05:00
{
data << uint32 ( pQuest -> RewItemId [ iI ]);
data << uint32 ( pQuest -> RewItemCount [ iI ]);
}
2009-04-29 00:26:07 -05:00
for ( iI = 0 ; iI < QUEST_REWARD_CHOICES_COUNT ; ++ iI )
2008-10-11 14:16:25 -05:00
{
data << uint32 ( pQuest -> RewChoiceItemId [ iI ]);
data << uint32 ( pQuest -> RewChoiceItemCount [ iI ]);
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i ) // reward factions ids
2010-02-14 19:13:14 -07:00
data << uint32 ( pQuest -> RewRepFaction [ i ]);
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i ) // columnid+1 QuestFactionReward.dbc?
2010-02-14 19:13:14 -07:00
data << int32 ( pQuest -> RewRepValueId [ i ]);
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i ) // unk (0)
2010-02-14 19:13:14 -07:00
data << int32 ( pQuest -> RewRepValue [ i ]);
2008-10-11 14:16:25 -05:00
data << pQuest -> GetPointMapId ();
data << pQuest -> GetPointX ();
data << pQuest -> GetPointY ();
data << pQuest -> GetPointOpt ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << Title ;
data << Objectives ;
data << Details ;
data << EndText ;
2010-03-02 09:59:59 -07:00
data << CompletedText ; // display in quest objectives window once all objectives are completed
2009-10-17 15:51:44 -07:00
2009-04-29 00:26:07 -05:00
for ( iI = 0 ; iI < QUEST_OBJECTIVES_COUNT ; ++ iI )
2008-10-11 14:16:25 -05:00
{
if ( pQuest -> ReqCreatureOrGOId [ iI ] < 0 )
{
// client expected gameobject template id in form (id|0x80000000)
data << uint32 (( pQuest -> ReqCreatureOrGOId [ iI ] * ( - 1 )) | 0x80000000 );
}
else
{
data << uint32 ( pQuest -> ReqCreatureOrGOId [ iI ]);
}
data << uint32 ( pQuest -> ReqCreatureOrGOCount [ iI ]);
2009-02-20 15:19:14 -06:00
data << uint32 ( pQuest -> ReqSourceId [ iI ]);
2010-02-14 19:13:14 -07:00
data << uint32 ( 0 ); // req source count?
2009-01-30 19:22:49 -06:00
}
2009-10-17 15:51:44 -07:00
2009-12-17 11:11:54 +01:00
for ( iI = 0 ; iI < QUEST_ITEM_OBJECTIVES_COUNT ; ++ iI )
2009-01-30 19:22:49 -06:00
{
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> ReqItemId [ iI ]);
data << uint32 ( pQuest -> ReqItemCount [ iI ]);
}
2009-10-17 15:51:44 -07:00
2009-04-29 00:26:07 -05:00
for ( iI = 0 ; iI < QUEST_OBJECTIVES_COUNT ; ++ iI )
2008-10-11 14:16:25 -05:00
data << ObjectiveText [ iI ];
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u" , pQuest -> GetQuestId ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendQuestGiverOfferReward ( Quest const * pQuest , uint64 npcGUID , bool EnableNext )
2008-10-11 14:16:25 -05:00
{
std :: string Title = pQuest -> GetTitle ();
std :: string OfferRewardText = pQuest -> GetOfferRewardText ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
QuestLocale const * ql = objmgr . GetQuestLocale ( pQuest -> GetQuestId ());
if ( ql )
{
if ( ql -> Title . size () > loc_idx && ! ql -> Title [ loc_idx ]. empty ())
Title = ql -> Title [ loc_idx ];
if ( ql -> OfferRewardText . size () > loc_idx && ! ql -> OfferRewardText [ loc_idx ]. empty ())
OfferRewardText = ql -> OfferRewardText [ loc_idx ];
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_QUESTGIVER_OFFER_REWARD , 50 ); // guess size
2009-10-17 15:51:44 -07:00
2010-02-14 19:13:14 -07:00
data << uint64 ( npcGUID );
data << uint32 ( pQuest -> GetQuestId ());
2008-10-11 14:16:25 -05:00
data << Title ;
data << OfferRewardText ;
2009-10-17 15:51:44 -07:00
2010-04-11 20:20:38 +02:00
data << uint8 ( EnableNext ? 1 : 0 ); // Auto Finish
data << uint32 ( pQuest -> GetFlags ()); // 3.3.3 questFlags
2010-04-11 11:13:08 +04:00
data << uint32 ( pQuest -> GetSuggestedPlayers ()); // SuggestedGroupNum
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 EmoteCount = 0 ;
2009-04-29 00:26:07 -05:00
for ( uint32 i = 0 ; i < QUEST_EMOTE_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pQuest -> OfferRewardEmote [ i ] <= 0 )
2008-10-11 14:16:25 -05:00
break ;
++ EmoteCount ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << EmoteCount ; // Emote Count
2009-04-29 00:26:07 -05:00
for ( uint32 i = 0 ; i < EmoteCount ; ++ i )
2008-10-11 14:16:25 -05:00
{
2009-06-03 19:23:49 -05:00
data << uint32 ( pQuest -> OfferRewardEmoteDelay [ i ]); // Delay Emote
data << uint32 ( pQuest -> OfferRewardEmote [ i ]);
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ItemPrototype const * pItem ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewChoiceItemsCount ());
2009-04-29 00:26:07 -05:00
for ( uint32 i = 0 ; i < pQuest -> GetRewChoiceItemsCount (); ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
pItem = objmgr . GetItemPrototype ( pQuest -> RewChoiceItemId [ i ]);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> RewChoiceItemId [ i ]);
data << uint32 ( pQuest -> RewChoiceItemCount [ i ]);
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( pItem )
2008-10-11 14:16:25 -05:00
data << uint32 ( pItem -> DisplayInfoID );
else
data << uint32 ( 0 );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewItemsCount ());
2010-04-11 11:13:08 +04:00
for ( uint32 i = 0 ; i < pQuest -> GetRewItemsCount (); ++ i )
2008-10-11 14:16:25 -05:00
{
pItem = objmgr . GetItemPrototype ( pQuest -> RewItemId [ i ]);
data << uint32 ( pQuest -> RewItemId [ i ]);
data << uint32 ( pQuest -> RewItemCount [ i ]);
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( pItem )
2008-10-11 14:16:25 -05:00
data << uint32 ( pItem -> DisplayInfoID );
else
data << uint32 ( 0 );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( pQuest -> GetRewOrReqMoney ());
2010-03-09 22:37:07 +01:00
data << uint32 ( pQuest -> XPValue ( pSession -> GetPlayer ()));
2009-10-17 15:51:44 -07:00
2008-10-22 07:02:05 -05:00
// rewarded honor points. Multiply with 10 to satisfy client
data << uint32 ( 10 * Trinity :: Honor :: hk_honor_at_level ( pSession -> GetPlayer () -> getLevel (), pQuest -> GetRewHonorableKills ()));
2010-03-27 15:10:26 +01:00
data << float ( 0 ); // unk, honor multiplier?
2008-10-11 14:16:25 -05:00
data << uint32 ( 0x08 ); // unused by client?
2010-04-07 23:25:02 +02:00
data << uint32 ( pQuest -> GetRewSpell ()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
2009-12-21 14:48:30 -07:00
data << int32 ( pQuest -> GetRewSpellCast ()); // casted spell
2008-12-24 09:58:26 -06:00
data << uint32 ( 0 ); // unknown
data << uint32 ( pQuest -> GetBonusTalents ()); // bonus talents
2010-03-27 15:10:26 +01:00
data << uint32 ( pQuest -> GetRewArenaPoints ()); // arena points
2010-02-14 19:13:14 -07:00
data << uint32 ( 0 );
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i ) // reward factions ids
2010-02-14 19:13:14 -07:00
data << uint32 ( pQuest -> RewRepFaction [ i ]);
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i ) // columnid in QuestFactionReward.dbc (zero based)?
2010-02-14 19:13:14 -07:00
data << int32 ( pQuest -> RewRepValueId [ i ]);
2010-04-07 19:12:44 +02:00
for ( int i = 0 ; i < QUEST_REPUTATIONS_COUNT ; ++ i ) // reward reputation override?
2010-02-14 19:13:14 -07:00
data << uint32 ( pQuest -> RewRepValue [ i ]);
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u" , GUID_LOPART ( npcGUID ), pQuest -> GetQuestId ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void PlayerMenu :: SendQuestGiverRequestItems ( Quest const * pQuest , uint64 npcGUID , bool Completable , bool CloseOnCancel )
2008-10-11 14:16:25 -05:00
{
// We can always call to RequestItems, but this packet only goes out if there are actually
// items. Otherwise, we'll skip straight to the OfferReward
2009-10-17 15:51:44 -07:00
2009-02-17 14:46:12 -06:00
std :: string Title = pQuest -> GetTitle ();
std :: string RequestItemsText = pQuest -> GetRequestItemsText ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int loc_idx = pSession -> GetSessionDbLocaleIndex ();
if ( loc_idx >= 0 )
{
QuestLocale const * ql = objmgr . GetQuestLocale ( pQuest -> GetQuestId ());
if ( ql )
{
if ( ql -> Title . size () > loc_idx && ! ql -> Title [ loc_idx ]. empty ())
Title = ql -> Title [ loc_idx ];
if ( ql -> RequestItemsText . size () > loc_idx && ! ql -> RequestItemsText [ loc_idx ]. empty ())
RequestItemsText = ql -> RequestItemsText [ loc_idx ];
}
}
2009-10-17 15:51:44 -07:00
2009-06-11 00:45:59 -05:00
if ( ! pQuest -> GetReqItemsCount () && Completable )
2009-02-17 14:46:12 -06:00
{
SendQuestGiverOfferReward ( pQuest , npcGUID , true );
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
WorldPacket data ( SMSG_QUESTGIVER_REQUEST_ITEMS , 50 ); // guess size
2010-04-11 11:13:08 +04:00
data << uint64 ( npcGUID );
data << uint32 ( pQuest -> GetQuestId ());
2008-10-11 14:16:25 -05:00
data << Title ;
data << RequestItemsText ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint32 ( 0x00 ); // unknown
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( Completable )
2008-10-11 14:16:25 -05:00
data << pQuest -> GetCompleteEmote ();
else
data << pQuest -> GetIncompleteEmote ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Close Window after cancel
if ( CloseOnCancel )
data << uint32 ( 0x01 );
else
data << uint32 ( 0x00 );
2009-10-17 15:51:44 -07:00
2010-04-11 11:13:08 +04:00
data << uint32 ( pQuest -> GetFlags ()); // 3.3.3 questFlags
data << uint32 ( pQuest -> GetSuggestedPlayers ()); // SuggestedGroupNum
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Required Money
data << uint32 ( pQuest -> GetRewOrReqMoney () < 0 ? - pQuest -> GetRewOrReqMoney () : 0 );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
data << uint32 ( pQuest -> GetReqItemsCount ());
2008-10-11 14:16:25 -05:00
ItemPrototype const * pItem ;
2009-12-17 11:11:54 +01:00
for ( int i = 0 ; i < QUEST_ITEM_OBJECTIVES_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ! pQuest -> ReqItemId [ i ]) continue ;
2008-10-11 14:16:25 -05:00
pItem = objmgr . GetItemPrototype ( pQuest -> ReqItemId [ i ]);
data << uint32 ( pQuest -> ReqItemId [ i ]);
data << uint32 ( pQuest -> ReqItemCount [ i ]);
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( pItem )
2008-10-11 14:16:25 -05:00
data << uint32 ( pItem -> DisplayInfoID );
else
data << uint32 ( 0 );
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! Completable )
2008-10-11 14:16:25 -05:00
data << uint32 ( 0x00 );
else
data << uint32 ( 0x03 );
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
data << uint32 ( 0x04 );
data << uint32 ( 0x08 );
data << uint32 ( 0x10 );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pSession -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u" , GUID_LOPART ( npcGUID ), pQuest -> GetQuestId ());
2008-10-11 14:16:25 -05:00
}