diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index 171eef015..5eba95918 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -11,6 +11,7 @@ #include "TemporarySummon.h" #include "Pet.h" #include "Player.h" +#include "ScriptMgr.h" TempSummon::TempSummon(SummonPropertiesEntry const* properties, uint64 owner, bool isWorldObject) : Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN), @@ -147,13 +148,16 @@ void TempSummon::InitStats(uint32 duration) { ASSERT(!IsPet()); + Unit* owner = GetSummoner(); + if (Player* player = owner->ToPlayer()) + sScriptMgr->OnBeforeTempSummonInitStats(player, this, duration); + m_timer = duration; m_lifetime = duration; if (m_type == TEMPSUMMON_MANUAL_DESPAWN) m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; - Unit* owner = GetSummoner(); if (owner) { if (IsTrigger() && m_spells[0]) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 88f12d59a..a94687f7f 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -152,9 +152,12 @@ bool Pet::LoadPetFromDB(Player* owner, uint8 asynchLoadType, uint32 petentry, ui if (owner->IsSpectator() || owner->GetPet() || !owner->IsInWorld() || !owner->FindMap()) return false; - // DK Pet exception - if (owner->getClass() == CLASS_DEATH_KNIGHT && !owner->CanSeeDKPet()) - return false; + bool forceLoadFromDB = false; + sScriptMgr->OnBeforeLoadPetFromDB(owner, petentry, petnumber, current, forceLoadFromDB); + + if (!forceLoadFromDB) + if (owner->getClass() == CLASS_DEATH_KNIGHT && !owner->CanSeeDKPet()) // DK Pet exception + return false; uint32 ownerid = owner->GetGUIDLow(); PreparedStatement* stmt; @@ -720,20 +723,31 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) //Determine pet type PetType petType = MAX_PET_TYPE; - if (IsPet() && owner->GetTypeId() == TYPEID_PLAYER) + if (owner->GetTypeId() == TYPEID_PLAYER) { - if (owner->getClass() == CLASS_WARLOCK || - owner->getClass() == CLASS_SHAMAN || // Fire Elemental - owner->getClass() == CLASS_DEATH_KNIGHT || // Risen Ghoul - owner->getClass() == CLASS_MAGE) // Water Elemental with glyph - petType = SUMMON_PET; - else if (owner->getClass() == CLASS_HUNTER) + sScriptMgr->OnBeforeGuardianInitStatsForLevel(owner->ToPlayer(), this, cinfo, petType); + + if (IsPet()) { - petType = HUNTER_PET; - m_unitTypeMask |= UNIT_MASK_HUNTER_PET; + if (petType == MAX_PET_TYPE) + { + // The petType was not overwritten by the hook, continue with default initialization + if (owner->getClass() == CLASS_WARLOCK || + owner->getClass() == CLASS_SHAMAN || // Fire Elemental + owner->getClass() == CLASS_DEATH_KNIGHT || // Risen Ghoul + owner->getClass() == CLASS_MAGE) // Water Elemental with glyph + petType = SUMMON_PET; + else if (owner->getClass() == CLASS_HUNTER) + { + petType = HUNTER_PET; + } + } + + if (petType == HUNTER_PET) + m_unitTypeMask |= UNIT_MASK_HUNTER_PET; + else if (petType != SUMMON_PET) + sLog->outError("Unknown type pet %u is summoned by player class %u", GetEntry(), owner->getClass()); } - else - sLog->outError("Unknown type pet %u is summoned by player class %u", GetEntry(), owner->getClass()); } uint32 creature_ID = (petType == HUNTER_PET) ? 1 : cinfo->Entry; @@ -1066,8 +1080,8 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetFullHealth(); SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); - if (Pet* pet = ToPet()) - sScriptMgr->OnPetInitStatsForLevel(pet); + if (owner->GetTypeId() == TYPEID_PLAYER) + sScriptMgr->OnAfterGuardianInitStatsForLevel(owner->ToPlayer(), this); return true; } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 0d82d3225..f44ff27c5 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1653,9 +1653,24 @@ bool ScriptMgr::CanJoinInBattlegroundQueue(Player* player, uint64 BattlemasterGu return ret; } -void ScriptMgr::OnPetInitStatsForLevel(Pet* pet) +void ScriptMgr::OnBeforeTempSummonInitStats(Player* player, TempSummon* tempSummon, uint32& duration) { - FOREACH_SCRIPT(PlayerScript)->OnPetInitStatsForLevel(pet); + FOREACH_SCRIPT(PlayerScript)->OnBeforeTempSummonInitStats(player, tempSummon, duration); +} + +void ScriptMgr::OnBeforeGuardianInitStatsForLevel(Player* player, Guardian* guardian, CreatureTemplate const* cinfo, PetType& petType) +{ + FOREACH_SCRIPT(PlayerScript)->OnBeforeGuardianInitStatsForLevel(player, guardian, cinfo, petType); +} + +void ScriptMgr::OnAfterGuardianInitStatsForLevel(Player* player, Guardian* guardian) +{ + FOREACH_SCRIPT(PlayerScript)->OnAfterGuardianInitStatsForLevel(player, guardian); +} + +void ScriptMgr::OnBeforeLoadPetFromDB(Player* player, uint32& petentry, uint32& petnumber, bool& current, bool& forceLoadFromDB) +{ + FOREACH_SCRIPT(PlayerScript)->OnBeforeLoadPetFromDB(player, petentry, petnumber, current, forceLoadFromDB); } // Account diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 67e7c7b76..cca463b7b 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -18,6 +18,7 @@ #include "DynamicObject.h" #include "ArenaTeam.h" #include "GameEventMgr.h" +#include "PetDefines.h" #include class AuctionHouseObject; @@ -962,8 +963,17 @@ class PlayerScript : public ScriptObject virtual bool CanJoinInBattlegroundQueue(Player* /*player*/, uint64 /*BattlemasterGuid*/, BattlegroundTypeId /*BGTypeID*/, uint8 /*joinAsGroup*/, GroupJoinBattlegroundResult& /*err*/) { return true; } - // Called after the player's pet has been loaded and initialized - virtual void OnPetInitStatsForLevel(Pet* /*pet*/) { } + // Called before the player's temporary summoned creature has initialized it's stats + virtual void OnBeforeTempSummonInitStats(Player* /*player*/, TempSummon* /*tempSummon*/, uint32& /*duration*/) { } + + // Called before the player's guardian / pet has initialized it's stats for the player's level + virtual void OnBeforeGuardianInitStatsForLevel(Player* /*player*/, Guardian* /*guardian*/, CreatureTemplate const* /*cinfo*/, PetType& /*petType*/) { } + + // Called after the player's guardian / pet has initialized it's stats for the player's level + virtual void OnAfterGuardianInitStatsForLevel(Player* /*player*/, Guardian* /*guardian*/) { } + + // Called before loading a player's pet from the DB + virtual void OnBeforeLoadPetFromDB(Player* /*player*/, uint32& /*petentry*/, uint32& /*petnumber*/, bool& /*current*/, bool& /*forceLoadFromDB*/) { } }; class AccountScript : public ScriptObject @@ -1415,7 +1425,10 @@ class ScriptMgr void OnFirstLogin(Player* player); void OnPlayerCompleteQuest(Player* player, Quest const* quest); bool CanJoinInBattlegroundQueue(Player* player, uint64 BattlemasterGuid, BattlegroundTypeId BGTypeID, uint8 joinAsGroup, GroupJoinBattlegroundResult& err); - void OnPetInitStatsForLevel(Pet* pet); + void OnBeforeTempSummonInitStats(Player* player, TempSummon* tempSummon, uint32& duration); + void OnBeforeGuardianInitStatsForLevel(Player* player, Guardian* guardian, CreatureTemplate const* cinfo, PetType& petType); + void OnAfterGuardianInitStatsForLevel(Player* player, Guardian* guardian); + void OnBeforeLoadPetFromDB(Player* player, uint32& petentry, uint32& petnumber, bool& current, bool& forceLoadFromDB); public: /* AccountScript */