Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
Core/Packets: converted a bunch more pet packets to packet class and …
Browse files Browse the repository at this point in the history
…moved some pet packets from NPCHandler over into PetHandler
  • Loading branch information
Ovahlord committed Oct 14, 2023
1 parent 17535e0 commit 42dd9e1
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 172 deletions.
17 changes: 7 additions & 10 deletions src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,15 @@ void NewPet::Dismiss(bool permanent /*= true*/)
player->SetActiveClassPetDataKey(_playerPetDataKey);
}

if (IsClassPet())
// Warlock pets do play dismiss sounds when releasing them permanently
if (IsClassPet() && permanent && player->getClass() == CLASS_WARLOCK)
{
// Warlock pets do play dismiss sounds when releasing them permanently
if (permanent && player->getClass() == CLASS_WARLOCK)
if (CreatureDisplayInfoEntry const* creatureDisplay = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId()))
{
if (CreatureDisplayInfoEntry const* creatureDisplay = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId()))
{
WorldPackets::Pet::PetDismissSound dismissSound;
dismissSound.ModelID = creatureDisplay->ModelID;
dismissSound.ModelPosition = GetPosition();
player->SendDirectMessage(dismissSound.Write());
}
WorldPackets::Pet::PetDismissSound dismissSound;
dismissSound.ModelID = creatureDisplay->ModelID;
dismissSound.ModelPosition = GetPosition();
player->SendDirectMessage(dismissSound.Write());
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/Entities/Creature/TemporarySummon/NewPet.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class TC_GAME_API NewPet final : public NewGuardian
bool ShouldDespawnOnSummonerLogout() const override { return true; }
bool ShouldJoinSummonerSpawnGroupAfterCreation() const override { return true; }

// Returns true if the pet is belongs to a specific class (Hunter Pets, Mage Water Elementals, DK Ghouls and Warlock Demons)
// Returns true if the pet is belongs to a specific class (Hunter Pets, Mage Water Elementals, DK Ghouls and Warlock Minions)
bool IsClassPet() const { return _isClassPet; }
// Returns true if the pet is a hunter class pet. This is the case when the pet has player pet data and is stored under creatureId = 0
bool IsHunterPet() const { return _playerPetDataKey.has_value() && _playerPetDataKey->second == 0; }
Expand All @@ -73,7 +73,7 @@ class TC_GAME_API NewPet final : public NewGuardian
bool HasSpell(uint32 spellID) const override;
// Enables or disables auto casting for the given spell
void ToggleAutocast(SpellInfo const* spellInfo, bool apply);
// Returns a map of a class pet's learned spells
// Returns a map of a pet's known spells
PetSpellMap const& GetSpells() const { return _spells; }
// Sets the PlayerPetData map key for accessing the summoner's player pet data at any given time
void SetPlayerPetDataKey(uint8 slot, uint32 creatureId);
Expand Down
104 changes: 0 additions & 104 deletions src/server/game/Handlers/NPCHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,110 +297,6 @@ void WorldSession::SendBindPoint(Creature* npc)
_player->PlayerTalkClass->SendCloseGossip();
}

void WorldSession::HandleListStabledPetsOpcode(WorldPackets::Pet::CPetStableList& packet)
{
if (!CheckStableMaster(packet.StableMaster))
return;

// remove fake death
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

// remove mounts this fix bug where getting pet from stable while mounted deletes pet.
if (GetPlayer()->IsMounted())
GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);

SendPetStableList(packet.StableMaster);
}

void WorldSession::SendPetStableList(ObjectGuid stableMasterGuid)
{
WorldPackets::Pet::SPetStableList packet;
packet.StableMaster = stableMasterGuid;
packet.StableSlots = 20;

for (auto const& pair : _player->GetPlayerPetDataMap())
{
WorldPackets::Pet::PetStableInfo& stableInfo = packet.Pets.emplace_back();
stableInfo.CreatureID = pair.second->TamedCreatureId;
stableInfo.DisplayID = pair.second->DisplayId;
stableInfo.ExperienceLevel = _player->getLevel();
stableInfo.PetName = pair.second->Name;
stableInfo.PetNumber = pair.second->PetNumber;
stableInfo.PetSlot = pair.second->Slot;
stableInfo.PetFlags = (pair.second->Slot <= PET_SLOT_LAST_ACTIVE_SLOT ? PET_STABLE_ACTIVE : PET_STABLE_INACTIVE);
}

SendPacket(packet.Write());
}

void WorldSession::SendStableResult(uint8 result)
{
WorldPackets::Pet::PetStableResult packet;
packet.Result = result;
SendPacket(packet.Write());
}

