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

Commit

Permalink
Core/Pets: fixed showing pet actions bars for Hunter and Warlocks whe…
Browse files Browse the repository at this point in the history
…n relogging
  • Loading branch information
Ovahlord committed Sep 27, 2023
1 parent 56424e3 commit 6b9ab6e
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 80 deletions.
85 changes: 20 additions & 65 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17875,30 +17875,6 @@ void Player::AbandonPet()
_playerPetDataMap.erase(itr);
}

PlayerPetData* Player::GetPlayerPetDataCurrent()
{
return nullptr;
}

Optional<uint8> Player::GetFirstUnusedActivePetSlot()
{
std::set<uint8> unusedActiveSlot = { 0, 1, 2, 3, 4 }; //unfiltered
return Optional<uint8>{};
}

Optional<uint8> Player::GetFirstUnusedPetSlot()
{
return Optional<uint8>{};
}

void Player::DeleteFromPlayerPetDataStore(uint32 petNumber)
{
}

void Player::AddToPlayerPetDataStore(PlayerPetData&& playerPetData)
{
}

void Player::_LoadQuestStatus(PreparedQueryResult result)
{
uint16 slot = 0;
Expand Down Expand Up @@ -20417,7 +20393,7 @@ bool Player::RemoveMItem(uint32 id)
return mMitems.erase(id) ? true : false;
}

void Player::SendPetSpellsMessage(NewPet* pet)
void Player::SendPetSpellsMessage(NewPet* pet, bool remove /*= false*/)
{
// Warlocks and Hunters cannot control their pets until they have learned their respective control spell
if (pet->IsClassPet() && !CanControlClassPets())
Expand All @@ -20431,26 +20407,29 @@ void Player::SendPetSpellsMessage(NewPet* pet)
}

WorldPackets::Pet::PetSpellsMessage packet;
packet.PetGUID = pet->GetGUID();
packet._CreatureFamily = pet->GetCreatureTemplate()->family; // creature family (required for pet talents)
packet.TimeLimit = pet->GetRemainingSummonDuration().count();
packet.ReactState = pet->GetReactState();
packet.CommandState = charmInfo->GetCommandState();
packet.Flag = 0;

charmInfo->BuildActionBar(packet.ActionButtons);
if (pet->IsClassPet())
if (!remove)
{
for (auto const& itr : pet->GetSpells())
packet.PetGUID = pet->GetGUID();
packet._CreatureFamily = pet->GetCreatureTemplate()->family; // creature family (required for pet talents)
packet.TimeLimit = pet->GetRemainingSummonDuration().count();
packet.ReactState = pet->GetReactState();
packet.CommandState = charmInfo->GetCommandState();
packet.Flag = 0;

charmInfo->BuildActionBar(packet.ActionButtons);
if (pet->IsClassPet())
{
if (itr.second.State == PETSPELL_REMOVED)
continue;
for (auto const& itr : pet->GetSpells())
{
if (itr.second.State == PETSPELL_REMOVED)
continue;

packet.Actions.push_back(MAKE_UNIT_ACTION_BUTTON(itr.first, itr.second.Active));
}
packet.Actions.push_back(MAKE_UNIT_ACTION_BUTTON(itr.first, itr.second.Active));
}

// Cooldowns
pet->GetSpellHistory()->WritePetSpellHistory(packet);
// Cooldowns
pet->GetSpellHistory()->WritePetSpellHistory(packet);
}
}

SendDirectMessage(packet.Write());
Expand All @@ -20476,30 +20455,6 @@ void Player::SendOnCancelExpectedVehicleRideAura() const
SendDirectMessage(&data);
}

bool Player::CanControlPet(uint32 spellId) const
{
// Hunters and Warlocks cannot control their pets until they learned their spell
if (spellId)
{
switch (spellId)
{
case 93321: // Control Pet
return getClass() == CLASS_HUNTER;
case 93375: // Control Demon
return getClass() == CLASS_WARLOCK;
}
}
else
{
if (getClass() == CLASS_HUNTER && !HasAura(93321))
return false;
if (getClass() == CLASS_WARLOCK && !HasAura(93375))
return false;
}

return true;
}

void Player::PetSpellInitialize()
{
// Do not send the pet action bar when Hunters or Warlocks cannot control their pet
Expand Down
9 changes: 1 addition & 8 deletions src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1563,13 +1563,12 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool RemoveMItem(uint32 id);

// Pets
void SendPetSpellsMessage(NewPet* pet);
void SendPetSpellsMessage(NewPet* pet, bool remove = false);
void SetCanControlClassPets();
bool CanControlClassPets() const;

public:
void SendOnCancelExpectedVehicleRideAura() const;
bool CanControlPet(uint32 spellId = 0) const;
void PetSpellInitialize();

void CharmSpellInitialize();
Expand Down Expand Up @@ -2392,12 +2391,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
// Unsummons the currently active pet and removes the player pet data from its container. The database data will be erased on the next save cycle.
void AbandonPet();

PlayerPetData* GetPlayerPetDataCurrent();
Optional<uint8> GetFirstUnusedActivePetSlot();
Optional<uint8> GetFirstUnusedPetSlot();
void DeleteFromPlayerPetDataStore(uint32 petNumber);
void AddToPlayerPetDataStore(PlayerPetData&& playerPetData);

protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Entities/Unit/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5583,7 +5583,7 @@ void Unit::SetActivelyControlledSummon(NewPet* pet, bool apply)
}

