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
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 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-18 19:40:06 -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-18 19:40:06 -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 "Common.h"
#include "Language.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "GossipDef.h"
#include "UpdateMask.h"
#include "ScriptCalls.h"
#include "ObjectAccessor.h"
#include "Creature.h"
#include "Pet.h"
#include "BattleGroundMgr.h"
#include "BattleGround.h"
#include "Guild.h"
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleTabardVendorActivateOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
recv_data >> guid ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_TABARDDESIGNER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleTabardVendorActivateOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendTabardVendorActivate ( guid );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: SendTabardVendorActivate ( uint64 guid )
{
WorldPacket data ( MSG_TABARDVENDOR_ACTIVATE , 8 );
data << guid ;
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleBankerActivateOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "WORLD: Received CMSG_BANKER_ACTIVATE" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> guid ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_BANKER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleBankerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendShowBank ( guid );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: SendShowBank ( uint64 guid )
{
WorldPacket data ( SMSG_SHOW_BANK , 8 );
data << guid ;
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleTrainerListOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> guid ;
SendTrainerList ( guid );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: SendTrainerList ( uint64 guid )
{
2008-10-14 11:57:03 -05:00
std :: string str = GetTrinityString ( LANG_NPC_TAINER_HELLO );
2008-10-11 14:16:25 -05:00
SendTrainerList ( guid , str );
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
void WorldSession :: SendTrainerList ( uint64 guid , const std :: string & strTitle )
2008-10-11 14:16:25 -05:00
{
sLog . outDebug ( "WORLD: SendTrainerList" );
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_TRAINER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: SendTrainerList - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// trainer list loaded at check;
if ( ! unit -> isCanTrainingOf ( _player , true ))
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CreatureInfo const * ci = unit -> GetCreatureInfo ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! ci )
{
2008-11-14 17:03:03 -06:00
sLog . outDebug ( "WORLD: SendTrainerList - (GUID: %u) NO CREATUREINFO!" , GUID_LOPART ( guid ) );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
TrainerSpellData const * trainer_spells = unit -> GetTrainerSpells ();
if ( ! trainer_spells )
{
2008-11-14 17:03:03 -06:00
sLog . outDebug ( "WORLD: SendTrainerList - Training spells not found for creature (GUID: %u Entry: %u)" ,
GUID_LOPART ( guid ), unit -> GetEntry ());
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( SMSG_TRAINER_LIST , 8 + 4 + 4 + trainer_spells -> spellList . size () * 38 + strTitle . size () + 1 );
data << guid ;
data << uint32 ( trainer_spells -> trainerType );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
size_t count_pos = data . wpos ();
data << uint32 ( trainer_spells -> spellList . size ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// reputation discount
float fDiscountMod = _player -> GetReputationPriceDiscount ( unit );
2009-06-02 17:50:12 -05:00
bool can_learn_primary_prof = GetPlayer () -> GetFreePrimaryProfessionPoints () > 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 16:20:24 -07:00
for ( TrainerSpellMap :: const_iterator itr = trainer_spells -> spellList . begin (); itr != trainer_spells -> spellList . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2009-02-16 20:10:04 -06:00
TrainerSpell const * tSpell = & itr -> second ;
2009-10-17 15:51:44 -07:00
2009-02-09 20:09:03 -06:00
if ( ! _player -> IsSpellFitByClassAndRace ( tSpell -> learnedSpell ))
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2009-02-09 20:09:03 -06:00
bool primary_prof_first_rank = spellmgr . IsPrimaryProfessionFirstRankSpell ( tSpell -> learnedSpell );
SpellChainNode const * chain_node = spellmgr . GetSpellChainNode ( tSpell -> learnedSpell );
2008-12-22 02:11:11 +01:00
uint32 req_spell = spellmgr . GetSpellRequired ( tSpell -> spell );
2009-05-01 01:33:08 -05:00
TrainerSpellState state = _player -> GetTrainerSpellState ( tSpell );
2009-10-17 15:51:44 -07:00
2009-01-14 00:35:13 -06:00
data << uint32 ( tSpell -> spell ); // learned spell (or cast-spell in profession case)
2009-05-01 01:33:08 -05:00
data << uint8 ( state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state );
2009-02-09 20:09:03 -06:00
data << uint32 ( floor ( tSpell -> spellCost * fDiscountMod ));
2009-10-17 15:51:44 -07:00
2009-05-01 01:33:08 -05:00
data << uint32 ( primary_prof_first_rank && can_learn_primary_prof ? 1 : 0 );
// primary prof. learn confirmation dialog
2008-10-11 14:16:25 -05:00
data << uint32 ( primary_prof_first_rank ? 1 : 0 ); // must be equal prev. field to have learn button in enabled state
2009-02-09 20:09:03 -06:00
data << uint8 ( tSpell -> reqLevel );
data << uint32 ( tSpell -> reqSkill );
data << uint32 ( tSpell -> reqSkillValue );
2009-05-01 01:33:08 -05:00
//prev + req or req + 0
data << uint32 ( ! tSpell -> IsCastable () && chain_node && chain_node -> prev ? chain_node -> prev : req_spell );
data << uint32 ( ! tSpell -> IsCastable () && chain_node && chain_node -> prev ? req_spell : 0 );
2008-10-11 14:16:25 -05:00
data << uint32 ( 0 );
2009-10-17 15:51:44 -07:00
2009-05-01 01:33:08 -05:00
++ count ;
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 << strTitle ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data . put < uint32 > ( count_pos , count );
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleTrainerBuySpellOpcode ( WorldPacket & recv_data )
{
uint64 guid ;
uint32 spellId = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> guid >> spellId ;
sLog . outDebug ( "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u" , uint32 ( GUID_LOPART ( guid )), spellId );
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_TRAINER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! unit -> isCanTrainingOf ( _player , true ))
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check present spell in trainer spell list
TrainerSpellData const * trainer_spells = unit -> GetTrainerSpells ();
if ( ! trainer_spells )
2008-11-18 19:40:06 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// not found, cheat?
TrainerSpell const * trainer_spell = trainer_spells -> Find ( spellId );
if ( ! trainer_spell )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// can't be learn, cheat? Or double learn with lags...
if ( _player -> GetTrainerSpellState ( trainer_spell ) != TRAINER_SPELL_GREEN )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// apply reputation discount
2009-02-09 20:09:03 -06:00
uint32 nSpellCost = uint32 ( floor ( trainer_spell -> spellCost * _player -> GetReputationPriceDiscount ( unit )));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check money requirement
if ( _player -> GetMoney () < nSpellCost )
return ;
2009-10-17 15:51:44 -07:00
2009-01-14 00:35:13 -06:00
_player -> ModifyMoney ( - int32 ( nSpellCost ) );
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
WorldPacket data ( SMSG_PLAY_SPELL_VISUAL , 12 ); // visual effect on trainer
data << uint64 ( guid ) << uint32 ( 0xB3 );
SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
data . Initialize ( SMSG_PLAY_SPELL_IMPACT , 12 ); // visual effect on player
data << uint64 ( _player -> GetGUID ()) << uint32 ( 0x016A );
SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2009-01-14 00:35:13 -06:00
// learn explicitly or cast explicitly
if ( trainer_spell -> IsCastable ())
//FIXME: prof. spell entry in trainer list not marked gray until list re-open.
2009-01-25 16:35:14 -06:00
_player -> CastSpell ( _player , trainer_spell -> spell , true );
2009-01-14 00:35:13 -06:00
else
2009-01-25 16:35:14 -06:00
_player -> learnSpell ( spellId , false );
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
data . Initialize ( SMSG_TRAINER_BUY_SUCCEEDED , 12 );
2009-01-14 00:35:13 -06:00
data << uint64 ( guid ) << uint32 ( trainer_spell -> spell );
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleGossipHelloOpcode ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Received CMSG_GOSSIP_HELLO" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint64 guid ;
recv_data >> guid ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_NONE );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-11-12 16:21:08 -06:00
GetPlayer () -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_TALK );
2008-10-11 14:16:25 -05:00
// remove fake death
2008-11-12 16:21:08 -06:00
//if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
2009-04-06 13:31:14 +02:00
// GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( unit -> isArmorer () || unit -> isCivilian () || unit -> isQuestGiver () || unit -> isServiceProvider ())
{
unit -> StopMoving ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// If spiritguide, no need for gossip menu, just put player into resurrect queue
if ( unit -> isSpiritGuide ())
{
BattleGround * bg = _player -> GetBattleGround ();
if ( bg )
{
bg -> AddPlayerToResurrectQueue ( unit -> GetGUID (), _player -> GetGUID ());
sBattleGroundMgr . SendAreaSpiritHealerQueryOpcode ( _player , bg , unit -> GetGUID ());
return ;
}
}
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
if ( ! Script -> GossipHello ( _player , unit ))
2008-10-11 14:16:25 -05:00
{
2009-12-20 13:35:08 +02:00
_player -> TalkedToCreature ( unit -> GetEntry (), unit -> GetGUID ());
_player -> PrepareGossipMenu ( unit , unit -> GetCreatureInfo () -> GossipMenuId );
_player -> SendPreparedGossip ( unit );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-01-12 19:02:54 -07:00
void WorldSession :: HandleGossipSelectOptionOpcode ( WorldPacket & recv_data )
2008-10-11 14:16:25 -05:00
{
sLog . outDebug ( "WORLD: CMSG_GOSSIP_SELECT_OPTION" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 option ;
uint32 unk ;
uint64 guid ;
std :: string code = "" ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> guid >> unk >> option ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( _player -> PlayerTalkClass -> GossipOptionCoded ( option ))
{
2009-01-15 22:01:47 -05:00
sLog . outDebug ( "reading string" );
2008-10-11 14:16:25 -05:00
recv_data >> code ;
2009-01-15 22:01:47 -05:00
sLog . outDebug ( "string read: %s" , code . c_str ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_NONE );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! code . empty ())
{
2008-11-05 09:22:56 -06:00
if ( ! Script -> GossipSelectWithCode ( _player , unit , _player -> PlayerTalkClass -> GossipOptionSender ( option ), _player -> PlayerTalkClass -> GossipOptionAction ( option ), code . c_str ()))
unit -> OnGossipSelect ( _player , option );
2008-10-11 14:16:25 -05:00
}
else
2008-11-05 09:22:56 -06:00
{
if ( ! Script -> GossipSelect ( _player , unit , _player -> PlayerTalkClass -> GossipOptionSender ( option ), _player -> PlayerTalkClass -> GossipOptionAction ( option )))
2008-11-18 19:40:06 -06:00
unit -> OnGossipSelect ( _player , option );
2008-11-05 09:22:56 -06:00
}
2010-01-12 19:02:54 -07:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleSpiritHealerActivateOpcode ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint64 guid ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> guid ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_SPIRITHEALER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleSpiritHealerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendSpiritResurrect ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: SendSpiritResurrect ()
{
2008-11-18 19:40:06 -06:00
_player -> ResurrectPlayer ( 0.5f , true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> DurabilityLossAll ( 0.25f , true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// get corpse nearest graveyard
WorldSafeLocsEntry const * corpseGrave = NULL ;
Corpse * corpse = _player -> GetCorpse ();
if ( corpse )
corpseGrave = objmgr . GetClosestGraveYard (
corpse -> GetPositionX (), corpse -> GetPositionY (), corpse -> GetPositionZ (), corpse -> GetMapId (), _player -> GetTeam () );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// now can spawn bones
_player -> SpawnCorpseBones ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// teleport to nearest from corpse graveyard, if different from nearest to player ghost
if ( corpseGrave )
{
WorldSafeLocsEntry const * ghostGrave = objmgr . GetClosestGraveYard (
_player -> GetPositionX (), _player -> GetPositionY (), _player -> GetPositionZ (), _player -> GetMapId (), _player -> GetTeam () );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( corpseGrave != ghostGrave )
_player -> TeleportTo ( corpseGrave -> map_id , corpseGrave -> x , corpseGrave -> y , corpseGrave -> z , _player -> GetOrientation ());
// or update at original position
else
2008-12-20 17:42:40 -06:00
//ObjectAccessor::UpdateVisibilityForPlayer(_player);
_player -> SetToNotify ();
2008-10-11 14:16:25 -05:00
}
// or update at original position
else
2008-12-20 17:42:40 -06:00
//ObjectAccessor::UpdateVisibilityForPlayer(_player);
_player -> SetToNotify ();
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 WorldSession :: HandleBinderActivateOpcode ( WorldPacket & recv_data )
{
uint64 npcGUID ;
recv_data >> npcGUID ;
2009-10-17 15:51:44 -07:00
2009-07-01 18:36:03 -05:00
if ( ! GetPlayer () -> IsInWorld () || ! GetPlayer () -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_INNKEEPER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleBinderActivateOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendBindPoint ( unit );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: SendBindPoint ( Creature * npc )
{
2009-05-05 14:46:53 -05:00
// prevent set homebind to instances in any case
2009-07-01 18:36:03 -05:00
if ( GetPlayer () -> GetMap () -> Instanceable ())
2009-05-05 14:46:53 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 bindspell = 3286 ;
2009-03-11 16:17:37 -06:00
uint32 zone_id = _player -> GetZoneId ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// update sql homebind
2009-03-11 16:17:37 -06:00
CharacterDatabase . PExecute ( "UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'" , _player -> GetMapId (), zone_id , _player -> GetPositionX (), _player -> GetPositionY (), _player -> GetPositionZ (), _player -> GetGUIDLow ());
2008-10-11 14:16:25 -05:00
_player -> m_homebindMapId = _player -> GetMapId ();
2009-03-11 16:17:37 -06:00
_player -> m_homebindZoneId = zone_id ;
2008-10-11 14:16:25 -05:00
_player -> m_homebindX = _player -> GetPositionX ();
_player -> m_homebindY = _player -> GetPositionY ();
_player -> m_homebindZ = _player -> GetPositionZ ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// send spell for bind 3286 bind magic
2009-05-04 18:31:37 +02:00
_player -> CastSpell ( _player , bindspell , true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( SMSG_TRAINER_BUY_SUCCEEDED , ( 8 + 4 ));
data << npc -> GetGUID ();
data << bindspell ;
SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// binding
data . Initialize ( SMSG_BINDPOINTUPDATE , ( 4 + 4 + 4 + 4 + 4 ) );
data << float ( _player -> GetPositionX ());
data << float ( _player -> GetPositionY ());
data << float ( _player -> GetPositionZ ());
data << uint32 ( _player -> GetMapId ());
2009-03-11 16:17:37 -06:00
data << uint32 ( zone_id );
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
DEBUG_LOG ( "New Home Position X is %f" , _player -> GetPositionX ());
DEBUG_LOG ( "New Home Position Y is %f" , _player -> GetPositionY ());
DEBUG_LOG ( "New Home Position Z is %f" , _player -> GetPositionZ ());
DEBUG_LOG ( "New Home MapId is %u" , _player -> GetMapId ());
2009-03-11 16:17:37 -06:00
DEBUG_LOG ( "New Home ZoneId is %u" , zone_id );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// zone update
data . Initialize ( SMSG_PLAYERBOUND , 8 + 4 );
data << uint64 ( _player -> GetGUID ());
2009-03-11 16:17:37 -06:00
data << uint32 ( zone_id );
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> PlayerTalkClass -> CloseGossip ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleListStabledPetsOpcode ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Recv MSG_LIST_STABLED_PETS" );
uint64 npcGUID ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> npcGUID ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_STABLEMASTER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleListStabledPetsOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2009-01-24 12:52:33 +00:00
// remove mounts this fix bug where getting pet from stable while mounted deletes pet.
if ( GetPlayer () -> IsMounted ())
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendStablePet ( npcGUID );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: SendStablePet ( uint64 guid )
{
sLog . outDebug ( "WORLD: Recv MSG_LIST_STABLED_PETS Send." );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( MSG_LIST_STABLED_PETS , 200 ); // guess size
data << uint64 ( guid );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Pet * pet = _player -> GetPet ();
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
size_t wpos = data . wpos ();
2008-10-11 14:16:25 -05:00
data << uint8 ( 0 ); // place holder for slot show number
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint8 ( GetPlayer () -> m_stableSlots );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint8 num = 0 ; // counter for place holder
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// not let move dead pet in slot
if ( pet && pet -> isAlive () && pet -> getPetType () == HUNTER_PET )
{
data << uint32 ( pet -> GetCharmInfo () -> GetPetNumber ());
data << uint32 ( pet -> GetEntry ());
data << uint32 ( pet -> getLevel ());
data << pet -> GetName (); // petname
2009-04-10 18:18:44 -05:00
data << uint8 ( 1 ); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
2008-10-11 14:16:25 -05:00
++ num ;
}
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
// 0 1 2 3 4
QueryResult * result = CharacterDatabase . PQuery ( "SELECT owner, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot" ,
_player -> GetGUIDLow (), PET_SAVE_FIRST_STABLE_SLOT , PET_SAVE_LAST_STABLE_SLOT );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( result )
{
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
data << uint32 ( fields [ 1 ]. GetUInt32 ()); // petnumber
data << uint32 ( fields [ 2 ]. GetUInt32 ()); // creature entry
data << uint32 ( fields [ 3 ]. GetUInt32 ()); // level
data << fields [ 4 ]. GetString (); // name
data << uint8 ( 2 ); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ num ;
} while ( result -> NextRow () );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
delete result ;
}
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
data . put < uint8 > ( wpos , num ); // set real data to placeholder
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleStablePet ( WorldPacket & recv_data )
{
2008-12-12 11:21:28 -06:00
sLog . outDebug ( "WORLD: Recv CMSG_STABLE_PET" );
2008-10-11 14:16:25 -05:00
uint64 npcGUID ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> npcGUID ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! GetPlayer () -> isAlive ())
return ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_STABLEMASTER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleStablePet - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Pet * pet = _player -> GetPet ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// can't place in stable dead pet
if ( ! pet ||! pet -> isAlive () || pet -> getPetType () != HUNTER_PET )
{
2009-06-06 20:31:23 -05:00
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
2008-10-11 14:16:25 -05:00
data << uint8 ( 0x06 );
SendPacket ( & data );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 free_slot = 1 ;
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
QueryResult * result = CharacterDatabase . PQuery ( "SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot " ,
_player -> GetGUIDLow (), PET_SAVE_FIRST_STABLE_SLOT , PET_SAVE_LAST_STABLE_SLOT );
2008-10-11 14:16:25 -05:00
if ( result )
{
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 slot = fields [ 1 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
// slots ordered in query, and if not equal then free
if ( slot != free_slot )
break ;
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
// this slot not free, skip
++ free_slot ;
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow () );
2009-10-17 15:51:44 -07:00
2009-04-11 14:47:38 -05:00
delete result ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
2008-10-11 14:16:25 -05:00
if ( free_slot > 0 && free_slot <= GetPlayer () -> m_stableSlots )
{
_player -> RemovePet ( pet , PetSaveMode ( free_slot ));
data << uint8 ( 0x08 );
}
else
data << uint8 ( 0x06 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleUnstablePet ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Recv CMSG_UNSTABLE_PET." );
uint64 npcGUID ;
uint32 petnumber ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> npcGUID >> petnumber ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_STABLEMASTER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleUnstablePet - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
uint32 creature_id = 0 ;
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
{
QueryResult * result = CharacterDatabase . PQuery ( "SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'" ,
_player -> GetGUIDLow (), petnumber , PET_SAVE_FIRST_STABLE_SLOT , PET_SAVE_LAST_STABLE_SLOT );
if ( result )
{
Field * fields = result -> Fetch ();
creature_id = fields [ 0 ]. GetUInt32 ();
delete result ;
}
}
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
if ( ! creature_id )
{
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
data << uint8 ( 0x06 );
SendPacket ( & data );
return ;
}
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
CreatureInfo const * creatureInfo = objmgr . GetCreatureTemplate ( creature_id );
if ( ! creatureInfo || ! creatureInfo -> isTameable ( _player -> CanTameExoticPets ()))
{
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
data << uint8 ( 0x06 );
SendPacket ( & data );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Pet * pet = _player -> GetPet ();
if ( pet && pet -> isAlive ())
{
2009-06-06 20:31:23 -05:00
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
2009-04-10 18:18:44 -05:00
data << uint8 ( 0x06 );
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// delete dead pet
if ( pet )
_player -> RemovePet ( pet , PET_SAVE_AS_DELETED );
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
Pet * newpet = new Pet ( _player , HUNTER_PET );
if ( ! newpet -> LoadPetFromDB ( _player , creature_id , petnumber ))
2008-10-11 14:16:25 -05:00
{
2009-06-06 20:31:23 -05:00
delete newpet ;
newpet = NULL ;
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
data << uint8 ( 0x06 );
SendPacket ( & data );
return ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
data << uint8 ( 0x09 );
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleBuyStableSlot ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Recv CMSG_BUY_STABLE_SLOT." );
uint64 npcGUID ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> npcGUID ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_STABLEMASTER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleBuyStableSlot - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( SMSG_STABLE_RESULT , 200 );
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
if ( GetPlayer () -> m_stableSlots < MAX_PET_STABLES )
2008-10-11 14:16:25 -05:00
{
StableSlotPricesEntry const * SlotPrice = sStableSlotPricesStore . LookupEntry ( GetPlayer () -> m_stableSlots + 1 );
if ( _player -> GetMoney () >= SlotPrice -> Price )
{
++ GetPlayer () -> m_stableSlots ;
_player -> ModifyMoney ( - int32 ( SlotPrice -> Price ));
data << uint8 ( 0x0A ); // success buy
}
else
data << uint8 ( 0x06 );
}
else
data << uint8 ( 0x06 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleStableRevivePet ( WorldPacket & /* recv_data */ )
{
sLog . outDebug ( "HandleStableRevivePet: Not implemented" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleStableSwapPet ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Recv CMSG_STABLE_SWAP_PET." );
uint64 npcGUID ;
uint32 pet_number ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> npcGUID >> pet_number ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_STABLEMASTER );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleStableSwapPet - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( SMSG_STABLE_RESULT , 200 ); // guess size
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Pet * pet = _player -> GetPet ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! pet || pet -> getPetType () != HUNTER_PET )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// find swapped pet slot in stable
2009-04-10 18:18:44 -05:00
QueryResult * result = CharacterDatabase . PQuery ( "SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'" ,
_player -> GetGUIDLow (), pet_number );
2008-10-11 14:16:25 -05:00
if ( ! result )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
uint32 slot = fields [ 0 ]. GetUInt32 ();
uint32 creature_id = fields [ 1 ]. GetUInt32 ();
2008-10-11 14:16:25 -05:00
delete result ;
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
if ( ! creature_id )
{
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
data << uint8 ( 0x06 );
SendPacket ( & data );
return ;
}
2009-10-17 15:51:44 -07:00
2009-06-06 20:31:23 -05:00
CreatureInfo const * creatureInfo = objmgr . GetCreatureTemplate ( creature_id );
if ( ! creatureInfo || ! creatureInfo -> isTameable ( _player -> CanTameExoticPets ()))
{
WorldPacket data ( SMSG_STABLE_RESULT , 1 );
data << uint8 ( 0x06 );
SendPacket ( & data );
return ;
}
2009-10-17 15:51:44 -07:00
2009-04-10 18:18:44 -05:00
// move alive pet to slot or delete dead pet
2008-10-11 14:16:25 -05:00
_player -> RemovePet ( pet , pet -> isAlive () ? PetSaveMode ( slot ) : PET_SAVE_AS_DELETED );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// summon unstabled pet
2009-03-25 21:32:34 -06:00
Pet * newpet = new Pet ( _player );
2009-06-06 20:31:23 -05:00
if ( ! newpet -> LoadPetFromDB ( _player , creature_id , pet_number ))
2008-10-11 14:16:25 -05:00
{
delete newpet ;
data << uint8 ( 0x06 );
}
else
data << uint8 ( 0x09 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void WorldSession :: HandleRepairItemOpcode ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: CMSG_REPAIR_ITEM" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint64 npcGUID , itemGUID ;
uint8 guildBank ; // new in 2.3.2, bool that means from guild bank money
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
recv_data >> npcGUID >> itemGUID >> guildBank ;
2009-10-17 15:51:44 -07:00
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( npcGUID , UNIT_NPC_FLAG_REPAIR );
2008-10-11 14:16:25 -05:00
if ( ! unit )
{
sLog . outDebug ( "WORLD: HandleRepairItemOpcode - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( npcGUID )) );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -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 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// reputation discount
float discountMod = _player -> GetReputationPriceDiscount ( unit );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 TotalCost = 0 ;
if ( itemGUID )
{
sLog . outDebug ( "ITEM: Repair item, itemGUID = %u, npcGUID = %u" , GUID_LOPART ( itemGUID ), GUID_LOPART ( npcGUID ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * item = _player -> GetItemByGuid ( itemGUID );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( item )
TotalCost = _player -> DurabilityRepair ( item -> GetPos (), true , discountMod , guildBank > 0 ? true : false );
}
else
{
sLog . outDebug ( "ITEM: Repair all items, npcGUID = %u" , GUID_LOPART ( npcGUID ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
TotalCost = _player -> DurabilityRepairAll ( true , discountMod , guildBank > 0 ? true : false );
}
if ( guildBank )
{
uint32 GuildId = _player -> GetGuildId ();
if ( ! GuildId )
return ;
Guild * pGuild = objmgr . GetGuildById ( GuildId );
if ( ! pGuild )
return ;
pGuild -> LogBankEvent ( GUILD_BANK_LOG_REPAIR_MONEY , 0 , _player -> GetGUIDLow (), TotalCost );
pGuild -> SendMoneyInfo ( this , _player -> GetGUIDLow ());
}
}
2009-02-17 20:07:49 -06:00