From d87d0a2ae892286a44a85cc230fa66d44479d4bd Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Wed, 15 Dec 2021 09:32:16 +0100 Subject: [PATCH] fix(Core/Pets): Improved Revive Pet should affect dead despawned pet. (#9625) * fix(Core/Pets): Improved Revive Pet should affect dead despawned pet. Fixes #9589 --- src/server/game/Entities/Pet/Pet.cpp | 7 ++++++- src/server/game/Entities/Pet/Pet.h | 6 +++--- src/server/game/Entities/Player/Player.cpp | 4 ++-- src/server/game/Entities/Player/Player.h | 2 +- src/server/game/Handlers/PetHandler.cpp | 13 +++++++++---- src/server/game/Server/WorldSession.h | 4 ++-- src/server/game/Spells/SpellEffects.cpp | 2 +- 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index f7d7094bf..29bcc7442 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -222,7 +222,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint8 asynchLoadType, uint32 petentry, ui { // process only if player is in world (teleport crashes?) // otherwise wait with result till he logs in - uint8 loadResult = mySess->HandleLoadPetFromDBFirstCallback(result, asynchLoadType); + uint8 loadResult = mySess->HandleLoadPetFromDBFirstCallback(result, asynchLoadType, info); if (loadResult != PET_LOAD_OK) Pet::HandleAsynchLoadFailed(info, owner, asynchLoadType, loadResult); @@ -2328,6 +2328,11 @@ void Pet::HandleAsynchLoadFailed(AsynchPetSummon* info, Player* player, uint8 as //owner->PetSpellInitialize(); pet->SavePetToDB(PET_SAVE_AS_CURRENT, false); } + + if (info->m_healthPct) + { + pet->SetHealth(pet->CountPctFromMaxHealth(info->m_healthPct)); + } } } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index e09910b17..ca7127cc8 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -35,15 +35,15 @@ struct PetSpell class AsynchPetSummon { public: - AsynchPetSummon(uint32 entry, Position position, PetType petType, uint32 duration, uint32 createdBySpell, ObjectGuid casterGUID) : - m_entry(entry), pos(position), m_petType(petType), - m_duration(duration), m_createdBySpell(createdBySpell), m_casterGUID(casterGUID) { } + AsynchPetSummon(uint32 entry, Position position, PetType petType, uint32 duration, uint32 createdBySpell, ObjectGuid casterGUID, int32 healthPct = 0) : + m_entry(entry), pos(position), m_petType(petType), m_duration(duration), m_createdBySpell(createdBySpell), m_casterGUID(casterGUID), m_healthPct(healthPct) { } uint32 m_entry; Position pos; PetType m_petType; uint32 m_duration, m_createdBySpell; ObjectGuid m_casterGUID; + int32 m_healthPct; }; typedef std::unordered_map PetSpellMap; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9ac67ab1b..1f658ede9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -15136,13 +15136,13 @@ Guild* Player::GetGuild() const return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; } -void Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration, uint32 createdBySpell, ObjectGuid casterGUID, uint8 asynchLoadType) +void Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration, uint32 createdBySpell, ObjectGuid casterGUID, uint8 asynchLoadType, int32 healthPct /*= 0*/) { Position pos = {x, y, z, ang}; if (!pos.IsPositionValid()) return; - AsynchPetSummon* asynchPetInfo = new AsynchPetSummon(entry, pos, petType, duration, createdBySpell, casterGUID); + AsynchPetSummon* asynchPetInfo = new AsynchPetSummon(entry, pos, petType, duration, createdBySpell, casterGUID, healthPct); Pet::LoadPetFromDB(this, asynchLoadType, entry, 0, false, asynchPetInfo); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 6d00af4ae..c8fedc792 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1165,7 +1165,7 @@ public: [[nodiscard]] Pet* GetPet() const; bool IsPetDismissed(); - void SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime, uint32 createdBySpell, ObjectGuid casterGUID, uint8 asynchLoadType); + void SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime, uint32 createdBySpell, ObjectGuid casterGUID, uint8 asynchLoadType, int32 healthPct = 0); void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); [[nodiscard]] uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index a148d015d..e1117ad3a 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -94,7 +94,7 @@ bool LoadPetFromDBQueryHolder::Initialize() return res; } -uint8 WorldSession::HandleLoadPetFromDBFirstCallback(PreparedQueryResult result, uint8 asynchLoadType) +uint8 WorldSession::HandleLoadPetFromDBFirstCallback(PreparedQueryResult result, uint8 asynchLoadType, AsynchPetSummon* info) { if (!result) return PET_LOAD_NO_RESULT; @@ -300,15 +300,15 @@ uint8 WorldSession::HandleLoadPetFromDBFirstCallback(PreparedQueryResult result, pet->SetAsynchLoadType(asynchLoadType); - AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this, info](SQLQueryHolderBase const& holder) { - HandleLoadPetFromDBSecondCallback(static_cast(holder)); + HandleLoadPetFromDBSecondCallback(static_cast(holder), info); }); return PET_LOAD_OK; } -void WorldSession::HandleLoadPetFromDBSecondCallback(LoadPetFromDBQueryHolder const& holder) +void WorldSession::HandleLoadPetFromDBSecondCallback(LoadPetFromDBQueryHolder const& holder, AsynchPetSummon* info) { if (!GetPlayer()) return; @@ -377,6 +377,11 @@ void WorldSession::HandleLoadPetFromDBSecondCallback(LoadPetFromDBQueryHolder co } pet->HandleAsynchLoadSucceed(); + + if (info && info->m_healthPct) + { + pet->SetHealth(pet->CountPctFromMaxHealth(info->m_healthPct)); + } } void WorldSession::HandleDismissCritter(WorldPacket& recvData) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 668cb9a5d..8a4bc69a6 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -691,8 +691,8 @@ public: // opcodes handlers void HandleOpenWrappedItemCallback(uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result); void HandleLoadActionsSwitchSpec(PreparedQueryResult result); void HandleCharacterAuraFrozen(PreparedQueryResult result); - uint8 HandleLoadPetFromDBFirstCallback(PreparedQueryResult result, uint8 asynchLoadType); - void HandleLoadPetFromDBSecondCallback(LoadPetFromDBQueryHolder const& holder); + uint8 HandleLoadPetFromDBFirstCallback(PreparedQueryResult result, uint8 asynchLoadType, AsynchPetSummon* info); + void HandleLoadPetFromDBSecondCallback(LoadPetFromDBQueryHolder const& holder, AsynchPetSummon* info); void HandleDuelAcceptedOpcode(WorldPacket& recvPacket); void HandleDuelCancelledOpcode(WorldPacket& recvPacket); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index b29e12205..9db5436ff 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5403,7 +5403,7 @@ void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/) player->GetPosition(x, y, z); if (!pet) { - player->SummonPet(0, x, y, z, player->GetOrientation(), SUMMON_PET, 0, 0, ObjectGuid((uint64)damage), PET_LOAD_SUMMON_DEAD_PET); + player->SummonPet(0, x, y, z, player->GetOrientation(), SUMMON_PET, 0, 0, ObjectGuid((uint64)damage), PET_LOAD_SUMMON_DEAD_PET, damage); return; }