mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-01 18:13:48 +00:00
@@ -202,7 +202,7 @@ std::pair<PetStable::PetInfo const*, PetSaveMode> Pet::GetLoadPetInfo(PetStable
|
|||||||
return { nullptr, PET_SAVE_AS_DELETED };
|
return { nullptr, PET_SAVE_AS_DELETED };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool current)
|
bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool current, uint32 healthPct /*= 0*/)
|
||||||
{
|
{
|
||||||
m_loading = true;
|
m_loading = true;
|
||||||
|
|
||||||
@@ -408,7 +408,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
|
|||||||
owner->ToPlayer()->SetLastPetNumber(petInfo->PetNumber);
|
owner->ToPlayer()->SetLastPetNumber(petInfo->PetNumber);
|
||||||
|
|
||||||
owner->GetSession()->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(std::make_shared<PetLoadQueryHolder>(ownerid, petInfo->PetNumber)))
|
owner->GetSession()->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(std::make_shared<PetLoadQueryHolder>(ownerid, petInfo->PetNumber)))
|
||||||
.AfterComplete([this, owner, session = owner->GetSession(), isTemporarySummon, current, lastSaveTime = petInfo->LastSaveTime, savedhealth = petInfo->Health, savedmana = petInfo->Mana]
|
.AfterComplete([this, owner, session = owner->GetSession(), isTemporarySummon, current, lastSaveTime = petInfo->LastSaveTime, savedhealth = petInfo->Health, savedmana = petInfo->Mana, healthPct]
|
||||||
(SQLQueryHolderBase const& holder)
|
(SQLQueryHolderBase const& holder)
|
||||||
{
|
{
|
||||||
if (session->GetPlayer() != owner || owner->GetPet() != this)
|
if (session->GetPlayer() != owner || owner->GetPet() != this)
|
||||||
@@ -458,6 +458,12 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 curHealth = savedhealth;
|
||||||
|
if (healthPct)
|
||||||
|
{
|
||||||
|
curHealth = CountPctFromMaxHealth(healthPct);
|
||||||
|
}
|
||||||
|
|
||||||
if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
|
if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
|
||||||
{
|
{
|
||||||
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
||||||
@@ -465,11 +471,11 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!savedhealth && getPetType() == HUNTER_PET)
|
if (!curHealth && getPetType() == HUNTER_PET)
|
||||||
setDeathState(JUST_DIED);
|
setDeathState(JUST_DIED);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth);
|
SetHealth(curHealth > GetMaxHealth() ? GetMaxHealth() : curHealth);
|
||||||
SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana);
|
SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
bool CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner);
|
bool CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner);
|
||||||
bool CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask);
|
bool CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask);
|
||||||
static std::pair<PetStable::PetInfo const*, PetSaveMode> GetLoadPetInfo(PetStable const& stable, uint32 petEntry, uint32 petnumber, bool current);
|
static std::pair<PetStable::PetInfo const*, PetSaveMode> GetLoadPetInfo(PetStable const& stable, uint32 petEntry, uint32 petnumber, bool current);
|
||||||
bool LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool current);
|
bool LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool current, uint32 healthPct = 0);
|
||||||
bool isBeingLoaded() const override { return m_loading; }
|
bool isBeingLoaded() const override { return m_loading; }
|
||||||
void SavePetToDB(PetSaveMode mode);
|
void SavePetToDB(PetSaveMode mode);
|
||||||
void FillPetInfo(PetStable::PetInfo* petInfo) const;
|
void FillPetInfo(PetStable::PetInfo* petInfo) const;
|
||||||
|
|||||||
@@ -8737,13 +8737,13 @@ Pet* Player::GetPet() const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration /*= 0s*/)
|
Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration /*= 0s*/, uint32 healthPct /*= 0*/)
|
||||||
{
|
{
|
||||||
PetStable& petStable = GetOrInitPetStable();
|
PetStable& petStable = GetOrInitPetStable();
|
||||||
|
|
||||||
Pet* pet = new Pet(this, petType);
|
Pet* pet = new Pet(this, petType);
|
||||||
|
|
||||||
if (petType == SUMMON_PET && pet->LoadPetFromDB(this, entry, 0, false))
|
if (petType == SUMMON_PET && pet->LoadPetFromDB(this, entry, 0, false, healthPct))
|
||||||
{
|
{
|
||||||
// Remove Demonic Sacrifice auras (known pet)
|
// Remove Demonic Sacrifice auras (known pet)
|
||||||
Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
|
Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
|
||||||
@@ -8810,23 +8810,27 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
|
|||||||
|
|
||||||
switch (petType)
|
switch (petType)
|
||||||
{
|
{
|
||||||
case SUMMON_PET:
|
case SUMMON_PET:
|
||||||
{
|
{
|
||||||
if (pet->GetCreatureTemplate()->type == CREATURE_TYPE_DEMON || pet->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD)
|
if (pet->GetCreatureTemplate()->type == CREATURE_TYPE_DEMON || pet->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD)
|
||||||
pet->GetCharmInfo()->SetPetNumber(pet_number, true); // Show pet details tab (Shift+P) only for demons & undead
|
{
|
||||||
else
|
pet->GetCharmInfo()->SetPetNumber(pet_number, true); // Show pet details tab (Shift+P) only for demons & undead
|
||||||
pet->GetCharmInfo()->SetPetNumber(pet_number, false);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pet->GetCharmInfo()->SetPetNumber(pet_number, false);
|
||||||
|
}
|
||||||
|
|
||||||
pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
|
pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
|
||||||
pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
|
pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
|
||||||
pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
|
pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
|
||||||
pet->SetFullHealth();
|
pet->SetFullHealth();
|
||||||
pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA));
|
pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA));
|
||||||
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped in this case
|
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped in this case
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
map->AddToMap(pet->ToCreature(), true);
|
map->AddToMap(pet->ToCreature(), true);
|
||||||
|
|||||||
@@ -1171,7 +1171,7 @@ public:
|
|||||||
[[nodiscard]] PetStable const* GetPetStable() const { return m_petStable.get(); }
|
[[nodiscard]] PetStable const* GetPetStable() const { return m_petStable.get(); }
|
||||||
|
|
||||||
[[nodiscard]] Pet* GetPet() const;
|
[[nodiscard]] Pet* GetPet() const;
|
||||||
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration = 0s);
|
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration = 0s, uint32 healthPct = 0);
|
||||||
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
||||||
bool CanPetResurrect();
|
bool CanPetResurrect();
|
||||||
bool IsExistPet();
|
bool IsExistPet();
|
||||||
|
|||||||
@@ -5379,35 +5379,31 @@ void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/)
|
|||||||
|
|
||||||
Player* player = m_caster->ToPlayer();
|
Player* player = m_caster->ToPlayer();
|
||||||
if (!player)
|
if (!player)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Maybe player dismissed dead pet or pet despawned?
|
Pet* pet = player->GetPet();
|
||||||
bool hadPet = true;
|
if (!pet)
|
||||||
|
|
||||||
if (!player->GetPet())
|
|
||||||
{
|
{
|
||||||
// Position passed to SummonPet is irrelevant with current implementation,
|
// Position passed to SummonPet is irrelevant with current implementation,
|
||||||
// pet will be relocated without using these coords in Pet::LoadPetFromDB
|
// pet will be relocated without using these coords in Pet::LoadPetFromDB
|
||||||
player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET);
|
player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
|
||||||
hadPet = false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
|
// TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
|
||||||
Pet* pet = player->GetPet(); // Attempt to get current pet
|
if (pet->IsAlive())
|
||||||
if (!pet || pet->IsAlive())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If player did have a pet before reviving, teleport it
|
|
||||||
if (hadPet)
|
|
||||||
{
|
{
|
||||||
// Reposition the pet's corpse before reviving so as not to grab aggro
|
return;
|
||||||
// We can use a different, more accurate version of GetClosePoint() since we have a pet
|
|
||||||
float x, y, z; // Will be used later to reposition the pet if we have one
|
|
||||||
player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
|
|
||||||
pet->NearTeleportTo(x, y, z, player->GetOrientation());
|
|
||||||
pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reposition the pet's corpse before reviving so as not to grab aggro
|
||||||
|
// We can use a different, more accurate version of GetClosePoint() since we have a pet
|
||||||
|
float x, y, z; // Will be used later to reposition the pet if we have one
|
||||||
|
player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
|
||||||
|
pet->NearTeleportTo(x, y, z, player->GetOrientation());
|
||||||
|
pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
|
||||||
pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
|
pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
|
||||||
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
||||||
pet->setDeathState(ALIVE);
|
pet->setDeathState(ALIVE);
|
||||||
|
|||||||
Reference in New Issue
Block a user