From b0c8eceb08b9a7688893991e5ba4a3350617e6ed Mon Sep 17 00:00:00 2001 From: Yehonal Date: Fri, 12 Aug 2016 00:46:43 +0200 Subject: Refactoring part 2 [W.I.P] --- src/scripts/Commands/cs_learn.cpp | 528 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 528 insertions(+) create mode 100644 src/scripts/Commands/cs_learn.cpp (limited to 'src/scripts/Commands/cs_learn.cpp') diff --git a/src/scripts/Commands/cs_learn.cpp b/src/scripts/Commands/cs_learn.cpp new file mode 100644 index 0000000000..5fd16c6f1a --- /dev/null +++ b/src/scripts/Commands/cs_learn.cpp @@ -0,0 +1,528 @@ +/* + * Copyright (C) + * + * 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: learn_commandscript +%Complete: 100 +Comment: All learn related commands +Category: commandscripts +EndScriptData */ + +#include "Chat.h" +#include "ScriptMgr.h" +#include "ObjectMgr.h" +#include "Language.h" +#include "SpellMgr.h" +#include "SpellInfo.h" +#include "Player.h" +#include "Pet.h" + +class learn_commandscript : public CommandScript +{ +public: + learn_commandscript() : CommandScript("learn_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand learnAllMyCommandTable[] = + { + { "class", SEC_ADMINISTRATOR, false, &HandleLearnAllMyClassCommand, "", NULL }, + { "pettalents", SEC_ADMINISTRATOR, false, &HandleLearnAllMyPetTalentsCommand, "", NULL }, + { "spells", SEC_ADMINISTRATOR, false, &HandleLearnAllMySpellsCommand, "", NULL }, + { "talents", SEC_ADMINISTRATOR, false, &HandleLearnAllMyTalentsCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand learnAllCommandTable[] = + { + { "my", SEC_ADMINISTRATOR, false, NULL, "", learnAllMyCommandTable }, + { "gm", SEC_GAMEMASTER, false, &HandleLearnAllGMCommand, "", NULL }, + { "crafts", SEC_GAMEMASTER, false, &HandleLearnAllCraftsCommand, "", NULL }, + { "default", SEC_GAMEMASTER, false, &HandleLearnAllDefaultCommand, "", NULL }, + { "lang", SEC_GAMEMASTER, false, &HandleLearnAllLangCommand, "", NULL }, + { "recipes", SEC_GAMEMASTER, false, &HandleLearnAllRecipesCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand learnCommandTable[] = + { + { "all", SEC_ADMINISTRATOR, false, NULL, "", learnAllCommandTable }, + { "", SEC_ADMINISTRATOR, false, &HandleLearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "learn", SEC_GAMEMASTER, false, NULL, "", learnCommandTable }, + { "unlearn", SEC_ADMINISTRATOR, false, &HandleUnLearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleLearnCommand(ChatHandler* handler, char const* args) + { + Player* targetPlayer = handler->getSelectedPlayer(); + + if (!targetPlayer) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = handler->extractSpellIdFromLink((char*)args); + if (!spell) + return false; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); + if (!spellInfo) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (!SpellMgr::IsSpellValid(spellInfo)) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); + handler->SetSentErrorMessage(true); + return false; + } + + SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spell); + uint32 spellDifficultyId = sSpellMgr->GetSpellDifficultyId(spell); + if (handler->GetSession()->GetSecurity() < SEC_CONSOLE && (bounds.first != bounds.second || spellDifficultyId)) + { + handler->PSendSysMessage("Spell %u cannot be learnt using a command!", spell); + handler->SetSentErrorMessage(true); + return false; + } + + char const* all = strtok(NULL, " "); + bool allRanks = all ? (strncmp(all, "all", strlen(all)) == 0) : false; + + if (!allRanks && targetPlayer->HasSpell(spell)) + { + if (targetPlayer == handler->GetSession()->GetPlayer()) + handler->SendSysMessage(LANG_YOU_KNOWN_SPELL); + else + handler->PSendSysMessage(LANG_TARGET_KNOWN_SPELL, handler->GetNameLink(targetPlayer).c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (allRanks) + targetPlayer->learnSpellHighRank(spell); + else + targetPlayer->learnSpell(spell); + + uint32 firstSpell = sSpellMgr->GetFirstSpellInChain(spell); + if (GetTalentSpellCost(firstSpell)) + targetPlayer->SendTalentsInfoData(false); + + return true; + } + + static bool HandleLearnAllGMCommand(ChatHandler* handler, char const* /*args*/) + { + for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) + continue; + + if (!spellInfo->IsAbilityOfSkillType(SKILL_INTERNAL)) + continue; + + handler->GetSession()->GetPlayer()->learnSpell(i); + } + + handler->SendSysMessage(LANG_LEARNING_GM_SKILLS); + return true; + } + + static bool HandleLearnAllMyClassCommand(ChatHandler* handler, char const* /*args*/) + { + HandleLearnAllMySpellsCommand(handler, ""); + HandleLearnAllMyTalentsCommand(handler, ""); + return true; + } + + static bool HandleLearnAllMySpellsCommand(ChatHandler* handler, char const* /*args*/) + { + ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(handler->GetSession()->GetPlayer()->getClass()); + if (!classEntry) + return true; + uint32 family = classEntry->spellfamily; + + for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i) + { + SkillLineAbilityEntry const* entry = sSkillLineAbilityStore.LookupEntry(i); + if (!entry) + continue; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->spellId); + if (!spellInfo) + continue; + + // skip server-side/triggered spells + if (spellInfo->SpellLevel == 0) + continue; + + // skip wrong class/race skills + if (!handler->GetSession()->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id)) + continue; + + // skip other spell families + if (spellInfo->SpellFamilyName != family) + continue; + + // skip spells with first rank learned as talent (and all talents then also) + uint32 firstRank = sSpellMgr->GetFirstSpellInChain(spellInfo->Id); + if (GetTalentSpellCost(firstRank) > 0) + continue; + + // skip broken spells + if (!SpellMgr::IsSpellValid(spellInfo)) + continue; + + handler->GetSession()->GetPlayer()->learnSpell(spellInfo->Id); + } + + handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); + return true; + } + + static bool HandleLearnAllMyTalentsCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + uint32 classMask = player->getClassMask(); + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) + continue; + + TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); + if (!talentTabInfo) + continue; + + if ((classMask & talentTabInfo->ClassMask) == 0) + continue; + + // xinef: search highest talent rank + uint32 spellId = 0; + uint8 rankId = MAX_TALENT_RANK; + for (int8 rank = MAX_TALENT_RANK - 1; rank >= 0; --rank) + { + if (talentInfo->RankID[rank] != 0) + { + rankId = rank; + spellId = talentInfo->RankID[rank]; + break; + } + } + + // xinef: some errors? + if (!spellId || rankId == MAX_TALENT_RANK) + continue; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) + continue; + + player->LearnTalent(talentInfo->TalentID, rankId); + } + + handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); + return true; + } + + static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + Pet* pet = player->GetPet(); + if (!pet) + { + handler->SendSysMessage(LANG_NO_PET_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* creatureInfo = pet->GetCreatureTemplate(); + if (!creatureInfo) + { + handler->SendSysMessage(LANG_WRONG_PET_TYPE); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureFamilyEntry const* petFamily = sCreatureFamilyStore.LookupEntry(creatureInfo->family); + if (!petFamily) + { + handler->SendSysMessage(LANG_WRONG_PET_TYPE); + handler->SetSentErrorMessage(true); + return false; + } + + if (petFamily->petTalentType < 0) // not hunter pet + { + handler->SendSysMessage(LANG_WRONG_PET_TYPE); + handler->SetSentErrorMessage(true); + return false; + } + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) + continue; + + TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); + if (!talentTabInfo) + continue; + + // prevent learn talent for different family (cheating) + if (((1 << petFamily->petTalentType) & talentTabInfo->petTalentMask) == 0) + continue; + + // search highest talent rank + uint32 spellId = 0; + + for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank) + { + if (talentInfo->RankID[rank] != 0) + { + spellId = talentInfo->RankID[rank]; + break; + } + } + + if (!spellId) // ??? none spells in talent + continue; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) + continue; + + // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) + pet->learnSpellHighRank(spellId); + } + + pet->SetFreeTalentPoints(0); + + handler->SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); + return true; + } + + static bool HandleLearnAllLangCommand(ChatHandler* handler, char const* /*args*/) + { + // skipping UNIVERSAL language (0) + for (uint8 i = 1; i < LANGUAGES_COUNT; ++i) + handler->GetSession()->GetPlayer()->learnSpell(lang_description[i].spell_id); + + handler->SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); + return true; + } + + static bool HandleLearnAllDefaultCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + target->learnDefaultSpells(); + target->learnQuestRewardedSpells(); + + handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST, handler->GetNameLink(target).c_str()); + return true; + } + + static bool HandleLearnAllCraftsCommand(ChatHandler* handler, char const* /*args*/) + { + for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) + { + SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i); + if (!skillInfo) + continue; + + if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) && + skillInfo->canLink) // only prof. with recipes have + { + HandleLearnSkillRecipesHelper(handler->GetSession()->GetPlayer(), skillInfo->id); + } + } + + handler->SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT); + return true; + } + + static bool HandleLearnAllRecipesCommand(ChatHandler* handler, char const* args) + { + // Learns all recipes of specified profession and sets skill to max + // Example: .learn all_recipes enchanting + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + return false; + } + + if (!*args) + return false; + + std::wstring namePart; + + if (!Utf8toWStr(args, namePart)) + return false; + + // converting string that we try to find to lower case + wstrToLower(namePart); + + std::string name; + + SkillLineEntry const* targetSkillInfo = NULL; + for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i) + { + SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i); + if (!skillInfo) + continue; + + if ((skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && + skillInfo->categoryId != SKILL_CATEGORY_SECONDARY) || + !skillInfo->canLink) // only prof with recipes have set + continue; + + int locale = handler->GetSessionDbcLocale(); + name = skillInfo->name[locale]; + if (name.empty()) + continue; + + if (!Utf8FitTo(name, namePart)) + { + locale = 0; + for (; locale < TOTAL_LOCALES; ++locale) + { + if (locale == handler->GetSessionDbcLocale()) + continue; + + name = skillInfo->name[locale]; + if (name.empty()) + continue; + + if (Utf8FitTo(name, namePart)) + break; + } + } + + if (locale < TOTAL_LOCALES) + { + targetSkillInfo = skillInfo; + break; + } + } + + if (!targetSkillInfo) + return false; + + HandleLearnSkillRecipesHelper(target, targetSkillInfo->id); + + uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->id); + target->SetSkill(targetSkillInfo->id, target->GetSkillStep(targetSkillInfo->id), maxLevel, maxLevel); + handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); + return true; + } + + static void HandleLearnSkillRecipesHelper(Player* player, uint32 skillId) + { + uint32 classmask = player->getClassMask(); + + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + { + SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); + if (!skillLine) + continue; + + // wrong skill + if (skillLine->skillId != skillId) + continue; + + // not high rank + if (skillLine->forward_spellid) + continue; + + // skip racial skills + if (skillLine->racemask != 0) + continue; + + // skip wrong class skills + if (skillLine->classmask && (skillLine->classmask & classmask) == 0) + continue; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(skillLine->spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) + continue; + + player->learnSpell(skillLine->spellId); + } + } + + static bool HandleUnLearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + char const* allStr = strtok(NULL, " "); + bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (allRanks) + spellId = sSpellMgr->GetFirstSpellInChain (spellId); + + if (target->HasSpell(spellId)) + target->removeSpell(spellId, SPEC_MASK_ALL, false); + else + handler->SendSysMessage(LANG_FORGET_SPELL); + + if (GetTalentSpellCost(spellId)) + target->SendTalentsInfoData(false); + + return true; + } +}; + +void AddSC_learn_commandscript() +{ + new learn_commandscript(); +} -- cgit v1.2.3