diff options
author | Giacomo Pozzoni <giacomopoz@gmail.com> | 2021-05-10 22:01:41 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-01-31 00:26:54 +0100 |
commit | 40d882b7544cff556f5e2dc6ac570c3fee5b9659 (patch) | |
tree | c58f7e3cc69556fb05ea8073266dd850bad8365a | |
parent | 33e747bc8faf4bee2cf0a987f7fc3901b227db8b (diff) |
Core/Pet: Attempt to fix assertions triggered when summoning pets (#26501)
* Core/Pet: Attempt to fix an assertion triggered when re-summoning the current pet
* Core/Pet: Attempt to fix an assertion triggered when stabling a pet while in a vehicle
* Core/Pet: Attempt to fix an assertion triggered when stabling a pet and casting spell 6962
* Core/Pet: Attempt to fix an assertion triggered when casting spell 6962 while being dead
* Core/Pet: Attempt to fix an assertion triggered when summoning a pet while on vehicle 34775
* Handle cases in a generic way
* Code cleanup
* Core/Pet: Attempt to fix an assertion triggered when summoning a pet while on vehicle 34775 with a new character
(cherry picked from commit e203ecda88a327c4e93588f39cc4ffdcf99b30f7)
-rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 2 |
3 files changed, 25 insertions, 3 deletions
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 74c86e4c7ca..aba5a14ad77 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -210,6 +210,10 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c return false; } + // Don't try to reload the current pet + if (petStable->CurrentPet && owner->GetPet() && petStable->CurrentPet.value().PetNumber == petInfo->PetNumber) + return false; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(petInfo->CreatedBySpellId, owner->GetMap()->GetDifficultyID()); bool isTemporarySummon = spellInfo && spellInfo->GetDuration() > 0; @@ -330,9 +334,13 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) if (slot == PET_SAVE_NOT_IN_SLOT) { + uint32 petInfoNumber = petInfo->PetNumber; + if (petStable->CurrentPet) + owner->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT); + auto unslottedPetItr = std::find_if(petStable->UnslottedPets.begin(), petStable->UnslottedPets.end(), [&](PetStable::PetInfo const& unslottedPet) { - return unslottedPet.PetNumber == petInfo->PetNumber; + return unslottedPet.PetNumber == petInfoNumber; }); ASSERT(!petStable->CurrentPet); ASSERT(unslottedPetItr != petStable->UnslottedPets.end()); @@ -343,6 +351,19 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c // old petInfo pointer is no longer valid, refresh it petInfo = &petStable->CurrentPet.value(); } + else if (PET_SAVE_FIRST_STABLE_SLOT <= slot && slot <= PET_SAVE_LAST_STABLE_SLOT) + { + auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petnumber](Optional<PetStable::PetInfo> const& pet) + { + return pet && pet->PetNumber == petnumber; + }); + ASSERT(stabledPet != petStable->StabledPets.end()); + + std::swap(*stabledPet, petStable->CurrentPet); + + // old petInfo pointer is no longer valid, refresh it + petInfo = &petStable->CurrentPet.value(); + } // Send fake summon spell cast - this is needed for correct cooldown application for spells // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 708f07b34d6..8c4b8db42bf 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -28718,6 +28718,9 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy return nullptr; } + if (petType == SUMMON_PET && petStable.CurrentPet) + RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT); + PhasingHandler::InheritPhaseShift(pet, this); pet->SetCreatorGUID(GetGUID()); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 9854aaa6710..4d618e612ec 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -598,8 +598,6 @@ void WorldSession::HandleUnstablePet(WorldPacket& recvData) } else { - std::swap(*stabledPet, petStable->CurrentPet); - // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID); stmt->setUInt8(0, PET_SAVE_AS_CURRENT); |