From 84d1c0cceb5aa85725f0ccbbdf22214db779b080 Mon Sep 17 00:00:00 2001 From: iThorgrim <125808072+iThorgrim@users.noreply.github.com> Date: Fri, 29 Aug 2025 03:59:04 +0200 Subject: [PATCH] feat(Pet): Add Pet Object and Methods (#288) --- src/LuaEngine/LuaFunctions.cpp | 81 ++++ src/LuaEngine/methods/PetMethods.h | 665 ++++++++++++++++++++++++++ src/LuaEngine/methods/PlayerMethods.h | 310 ++++++++++-- 3 files changed, 1029 insertions(+), 27 deletions(-) create mode 100644 src/LuaEngine/methods/PetMethods.h diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index 0f432ae..75dc518 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -42,6 +42,7 @@ extern "C" #include "RollMethods.h" #include "TicketMethods.h" #include "SpellInfoMethods.h" +#include "PetMethods.h" #include "LootMethods.h" // DBCStores includes @@ -546,8 +547,16 @@ ElunaRegister PlayerMethods[] = { "GetTrader", &LuaPlayer::GetTrader }, { "GetBonusTalentCount", &LuaPlayer::GetBonusTalentCount }, { "GetKnownTaxiNodes", &LuaPlayer::GetKnownTaxiNodes }, + { "GetPet", &LuaPlayer::GetPet }, + { "GetTemporaryUnsummonedPetNumber", &LuaPlayer::GetTemporaryUnsummonedPetNumber }, + { "GetLastPetNumber", &LuaPlayer::GetLastPetNumber }, + { "GetLastPetSpell", &LuaPlayer::GetLastPetSpell }, // Setters + { "SetTemporaryUnsummonedPetNumber", &LuaPlayer::SetTemporaryUnsummonedPetNumber }, + { "SetLastPetNumber", &LuaPlayer::SetLastPetNumber }, + { "SetLastPetSpell", &LuaPlayer::SetLastPetSpell }, + { "SetShowDKPet", &LuaPlayer::SetShowDKPet }, { "AdvanceSkillsToMax", &LuaPlayer::AdvanceSkillsToMax }, { "AdvanceSkill", &LuaPlayer::AdvanceSkill }, { "AdvanceAllSkills", &LuaPlayer::AdvanceAllSkills }, @@ -670,6 +679,12 @@ ElunaRegister PlayerMethods[] = { "CanFly", &LuaPlayer::CanFly }, { "IsMoving", &LuaPlayer::IsMoving }, { "IsFlying", &LuaPlayer::IsFlying }, + { "CanPetResurrect", &LuaPlayer::CanPetResurrect }, + { "IsExistPet", &LuaPlayer::IsExistPet }, + { "CanTameExoticPets", &LuaPlayer::CanTameExoticPets }, + { "IsPetNeedBeTemporaryUnsummoned", &LuaPlayer::IsPetNeedBeTemporaryUnsummoned }, + { "CanResummonPet", &LuaPlayer::CanResummonPet }, + { "CanSeeDKPet", &LuaPlayer::CanSeeDKPet }, { "IsMaxLevel", &LuaPlayer::IsMaxLevel }, { "IsDailyQuestDone", &LuaPlayer::IsDailyQuestDone }, { "IsPvP", &LuaPlayer::IsPvP }, @@ -788,6 +803,13 @@ ElunaRegister PlayerMethods[] = { "SendMovieStart", &LuaPlayer::SendMovieStart }, { "UpdatePlayerSetting", &LuaPlayer::UpdatePlayerSetting }, { "TeleportTo", &LuaPlayer::TeleportTo }, + { "SummonPet", &LuaPlayer::SummonPet }, + { "CreatePet", &LuaPlayer::CreatePet }, + { "UnsummonPetTemporarily", &LuaPlayer::UnsummonPetTemporarily }, + { "RemovePet", &LuaPlayer::RemovePet }, + { "ResetPetTalents", &LuaPlayer::ResetPetTalents }, + { "LearnPetTalent", &LuaPlayer::LearnPetTalent }, + { "ResummonPetTemporaryUnSummonedIfAny", &LuaPlayer::ResummonPetTemporaryUnSummonedIfAny }, { "SetPlayerFlag", &LuaPlayer::SetPlayerFlag }, { "RemovePlayerFlag", &LuaPlayer::RemovePlayerFlag }, { "DoRandomRoll", &LuaPlayer::DoRandomRoll }, @@ -1600,6 +1622,65 @@ ElunaRegister SpellEntryMethods[] = { NULL, NULL } }; +ElunaRegister PetMethods[] = +{ + // Getters + { "GetPetType", &LuaPet::GetPetType }, + { "GetDuration", &LuaPet::GetDuration }, + { "GetHappinessState", &LuaPet::GetHappinessState }, + { "GetCurrentFoodBenefitLevel", &LuaPet::GetCurrentFoodBenefitLevel }, + { "GetMaxTalentPointsForLevel", &LuaPet::GetMaxTalentPointsForLevel }, + { "GetFreeTalentPoints", &LuaPet::GetFreeTalentPoints }, + { "GetUsedTalentCount", &LuaPet::GetUsedTalentCount }, + { "GetAuraUpdateMaskForRaid", &LuaPet::GetAuraUpdateMaskForRaid }, + { "GetOwner", &LuaPet::GetOwner }, + { "GetPetAutoSpellSize", &LuaPet::GetPetAutoSpellSize }, + { "GetPetAutoSpellOnPos", &LuaPet::GetPetAutoSpellOnPos }, + + // Setters + { "SetPetType", &LuaPet::SetPetType }, + { "SetDuration", &LuaPet::SetDuration }, + { "SetFreeTalentPoints", &LuaPet::SetFreeTalentPoints }, + { "SetUsedTalentCount", &LuaPet::SetUsedTalentCount }, + { "SetAuraUpdateMaskForRaid", &LuaPet::SetAuraUpdateMaskForRaid }, + { "SetRemoved", &LuaPet::SetRemoved }, + + // Boolean + { "IsControlled", &LuaPet::IsControlled }, + { "IsTemporarySummoned", &LuaPet::IsTemporarySummoned }, + { "IsPermanentPetFor", &LuaPet::IsPermanentPetFor }, + { "HaveInDiet", &LuaPet::HaveInDiet }, + { "HasTempSpell", &LuaPet::HasTempSpell }, + { "IsRemoved", &LuaPet::IsRemoved }, + { "IsBeingLoaded", &LuaPet::IsBeingLoaded }, + + // Other + { "CreateBaseAtCreature", &LuaPet::CreateBaseAtCreature }, + { "GivePetXP", &LuaPet::GivePetXP }, + { "GivePetLevel", &LuaPet::GivePetLevel }, + { "SynchronizeLevelWithOwner", &LuaPet::SynchronizeLevelWithOwner }, + { "ToggleAutocast", &LuaPet::ToggleAutocast }, + { "LearnPetPassives", &LuaPet::LearnPetPassives }, + { "CastWhenWillAvailable", &LuaPet::CastWhenWillAvailable }, + { "ClearCastWhenWillAvailable", &LuaPet::ClearCastWhenWillAvailable }, + { "AddSpell", &LuaPet::AddSpell }, + { "LearnSpell", &LuaPet::LearnSpell }, + { "LearnSpellHighRank", &LuaPet::LearnSpellHighRank }, + { "InitLevelupSpellsForLevel", &LuaPet::InitLevelupSpellsForLevel }, + { "UnlearnSpell", &LuaPet::UnlearnSpell }, + { "RemoveSpell", &LuaPet::RemoveSpell }, + { "CleanupActionBar", &LuaPet::CleanupActionBar }, + { "GenerateActionBarData", &LuaPet::GenerateActionBarData }, + { "InitPetCreateSpells", &LuaPet::InitPetCreateSpells }, + { "ResetTalents", &LuaPet::ResetTalents }, + { "InitTalentForLevel", &LuaPet::InitTalentForLevel }, + { "ResetAuraUpdateMaskForRaid", &LuaPet::ResetAuraUpdateMaskForRaid }, + { "SavePetToDB", &LuaPet::SavePetToDB }, + { "Remove", &LuaPet::Remove }, + + { NULL, NULL } +}; + ElunaRegister LootMethods[] = { // Get diff --git a/src/LuaEngine/methods/PetMethods.h b/src/LuaEngine/methods/PetMethods.h new file mode 100644 index 0000000..60c16c8 --- /dev/null +++ b/src/LuaEngine/methods/PetMethods.h @@ -0,0 +1,665 @@ +/* +* Copyright (C) 2010 - 2025 Eluna Lua Engine +* This program is free software licensed under GPL version 3 +* Please see the included DOCS/LICENSE.md for more information +*/ + +#ifndef PETMETHODS_H +#define PETMETHODS_H + +/*** + * Non-[Player] controlled companions that fight alongside their owners. + * + * Includes hunter pets, warlock demons, death knight ghouls, and other summoned creatures. + * [Pet]s can be temporary or permanent and have various AI behaviors and spell abilities. + * + * Inherits all methods from: [Object], [WorldObject], [Unit], [Guardian] + */ +namespace LuaPet +{ + /** + * Returns the [Pet]'s type. + * + *
+     * enum PetType
+     * {
+     *      SUMMON_PET                  = 0,
+     *      HUNTER_PET                  = 1,
+     *      MAX_PET_TYPE                = 4
+     * };
+     * 
+ * + * @return [PetType] petType + */ + int GetPetType(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->getPetType()); + return 1; + } + + /** + * Sets the [Pet]'s type. + * + *
+     * enum PetType
+     * {
+     *      SUMMON_PET                  = 0,
+     *      HUNTER_PET                  = 1,
+     *      MAX_PET_TYPE                = 4
+     * };
+     * 
+ * + * @param [PetType] petType : the pet type to set + */ + int SetPetType(lua_State* L, Pet* pet) + { + uint32 petType = Eluna::CHECKVAL(L, 2); + pet->setPetType(static_cast(petType)); + return 0; + } + + /** + * Returns `true` if the [Pet] is controlled by a player, returns `false` otherwise. + * + * @return bool isControlled + */ + int IsControlled(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->isControlled()); + return 1; + } + + /** + * Returns `true` if the [Pet] is temporarily summoned, returns `false` otherwise. + * + * @return bool isTemporary + */ + int IsTemporarySummoned(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->isTemporarySummoned()); + return 1; + } + + /** + * Returns `true` if the [Pet] is a permanent pet for the specified [Player], returns `false` otherwise. + * + * @param [Player] owner : the player to check ownership for + * @return bool isPermanent + */ + int IsPermanentPetFor(lua_State* L, Pet* pet) + { + Player* owner = Eluna::CHECKOBJ(L, 2); + Eluna::Push(L, pet->IsPermanentPetFor(owner)); + return 1; + } + + /** + * Creates the [Pet]'s base stats and properties from an existing [Creature]. + * + * @param [Creature] creature : the creature to base the pet on + * @return bool success : `true` if successful, `false` otherwise + */ + int CreateBaseAtCreature(lua_State* L, Pet* pet) + { + Creature* creature = Eluna::CHECKOBJ(L, 2); + Eluna::Push(L, pet->CreateBaseAtCreature(creature)); + return 1; + } + + /** + * Returns the [Pet]'s remaining duration in milliseconds. + * + * @return uint32 duration : remaining time in milliseconds, 0 if permanent + */ + int GetDuration(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GetDuration().count()); + return 1; + } + + /** + * Sets the [Pet]'s duration in milliseconds. + * + * @param uint32 duration : duration in milliseconds, 0 for permanent + */ + int SetDuration(lua_State* L, Pet* pet) + { + uint32 duration = Eluna::CHECKVAL(L, 2); + pet->SetDuration(Milliseconds(duration)); + return 0; + } + + /** + * Returns the [Pet]'s current happiness state. + * + *
+     * enum HappinessState
+     * {
+     *      UNHAPPY                     = 1,
+     *      CONTENT                     = 2,
+     *      HAPPY                       = 3
+     * };
+     * 
+ * + * @return [HappinessState] happinessState + */ + int GetHappinessState(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GetHappinessState()); + return 1; + } + + /** + * Gives experience points to the [Pet]. + * + * @param uint32 xp : amount of experience to give + */ + int GivePetXP(lua_State* L, Pet* pet) + { + uint32 xp = Eluna::CHECKVAL(L, 2); + pet->GivePetXP(xp); + return 0; + } + + /** + * Sets the [Pet]'s level directly. + * + * @param uint8 level : the level to set + */ + int GivePetLevel(lua_State* L, Pet* pet) + { + uint8 level = Eluna::CHECKVAL(L, 2); + pet->GivePetLevel(level); + return 0; + } + + /** + * Synchronizes the [Pet]'s level with its owner's level. + * + * The pet's level will be adjusted based on the owner's level and pet scaling rules. + */ + int SynchronizeLevelWithOwner(lua_State* /*L*/, Pet* pet) + { + pet->SynchronizeLevelWithOwner(); + return 0; + } + + /** + * Returns `true` if the [Pet] can eat the specified [Item], returns `false` otherwise. + * + * @param [Item] item : the item to check + * @return bool canEat + */ + int HaveInDiet(lua_State* L, Pet* pet) + { + Item* item = Eluna::CHECKOBJ(L, 2); + Eluna::Push(L, pet->HaveInDiet(item->GetTemplate())); + return 1; + } + + /** + * Returns the food benefit level for an item of the specified level. + * + * @param uint32 itemLevel : the level of the food item + * @return uint32 benefitLevel + */ + int GetCurrentFoodBenefitLevel(lua_State* L, Pet* pet) + { + uint32 itemLevel = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, pet->GetCurrentFoodBenefitLevel(itemLevel)); + return 1; + } + + /** + * Toggles autocast on or off for the specified spell. + * + * @param uint32 spellId : the spell ID to toggle autocast for + * @param bool apply : `true` to enable autocast, `false` to disable + */ + int ToggleAutocast(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + bool apply = Eluna::CHECKVAL(L, 3); + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (spellInfo) + pet->ToggleAutocast(spellInfo, apply); + + return 0; + } + + /** + * Makes the [Pet] learn all passive spells it should know. + * + * This includes racial passives and pet-specific passive abilities. + */ + int LearnPetPassives(lua_State* /*L*/, Pet* pet) + { + pet->LearnPetPassives(); + return 0; + } + + /** + * Queues a spell to be cast when the [Pet] becomes available. + * + * @param uint32 spellId : the spell ID to cast + * @param [Unit] target : the target for the spell + * @param bool isPositive = false : whether the spell is beneficial + */ + int CastWhenWillAvailable(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + Unit* target = Eluna::CHECKOBJ(L, 3); + ObjectGuid oldTarget = ObjectGuid::Empty; + bool isPositive = Eluna::CHECKVAL(L, 4, false); + + pet->CastWhenWillAvailable(spellId, target, oldTarget, isPositive); + return 0; + } + + /** + * Clears any queued spell that was set to cast when available. + */ + int ClearCastWhenWillAvailable(lua_State* /*L*/, Pet* pet) + { + pet->ClearCastWhenWillAvailable(); + return 0; + } + + /** + * Adds a spell to the [Pet]'s spellbook. + * + *
+     * enum ActiveStates : uint8
+     * {
+     *     ACT_PASSIVE  = 0x01,                                    // 0x01 - passive
+     *     ACT_DISABLED = 0x81,                                    // 0x80 - castable
+     *     ACT_ENABLED  = 0xC1,                                    // 0x40 | 0x80 - auto cast + castable
+     *     ACT_COMMAND  = 0x07,                                    // 0x01 | 0x02 | 0x04
+     *     ACT_REACTION = 0x06,                                    // 0x02 | 0x04
+     *     ACT_DECIDE   = 0x00                                     // custom
+     * };
+     * 
+ * + *
+     * enum PetSpellState
+     * {
+     *     PETSPELL_UNCHANGED          = 0,
+     *     PETSPELL_CHANGED            = 1,
+     *     PETSPELL_NEW                = 2,
+     *     PETSPELL_REMOVED            = 3
+     * };
+     * 
+ * + *
+     * enum PetSpellType
+     * {
+     *     PETSPELL_NORMAL             = 0,
+     *     PETSPELL_FAMILY             = 1,
+     *     PETSPELL_TALENT             = 2
+     * };
+     * 
+ * + * @param uint32 spellId : the spell ID to add + * @param [ActiveStates] active : the spell's active state by default is ACT_DECIDE + * @param [PetSpellState] state : the spell's state by default is PETSPELL_NEW + * @param [PetSpellType] type : the spell's type by default is PETSPELL_NORMAL + * @return bool success : `true` if the spell was added successfully + */ + int AddSpell(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + uint32 active = Eluna::CHECKVAL(L, 3, ACT_DECIDE); + uint32 state = Eluna::CHECKVAL(L, 4, PETSPELL_NEW); + uint32 type = Eluna::CHECKVAL(L, 5, PETSPELL_NORMAL); + + Eluna::Push(L, pet->addSpell(spellId, static_cast(active), static_cast(state), static_cast(type))); + return 1; + } + + /** + * Makes the [Pet] learn a spell. + * + * @param uint32 spellId : the spell ID to learn + * @return bool success : `true` if the spell was learned successfully + */ + int LearnSpell(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, pet->learnSpell(spellId)); + return 1; + } + + /** + * Makes the [Pet] learn the highest available rank of a spell. + * + * @param uint32 spellId : the base spell ID + */ + int LearnSpellHighRank(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + pet->learnSpellHighRank(spellId); + return 0; + } + + /** + * Initializes level-up spells for the [Pet]'s current level. + * + * This teaches the pet all spells it should know at its current level. + */ + int InitLevelupSpellsForLevel(lua_State* /*L*/, Pet* pet) + { + pet->InitLevelupSpellsForLevel(); + return 0; + } + + /** + * Makes the [Pet] unlearn a spell. + * + * @param uint32 spellId : the spell ID to unlearn + * @param bool learnPrev : if `true`, learns the previous rank by default is false + * @param bool clearAb : if `true`, clears the spell from action bar by default is true + * @return bool success : `true` if the spell was unlearned successfully + */ + int UnlearnSpell(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + bool learnPrev = Eluna::CHECKVAL(L, 3, false); + bool clearAb = Eluna::CHECKVAL(L, 4, true); + + Eluna::Push(L, pet->unlearnSpell(spellId, learnPrev, clearAb)); + return 1; + } + + /** + * Removes a spell from the [Pet]'s spellbook. + * + * @param uint32 spellId : the spell ID to remove + * @param bool learnPrev : if `true`, learns the previous rank by default is false + * @param bool clearAb : if `true`, clears the spell from action bar by default is true + * @return bool success : `true` if the spell was removed successfully + */ + int RemoveSpell(lua_State* L, Pet* pet) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + bool learnPrev = Eluna::CHECKVAL(L, 3, false); + bool clearAb = Eluna::CHECKVAL(L, 4, true); + + Eluna::Push(L, pet->removeSpell(spellId, learnPrev, clearAb)); + return 1; + } + + /** + * Cleans up the [Pet]'s action bar, removing invalid spells. + */ + int CleanupActionBar(lua_State* /*L*/, Pet* pet) + { + pet->CleanupActionBar(); + return 0; + } + + /** + * Generates action bar data for the [Pet]. + * + * @return string actionBarData : the action bar data as a string + */ + int GenerateActionBarData(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GenerateActionBarData()); + return 1; + } + + /** + * Initializes the [Pet]'s creation spells. + * + * This sets up the basic spells the pet should have when first created. + */ + int InitPetCreateSpells(lua_State* /*L*/, Pet* pet) + { + pet->InitPetCreateSpells(); + return 0; + } + + /** + * Resets all of the [Pet]'s talents. + * + * @return bool success : `true` if talents were reset successfully + */ + int ResetTalents(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->resetTalents()); + return 1; + } + + /** + * Initializes talents for the [Pet]'s current level. + * + * This assigns talent points based on the pet's level. + */ + int InitTalentForLevel(lua_State* /*L*/, Pet* pet) + { + pet->InitTalentForLevel(); + return 0; + } + + /** + * Returns the maximum number of talent points available at the specified level. + * + * @param uint8 level : the level to check + * @return uint8 maxTalentPoints + */ + int GetMaxTalentPointsForLevel(lua_State* L, Pet* pet) + { + uint8 level = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, pet->GetMaxTalentPointsForLevel(level)); + return 1; + } + + /** + * Returns the number of unspent talent points the [Pet] has. + * + * @return uint8 freeTalentPoints + */ + int GetFreeTalentPoints(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GetFreeTalentPoints()); + return 1; + } + + /** + * Sets the number of unspent talent points for the [Pet]. + * + * @param uint8 points : the number of free talent points to set + */ + int SetFreeTalentPoints(lua_State* L, Pet* pet) + { + uint8 points = Eluna::CHECKVAL(L, 2); + pet->SetFreeTalentPoints(points); + return 0; + } + + /** + * Returns the number of talents the [Pet] has used. + * + * @return uint32 usedTalentCount + */ + int GetUsedTalentCount(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->m_usedTalentCount); + return 1; + } + + /** + * Sets the number of talents the [Pet] has used. + * + * @param uint32 count : the number of used talents to set + */ + int SetUsedTalentCount(lua_State* L, Pet* pet) + { + uint32 count = Eluna::CHECKVAL(L, 2); + pet->m_usedTalentCount = count; + return 0; + } + + /** + * Returns the aura update mask for raid members. + * + * @return uint64 auraUpdateMask + */ + int GetAuraUpdateMaskForRaid(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GetAuraUpdateMaskForRaid()); + return 1; + } + + /** + * Sets an aura slot in the raid update mask. + * + * @param uint8 slot : the aura slot to set + */ + int SetAuraUpdateMaskForRaid(lua_State* L, Pet* pet) + { + uint8 slot = Eluna::CHECKVAL(L, 2); + pet->SetAuraUpdateMaskForRaid(slot); + return 0; + } + + /** + * Resets the aura update mask for raid members. + */ + int ResetAuraUpdateMaskForRaid(lua_State* /*L*/, Pet* pet) + { + pet->ResetAuraUpdateMaskForRaid(); + return 0; + } + + /** + * Returns the [Player] who owns this [Pet]. + * + * @return [Player] owner : the pet's owner + */ + int GetOwner(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GetOwner()); + return 1; + } + + /** + * Returns `true` if the [Pet] has a temporary spell queued, returns `false` otherwise. + * + * @return bool hasTempSpell + */ + int HasTempSpell(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->HasTempSpell()); + return 1; + } + + /** + * Returns `true` if the [Pet] is marked as removed, returns `false` otherwise. + * + * @return bool isRemoved + */ + int IsRemoved(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->m_removed); + return 1; + } + + /** + * Sets whether the [Pet] is marked as removed. + * + * @param bool removed : `true` to mark as removed, `false` otherwise + */ + int SetRemoved(lua_State* L, Pet* pet) + { + bool removed = Eluna::CHECKVAL(L, 2); + pet->m_removed = removed; + return 0; + } + + /** + * Returns the number of auto-spells the [Pet] has. + * + * @return uint8 autoSpellCount + */ + int GetPetAutoSpellSize(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->GetPetAutoSpellSize()); + return 1; + } + + /** + * Returns the auto-spell at the specified position. + * + * @param uint8 pos : the position in the auto-spell list + * @return uint32 spellId : the spell ID, or 0 if invalid position + */ + int GetPetAutoSpellOnPos(lua_State* L, Pet* pet) + { + uint8 pos = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, pet->GetPetAutoSpellOnPos(pos)); + return 1; + } + + /** + * Saves the [Pet] to the database. + * + *
+     * enum PetSaveMode
+     * {
+     *     PET_SAVE_AS_DELETED         = -1,                        // not saved in fact
+     *     PET_SAVE_AS_CURRENT         =  0,                        // in current slot (with player)
+     *     PET_SAVE_FIRST_STABLE_SLOT  =  1,
+     *     PET_SAVE_LAST_STABLE_SLOT   =  MAX_PET_STABLES,          // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
+     *     PET_SAVE_NOT_IN_SLOT        =  100                       // for avoid conflict with stable size grow will use 100
+     * };
+     * 
+ * + * @param [PetSaveMode] mode : the save mode to use + */ + int SavePetToDB(lua_State* L, Pet* pet) + { + uint32 mode = Eluna::CHECKVAL(L, 2); + pet->SavePetToDB(static_cast(mode)); + return 0; + } + + /** + * Removes the [Pet] from the world. + * + *
+     * enum PetSaveMode
+     * {
+     *     PET_SAVE_AS_DELETED         = -1,                        // not saved in fact
+     *     PET_SAVE_AS_CURRENT         =  0,                        // in current slot (with player)
+     *     PET_SAVE_FIRST_STABLE_SLOT  =  1,
+     *     PET_SAVE_LAST_STABLE_SLOT   =  MAX_PET_STABLES,          // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
+     *     PET_SAVE_NOT_IN_SLOT        =  100                       // for avoid conflict with stable size grow will use 100
+     * };
+     * 
+ * + * @param [PetSaveMode] mode : how to handle the removal + * @param bool returnReagent = false : if `true`, returns reagents used to summon + */ + int Remove(lua_State* L, Pet* pet) + { + uint32 mode = Eluna::CHECKVAL(L, 2); + bool returnReagent = Eluna::CHECKVAL(L, 3, false); + pet->Remove(static_cast(mode), returnReagent); + return 0; + } + + /** + * Returns `true` if the [Pet] is currently being loaded from the database, returns `false` otherwise. + * + * @return bool isBeingLoaded + */ + int IsBeingLoaded(lua_State* L, Pet* pet) + { + Eluna::Push(L, pet->isBeingLoaded()); + return 1; + } +}; +#endif // PETMETHODS_H + diff --git a/src/LuaEngine/methods/PlayerMethods.h b/src/LuaEngine/methods/PlayerMethods.h index 87a0ddf..fc4939b 100644 --- a/src/LuaEngine/methods/PlayerMethods.h +++ b/src/LuaEngine/methods/PlayerMethods.h @@ -2072,18 +2072,6 @@ namespace LuaPlayer return 0; }*/ - /** - * Resets the [Player]s pets talent points - */ - int ResetPetTalents(lua_State* /*L*/, Player* player) - { - Pet* pet = player->GetPet(); - Pet::resetTalentsForAllPetsOf(player, pet); - if (pet) - player->SendTalentsInfoData(true); - return 0; - } - /** * Reset the [Player]s completed achievements */ @@ -4040,6 +4028,17 @@ namespace LuaPlayer return 0; } + /** + * Returns the [Player]'s current [Pet], if any. + * + * @return [Pet] pet : the player's pet, or `nil` if no pet + */ + int GetPet(lua_State* L, Player* player) + { + Eluna::Push(L, player->GetPet()); + return 1; + } + /** * Returns `true` if the [Player] is at maximum level, `false` otherwise. * @@ -4051,6 +4050,35 @@ namespace LuaPlayer return 1; } + /** + * Summons a [Pet] at the specified location. + * + * @param uint32 entry : the creature entry ID to summon + * @param float x : X coordinate + * @param float y : Y coordinate + * @param float z : Z coordinate + * @param float ang : orientation angle + * @param [PetType] petType : the type of pet to summon + * @param uint32 duration = 0 : duration in milliseconds, 0 for permanent + * @param uint32 healthPct = 0 : initial health percentage + * @return [Pet] pet : the summoned pet, or `nil` if failed + */ + int SummonPet(lua_State* L, Player* player) + { + uint32 entry = Eluna::CHECKVAL(L, 2); + float x = Eluna::CHECKVAL(L, 3); + float y = Eluna::CHECKVAL(L, 4); + float z = Eluna::CHECKVAL(L, 5); + float ang = Eluna::CHECKVAL(L, 6); + uint32 petType = Eluna::CHECKVAL(L, 7); + uint32 duration = Eluna::CHECKVAL(L, 8, 0); + uint32 healthPct = Eluna::CHECKVAL(L, 9, 0); + + Pet* pet = player->SummonPet(entry, x, y, z, ang, static_cast(petType), Milliseconds(duration), healthPct); + Eluna::Push(L, pet); + return 1; + } + /** * Returns the average item level of the [Player]'s equipment. * @@ -4062,6 +4090,36 @@ namespace LuaPlayer return 1; } + /** + * Creates a tamed [Pet] from a [Creature] or creature entry. + * + * Can be called with either: + * - `player:CreatePet(creatureEntry)` - creates pet from entry ID + * - `player:CreatePet(creature, spellID)` - tames existing creature + * + * @param uint32 creatureEntry : creature entry ID (first form) + * @param [Creature] creature : target creature to tame (second form) + * @param uint32 spellID = 0 : spell used for taming (second form) + * @return [Pet] pet : the created pet, or `nil` if failed + */ + int CreatePet(lua_State* L, Player* player) + { + if (lua_gettop(L) == 2) + { + uint32 creatureEntry = Eluna::CHECKVAL(L, 2); + Pet* pet = player->CreatePet(creatureEntry); + Eluna::Push(L, pet); + } + else + { + Creature* creatureTarget = Eluna::CHECKOBJ(L, 2); + uint32 spellID = Eluna::CHECKVAL(L, 3, 0); + Pet* pet = player->CreatePet(creatureTarget, spellID); + Eluna::Push(L, pet); + } + return 1; + } + /** * Returns `true` if the [Player] has completed the daily quest, `false` otherwise. * @@ -4075,6 +4133,17 @@ namespace LuaPlayer return 1; } + /** + * Temporarily unsummons the [Player]'s current [Pet]. + * + * The pet can be resummoned later. Used during teleportation, mounting, etc. + */ + int UnsummonPetTemporarily(lua_State* /*L*/, Player* player) + { + player->UnsummonPetTemporaryIfAny(); + return 0; + } + /** * Sets the specified player flag on the [Player]. * @@ -4087,6 +4156,22 @@ namespace LuaPlayer return 0; } + /** + * Removes the specified [Pet] from the [Player]. + * + * @param [Pet] pet : the pet to remove + * @param [PetSaveMode] mode : how to handle pet removal + * @param bool returnReagent = false : if `true`, returns reagents used to summon + */ + int RemovePet(lua_State* L, Player* player) + { + Pet* pet = Eluna::CHECKOBJ(L, 2); + uint32 mode = Eluna::CHECKVAL(L, 3); + bool returnReagent = Eluna::CHECKVAL(L, 4, false); + player->RemovePet(pet, static_cast(mode), returnReagent); + return 1; + } + /** * Removes the specified player flag from the [Player]. * @@ -4099,6 +4184,17 @@ namespace LuaPlayer return 0; } + /** + * Returns `true` if the [Player] can resurrect their [Pet] and returns `false` otherwise. + * + * @return bool canResurrect + */ + int CanPetResurrect(lua_State* L, Player* player) + { + Eluna::Push(L, player->CanPetResurrect()); + return 1; + } + /** * Returns a random number between the specified minimum and maximum values. * @@ -4184,6 +4280,17 @@ namespace LuaPlayer return 1; } + /** + * Returns `true` if the [Player] has a [Pet] (active or stored) and returns `false` otherwise. + * + * @return bool hasExistingPet + */ + int IsExistPet(lua_State* L, Player* player) + { + Eluna::Push(L, player->IsExistPet()); + return 1; + } + /** * Returns `true` if the [Player] can take the specified quest, `false` otherwise. * @@ -4199,6 +4306,16 @@ namespace LuaPlayer return 1; } + /** + * Resets the [Player]'s pet talents. + * + */ + int ResetPetTalents(lua_State* /*L*/, Player* player) + { + player->ResetPetTalents(); + return 0; + } + /** * Returns `true` if the [Player] can add the specified quest, `false` otherwise. * @@ -4290,6 +4407,22 @@ namespace LuaPlayer return 0; } + /** + * Learns a pet talent for the specified [Pet] of the [Player]. + * + * @param ObjectGuid petGuid : GUID of the pet to learn the talent for + * @param uint32 talentId : ID of the talent to learn + * @param uint32 talentRank : rank of the talent to learn + */ + int LearnPetTalent(lua_State* L, Player* player) + { + ObjectGuid petGuid = Eluna::CHECKVAL(L, 2); + uint32 talentId = Eluna::CHECKVAL(L, 3); + uint32 talentRank = Eluna::CHECKVAL(L, 4); + player->LearnPetTalent(petGuid, talentId, talentRank); + return 0; + } + /** * Returns `true` if the [Player] has a title by bit index, `false` otherwise. * @@ -4341,6 +4474,17 @@ namespace LuaPlayer return 0; } + /** + * Returns `true` if the [Player] can tame exotic pets, and `false` otherwise. + * + * @return bool canTameExoticPets : `true` if the player can tame exotic pets, `false` otherwise + */ + int CanTameExoticPets(lua_State* L, Player* player) + { + Eluna::Push(L, player->CanTameExoticPets()); + return 1; + } + /** * Returns the [Player]'s weapon proficiency flags. * @@ -4352,6 +4496,17 @@ namespace LuaPlayer return 1; } + /** + * Returns the temporary unsummoned pet number for the [Player]. + * + * @return uint32 petNumber : the temporary unsummoned pet number + */ + int GetTemporaryUnsummonedPetNumber(lua_State* L, Player* player) + { + Eluna::Push(L, player->GetTemporaryUnsummonedPetNumber()); + return 1; + } + /** * Returns the [Player]'s armor proficiency flags. * @@ -4363,6 +4518,18 @@ namespace LuaPlayer return 1; } + /** + * Sets the temporary unsummoned pet number for the [Player]. + * + * @param uint32 petNumber : the pet number to set + */ + int SetTemporaryUnsummonedPetNumber(lua_State* L, Player* player) + { + uint32 petNumber = Eluna::CHECKVAL(L, 2); + player->SetTemporaryUnsummonedPetNumber(petNumber); + return 0; + } + /** * Adds weapon proficiency to the [Player]. * @@ -4375,6 +4542,16 @@ namespace LuaPlayer return 0; } + /** + * Resummons the [Player]'s pet if it was temporarily unsummoned. + * + */ + int ResummonPetTemporaryUnSummonedIfAny(lua_State* /*L*/, Player* player) + { + player->ResummonPetTemporaryUnSummonedIfAny(); + return 0; + } + /** * Adds armor proficiency to the [Player]. * @@ -4387,6 +4564,18 @@ namespace LuaPlayer return 0; } + /** + * Returns `true` if the [Player] needs to temporarily unsummon their [Pet], and `false` otherwise. + * + * + * @return bool isPetNeedBeTemporaryUnsummoned : `true` if the pet needs to be temporarily unsummoned, `false` otherwise + */ + int IsPetNeedBeTemporaryUnsummoned(lua_State* L, Player* player) + { + Eluna::Push(L, player->IsPetNeedBeTemporaryUnsummoned()); + return 1; + } + /** * Sets the [Player]'s ammo item. * @@ -4419,6 +4608,19 @@ namespace LuaPlayer return 1; } + /** + * Returns `true` if the [Player] can resummon a [Pet] with the specified spell ID, and `false` otherwise. + * + * @param uint32 spellId : the spell ID to check + * @return bool canResummon : `true` if the player can resummon the pet, `false` otherwise + */ + int CanResummonPet(lua_State* L, Player* player) + { + uint32 spellId = Eluna::CHECKVAL(L, 2); + Eluna::Push(L, player->CanResummonPet(spellId)); + return 1; + } + /** * Returns the [Player]'s shield item. * @@ -4430,6 +4632,17 @@ namespace LuaPlayer return 1; } + /** + * Returns the last pet number for the [Player]. + * + * @return uint32 petNumber : the last pet number + */ + int GetLastPetNumber(lua_State* L, Player* player) + { + Eluna::Push(L, player->GetLastPetNumber()); + return 1; + } + /** * Returns `true` if the [Player] can teleport, `false` otherwise. * @@ -4441,6 +4654,18 @@ namespace LuaPlayer return 1; } + /** + * Sets the last pet number for the [Player]. + * + * @param uint32 petNumber : the pet number to set + */ + int SetLastPetNumber(lua_State* L, Player* player) + { + uint32 petNumber = Eluna::CHECKVAL(L, 2); + player->SetLastPetNumber(petNumber); + return 0; + } + /** * Sets whether the [Player] can teleport. * @@ -4453,6 +4678,17 @@ namespace LuaPlayer return 0; } + /** + * Returns the spell ID of the [Player]'s last [Pet] summoning spell. + * + * @return uint32 petSpell : the pet spell ID + */ + int GetLastPetSpell(lua_State* L, Player* player) + { + Eluna::Push(L, player->GetLastPetSpell()); + return 1; + } + /** * Returns the [Player]'s runes state for Death Knights. * @@ -4464,6 +4700,18 @@ namespace LuaPlayer return 1; } + /** + * Sets the spell ID of the [Player]'s last [Pet] summoning spell. + * + * @param uint32 petSpell : the pet spell ID to set + */ + int SetLastPetSpell(lua_State* L, Player* player) + { + uint32 petSpell = Eluna::CHECKVAL(L, 2); + player->SetLastPetSpell(petSpell); + return 0; + } + /** * Returns `true` if the [Player] is a spectator, `false` otherwise. * @@ -4487,6 +4735,17 @@ namespace LuaPlayer return 0; } + /** + * Returns `true` if the [Player] can see Death Knight [Pet]s, and `false` otherwise. + * + * @return bool canSeeDKPet + */ + int CanSeeDKPet(lua_State* L, Player* player) + { + Eluna::Push(L, player->CanSeeDKPet()); + return 1; + } + /** * Returns the [Player]'s current viewpoint target. * @@ -4498,6 +4757,18 @@ namespace LuaPlayer return 1; } + /** + * Sets whether the [Player] can see Death Knight [Pet]s. + * + * @param bool show : `true` to show DK pets, `false` to hide them + */ + int SetShowDKPet(lua_State* L, Player* player) + { + bool show = Eluna::CHECKVAL(L, 2); + player->SetShowDKPet(show); + return 0; + } + /** * Sets the [Player]'s viewpoint to the specified target. * @@ -4607,21 +4878,6 @@ namespace LuaPlayer Eluna::Push(L, player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot + BANK_SLOT_ITEM_START)); return 1; } - - // /** - // * Returns `true` if the [Player] has a spell mod for the specified spell and operation, `false` otherwise. - // * - // * @param uint32 spellId : the spell ID to check - // * @param uint32 op : the spell mod operation type - // * @return bool hasSpellMod - // */ - // int HasSpellMod(lua_State* L, Player* player) - // { - // uint32 spellId = Eluna::CHECKVAL(L, 2); - // uint32 op = Eluna::CHECKVAL(L, 3); - // Eluna::Push(L, player->HasSpellMod(spellId, SpellModOp(op))); - // return 1; - // } }; #endif