2 * Copyright (C) 2005-2010 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"
26 #include "ObjectMgr.h"
29 #include "GossipDef.h"
30 #include "UpdateMask.h"
31 #include "ScriptCalls.h"
32 #include "ObjectAccessor.h"
37 void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket
& recv_data
)
42 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(guid
,UNIT_NPC_FLAG_TABARDDESIGNER
);
45 sLog
.outDebug( "WORLD: HandleTabardVendorActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
50 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
51 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
53 SendTabardVendorActivate(guid
);
56 void WorldSession::SendTabardVendorActivate( uint64 guid
)
58 WorldPacket
data( MSG_TABARDVENDOR_ACTIVATE
, 8 );
63 void WorldSession::HandleBankerActivateOpcode( WorldPacket
& recv_data
)
67 sLog
.outDebug( "WORLD: Received CMSG_BANKER_ACTIVATE" );
71 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(guid
,UNIT_NPC_FLAG_BANKER
);
74 sLog
.outDebug( "WORLD: HandleBankerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
79 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
80 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
85 void WorldSession::SendShowBank( uint64 guid
)
87 WorldPacket
data( SMSG_SHOW_BANK
, 8 );
92 void WorldSession::HandleTrainerListOpcode( WorldPacket
& recv_data
)
97 SendTrainerList( guid
);
100 void WorldSession::SendTrainerList( uint64 guid
)
102 std::string str
= GetMangosString(LANG_NPC_TAINER_HELLO
);
103 SendTrainerList( guid
, str
);
106 void WorldSession::SendTrainerList( uint64 guid
, const std::string
& strTitle
)
108 sLog
.outDebug( "WORLD: SendTrainerList" );
110 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(guid
,UNIT_NPC_FLAG_TRAINER
);
113 sLog
.outDebug( "WORLD: SendTrainerList - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
118 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
119 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
121 // trainer list loaded at check;
122 if(!unit
->isCanTrainingOf(_player
,true))
125 CreatureInfo
const *ci
= unit
->GetCreatureInfo();
129 sLog
.outDebug( "WORLD: SendTrainerList - (GUID: %u) NO CREATUREINFO!",GUID_LOPART(guid
) );
133 TrainerSpellData
const* trainer_spells
= unit
->GetTrainerSpells();
136 sLog
.outDebug( "WORLD: SendTrainerList - Training spells not found for creature (GUID: %u Entry: %u)",
137 GUID_LOPART(guid
), unit
->GetEntry());
141 WorldPacket
data( SMSG_TRAINER_LIST
, 8+4+4+trainer_spells
->spellList
.size()*38 + strTitle
.size()+1);
143 data
<< uint32(trainer_spells
->trainerType
);
145 size_t count_pos
= data
.wpos();
146 data
<< uint32(trainer_spells
->spellList
.size());
148 // reputation discount
149 float fDiscountMod
= _player
->GetReputationPriceDiscount(unit
);
150 bool can_learn_primary_prof
= GetPlayer()->GetFreePrimaryProfessionPoints() > 0;
153 for(TrainerSpellMap::const_iterator itr
= trainer_spells
->spellList
.begin(); itr
!= trainer_spells
->spellList
.end(); ++itr
)
155 TrainerSpell
const* tSpell
= &itr
->second
;
157 if(!_player
->IsSpellFitByClassAndRace(tSpell
->learnedSpell
))
160 bool primary_prof_first_rank
= sSpellMgr
.IsPrimaryProfessionFirstRankSpell(tSpell
->learnedSpell
);
161 SpellChainNode
const* chain_node
= sSpellMgr
.GetSpellChainNode(tSpell
->learnedSpell
);
162 TrainerSpellState state
= _player
->GetTrainerSpellState(tSpell
);
164 data
<< uint32(tSpell
->spell
); // learned spell (or cast-spell in profession case)
165 data
<< uint8(state
==TRAINER_SPELL_GREEN_DISABLED
? TRAINER_SPELL_GREEN
: state
);
166 data
<< uint32(floor(tSpell
->spellCost
* fDiscountMod
));
168 data
<< uint32(primary_prof_first_rank
&& can_learn_primary_prof
? 1 : 0);
169 // primary prof. learn confirmation dialog
170 data
<< uint32(primary_prof_first_rank
? 1 : 0); // must be equal prev. field to have learn button in enabled state
171 data
<< uint8(tSpell
->reqLevel
);
172 data
<< uint32(tSpell
->reqSkill
);
173 data
<< uint32(tSpell
->reqSkillValue
);
174 data
<< uint32(!tSpell
->IsCastable() && chain_node
? (chain_node
->prev
? chain_node
->prev
: chain_node
->req
) : 0);
175 data
<< uint32(!tSpell
->IsCastable() && chain_node
&& chain_node
->prev
? chain_node
->req
: 0);
183 data
.put
<uint32
>(count_pos
,count
);
187 void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket
& recv_data
)
192 recv_data
>> guid
>> spellId
;
193 sLog
.outDebug( "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u",uint32(GUID_LOPART(guid
)), spellId
);
195 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(guid
, UNIT_NPC_FLAG_TRAINER
);
198 sLog
.outDebug( "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
203 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
204 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
206 if(!unit
->isCanTrainingOf(_player
,true))
209 // check present spell in trainer spell list
210 TrainerSpellData
const* trainer_spells
= unit
->GetTrainerSpells();
215 TrainerSpell
const* trainer_spell
= trainer_spells
->Find(spellId
);
219 // can't be learn, cheat? Or double learn with lags...
220 if(_player
->GetTrainerSpellState(trainer_spell
) != TRAINER_SPELL_GREEN
)
223 // apply reputation discount
224 uint32 nSpellCost
= uint32(floor(trainer_spell
->spellCost
* _player
->GetReputationPriceDiscount(unit
)));
226 // check money requirement
227 if(_player
->GetMoney() < nSpellCost
)
230 _player
->ModifyMoney( -int32(nSpellCost
) );
232 WorldPacket
data(SMSG_PLAY_SPELL_VISUAL
, 12); // visual effect on trainer
233 data
<< uint64(guid
) << uint32(0xB3);
236 data
.Initialize(SMSG_PLAY_SPELL_IMPACT
, 12); // visual effect on player
237 data
<< uint64(_player
->GetGUID()) << uint32(0x016A);
240 // learn explicitly or cast explicitly
241 if(trainer_spell
->IsCastable ())
242 //FIXME: prof. spell entry in trainer list not marked gray until list re-open.
243 _player
->CastSpell(_player
,trainer_spell
->spell
,true);
245 _player
->learnSpell(spellId
,false);
247 data
.Initialize(SMSG_TRAINER_BUY_SUCCEEDED
, 12);
248 data
<< uint64(guid
) << uint32(trainer_spell
->spell
);
252 void WorldSession::HandleGossipHelloOpcode(WorldPacket
& recv_data
)
254 sLog
.outDebug("WORLD: Received CMSG_GOSSIP_HELLO");
259 Creature
*pCreature
= GetPlayer()->GetNPCIfCanInteractWith(guid
, UNIT_NPC_FLAG_NONE
);
263 sLog
.outDebug("WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)));
268 if (GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
269 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
271 if (!pCreature
->IsStopped())
272 pCreature
->StopMoving();
274 if (pCreature
->isSpiritGuide())
275 pCreature
->SendAreaSpiritHealerQueryOpcode(_player
);
277 if (!Script
->GossipHello(_player
, pCreature
))
279 _player
->TalkedToCreature(pCreature
->GetEntry(), pCreature
->GetGUID());
280 _player
->PrepareGossipMenu(pCreature
, pCreature
->GetCreatureInfo()->GossipMenuId
);
281 _player
->SendPreparedGossip(pCreature
);
285 void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket
& recv_data
)
287 sLog
.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION");
292 std::string code
= "";
294 recv_data
>> guid
>> menuId
>> gossipListId
;
296 if (_player
->PlayerTalkClass
->GossipOptionCoded(gossipListId
))
298 sLog
.outBasic("reading string");
300 sLog
.outBasic("string read: %s", code
.c_str());
304 if (GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
305 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
307 // can vehicle have gossip? If so, need check for this also.
308 if (guid
.IsCreatureOrPet())
310 Creature
*pCreature
= GetPlayer()->GetNPCIfCanInteractWith(guid
, UNIT_NPC_FLAG_NONE
);
314 sLog
.outDebug("WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", guid
.GetString().c_str());
320 if (!Script
->GossipSelectWithCode(_player
, pCreature
, _player
->PlayerTalkClass
->GossipOptionSender(gossipListId
), _player
->PlayerTalkClass
->GossipOptionAction(gossipListId
), code
.c_str()))
321 _player
->OnGossipSelect(pCreature
, gossipListId
, menuId
);
325 if (!Script
->GossipSelect(_player
, pCreature
, _player
->PlayerTalkClass
->GossipOptionSender(gossipListId
), _player
->PlayerTalkClass
->GossipOptionAction(gossipListId
)))
326 _player
->OnGossipSelect(pCreature
, gossipListId
, menuId
);
329 else if (guid
.IsGameobject())
331 GameObject
*pGo
= GetPlayer()->GetGameObjectIfCanInteractWith(guid
);
335 sLog
.outDebug("WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", guid
.GetString().c_str());
341 if (!Script
->GOGossipSelectWithCode(_player
, pGo
, _player
->PlayerTalkClass
->GossipOptionSender(gossipListId
), _player
->PlayerTalkClass
->GossipOptionAction(gossipListId
), code
.c_str()))
342 _player
->OnGossipSelect(pGo
, gossipListId
, menuId
);
346 if (!Script
->GOGossipSelect(_player
, pGo
, _player
->PlayerTalkClass
->GossipOptionSender(gossipListId
), _player
->PlayerTalkClass
->GossipOptionAction(gossipListId
)))
347 _player
->OnGossipSelect(pGo
, gossipListId
, menuId
);
352 void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket
& recv_data
)
354 sLog
.outDebug("WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
360 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(guid
, UNIT_NPC_FLAG_SPIRITHEALER
);
363 sLog
.outDebug( "WORLD: HandleSpiritHealerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
368 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
369 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
371 SendSpiritResurrect();
374 void WorldSession::SendSpiritResurrect()
376 _player
->ResurrectPlayer(0.5f
, true);
378 _player
->DurabilityLossAll(0.25f
,true);
380 // get corpse nearest graveyard
381 WorldSafeLocsEntry
const *corpseGrave
= NULL
;
382 Corpse
*corpse
= _player
->GetCorpse();
384 corpseGrave
= sObjectMgr
.GetClosestGraveYard(
385 corpse
->GetPositionX(), corpse
->GetPositionY(), corpse
->GetPositionZ(), corpse
->GetMapId(), _player
->GetTeam() );
387 // now can spawn bones
388 _player
->SpawnCorpseBones();
390 // teleport to nearest from corpse graveyard, if different from nearest to player ghost
393 WorldSafeLocsEntry
const *ghostGrave
= sObjectMgr
.GetClosestGraveYard(
394 _player
->GetPositionX(), _player
->GetPositionY(), _player
->GetPositionZ(), _player
->GetMapId(), _player
->GetTeam() );
396 if(corpseGrave
!= ghostGrave
)
397 _player
->TeleportTo(corpseGrave
->map_id
, corpseGrave
->x
, corpseGrave
->y
, corpseGrave
->z
, _player
->GetOrientation());
398 // or update at original position
400 _player
->UpdateVisibilityForPlayer();
402 // or update at original position
404 _player
->UpdateVisibilityForPlayer();
407 void WorldSession::HandleBinderActivateOpcode( WorldPacket
& recv_data
)
410 recv_data
>> npcGUID
;
412 if(!GetPlayer()->IsInWorld() || !GetPlayer()->isAlive())
415 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
,UNIT_NPC_FLAG_INNKEEPER
);
418 sLog
.outDebug( "WORLD: HandleBinderActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
423 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
424 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
429 void WorldSession::SendBindPoint(Creature
*npc
)
431 // prevent set homebind to instances in any case
432 if(GetPlayer()->GetMap()->Instanceable())
435 // send spell for bind 3286 bind magic
436 npc
->CastSpell(_player
, 3286, true); // Bind
438 WorldPacket
data( SMSG_TRAINER_BUY_SUCCEEDED
, (8+4));
439 data
<< uint64(npc
->GetGUID());
440 data
<< uint32(3286); // Bind
443 _player
->PlayerTalkClass
->CloseGossip();
446 void WorldSession::HandleListStabledPetsOpcode( WorldPacket
& recv_data
)
448 sLog
.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS");
451 recv_data
>> npcGUID
;
453 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
456 sLog
.outDebug( "WORLD: HandleListStabledPetsOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
461 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
462 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
464 SendStablePet(npcGUID
);
467 void WorldSession::SendStablePet(uint64 guid
)
469 sLog
.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS Send.");
471 WorldPacket
data(MSG_LIST_STABLED_PETS
, 200); // guess size
472 data
<< uint64 ( guid
);
474 Pet
*pet
= _player
->GetPet();
476 size_t wpos
= data
.wpos();
477 data
<< uint8(0); // place holder for slot show number
479 data
<< uint8(GetPlayer()->m_stableSlots
);
481 uint8 num
= 0; // counter for place holder
483 // not let move dead pet in slot
484 if(pet
&& pet
->isAlive() && pet
->getPetType()==HUNTER_PET
)
486 data
<< uint32(pet
->GetCharmInfo()->GetPetNumber());
487 data
<< uint32(pet
->GetEntry());
488 data
<< uint32(pet
->getLevel());
489 data
<< pet
->GetName(); // petname
490 data
<< uint8(1); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
495 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",
496 _player
->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT
,PET_SAVE_LAST_STABLE_SLOT
);
502 Field
*fields
= result
->Fetch();
504 data
<< uint32(fields
[1].GetUInt32()); // petnumber
505 data
<< uint32(fields
[2].GetUInt32()); // creature entry
506 data
<< uint32(fields
[3].GetUInt32()); // level
507 data
<< fields
[4].GetString(); // name
508 data
<< uint8(2); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
511 }while( result
->NextRow() );
516 data
.put
<uint8
>(wpos
, num
); // set real data to placeholder
520 void WorldSession::HandleStablePet( WorldPacket
& recv_data
)
522 sLog
.outDebug("WORLD: Recv CMSG_STABLE_PET");
525 recv_data
>> npcGUID
;
527 if(!GetPlayer()->isAlive())
530 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
533 sLog
.outDebug( "WORLD: HandleStablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
538 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
539 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
541 Pet
*pet
= _player
->GetPet();
543 // can't place in stable dead pet
544 if(!pet
||!pet
->isAlive()||pet
->getPetType()!=HUNTER_PET
)
546 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
552 uint32 free_slot
= 1;
554 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot ",
555 _player
->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT
,PET_SAVE_LAST_STABLE_SLOT
);
560 Field
*fields
= result
->Fetch();
562 uint32 slot
= fields
[1].GetUInt32();
564 // slots ordered in query, and if not equal then free
568 // this slot not free, skip
570 }while( result
->NextRow() );
575 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
576 if( free_slot
> 0 && free_slot
<= GetPlayer()->m_stableSlots
)
578 _player
->RemovePet(pet
,PetSaveMode(free_slot
));
587 void WorldSession::HandleUnstablePet( WorldPacket
& recv_data
)
589 sLog
.outDebug("WORLD: Recv CMSG_UNSTABLE_PET.");
593 recv_data
>> npcGUID
>> petnumber
;
595 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
598 sLog
.outDebug( "WORLD: HandleUnstablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
603 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
604 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
606 uint32 creature_id
= 0;
609 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'",
610 _player
->GetGUIDLow(),petnumber
,PET_SAVE_FIRST_STABLE_SLOT
,PET_SAVE_LAST_STABLE_SLOT
);
613 Field
*fields
= result
->Fetch();
614 creature_id
= fields
[0].GetUInt32();
621 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
627 CreatureInfo
const* creatureInfo
= ObjectMgr::GetCreatureTemplate(creature_id
);
628 if(!creatureInfo
|| !creatureInfo
->isTameable(_player
->CanTameExoticPets()))
630 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
636 Pet
* pet
= _player
->GetPet();
637 if(pet
&& pet
->isAlive())
639 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
647 _player
->RemovePet(pet
,PET_SAVE_AS_DELETED
);
649 Pet
*newpet
= new Pet(HUNTER_PET
);
650 if(!newpet
->LoadPetFromDB(_player
,creature_id
,petnumber
))
654 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
660 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
665 void WorldSession::HandleBuyStableSlot( WorldPacket
& recv_data
)
667 sLog
.outDebug("WORLD: Recv CMSG_BUY_STABLE_SLOT.");
670 recv_data
>> npcGUID
;
672 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
675 sLog
.outDebug( "WORLD: HandleBuyStableSlot - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
680 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
681 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
683 WorldPacket
data(SMSG_STABLE_RESULT
, 200);
685 if(GetPlayer()->m_stableSlots
< MAX_PET_STABLES
)
687 StableSlotPricesEntry
const *SlotPrice
= sStableSlotPricesStore
.LookupEntry(GetPlayer()->m_stableSlots
+1);
688 if(_player
->GetMoney() >= SlotPrice
->Price
)
690 ++GetPlayer()->m_stableSlots
;
691 _player
->ModifyMoney(-int32(SlotPrice
->Price
));
692 data
<< uint8(0x0A); // success buy
703 void WorldSession::HandleStableRevivePet( WorldPacket
&/* recv_data */)
705 sLog
.outDebug("HandleStableRevivePet: Not implemented");
708 void WorldSession::HandleStableSwapPet( WorldPacket
& recv_data
)
710 sLog
.outDebug("WORLD: Recv CMSG_STABLE_SWAP_PET.");
714 recv_data
>> npcGUID
>> pet_number
;
716 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
, UNIT_NPC_FLAG_STABLEMASTER
);
719 sLog
.outDebug( "WORLD: HandleStableSwapPet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
724 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
725 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
728 Pet
* pet
= _player
->GetPet();
730 if(!pet
|| pet
->getPetType()!=HUNTER_PET
)
733 // find swapped pet slot in stable
734 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'",
735 _player
->GetGUIDLow(),pet_number
);
739 Field
*fields
= result
->Fetch();
741 uint32 slot
= fields
[0].GetUInt32();
742 uint32 creature_id
= fields
[1].GetUInt32();
747 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
753 CreatureInfo
const* creatureInfo
= ObjectMgr::GetCreatureTemplate(creature_id
);
754 if(!creatureInfo
|| !creatureInfo
->isTameable(_player
->CanTameExoticPets()))
756 WorldPacket
data(SMSG_STABLE_RESULT
, 1);
762 // move alive pet to slot or delete dead pet
763 _player
->RemovePet(pet
,pet
->isAlive() ? PetSaveMode(slot
) : PET_SAVE_AS_DELETED
);
765 WorldPacket
data(SMSG_STABLE_RESULT
, 1); // guess size
767 // summon unstabled pet
768 Pet
*newpet
= new Pet
;
769 if(!newpet
->LoadPetFromDB(_player
,creature_id
,pet_number
))
780 void WorldSession::HandleRepairItemOpcode( WorldPacket
& recv_data
)
782 sLog
.outDebug("WORLD: CMSG_REPAIR_ITEM");
784 uint64 npcGUID
, itemGUID
;
785 uint8 guildBank
; // new in 2.3.2, bool that means from guild bank money
787 recv_data
>> npcGUID
>> itemGUID
>> guildBank
;
789 Creature
*unit
= GetPlayer()->GetNPCIfCanInteractWith(npcGUID
, UNIT_NPC_FLAG_REPAIR
);
792 sLog
.outDebug( "WORLD: HandleRepairItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID
)) );
797 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
798 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
800 // reputation discount
801 float discountMod
= _player
->GetReputationPriceDiscount(unit
);
803 uint32 TotalCost
= 0;
806 sLog
.outDebug("ITEM: Repair item, itemGUID = %u, npcGUID = %u", GUID_LOPART(itemGUID
), GUID_LOPART(npcGUID
));
808 Item
* item
= _player
->GetItemByGuid(itemGUID
);
811 TotalCost
= _player
->DurabilityRepair(item
->GetPos(),true,discountMod
,guildBank
>0?true:false);
815 sLog
.outDebug("ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGUID
));
817 TotalCost
= _player
->DurabilityRepairAll(true,discountMod
,guildBank
>0?true:false);
821 uint32 GuildId
= _player
->GetGuildId();
824 Guild
*pGuild
= sObjectMgr
.GetGuildById(GuildId
);
827 pGuild
->LogBankEvent(GUILD_BANK_LOG_REPAIR_MONEY
, 0, _player
->GetGUIDLow(), TotalCost
);
828 pGuild
->SendMoneyInfo(this, _player
->GetGUIDLow());