/* * 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 . */ /* ScriptData Name: reset_commandscript %Complete: 100 Comment: All reset related commands Category: commandscripts EndScriptData */ #include "ScriptMgr.h" #include "AchievementMgr.h" #include "Chat.h" #include "ChatCommand.h" #include "DatabaseEnv.h" #include "DB2Stores.h" #include "Language.h" #include "Log.h" #include "ObjectAccessor.h" #include "Pet.h" #include "Player.h" #include "RBAC.h" #include "World.h" #include "WorldSession.h" #if TRINITY_COMPILER == TRINITY_COMPILER_GNU #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif class reset_commandscript : public CommandScript { public: reset_commandscript() : CommandScript("reset_commandscript") { } std::vector GetCommands() const override { static std::vector resetCommandTable = { { "achievements", rbac::RBAC_PERM_COMMAND_RESET_ACHIEVEMENTS, true, &HandleResetAchievementsCommand, "" }, { "honor", rbac::RBAC_PERM_COMMAND_RESET_HONOR, true, &HandleResetHonorCommand, "" }, { "level", rbac::RBAC_PERM_COMMAND_RESET_LEVEL, true, &HandleResetLevelCommand, "" }, { "spells", rbac::RBAC_PERM_COMMAND_RESET_SPELLS, true, &HandleResetSpellsCommand, "" }, { "stats", rbac::RBAC_PERM_COMMAND_RESET_STATS, true, &HandleResetStatsCommand, "" }, { "talents", rbac::RBAC_PERM_COMMAND_RESET_TALENTS, true, &HandleResetTalentsCommand, "" }, { "all", rbac::RBAC_PERM_COMMAND_RESET_ALL, true, &HandleResetAllCommand, "" }, }; static std::vector commandTable = { { "reset", rbac::RBAC_PERM_COMMAND_RESET, true, nullptr, "", resetCommandTable }, }; return commandTable; } static bool HandleResetAchievementsCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid targetGuid; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) return false; if (target) target->ResetAchievements(); else PlayerAchievementMgr::DeleteFromDB(targetGuid); return true; } static bool HandleResetHonorCommand(ChatHandler* handler, char const* args) { Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; target->ResetHonorStats(); target->UpdateCriteria(CriteriaType::HonorableKills); return true; } static bool HandleResetStatsOrLevelHelper(Player* player) { ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(player->GetClass()); if (!classEntry) { TC_LOG_ERROR("misc", "Class {} not found in DBC (Wrong DBC files?)", player->GetClass()); return false; } uint8 powerType = classEntry->DisplayPower; // reset m_form if no aura if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) player->SetShapeshiftForm(FORM_NONE); player->SetFactionForRace(player->GetRace()); player->SetPowerType(Powers(powerType)); // reset only if player not in some form; if (player->GetShapeshiftForm() == FORM_NONE) player->InitDisplayIds(); player->ReplaceAllPvpFlags(UNIT_BYTE2_FLAG_PVP); player->ReplaceAllUnitFlags(UNIT_FLAG_PLAYER_CONTROLLED); //-1 is default value player->SetWatchedFactionIndex(-1); return true; } static bool HandleResetLevelCommand(ChatHandler* handler, char const* args) { Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; if (!HandleResetStatsOrLevelHelper(target)) return false; uint8 oldLevel = target->GetLevel(); // set starting level uint8 startLevel = target->GetStartLevel(target->GetRace(), target->GetClass(), {}); target->_ApplyAllLevelScaleItemMods(false); target->SetLevel(startLevel); target->InitRunes(); target->InitStatsForLevel(true); target->InitTaxiNodesForLevel(); target->InitTalentForLevel(); target->SetXP(0); target->_ApplyAllLevelScaleItemMods(true); // reset level for pet if (Pet* pet = target->GetPet()) pet->SynchronizeLevelWithOwner(); sScriptMgr->OnPlayerLevelChanged(target, oldLevel); return true; } static bool HandleResetSpellsCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid targetGuid; std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; if (target) { target->ResetSpells(/* bool myClassOnly */); ChatHandler(target->GetSession()).SendSysMessage(LANG_RESET_SPELLS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) handler->PSendSysMessage(LANG_RESET_SPELLS_ONLINE, handler->GetNameLink(target).c_str()); } else { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS)); stmt->setUInt64(1, targetGuid.GetCounter()); CharacterDatabase.Execute(stmt); handler->PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str()); } return true; } static bool HandleResetStatsCommand(ChatHandler* handler, char const* args) { Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; if (!HandleResetStatsOrLevelHelper(target)) return false; target->InitRunes(); target->InitStatsForLevel(true); target->InitTaxiNodesForLevel(); target->InitTalentForLevel(); return true; } static bool HandleResetTalentsCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid targetGuid; std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) { /* TODO: 6.x remove/update pet talents // Try reset talents as Hunter Pet Creature* creature = handler->getSelectedCreature(); if (!*args && creature && creature->IsPet()) { Unit* owner = creature->GetOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer())) { creature->ToPet()->resetTalents(); owner->ToPlayer()->SendTalentsInfoData(true); ChatHandler(owner->ToPlayer()->GetSession()).SendSysMessage(LANG_RESET_PET_TALENTS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != owner->ToPlayer()) handler->PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, handler->GetNameLink(owner->ToPlayer()).c_str()); } return true; } */ handler->SendSysMessage(LANG_NO_CHAR_SELECTED); handler->SetSentErrorMessage(true); return false; } if (target) { target->ResetTalents(true); target->ResetTalentSpecialization(); target->SendTalentsInfoData(); ChatHandler(target->GetSession()).SendSysMessage(LANG_RESET_TALENTS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) handler->PSendSysMessage(LANG_RESET_TALENTS_ONLINE, handler->GetNameLink(target).c_str()); /* TODO: 6.x remove/update pet talents Pet* pet = target->GetPet(); Pet::resetTalentsForAllPetsOf(target, pet); if (pet) target->SendTalentsInfoData(true); */ return true; } else if (!targetGuid.IsEmpty()) { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS)); stmt->setUInt64(1, targetGuid.GetCounter()); CharacterDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); handler->PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str()); return true; } handler->SendSysMessage(LANG_NO_CHAR_SELECTED); handler->SetSentErrorMessage(true); return false; } static bool HandleResetAllCommand(ChatHandler* handler, char const* args) { if (!*args) return false; std::string caseName = args; AtLoginFlags atLogin; // Command specially created as single command to prevent using short case names if (caseName == "spells") { atLogin = AT_LOGIN_RESET_SPELLS; sWorld->SendWorldText(LANG_RESETALL_SPELLS); if (!handler->GetSession()) handler->SendSysMessage(LANG_RESETALL_SPELLS); } else if (caseName == "talents") { atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS); sWorld->SendWorldText(LANG_RESETALL_TALENTS); if (!handler->GetSession()) handler->SendSysMessage(LANG_RESETALL_TALENTS); } else { handler->PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args); handler->SetSentErrorMessage(true); return false; } CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS); stmt->setUInt16(0, uint16(atLogin)); CharacterDatabase.Execute(stmt); std::shared_lock lock(*HashMapHolder::GetLock()); HashMapHolder::MapType const& plist = ObjectAccessor::GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) itr->second->SetAtLoginFlag(atLogin); return true; } }; void AddSC_reset_commandscript() { new reset_commandscript(); }