void WorldSession::HandleSetPetSlot(WorldPackets::Pet::SetPetSlot& packet)
{
if (!_player->IsAlive() || !CheckStableMaster(packet.StableMaster) || packet.DestSlot > PET_SLOT_LAST_STABLE_SLOT)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}

PlayerPetData* sourceData = _player->GetPlayerPetDataByPetNumber(packet.PetNumber);
if (!sourceData)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}

PlayerPetData* destData = _player->GetPlayerPetData(packet.DestSlot, 0);
if (packet.DestSlot <= PET_SLOT_LAST_ACTIVE_SLOT)
{
if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(sourceData->TamedCreatureId))
{
if (!cInfo->IsTameable(_player->CanTameExoticPets()))
{
SendStableResult(STABLE_ERR_EXOTIC);
return;
}
}
}

/*
// remove fake death 2
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Pet* pet = _player->GetPet();
// can't place in stable dead pet
if (pet)
{
if (pet->GetCharmInfo()->GetPetNumber() == petId)
{
if (!pet->IsAlive() || !pet->IsHunterPet())
{
SendStableResult(STABLE_ERR_STABLE);
return;
}
}
}
if (playerPetData)
{
UpdatePetSlot(petId, playerPetData->Slot, new_slot);
}
*/
}

void WorldSession::HandleStableRevivePet(WorldPacket &/* recvData */)
{
TC_LOG_DEBUG("network", "HandleStableRevivePet: Not implemented");
}

void WorldSession::HandleRepairItemOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_REPAIR_ITEM");
Expand Down
175 changes: 121 additions & 54 deletions src/server/game/Handlers/PetHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,29 +219,10 @@ void WorldSession::HandlePetAction(WorldPackets::Pet::PetAction& packet)
HandlePetActionHelper(actionPet, _player, packet.TargetGUID, actionValue, actionFlags, packet.ActionPosition);
}

void WorldSession::HandlePetStopAttack(WorldPacket &recvData)
void WorldSession::HandlePetStopAttack(WorldPackets::Pet::PetStopAttack& packet)
{
ObjectGuid guid;
recvData >> guid;

TC_LOG_DEBUG("network.opcode", "WORLD: Received CMSG_PET_STOP_ATTACK for %s", guid.ToString().c_str());

Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);

if (!pet)
{
TC_LOG_ERROR("entities.pet", "HandlePetStopAttack: %s does not exist", guid.ToString().c_str());
return;
}

if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharmed())
{
TC_LOG_ERROR("entities.pet", "HandlePetStopAttack: %s isn't a pet or charmed creature of player %s",
guid.ToString().c_str(), GetPlayer()->GetName().c_str());
return;
}

if (!pet->IsAlive())
NewPet* pet = _player->GetActivelyControlledSummon();
if (!pet || pet->GetGUID() != packet.PetGUID || !pet->IsAlive())
return;

pet->AttackStop();
Expand Down Expand Up @@ -467,43 +448,26 @@ void WorldSession::HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet)
_player->AbandonPet();
}

void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
void WorldSession::HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutocast& packet)
{
TC_LOG_DEBUG("network.opcode", "WORLD: Received CMSG_PET_SPELL_AUTOCAST");
ObjectGuid guid;
uint32 spellid;
uint8 state; //1 for on, 0 for off
recvPacket >> guid >> spellid >> state;

if (guid.IsPlayer())
if (packet.PetGUID.IsEmpty() || packet.PetGUID.IsPlayer())
return;

Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);

SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
if (!spellInfo)
{
TC_LOG_ERROR("spells.pet", "WORLD: unknown PET spell id %u", spellid);
NewPet* pet = _player->GetActivelyControlledSummon();
if (!pet || pet->GetGUID() != packet.PetGUID)
return;
}

SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
// do not add not learned spells/ passive spells
if (!pet->HasSpell(spellid) || !spellInfo->IsAutocastable())
if (!spellInfo || spellInfo->IsAutocastable() || !pet->HasSpell(spellInfo->Id))
return;

CharmInfo* charmInfo = pet->GetCharmInfo();
if (!charmInfo)
{
TC_LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().GetCounter(), pet->GetTypeId());
return;
}

if (pet->IsPet())
((Pet*)pet)->ToggleAutocast(spellInfo, state != 0);
else
pet->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, state != 0);

charmInfo->SetSpellAutocast(spellInfo, state != 0);
pet->ToggleAutocast(spellInfo, packet.AutocastEnabled);
charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
}

