46 TC_LOG_DEBUG(
"entities.pet",
"Vanitypet ({}) does not exist - player '{}' ({} / account: {}) attempted to dismiss it (possibly lagged out)",
80 if (pet !=
GetPlayer()->GetFirstControlled())
104 std::vector<Unit*> controlled;
106 if ((*itr)->GetEntry() == pet->
GetEntry() && (*itr)->IsAlive())
107 controlled.push_back(*itr);
108 for (std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr)
125 TC_LOG_ERROR(
"entities.pet",
"HandlePetStopAttack: {} isn't a pet or charmed creature of player {}",
141 TC_LOG_DEBUG(
"entities.pet",
"WorldSession::HandlePetAction(petGuid: {}, tagGuid: {}, spellId: {}, flag: {}): object {} is considered pet-like but doesn't have a charminfo!",
183 if (!owner->IsValidAttackTarget(TargetUnit))
202 petAI->_AttackStart(TargetUnit);
223 pet->
Attack(TargetUnit,
true);
247 ((
Minion*)pet)->UnSummon();
252 TC_LOG_ERROR(
"entities.pet",
"WORLD: unknown PET flag Action {} and spellid {}.",
uint32(flag), spellid);
272 Unit* unit_target =
nullptr;
281 TC_LOG_ERROR(
"spells.pet",
"WORLD: unknown PET spell id {}", spellid);
355 petAI->_AttackStart(unit_target);
357 AI->AttackStart(unit_target);
384 TC_LOG_ERROR(
"entities.pet",
"WORLD: unknown PET flag Action {} and spellid {}.",
uint32(flag), spellid);
390 TC_LOG_DEBUG(
"network.opcode",
"WORLD: Received CMSG_PET_NAME_QUERY");
395 recvData >> petnumber;
407 data <<
uint32(petnumber);
416 data <<
uint32(petnumber);
420 if (pet->
IsPet() && ((
Pet*)pet)->GetDeclinedNames())
424 data << ((
Pet*)pet)->GetDeclinedNames()->name[i];
439 TC_LOG_DEBUG(
"entities.player.cheat",
"{} attempt open stable in cheating way.", guid.
ToString());
448 TC_LOG_DEBUG(
"entities.player",
"Stablemaster {} not found or you can't interact with him.", guid.
ToString());
457 TC_LOG_DEBUG(
"network.opcode",
"WORLD: Received CMSG_PET_SET_ACTION");
475 TC_LOG_ERROR(
"entities.pet",
"WorldSession::HandlePetSetAction: object {} is considered pet-like but doesn't have a charminfo!", pet->
GetGUID().
ToString());
479 count = (recvData.
size() == 24) ? 2 : 1;
483 bool move_command =
false;
485 for (
uint8 i = 0; i < count; ++i)
487 recvData >> position[i];
508 std::vector<Unit*> pets;
510 if (controlled->GetEntry() == pet->
GetEntry() && controlled->IsAlive())
511 pets.push_back(controlled);
513 for (
Unit* petControlled : pets)
523 if (!actionEntry_1 || spell_id_0 != actionEntry_1->
GetAction() ||
524 act_state_0 != actionEntry_1->
GetType())
533 if (!actionEntry_0 || spell_id_1 != actionEntry_0->
GetAction() ||
534 act_state_1 != actionEntry_0->
GetType())
539 for (
uint8 i = 0; i < count; ++i)
544 TC_LOG_DEBUG(
"entities.pet",
"Player {} has changed pet spell action. Position: {}, Spell: {}, State: 0x{:X}",
555 if (petControlled->GetTypeId() ==
TYPEID_UNIT && petControlled->IsPet())
556 ((
Pet*)petControlled)->ToggleAutocast(spellInfo,
true);
559 if ((*itr)->GetEntry() == petControlled->GetEntry())
560 (*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo,
true);
565 if (petControlled->GetTypeId() ==
TYPEID_UNIT && petControlled->IsPet())
566 ((
Pet*)petControlled)->ToggleAutocast(spellInfo,
false);
569 if ((*itr)->GetEntry() == petControlled->GetEntry())
570 (*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo,
false);
582 TC_LOG_DEBUG(
"network.opcode",
"WORLD: Received CMSG_PET_RENAME");
592 recvData >> isdeclined;
628 recvData >> declinedname.
name[i];
653 for (
uint8 i = 0; i < 5; i++)
700 TC_LOG_ERROR(
"entities.pet",
"WorldSession::HandlePetSpellAutocastOpcode: {} isn't pet of player {} ({}).",
712 std::vector<Unit*> pets;
714 if (controlled->GetEntry() == pet->
GetEntry() && controlled->IsAlive())
715 pets.push_back(controlled);
717 for (
Unit* petControlled : pets)
723 CharmInfo* charmInfo = petControlled->GetCharmInfo();
726 TC_LOG_ERROR(
"entities.pet",
"WorldSession::HandlePetSpellAutocastOpcode: object {} is considered pet-like but doesn't have a charminfo!", petControlled->GetGUID().ToString());
730 if (
Pet* summon = petControlled->
ToPet())
741 TC_LOG_DEBUG(
"network.opcode",
"WORLD: Received CMSG_PET_CAST_SPELL");
748 recvPacket >> guid >> castCount >> spellId >> castFlags;
750 TC_LOG_DEBUG(
"entities.pet",
"WORLD: CMSG_PET_CAST_SPELL, {}, castCount: {}, spellId {}, castFlags {}", guid.
ToString(), castCount, spellId, castFlags);
767 TC_LOG_ERROR(
"spells.pet",
"WORLD: unknown PET spell id {}", spellId);
772 targets.
Read(recvPacket, caster);
796 Spell* spell =
new Spell(caster, spellInfo, triggerCastFlags);
814 pet->SendPetAIReaction(guid);
841 data << declinedName->
name[i];
850 TC_LOG_DEBUG(
"network.opcode",
"WORLD: Received CMSG_PET_LEARN_TALENT");
853 uint32 talentId, requestedRank;
854 recvData >> guid >> talentId >> requestedRank;
862 TC_LOG_DEBUG(
"network.opcode",
"WORLD: Received CMSG_LEARN_PREVIEW_TALENTS_PET");
868 recvData >> talentsCount;
870 uint32 talentId, talentRank;
873 uint32 const MaxTalentsCount = 30;
875 for (
uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
877 recvData >> talentId >> talentRank;
@ CHAR_INS_CHAR_PET_DECLINEDNAME
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
@ GROUP_UPDATE_FLAG_PET_NAME
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
@ PET_ACTION_SPECIAL_SPELL
bool roll_chance_i(int chance)
@ TARGET_DEST_DYNOBJ_ENEMY
@ TARGET_UNIT_DEST_AREA_ENEMY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_ATTR0_CASTABLE_WHILE_DEAD
@ PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME
@ SPELL_FAILED_UNIT_NOT_INFRONT
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ UNIT_PET_FLAG_CAN_BE_RENAMED
#define MAX_DECLINED_NAME_CASES
@ UNIT_NPC_FLAG_STABLEMASTER
@ UNIT_FLAG_PLAYER_CONTROLLED
#define MAX_UNIT_ACTION_BAR_INDEX
#define UNIT_ACTION_BUTTON_ACTION(X)
#define UNIT_ACTION_BUTTON_TYPE(X)
@ UNIT_FIELD_PET_NAME_TIMESTAMP
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
void SetReactState(ReactStates st)
void MoveFollow(Unit *target, float dist, ChaseAngle angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
LowType GetCounter() const
std::string ToString() const
static bool CheckDeclinedNames(const std::wstring &w_ownname, DeclinedName const &names)
static PetNameInvalidReason CheckPetName(std::string_view name, LocaleConstant locale)
static Creature * ToCreature(Object *o)
uint32 GetUInt32Value(uint16 index) const
static ObjectGuid GetGUID(Object const *o)
void SendUpdateToPlayer(Player *player)
static Player * ToPlayer(Object *o)
Optional< PetInfo > CurrentPet
Player * GetOwner() const
PetType getPetType() const
void SendTalentsInfoData(bool pet)
void SetGroupUpdateFlag(uint32 flag)
void SendDirectMessage(WorldPacket const *data) const
void CharmSpellInitialize()
PetStable * GetPetStable()
void PetSpellInitialize()
void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank)
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
void PossessSpellInitialize()
void VehicleSpellInitialize()
void setUInt32(uint8 index, uint32 value)
void setString(uint8 index, std::string const &value)
void Read(ByteBuffer &data, Unit *caster)
Unit * GetUnitTarget() const
void ResetCooldown(uint32 spellId, bool update=false)
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
bool IsAutocastable() const
bool HasAttribute(SpellAttr0 attribute) const
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
SpellCastTargets m_targets
void SendPetCastResult(SpellCastResult result)
SpellCastResult prepare(SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
SpellCastResult CheckPetCast(Unit *target)
void InitExplicitTargets(SpellCastTargets const &targets)
void finish(bool ok=true)
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, uint32 *param1=nullptr, uint32 *param2=nullptr)
virtual void UnSummon(uint32 msTime=0)
virtual void AttackStart(Unit *)
Unit * GetCharmed() const
bool HasPetFlag(UnitPetFlag flags) const
void SendPetAIReaction(ObjectGuid guid) const
ObjectGuid GetOwnerGUID() const override
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
MotionMaster * GetMotionMaster()
void SetPetNameTimestamp(uint32 timestamp)
TempSummon * ToTempSummon()
CharmInfo * GetCharmInfo()
virtual bool HasSpell(uint32) const
Unit * GetCharmerOrOwner() const
bool Attack(Unit *victim, bool meleeAttack)
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool force=false)
void SendPetActionSound(PetAction action) const
void RemovePetFlag(UnitPetFlag flags)
ObjectGuid GetCritterGUID() const
virtual float GetFollowAngle() const
Unit * GetFirstControlled() const
uint32 HasUnitTypeMask(uint32 mask) const
SpellHistory * GetSpellHistory()
ObjectGuid GetCharmerGUID() const
virtual bool HasSpellFocus(Spell const *=nullptr) const
uint32 GetPower(Powers power) const
bool HasAuraTypeWithTriggerSpell(AuraType auratype, uint32 triggerSpell) const
void SetInFront(WorldObject const *target)
Guardian * GetGuardianPet() const
ObjectGuid GetPetGUID() const
void SendPetDismissSound() const
std::string const & GetName() const
void SetName(std::string newname)
bool CheckStableMaster(ObjectGuid guid)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void HandlePetRename(WorldPacket &recvData)
void HandlePetCastSpellOpcode(WorldPacket &recvPacket)
void HandleDismissCritter(WorldPackets::Pet::DismissCritter &dismissCritter)
void SendQueryPetNameResponse(ObjectGuid guid, uint32 petnumber)
void HandleQueryPetName(WorldPacket &recvData)
void HandlePetStopAttack(WorldPackets::Pet::PetStopAttack &packet)
void SendPetNameInvalid(uint32 error, std::string const &name, DeclinedName *declinedName)
LocaleConstant GetSessionDbcLocale() const
Player * GetPlayer() const
void HandlePetSetAction(WorldPacket &recvData)
void HandleLearnPreviewTalentsPet(WorldPacket &recvPacket)
void HandlePetAction(WorldPacket &recvData)
void HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutocast &packet)
uint32 GetAccountId() const
void HandlePetLearnTalent(WorldPacket &recvPacket)
void HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo &packet)
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
void HandlePetAbandon(WorldPackets::Pet::PetAbandon &packet)
void HandlePetActionHelper(Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
@ SMSG_PET_NAME_QUERY_RESPONSE
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Pet * GetPet(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const &)
void SetIsCommandFollow(bool val)
uint32 GetPetNumber() const
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
void SetIsAtStay(bool val)
void SetIsFollowing(bool val)
void SetIsReturning(bool val)
UnitActionBarEntry const * GetActionBarEntry(uint8 index) const
void SetSpellAutocast(SpellInfo const *spellInfo, bool state)
void ToggleCreatureAutocast(SpellInfo const *spellInfo, bool apply)
void SetCommandState(CommandStates st)
void SetIsCommandAttack(bool val)
std::string name[MAX_DECLINED_NAME_CASES]
ActiveStates GetType() const