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 SPELL_EFFECT_CREATE_TAMED_PET mechanic for the new p…
Browse files Browse the repository at this point in the history
…et system
  • Loading branch information
Ovahlord committed Sep 26, 2023
1 parent 6d22559 commit feeb8b9
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/server/game/Entities/Creature/TemporarySummon/NewPet.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class TC_GAME_API NewPet final : public NewGuardian

bool Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, uint32 petNumber);

// Synchronizes the pet's level with its summoner, updates the stats for the new level and learns new spells if available
void SynchronizeLevelWithSummoner();
bool HasSpell(uint32 spellID) const override;
void ToggleAutocast(SpellInfo const* spellInfo, bool apply);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "NewTemporarySummon.h"
#include "DBCStores.h"
Expand Down
11 changes: 11 additions & 0 deletions src/server/game/Entities/Pet/PetDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ enum PetSaveMode
PET_SAVE_TEMP_UNSUMMON = PET_SAVE_LOGOUT
};

enum PetCallSpells
{
SPELL_CALL_PET_1 = 883,
SPELL_CALL_PET_2 = 83242,
SPELL_CALL_PET_3 = 83243,
SPELL_CALL_PET_4 = 83244,
SPELL_CALL_PET_5 = 83245
};

static constexpr std::array<uint32, 5> PetCallSpellsArray = { SPELL_CALL_PET_1, SPELL_CALL_PET_2, SPELL_CALL_PET_3, SPELL_CALL_PET_4, SPELL_CALL_PET_5 };

enum PetStableSlot
{
PET_SLOT_FIRST = 0,
Expand Down
41 changes: 38 additions & 3 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17783,7 +17783,7 @@ PlayerPetData* Player::GetPlayerPetData(uint8 slot, uint32 creatureId) const
return itr->second.get();
}

PlayerPetData* Player::CreatePlayerPetData(uint8 slot, uint32 creatureId)
PlayerPetData* Player::CreatePlayerPetData(uint8 slot, uint32 creatureId, Optional<uint32> tamedCreatureId /*= {}*/)
{
// Make sure that we do not attempt to create data for already existing pets
if (_playerPetDataMap.find(std::make_pair(slot, creatureId)) != _playerPetDataMap.end())
Expand All @@ -17792,7 +17792,7 @@ PlayerPetData* Player::CreatePlayerPetData(uint8 slot, uint32 creatureId)
return nullptr;
}

CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureId);
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(tamedCreatureId.value_or(creatureId));
if (!cInfo)
{
TC_LOG_ERROR("entities.player", "Player::CreatePlayerPetData: Player(GUID: % u) tried to create pet data (slot %u, creatureId %u) which does not have a creature_template entry.", GetGUID().GetCounter(), slot, creatureId);
Expand All @@ -17803,13 +17803,32 @@ PlayerPetData* Player::CreatePlayerPetData(uint8 slot, uint32 creatureId)
petData->Slot = slot;
petData->CreatureId = creatureId;
petData->PetNumber = sObjectMgr->GeneratePetNumber();
petData->Name = sObjectMgr->GeneratePetName(creatureId);
petData->Name = sObjectMgr->GeneratePetName(tamedCreatureId.value_or(creatureId));
petData->Status = PlayerPetDataStatus::New;
petData->ReactState = REACT_ASSIST;
petData->TamedCreatureId = tamedCreatureId.value_or(0);

return _playerPetDataMap.emplace(std::make_pair(slot, creatureId), std::move(petData)).first->second.get();
}

Optional<uint8> Player::GetUnusedActivePetSlot()
{
for (uint8 i = PET_SLOT_FIRST; i <= PET_SLOT_LAST_ACTIVE_SLOT; ++i)
{
if (i >= PetCallSpellsArray.size())
break;

// Only allow tamed pets to be created for unlocked active slots
if (!HasSpell(PetCallSpellsArray[i]))
continue;

if (_playerPetDataMap.find(std::make_pair(i, 0)) == _playerPetDataMap.end())
return i;
}

return std::nullopt;
}

