Core/Pets: Implemented sound playback when dismissing warlock pets (#30683)

(cherry picked from commit a827230910fd7e3e64bcb5526e2778b8b4752da4)
This commit is contained in:
Mykhailo Redko
2026-06-07 19:51:13 +02:00
committed by Shauren
parent 22008f8ea1
commit c46cc865f5
7 changed files with 57 additions and 26 deletions
+3 -3
View File
@@ -89,10 +89,10 @@ enum class PetActionFeedback : uint8
NoPath = 4
};
enum PetTalk
enum PetAction : int32
{
PET_TALK_SPECIAL_SPELL = 0,
PET_TALK_ATTACK = 1
PET_ACTION_SPECIAL_SPELL = 0,
PET_ACTION_ATTACK = 1
};
#define PET_FOLLOW_DIST 1.0f
+14 -9
View File
@@ -10634,7 +10634,7 @@ void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProc
}
///----------Pet responses methods-----------------
void Unit::SendPetActionFeedback(PetActionFeedback msg, uint32 spellId)
void Unit::SendPetActionFeedback(PetActionFeedback msg, uint32 spellId) const
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
@@ -10646,19 +10646,24 @@ void Unit::SendPetActionFeedback(PetActionFeedback msg, uint32 spellId)
owner->ToPlayer()->SendDirectMessage(petActionFeedback.Write());
}
void Unit::SendPetTalk(uint32 pettalk)
void Unit::SendPetActionSound(PetAction action) const
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
WorldPackets::Pet::PetActionSound petActionSound;
petActionSound.UnitGUID = GetGUID();
petActionSound.Action = pettalk;
owner->ToPlayer()->SendDirectMessage(petActionSound.Write());
petActionSound.Action = action;
SendMessageToSet(petActionSound.Write(), false);
}
void Unit::SendPetAIReaction(ObjectGuid guid)
void Unit::SendPetDismissSound() const
{
WorldPackets::Pet::PetDismissSound petDismissSound;
petDismissSound.UnitGUID = GetGUID();
petDismissSound.CreatureDisplayInfoID = GetNativeDisplayId();
petDismissSound.ModelPosition = GetPosition();
SendMessageToSet(petDismissSound.Write(), false);
}
void Unit::SendPetAIReaction(ObjectGuid guid) const
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
+5 -3
View File
@@ -101,6 +101,7 @@ class VehicleJoinEvent;
enum CharmType : uint8;
enum class EncounterType : uint8;
enum PetAction : int32;
enum class PetActionFeedback : uint8;
enum MovementGeneratorType : uint8;
enum ProcFlagsHit : uint32;
@@ -1754,9 +1755,10 @@ class TC_GAME_API Unit : public WorldObject
void ApplyControlStatesIfNeeded();
///----------Pet responses methods-----------------
void SendPetActionFeedback(PetActionFeedback msg, uint32 spellId);
void SendPetTalk(uint32 pettalk);
void SendPetAIReaction(ObjectGuid guid);
void SendPetActionFeedback(PetActionFeedback msg, uint32 spellId) const;
void SendPetActionSound(PetAction action) const;
void SendPetDismissSound() const;
void SendPetAIReaction(ObjectGuid guid) const;
///----------End of Pet responses methods----------
void PropagateSpeedChange();
+13 -10
View File
@@ -219,8 +219,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
AI->AttackStart(TargetUnit);
// 10% chance to play special pet attack talk, else growl
if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
pet->SendPetTalk((uint32)PET_TALK_ATTACK);
if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance(10))
pet->SendPetActionSound(PET_ACTION_ATTACK);
else
{
// 90% chance for pet and 100% chance for charmed creature
@@ -249,10 +249,13 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
ASSERT(pet->GetTypeId() == TYPEID_UNIT);
if (pet->IsPet())
{
if (((Pet*)pet)->getPetType() == HUNTER_PET)
GetPlayer()->RemovePet((Pet*)pet, PET_SAVE_AS_DELETED);
if (pet->ToPet()->getPetType() == HUNTER_PET)
GetPlayer()->RemovePet(pet->ToPet(), PET_SAVE_AS_DELETED);
else
GetPlayer()->RemovePet((Pet*)pet, PET_SAVE_NOT_IN_SLOT);
{
pet->SendPetDismissSound();
GetPlayer()->RemovePet(pet->ToPet(), PET_SAVE_NOT_IN_SLOT);
}
}
else if (pet->HasUnitTypeMask(UNIT_MASK_MINION))
{
@@ -361,8 +364,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (pet->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != unit_target && roll_chance(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
else
{
pet->SendPetAIReaction(guid1);
@@ -743,10 +746,10 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell&
{
if (Pet* pet = creature->ToPet())
{
// 10% chance to play special pet attack talk, else growl
// 10% chance to play special pet attack sound, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk(PET_TALK_SPECIAL_SPELL);
if (pet->getPetType() == SUMMON_PET && roll_chance(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
else
pet->SendPetAIReaction(petCastSpell.PetGUID);
}
@@ -203,6 +203,15 @@ WorldPacket const* PetActionSound::Write()
return &_worldPacket;
}
WorldPacket const* PetDismissSound::Write()
{
_worldPacket << UnitGUID;
_worldPacket << int32(CreatureDisplayInfoID);
_worldPacket << ModelPosition;
return &_worldPacket;
}
WorldPacket const* PetTameFailure::Write()
{
_worldPacket << uint32(Result);
@@ -258,6 +258,18 @@ namespace WorldPackets
int32 Action = 0;
};
class PetDismissSound final : public ServerPacket
{
public:
PetDismissSound() : ServerPacket(SMSG_PET_DISMISS_SOUND, 18 + 4 + 12) { }
WorldPacket const* Write() override;
ObjectGuid UnitGUID;
int32 CreatureDisplayInfoID = 0;
TaggedPosition<Position::XYZ> ModelPosition;
};
class PetTameFailure final : public ServerPacket
{
public:
+1 -1
View File
@@ -2148,7 +2148,7 @@ void OpcodeTable::InitializeServerOpcodes()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BATTLE_SLOT_UPDATES, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_CLEAR_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_GOD_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_GUIDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);