diff --git a/src/server/game/Entities/Creature/TemporarySummon/NewGuardian.cpp b/src/server/game/Entities/Creature/TemporarySummon/NewGuardian.cpp index 9f3d692743..011f88b1c9 100644 --- a/src/server/game/Entities/Creature/TemporarySummon/NewGuardian.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon/NewGuardian.cpp @@ -2,6 +2,7 @@ #include "NewGuardian.h" #include "DBCStores.h" #include "ObjectMgr.h" +#include "NewPet.h" #include "SpellMgr.h" #include "SpellInfo.h" @@ -47,7 +48,17 @@ void NewGuardian::InitializeStats() SetMeleeDamageSchool(SpellSchools(creatureInfo->dmgschool)); - if (PetLevelInfo const* petLevelInfo = sObjectMgr->GetPetLevelInfo(creatureInfo->Entry, getLevel())) + uint32 creatureIdForStats = creatureInfo->Entry; + if (IsPet() && ToNewPet()->IsHunterPet()) + { + creatureIdForStats = 1; // hunter pet level stats are stored under creatureId 1 in pet_levelstats + SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_WARRIOR); + SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, GENDER_NONE); + SetSheath(SHEATH_STATE_MELEE); + SetPowerType(POWER_FOCUS); + } + + if (PetLevelInfo const* petLevelInfo = sObjectMgr->GetPetLevelInfo(creatureIdForStats, getLevel())) { for (uint8 i = 0; i < MAX_STATS; ++i) SetCreateStat(Stats(i), float(petLevelInfo->stats[i])); @@ -55,6 +66,7 @@ void NewGuardian::InitializeStats() if (petLevelInfo->armor > 0) SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(petLevelInfo->armor)); + SetMaxHealth(petLevelInfo->health); SetCreateHealth(petLevelInfo->health); SetCreateMana(petLevelInfo->mana); diff --git a/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp b/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp index a644d70cd2..969455a88f 100644 --- a/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp @@ -246,7 +246,8 @@ bool NewPet::LearnSpell(uint32 spellId) if (!AddSpell(spellId)) return false; - SendSpellLearnedToSummoner(spellId); + if (IsInWorld()) + SendSpellLearnedToSummoner(spellId); return true; } @@ -256,7 +257,9 @@ bool NewPet::UnlearnSpell(uint32 spellId, bool learnPreviousRank, bool clearActi if (!RemoveSpell(spellId, learnPreviousRank, clearActionbar)) return false; - SendSpellUnlearnedToSummoner(spellId); + if (IsInWorld()) + SendSpellUnlearnedToSummoner(spellId); + return true; } diff --git a/src/server/game/Entities/Creature/TemporarySummon/NewPet.h b/src/server/game/Entities/Creature/TemporarySummon/NewPet.h index 6396edd695..adc261085f 100644 --- a/src/server/game/Entities/Creature/TemporarySummon/NewPet.h +++ b/src/server/game/Entities/Creature/TemporarySummon/NewPet.h @@ -48,6 +48,9 @@ class TC_GAME_API NewPet final : public NewGuardian // Returns true if the pet is belongs to a specific class (Hunter Pets, Mage Water Elementals, DK Ghouls and Warlock Demons) 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; } + // Returns true if the summoner is allowed to dismiss the pet via pet action bool CanBeDismissed() const; // Returns or creates player pet data. Does return nullptr when the summon is a hunter pet and no pet data is available diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index a22f97910b..7fde113900 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5165,6 +5165,7 @@ void Unit::SetPowerType(Powers new_powertype) if (ToPlayer()->GetGroup()) ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE); } + /* else if (Pet* pet = ToCreature()->ToPet()) { if (pet->isControlled()) @@ -5173,7 +5174,7 @@ void Unit::SetPowerType(Powers new_powertype) if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); } - } + }*/ // Update max power UpdateMaxPower(new_powertype); @@ -5187,9 +5188,6 @@ void Unit::SetPowerType(Powers new_powertype) case POWER_RAGE: // Reset to zero SetPower(POWER_RAGE, 0); break; - case POWER_FOCUS: // Make it full - SetFullPower(new_powertype); - break; default: break; } @@ -5228,13 +5226,6 @@ void Unit::UpdateDisplayPower() else if (getClass() == CLASS_ROGUE) displayPower = POWER_ENERGY; } - else if (Pet* pet = ToPet()) - { - if (pet->getPetType() == HUNTER_PET) // Hunter pets have focus - displayPower = POWER_FOCUS; - else if (pet->IsPetGhoul() || pet->IsRisenAlly()) // DK pets have energy - displayPower = POWER_ENERGY; - } } break; } @@ -9008,9 +8999,7 @@ int32 Unit::GetCreatePowers(Powers power) const case POWER_RAGE: return 1000; case POWER_FOCUS: - if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_HUNTER) - return 100; - return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100); + return 100; case POWER_ENERGY: return 100; case POWER_RUNIC_POWER: @@ -14244,8 +14233,13 @@ NewPet* Unit::SummonPet(uint32 creatureId, uint8 slot, uint32 spellId, bool asCl } uint32 creatureTemplateEntry = creatureId; - if (playerPetData && playerPetData->TamedCreatureId) - creatureTemplateEntry = playerPetData->TamedCreatureId; + if (playerPetData) + { + if (playerPetData->TamedCreatureId) + creatureTemplateEntry = playerPetData->TamedCreatureId; + + pet->SetPlayerPetDataKey(slot, creatureId); + } Map* map = GetMap(); if (!pet->Create(map->GenerateLowGuid(), map, creatureTemplateEntry, playerPetData != nullptr ? playerPetData->PetNumber : 0)) @@ -14278,7 +14272,6 @@ NewPet* Unit::SummonPet(uint32 creatureId, uint8 slot, uint32 spellId, bool asCl // initialize pet behavior if (playerPetData) { - pet->SetPlayerPetDataKey(slot, creatureId); playerPetData->IsActive = true; playerPetData->DisplayId = pet->GetNativeDisplayId(); playerPetData->CreatedBySpellId = spellId; @@ -14286,12 +14279,31 @@ NewPet* Unit::SummonPet(uint32 creatureId, uint8 slot, uint32 spellId, bool asCl pet->GetCharmInfo()->LoadPetActionBar(playerPetData->ActionBar); pet->SetName(playerPetData->Name); pet->SetReactState(playerPetData->ReactState); + if (playerPetData->Status != PlayerPetDataStatus::New) + { + if (IsHunterPet()) + { + if (playerPetData->SavedHealth != 0) + pet->SetHealth(playerPetData->SavedHealth); + else + pet->setDeathState(JUST_DIED); + } + else + pet->SetFullHealth(); + } + else + pet->SetFullHealth(); if (!creatureId) + { + // Hunter pets have some special settings SetByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, playerPetData->HasBeenRenamed ? UNIT_CAN_BE_ABANDONED : (UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED)); + } else SetByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, 0); } + else + pet->SetFullHealth(); return map->AddToMap(pet->ToCreature()); }();