PlayerPetData* Player::GetPlayerPetDataCurrent()
{
return nullptr;
Expand Down Expand Up @@ -20383,6 +20402,22 @@ void Player::SendPetSpellsMessage(NewPet* pet)
SendDirectMessage(packet.Write());
}

void Player::SetCanControlClassPets()
{
_canControlClassPets = true;

if (NewPet* pet = GetActivelyControlledSummon())
SendPetSpellsMessage(pet);
}

bool Player::CanControlClassPets() const
{
// Warlocks and Hunter need to learn their corresponding control spells before they are allowed to perform pet actions
if (getClass() != CLASS_WARLOCK && getClass() != CLASS_HUNTER)
return true;

return _canControlClassPets;
}

void Player::SendOnCancelExpectedVehicleRideAura() const
{
Expand Down
7 changes: 4 additions & 3 deletions src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1563,8 +1563,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>

// Pets
void SendPetSpellsMessage(NewPet* pet);
void SetCanControlClassPets() { _canControlClassPets = true; }
bool CanControlClassPets() const { return _canControlClassPets; }
void SetCanControlClassPets();
bool CanControlClassPets() const;

public:
void SendOnCancelExpectedVehicleRideAura() const;
Expand Down Expand Up @@ -2381,7 +2381,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>

// Pets
PlayerPetData* GetPlayerPetData(uint8 slot, uint32 creatureId) const;
PlayerPetData* CreatePlayerPetData(uint8 slot, uint32 creatureId);
PlayerPetData* CreatePlayerPetData(uint8 slot, uint32 creatureId, Optional<uint32> tamedCreatureId = {});
Optional<uint8> GetUnusedActivePetSlot();

PlayerPetData* GetPlayerPetDataCurrent();
Optional<uint8> GetFirstUnusedActivePetSlot();
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Server/Packets/PetPackets.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace WorldPackets
class PetGuids final : public ServerPacket
{
public:
PetGuids() : ServerPacket(SMSG_PET_GUIDS, 1) { }
PetGuids() : ServerPacket(SMSG_PET_GUIDS, 4) { }

WorldPacket const* Write() override;

Expand Down
26 changes: 11 additions & 15 deletions src/server/game/Spells/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5211,29 +5211,25 @@ void Spell::EffectCreateTamedPet(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;

if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || unitTarget->getClass() != CLASS_HUNTER)
if (!unitTarget || !unitTarget->IsPlayer() || unitTarget->getClass() != CLASS_HUNTER)
return;

uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
if (!pet)
if (!sObjectMgr->GetCreatureTemplate(creatureEntry))
return;

// relocate
Position pos = unitTarget->GetPosition();
unitTarget->MovePositionToFirstCollision(pos, DEFAULT_FOLLOW_DISTANCE_PET, float(M_PI_2));
pet->Relocate(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), unitTarget->GetOrientation());
Player* player = unitTarget->ToPlayer();
Optional<uint8> slot = player->GetUnusedActivePetSlot();
if (!slot.has_value())
return;

// add to world
pet->GetMap()->AddToMap(pet->ToCreature());
if (player->CreatePlayerPetData(*slot, 0, creatureEntry) == nullptr)
return;

pet->InitTalentForLevel();
Position pos = unitTarget->GetPosition();
unitTarget->MovePositionToFirstCollision(pos, DEFAULT_FOLLOW_DISTANCE_PET, float(M_PI_2));

if (unitTarget->GetTypeId() == TYPEID_PLAYER)
{
pet->SavePetToDB(PET_SAVE_NEW_PET);
unitTarget->ToPlayer()->PetSpellInitialize();
}
player->SummonPet(0, *slot, m_spellInfo->Id, true, pos);
}

void Spell::EffectDiscoverTaxi(SpellEffIndex effIndex)
Expand Down

0 comments on commit feeb8b9

Please sign in to comment.