void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
Expand Down Expand Up @@ -671,14 +635,13 @@ void WorldSession::UpdatePetSlot(uint32 petNumberA, uint8 oldPetSlot, uint8 newP

void WorldSession::SendPetSlotUpdated(int32 petNumberA, int32 petSlotA, int32 petNumberB, int32 petSlotB)
{
WorldPacket data(SMSG_PET_SLOT_UPDATED, 4 + 4 + 4 + 4);

data << uint32(petNumberA);
data << uint32(petSlotA);
data << uint32(petNumberB);
data << uint32(petSlotB);
WorldPackets::Pet::PetSlotUpdated packet;
packet.PetNumberA = petNumberA;
packet.PetSlotA = petSlotA;
packet.PetNumberB = petNumberB;
packet.PetSlotB = petSlotB;

SendPacket(&data);
SendPacket(packet.Write());
}

void WorldSession::SendPetAdded(int32 petSlot, int32 petNumber, int32 creatureID, int32 level, std::string name)
Expand Down Expand Up @@ -717,3 +680,107 @@ void WorldSession::HandleRequestPetInfoOpcode(WorldPacket& /*recvData*/)
_player->CharmSpellInitialize();
}
}

void WorldSession::HandleListStabledPetsOpcode(WorldPackets::Pet::CPetStableList& packet)
{
if (!CheckStableMaster(packet.StableMaster))
return;

// remove fake death
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

// remove mounts this fix bug where getting pet from stable while mounted deletes pet.
if (GetPlayer()->IsMounted())
GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);

SendPetStableList(packet.StableMaster);
}

void WorldSession::SendPetStableList(ObjectGuid stableMasterGuid)
{
WorldPackets::Pet::SPetStableList packet;
packet.StableMaster = stableMasterGuid;
packet.StableSlots = 6;

for (auto const& pair : _player->GetPlayerPetDataMap())
{
WorldPackets::Pet::PetStableInfo& stableInfo = packet.Pets.emplace_back();
stableInfo.CreatureID = pair.second->TamedCreatureId;
stableInfo.DisplayID = pair.second->DisplayId;
stableInfo.ExperienceLevel = _player->getLevel();
stableInfo.PetName = pair.second->Name;
stableInfo.PetNumber = pair.second->PetNumber;
stableInfo.PetSlot = pair.second->Slot;
stableInfo.PetFlags = (pair.second->Slot <= PET_SLOT_LAST_ACTIVE_SLOT ? PET_STABLE_ACTIVE : PET_STABLE_INACTIVE);
}

SendPacket(packet.Write());
}

void WorldSession::SendStableResult(uint8 result)
{
WorldPackets::Pet::PetStableResult packet;
packet.Result = result;
SendPacket(packet.Write());
}

void WorldSession::HandleSetPetSlot(WorldPackets::Pet::SetPetSlot& packet)
{
if (!_player->IsAlive() || !CheckStableMaster(packet.StableMaster) || packet.DestSlot > PET_SLOT_LAST_STABLE_SLOT)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}

PlayerPetData* sourceData = _player->GetPlayerPetDataByPetNumber(packet.PetNumber);
if (!sourceData)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}

PlayerPetData* destData = _player->GetPlayerPetData(packet.DestSlot, 0);
if (packet.DestSlot <= PET_SLOT_LAST_ACTIVE_SLOT)
{
if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(sourceData->TamedCreatureId))
{
if (!cInfo->IsTameable(_player->CanTameExoticPets()))
{
SendStableResult(STABLE_ERR_EXOTIC);
return;
}
}
}

/*
// remove fake death 2
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Pet* pet = _player->GetPet();
// can't place in stable dead pet
if (pet)
{
if (pet->GetCharmInfo()->GetPetNumber() == petId)
{
if (!pet->IsAlive() || !pet->IsHunterPet())
{
SendStableResult(STABLE_ERR_STABLE);
return;
}
}
}
if (playerPetData)
{
UpdatePetSlot(petId, playerPetData->Slot, new_slot);
}
*/
}

void WorldSession::HandleStableRevivePet(WorldPacket &/* recvData */)
{
TC_LOG_DEBUG("network", "HandleStableRevivePet: Not implemented");
}
22 changes: 22 additions & 0 deletions src/server/game/Server/Packets/PetPackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,25 @@ WorldPacket const* WorldPackets::Pet::PetTameFailure::Write()

return &_worldPacket;
}

void WorldPackets::Pet::PetSpellAutocast::Read()
{
_worldPacket >> PetGUID;
_worldPacket >> SpellID;
_worldPacket >> AutocastEnabled;
}

WorldPacket const* WorldPackets::Pet::PetSlotUpdated::Write()
{
_worldPacket << int32(PetNumberA);
_worldPacket << int32(PetSlotA);
_worldPacket << int32(PetNumberB);
_worldPacket << int32(PetSlotB);

return &_worldPacket;
}

void WorldPackets::Pet::PetStopAttack::Read()
{
_worldPacket >> PetGUID;
}
Loading

0 comments on commit 42dd9e1

Please sign in to comment.