/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "ScriptMgr.h" #include "Chat.h" #include "ChatCommand.h" #include "Language.h" #include "Map.h" #include "Pet.h" #include "Player.h" #include "RBAC.h" #include "SpellInfo.h" #include "SpellMgr.h" #include "WorldSession.h" using namespace Trinity::ChatCommands; inline Pet* GetSelectedPlayerPetOrOwn(ChatHandler* handler) { if (Unit* target = handler->getSelectedUnit()) { if (target->GetTypeId() == TYPEID_PLAYER) return target->ToPlayer()->GetPet(); if (target->IsPet()) return target->ToPet(); return nullptr; } Player* player = handler->GetSession()->GetPlayer(); return player ? player->GetPet() : nullptr; } class pet_commandscript : public CommandScript { public: pet_commandscript() : CommandScript("pet_commandscript") { } ChatCommandTable GetCommands() const override { static ChatCommandTable petCommandTable = { { "create", HandlePetCreateCommand, rbac::RBAC_PERM_COMMAND_PET_CREATE, Console::No }, { "learn", HandlePetLearnCommand, rbac::RBAC_PERM_COMMAND_PET_LEARN, Console::No }, { "unlearn", HandlePetUnlearnCommand, rbac::RBAC_PERM_COMMAND_PET_UNLEARN, Console::No }, { "level", HandlePetLevelCommand, rbac::RBAC_PERM_COMMAND_PET_LEVEL, Console::No }, }; static ChatCommandTable commandTable = { { "pet", petCommandTable }, }; return commandTable; } static bool HandlePetCreateCommand(ChatHandler* handler) { Player* player = handler->GetSession()->GetPlayer(); Creature* creatureTarget = handler->getSelectedCreature(); if (!creatureTarget || creatureTarget->IsPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) { handler->PSendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } CreatureTemplate const* creatureTemplate = creatureTarget->GetCreatureTemplate(); // Creatures with family CREATURE_FAMILY_NONE crashes the server if (creatureTemplate->family == CREATURE_FAMILY_NONE) { handler->PSendSysMessage("This creature cannot be tamed. Family id: 0 (CREATURE_FAMILY_NONE)."); handler->SetSentErrorMessage(true); return false; } if (!player->GetPetGUID().IsEmpty()) { handler->PSendSysMessage("You already have a pet"); handler->SetSentErrorMessage(true); return false; } // Everything looks OK, create new pet Pet* pet = player->CreateTamedPetFrom(creatureTarget); // "kill" original creature creatureTarget->DespawnOrUnsummon(); // prepare visual effect for levelup pet->SetLevel(player->GetLevel() - 1); // add to world pet->GetMap()->AddToMap(pet->ToCreature()); // visual effect for levelup pet->SetLevel(player->GetLevel()); // caster have pet now player->SetMinion(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); return true; } static bool HandlePetLearnCommand(ChatHandler* handler, SpellInfo const* spellInfo) { Pet* pet = GetSelectedPlayerPetOrOwn(handler); if (!pet) { handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET); handler->SetSentErrorMessage(true); return false; } uint32 spellId = spellInfo->Id; // Check if pet already has it if (pet->HasSpell(spellId)) { handler->PSendSysMessage("Pet already has spell: %u", spellId); handler->SetSentErrorMessage(true); return false; } // Check if spell is valid if (!SpellMgr::IsSpellValid(spellInfo)) { handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); handler->SetSentErrorMessage(true); return false; } pet->learnSpell(spellId); handler->PSendSysMessage("Pet has learned spell %u", spellId); return true; } static bool HandlePetUnlearnCommand(ChatHandler* handler, SpellInfo const* spellInfo) { Pet* pet = GetSelectedPlayerPetOrOwn(handler); if (!pet) { handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET); handler->SetSentErrorMessage(true); return false; } uint32 spellId = spellInfo->Id; if (pet->HasSpell(spellId)) pet->removeSpell(spellId, false); else handler->PSendSysMessage("Pet doesn't have that spell"); return true; } static bool HandlePetLevelCommand(ChatHandler* handler, Optional level) { Pet* pet = GetSelectedPlayerPetOrOwn(handler); Player* owner = pet ? pet->GetOwner() : nullptr; if (!pet || !owner) { handler->SendSysMessage(LANG_SELECT_PLAYER_OR_PET); handler->SetSentErrorMessage(true); return false; } if (!level) level = owner->GetLevel() - pet->GetLevel(); if (level == 0 || level < -STRONG_MAX_LEVEL || level > STRONG_MAX_LEVEL) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } int32 newLevel = pet->GetLevel() + *level; if (newLevel < 1) newLevel = 1; else if (newLevel > owner->GetLevel()) newLevel = owner->GetLevel(); pet->GivePetLevel(newLevel); return true; } }; void AddSC_pet_commandscript() { new pet_commandscript(); }