2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "Database/DatabaseEnv.h"
22 #include "WorldPacket.h"
23 #include "WorldSession.h"
27 #include "ObjectMgr.h"
30 #include "GossipDef.h"
31 #include "SpellAuras.h"
32 #include "UpdateMask.h"
33 #include "ScriptCalls.h"
34 #include "ObjectAccessor.h"
36 #include "MapManager.h"
38 #include "BattleGroundMgr.h"
39 #include "BattleGround.h"
42 void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket
& recv_data
)
44 CHECK_PACKET_SIZE(recv_data
,8);
49 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_TABARDDESIGNER
);
52 sLog
.outDebug( "WORLD: HandleTabardVendorActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
57 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
58 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
60 SendTabardVendorActivate(guid
);
63 void WorldSession::SendTabardVendorActivate( uint64 guid
)
65 WorldPacket
data( MSG_TABARDVENDOR_ACTIVATE
, 8 );
70 void WorldSession::HandleBankerActivateOpcode( WorldPacket
& recv_data
)
72 CHECK_PACKET_SIZE(recv_data
,8);
76 sLog
.outDebug( "WORLD: Received CMSG_BANKER_ACTIVATE" );
80 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_BANKER
);
83 sLog
.outDebug( "WORLD: HandleBankerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
88 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
89 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
94 void WorldSession::SendShowBank( uint64 guid
)
96 WorldPacket
data( SMSG_SHOW_BANK
, 8 );
101 void WorldSession::HandleTrainerListOpcode( WorldPacket
& recv_data
)
103 CHECK_PACKET_SIZE(recv_data
,8);
108 SendTrainerList( guid
);
111 void WorldSession::SendTrainerList( uint64 guid
)
113 std::string str
= GetMangosString(LANG_NPC_TAINER_HELLO
);
114 SendTrainerList( guid
, str
);
117 void WorldSession::SendTrainerList( uint64 guid
,std::string strTitle
)
119 sLog
.outDebug( "WORLD: SendTrainerList" );
121 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_TRAINER
);
124 sLog
.outDebug( "WORLD: SendTrainerList - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
129 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
130 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
132 // trainer list loaded at check;
133 if(!unit
->isCanTrainingOf(_player
,true))
136 CreatureInfo
const *ci
= unit
->GetCreatureInfo();
140 sLog
.outDebug( "WORLD: SendTrainerList - (GUID: %u) NO CREATUREINFO!",GUID_LOPART(guid
) );
144 TrainerSpellData
const* trainer_spells
= unit
->GetTrainerSpells();
147 sLog
.outDebug( "WORLD: SendTrainerList - Training spells not found for creature (GUID: %u Entry: %u)",
148 GUID_LOPART(guid
), unit
->GetEntry());
152 WorldPacket
data( SMSG_TRAINER_LIST
, 8+4+4+trainer_spells
->spellList
.size()*38 + strTitle
.size()+1);
154 data
<< uint32(trainer_spells
->trainerType
);
156 size_t count_pos
= data
.wpos();
157 data
<< uint32(trainer_spells
->spellList
.size());
159 // reputation discount
160 float fDiscountMod
= _player
->GetReputationPriceDiscount(unit
);
163 for(TrainerSpellList::const_iterator itr
= trainer_spells
->spellList
.begin(); itr
!= trainer_spells
->spellList
.end(); ++itr
)
165 TrainerSpell
const* tSpell
= *itr
;
167 if(!_player
->IsSpellFitByClassAndRace(tSpell
->spell
))
172 bool primary_prof_first_rank
= spellmgr
.IsPrimaryProfessionFirstRankSpell(tSpell
->spell
);
174 SpellChainNode
const* chain_node
= spellmgr
.GetSpellChainNode(tSpell
->spell
);
176 data
<< uint32(tSpell
->spell
);
177 data
<< uint8(_player
->GetTrainerSpellState(tSpell
));
178 data
<< uint32(floor(tSpell
->spellcost
* fDiscountMod
));
180 data
<< uint32(primary_prof_first_rank
? 1 : 0); // primary prof. learn confirmation dialog
181 data
<< uint32(primary_prof_first_rank
? 1 : 0); // must be equal prev. field to have learn button in enabled state
182 data
<< uint8(tSpell
->reqlevel
);
183 data
<< uint32(tSpell
->reqskill
);
184 data
<< uint32(tSpell
->reqskillvalue
);
185 data
<< uint32(chain_node
? (chain_node
->prev
? chain_node
->prev
: chain_node
->req
) : 0);
186 data
<< uint32(chain_node
&& chain_node
->prev
? chain_node
->req
: 0);
192 data
.put
<uint32
>(count_pos
,count
);
196 void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket
& recv_data
)
198 CHECK_PACKET_SIZE(recv_data
,8+4);
203 recv_data
>> guid
>> spellId
;
204 sLog
.outDebug( "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u",uint32(GUID_LOPART(guid
)), spellId
);
206 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
, UNIT_NPC_FLAG_TRAINER
);
209 sLog
.outDebug( "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
214 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
215 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
217 if(!unit
->isCanTrainingOf(_player
,true))
220 // check present spell in trainer spell list
221 TrainerSpellData
const* trainer_spells
= unit
->GetTrainerSpells();
226 TrainerSpell
const* trainer_spell
= trainer_spells
->Find(spellId
);
230 // can't be learn, cheat? Or double learn with lags...
231 if(_player
->GetTrainerSpellState(trainer_spell
) != TRAINER_SPELL_GREEN
)
234 // apply reputation discount
235 uint32 nSpellCost
= uint32(floor(trainer_spell
->spellcost
* _player
->GetReputationPriceDiscount(unit
)));
237 // check money requirement
238 if(_player
->GetMoney() < nSpellCost
)
241 WorldPacket
data(SMSG_PLAY_SPELL_VISUAL
, 12); // visual effect on trainer
242 data
<< uint64(guid
) << uint32(0xB3);
245 data
.Initialize(SMSG_PLAY_SPELL_IMPACT
, 12); // visual effect on player
246 data
<< uint64(_player
->GetGUID()) << uint32(0x016A);
249 _player
->ModifyMoney( -int32(nSpellCost
) );
251 // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation
252 _player
->learnSpell(trainer_spell
->spell
);
254 data
.Initialize(SMSG_TRAINER_BUY_SUCCEEDED
, 12);
255 data
<< uint64(guid
) << uint32(spellId
);
259 void WorldSession::HandleGossipHelloOpcode( WorldPacket
& recv_data
)
261 CHECK_PACKET_SIZE(recv_data
,8);
263 sLog
.outDebug( "WORLD: Received CMSG_GOSSIP_HELLO" );
268 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
, UNIT_NPC_FLAG_NONE
);
271 sLog
.outDebug( "WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
276 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
277 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
279 if( unit
->isArmorer() || unit
->isCivilian() || unit
->isQuestGiver() || unit
->isServiceProvider())
284 // If spiritguide, no need for gossip menu, just put player into resurrect queue
285 if (unit
->isSpiritGuide())
287 BattleGround
*bg
= _player
->GetBattleGround();
290 bg
->AddPlayerToResurrectQueue(unit
->GetGUID(), _player
->GetGUID());
291 sBattleGroundMgr
.SendAreaSpiritHealerQueryOpcode(_player
, bg
, unit
->GetGUID());
296 if(!Script
->GossipHello( _player
, unit
))
298 _player
->TalkedToCreature(unit
->GetEntry(),unit
->GetGUID());
299 unit
->prepareGossipMenu(_player
);
300 unit
->sendPreparedGossip(_player
);
304 void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket
& recv_data
)
306 CHECK_PACKET_SIZE(recv_data
,8+4+4);
308 sLog
.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION");
313 std::string code
= "";
315 recv_data
>> guid
>> unk
>> option
;
317 if(_player
->PlayerTalkClass
->GossipOptionCoded( option
))
320 CHECK_PACKET_SIZE(recv_data
,8+4+1);
321 sLog
.outBasic("reading string");
323 sLog
.outBasic("string read: %s", code
.c_str());
326 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
, UNIT_NPC_FLAG_NONE
);
329 sLog
.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
334 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
335 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
339 if (!Script
->GossipSelectWithCode(_player
, unit
, _player
->PlayerTalkClass
->GossipOptionSender (option
), _player
->PlayerTalkClass
->GossipOptionAction( option
), code
.c_str()))
340 unit
->OnGossipSelect (_player
, option
);
344 if (!Script
->GossipSelect (_player
, unit
, _player
->PlayerTalkClass
->GossipOptionSender (option
), _player
->PlayerTalkClass
->GossipOptionAction (option
)))
345 unit
->OnGossipSelect (_player
, option
);
349 void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket
& recv_data
)
351 CHECK_PACKET_SIZE(recv_data
,8);
353 sLog
.outDebug("WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
359 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
, UNIT_NPC_FLAG_SPIRITHEALER
);
362 sLog
.outDebug( "WORLD: HandleSpiritHealerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
367 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
368 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
370 SendSpiritResurrect();
373 void WorldSession::SendSpiritResurrect()
375 _player
->ResurrectPlayer(0.5f
, true);
377 _player
->DurabilityLossAll(0.25f
,true);
379 // get corpse nearest graveyard
380 WorldSafeLocsEntry
const *corpseGrave
= NULL
;
381 Corpse
*corpse
= _player
->GetCorpse();
383 corpseGrave
= objmgr
.GetClosestGraveYard(
384 corpse
->GetPositionX(), corpse
->GetPositionY(), corpse
->GetPositionZ(), corpse
->GetMapId(), _player
->GetTeam() );
386 // now can spawn bones
387 _player
->SpawnCorpseBones();
389 // teleport to nearest from corpse graveyard, if different from nearest to player ghost
392 WorldSafeLocsEntry
const *ghostGrave
= objmgr
.GetClosestGraveYard(
393 _player
->GetPositionX(), _player
->GetPositionY(), _player
->GetPositionZ(), _player
->GetMapId(), _player
->GetTeam() );
395 if(corpseGrave
!= ghostGrave
)
396 _player
->TeleportTo(corpseGrave
->map_id
, corpseGrave
->x
, corpseGrave
->y
, corpseGrave
->z
, _player
->GetOrientation());
397 // or update at original position
399 ObjectAccessor::UpdateVisibilityForPlayer(_player
);
401 // or update at original position
403 ObjectAccessor::UpdateVisibilityForPlayer(_player
);
408 void WorldSession::HandleBinderActivateOpcode( WorldPacket
& recv_data
)
410 CHECK_PACKET_SIZE(recv_data
,8);
413 recv_data
>> npcGUID
;
415 if(!GetPlayer()->isAlive())
418 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
,UNIT_NPC_FLAG_INNKEEPER
);
421 sLog
.outDebug( "WORLD: HandleBinderActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
426 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
427 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
432 void WorldSession::SendBindPoint(Creature
*npc
)
434 uint32 bindspell
= 3286;
436 // update sql homebind
437 CharacterDatabase
.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player
->GetMapId(), _player
->GetZoneId(), _player
->GetPositionX(), _player
->GetPositionY(), _player
->GetPositionZ(), _player
->GetGUIDLow());
438 _player
->m_homebindMapId
= _player
->GetMapId();
439 _player
->m_homebindZoneId
= _player
->GetZoneId();
440 _player
->m_homebindX
= _player
->GetPositionX();
441 _player
->m_homebindY
= _player
->GetPositionY();
442 _player
->m_homebindZ
= _player
->GetPositionZ();
444 // send spell for bind 3286 bind magic
445 npc
->CastSpell(_player
, bindspell
, true);
447 WorldPacket
data( SMSG_TRAINER_BUY_SUCCEEDED
, (8+4));
448 data
<< npc
->GetGUID();
453 data
.Initialize( SMSG_BINDPOINTUPDATE
, (4+4+4+4+4) );
454 data
<< float(_player
->GetPositionX());
455 data
<< float(_player
->GetPositionY());
456 data
<< float(_player
->GetPositionZ());
457 data
<< uint32(_player
->GetMapId());
458 data
<< uint32(_player
->GetZoneId());
461 DEBUG_LOG("New Home Position X is %f",_player
->GetPositionX());
462 DEBUG_LOG("New Home Position Y is %f",_player
->GetPositionY());
463 DEBUG_LOG("New Home Position Z is %f",_player
->GetPositionZ());
464 DEBUG_LOG("New Home MapId is %u",_player
->GetMapId());
465 DEBUG_LOG("New Home ZoneId is %u",_player
->GetZoneId());
468 data
.Initialize( SMSG_PLAYERBOUND
, 8+4 );
469 data
<< uint64(_player
->GetGUID());
470 data
<< uint32(_player
->GetZoneId());
473 _player
->PlayerTalkClass
->CloseGossip();
477 void WorldSession::HandleListStabledPetsOpcode( WorldPacket
& recv_data
)
479 CHECK_PACKET_SIZE(recv_data
,8);
481 sLog
.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS");
484 recv_data
>> npcGUID
;
486 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
489 sLog
.outDebug( "WORLD: HandleListStabledPetsOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
494 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
495 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
497 SendStablePet(npcGUID
);
500 void WorldSession::SendStablePet(uint64 guid
)
502 sLog
.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS Send.");
504 WorldPacket
data(MSG_LIST_STABLED_PETS
, 200); // guess size
505 data
<< uint64 ( guid
);
507 Pet
*pet
= _player
->GetPet();
509 data
<< uint8(0); // place holder for slot show number
510 data
<< uint8(GetPlayer()->m_stableSlots
);
512 uint8 num
= 0; // counter for place holder
514 // not let move dead pet in slot
515 if(pet
&& pet
->isAlive() && pet
->getPetType()==HUNTER_PET
)
517 data
<< uint32(pet
->GetCharmInfo()->GetPetNumber());
518 data
<< uint32(pet
->GetEntry());
519 data
<< uint32(pet
->getLevel());
520 data
<< pet
->GetName(); // petname
521 data
<< uint32(pet
->GetLoyaltyLevel()); // loyalty
522 data
<< uint8(0x01); // client slot 1 == current pet (0)
527 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player
->GetGUIDLow());
533 Field
*fields
= result
->Fetch();
535 data
<< uint32(fields
[2].GetUInt32()); // petnumber
536 data
<< uint32(fields
[3].GetUInt32()); // creature entry
537 data
<< uint32(fields
[4].GetUInt32()); // level
538 data
<< fields
[6].GetString(); // name
539 data
<< uint32(fields
[5].GetUInt32()); // loyalty
540 data
<< uint8(fields
[1].GetUInt32()+1); // slot
543 }while( result
->NextRow() );
548 data
.put
<uint8
>(8, num
); // set real data to placeholder
552 void WorldSession::HandleStablePet( WorldPacket
& recv_data
)
554 CHECK_PACKET_SIZE(recv_data
,8);
556 sLog
.outDebug("WORLD: Recv CMSG_STABLE_PET not dispose.");
559 recv_data
>> npcGUID
;
561 if(!GetPlayer()->isAlive())
564 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
567 sLog
.outDebug( "WORLD: HandleStablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
572 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
573 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
575 Pet
*pet
= _player
->GetPet();
577 WorldPacket
data(SMSG_STABLE_RESULT
, 200); // guess size
579 // can't place in stable dead pet
580 if(!pet
||!pet
->isAlive()||pet
->getPetType()!=HUNTER_PET
)
587 uint32 free_slot
= 1;
589 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3 ORDER BY slot ",_player
->GetGUIDLow());
594 Field
*fields
= result
->Fetch();
596 uint32 slot
= fields
[1].GetUInt32();
598 if(slot
==free_slot
) // this slot not free
600 }while( result
->NextRow() );
604 if( free_slot
> 0 && free_slot
<= GetPlayer()->m_stableSlots
)
606 _player
->RemovePet(pet
,PetSaveMode(free_slot
));
615 void WorldSession::HandleUnstablePet( WorldPacket
& recv_data
)
617 CHECK_PACKET_SIZE(recv_data
,8+4);
619 sLog
.outDebug("WORLD: Recv CMSG_UNSTABLE_PET.");
623 recv_data
>> npcGUID
>> petnumber
;
625 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
628 sLog
.outDebug( "WORLD: HandleUnstablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
633 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
634 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
636 WorldPacket
data(SMSG_STABLE_RESULT
, 200); // guess size
638 Pet
* pet
= _player
->GetPet();
639 if(pet
&& pet
->isAlive())
649 _player
->RemovePet(pet
,PET_SAVE_AS_DELETED
);
653 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player
->GetGUIDLow(),petnumber
);
656 Field
*fields
= result
->Fetch();
657 uint32 petentry
= fields
[0].GetUInt32();
659 newpet
= new Pet(HUNTER_PET
);
660 if(!newpet
->LoadPetFromDB(_player
,petentry
,petnumber
))
675 void WorldSession::HandleBuyStableSlot( WorldPacket
& recv_data
)
677 CHECK_PACKET_SIZE(recv_data
,8);
679 sLog
.outDebug("WORLD: Recv CMSG_BUY_STABLE_SLOT.");
682 recv_data
>> npcGUID
;
684 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
687 sLog
.outDebug( "WORLD: HandleBuyStableSlot - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
692 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
693 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
695 WorldPacket
data(SMSG_STABLE_RESULT
, 200);
697 if(GetPlayer()->m_stableSlots
< 2) // max slots amount = 2
699 StableSlotPricesEntry
const *SlotPrice
= sStableSlotPricesStore
.LookupEntry(GetPlayer()->m_stableSlots
+1);
700 if(_player
->GetMoney() >= SlotPrice
->Price
)
702 ++GetPlayer()->m_stableSlots
;
703 _player
->ModifyMoney(-int32(SlotPrice
->Price
));
704 data
<< uint8(0x0A); // success buy
715 void WorldSession::HandleStableRevivePet( WorldPacket
&/* recv_data */)
717 sLog
.outDebug("HandleStableRevivePet: Not implemented");
720 void WorldSession::HandleStableSwapPet( WorldPacket
& recv_data
)
722 CHECK_PACKET_SIZE(recv_data
,8+4);
724 sLog
.outDebug("WORLD: Recv CMSG_STABLE_SWAP_PET.");
728 recv_data
>> npcGUID
>> pet_number
;
730 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
733 sLog
.outDebug( "WORLD: HandleStableSwapPet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
738 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
739 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
741 WorldPacket
data(SMSG_STABLE_RESULT
, 200); // guess size
743 Pet
* pet
= _player
->GetPet();
745 if(!pet
|| pet
->getPetType()!=HUNTER_PET
)
748 // find swapped pet slot in stable
749 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'",_player
->GetGUIDLow(),pet_number
);
753 Field
*fields
= result
->Fetch();
755 uint32 slot
= fields
[0].GetUInt32();
756 uint32 petentry
= fields
[1].GetUInt32();
759 // move alive pet to slot or delele dead pet
760 _player
->RemovePet(pet
,pet
->isAlive() ? PetSaveMode(slot
) : PET_SAVE_AS_DELETED
);
762 // summon unstabled pet
763 Pet
*newpet
= new Pet
;
764 if(!newpet
->LoadPetFromDB(_player
,petentry
,pet_number
))
775 void WorldSession::HandleRepairItemOpcode( WorldPacket
& recv_data
)
777 CHECK_PACKET_SIZE(recv_data
,8+8+1);
779 sLog
.outDebug("WORLD: CMSG_REPAIR_ITEM");
781 uint64 npcGUID
, itemGUID
;
782 uint8 guildBank
; // new in 2.3.2, bool that means from guild bank money
784 recv_data
>> npcGUID
>> itemGUID
>> guildBank
;
786 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, npcGUID
, UNIT_NPC_FLAG_REPAIR
);
789 sLog
.outDebug( "WORLD: HandleRepairItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
794 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
795 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
797 // reputation discount
798 float discountMod
= _player
->GetReputationPriceDiscount(unit
);
800 uint32 TotalCost
= 0;
803 sLog
.outDebug("ITEM: Repair item, itemGUID = %u, npcGUID = %u", GUID_LOPART(itemGUID
), GUID_LOPART(npcGUID
));
805 Item
* item
= _player
->GetItemByGuid(itemGUID
);
808 TotalCost
= _player
->DurabilityRepair(item
->GetPos(),true,discountMod
,guildBank
>0?true:false);
812 sLog
.outDebug("ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGUID
));
814 TotalCost
= _player
->DurabilityRepairAll(true,discountMod
,guildBank
>0?true:false);
818 uint32 GuildId
= _player
->GetGuildId();
821 Guild
*pGuild
= objmgr
.GetGuildById(GuildId
);
824 pGuild
->LogBankEvent(GUILD_BANK_LOG_REPAIR_MONEY
, 0, _player
->GetGUIDLow(), TotalCost
);
825 pGuild
->SendMoneyInfo(this, _player
->GetGUIDLow());