if (IsPlayer())
ToPlayer()->SendPetSpellsMessage(pet);
ToPlayer()->SendPetSpellsMessage(pet, !apply);
}

Player* Unit::GetControllingPlayer() const
Expand Down
3 changes: 2 additions & 1 deletion src/server/game/Handlers/PetHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void HandlePetActionHelper(NewPet* pet, Player* owner, ObjectGuid targetGuid, ui
printf("COMMAND_ATTACK -- %u\n", actionValue);
break;
case COMMAND_ABANDON:
printf("COMMAND_ABANDON -- %u\n", actionValue);
if (!pet->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_ABANDONED))
owner->DismissPet(false);
break;
Expand Down Expand Up @@ -712,7 +713,7 @@ void WorldSession::HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet)
return;

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

_player->AbandonPet();
Expand Down
3 changes: 3 additions & 0 deletions src/server/game/Server/Packets/PetPackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ WorldPacket const* WorldPackets::Pet::PetAdded::Write()
WorldPacket const* WorldPackets::Pet::PetSpellsMessage::Write()
{
_worldPacket << PetGUID;
if (PetGUID.IsEmpty())
return &_worldPacket;

_worldPacket << uint16(_CreatureFamily);
_worldPacket << uint32(TimeLimit);
_worldPacket << uint8(ReactState);
Expand Down
44 changes: 44 additions & 0 deletions src/server/scripts/Spells/spell_generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5608,6 +5608,48 @@ class spell_gen_dalaran_shop_keeper_greeting_ping : public SpellScript
}
};

enum ControlPet
{
SPELL_CONTROL_DEMON_EFFECT = 93376,
SPELL_CONTROL_PET_EFFECT = 93322,
};

// 93321 - Control Pet (Passive)
// 93375 - Control Demon (Passive)
class spell_gen_control_pet : public AuraScript
{
public:
spell_gen_control_pet(uint32 effectSpellId) : AuraScript(), _effectSpellId(effectSpellId) { }

bool Load() override
{
return GetCaster()->IsPlayer();
}

bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ _effectSpellId });
}

void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Player* player = GetTarget()->ToPlayer();
if (!player)
return;

if (!player->CanControlClassPets())
player->CastSpell(nullptr, _effectSpellId, TRIGGERED_FULL_MASK);
}

void Register() override
{
AfterEffectApply.Register(&spell_gen_control_pet::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}

private:
uint32 _effectSpellId = 0;
};

void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
Expand Down Expand Up @@ -5750,4 +5792,6 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_shadowmeld);
RegisterSpellScript(spell_gen_vehicle_control_link);
RegisterSpellScript(spell_gen_polymorph_cast_visual);
RegisterSpellScriptWithArgs(spell_gen_control_pet, "spell_gen_control_demon", SPELL_CONTROL_DEMON_EFFECT);
RegisterSpellScriptWithArgs(spell_gen_control_pet, "spell_gen_control_pet", SPELL_CONTROL_PET_EFFECT);
}
10 changes: 5 additions & 5 deletions src/server/scripts/Spells/spell_hunter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,12 @@ class spell_hun_tame_beast : public SpellScript
if (player->getClass() != CLASS_HUNTER)
return SendTameFailResult(PET_TAME_FAILURE_CANNOT_TAME_CREATURES);

if (!player->GetFirstUnusedActivePetSlot())
return SendTameFailResult(PET_TAME_FAILURE_TOO_MANY_PETS);
//if (!player->GetFirstUnusedActivePetSlot())
// return SendTameFailResult(PET_TAME_FAILURE_TOO_MANY_PETS);

if (Optional<uint8> slot = player->GetFirstUnusedActivePetSlot())
if (!player->HasSpell(callPetSpellIdBySlot[*slot]))
return SendTameFailResult(PET_TAME_FAILURE_SLOT_LOCKED);
//if (Optional<uint8> slot = player->GetFirstUnusedActivePetSlot())
// if (!player->HasSpell(callPetSpellIdBySlot[*slot]))
// return SendTameFailResult(PET_TAME_FAILURE_SLOT_LOCKED);

if (Creature* target = GetExplTargetUnit()->ToCreature())
{
Expand Down

0 comments on commit 6b9ab6e

Please sign in to comment.