/* * Copyright (C) 2012-2020 CypherCore * * 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 3 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 . */ using Framework.Constants; using Framework.IO; using Game.DataStorage; using Game.Entities; using Game.Spells; using System; using System.Collections.Generic; namespace Game.Chat.Commands { [CommandGroup("learn")] class LearnCommands { [Command("", RBACPermissions.CommandLearn)] static bool HandleLearnCommand(CommandHandler handler, StringArguments args) { Player targetPlayer = handler.GetSelectedPlayerOrSelf(); if (!targetPlayer) { handler.SendSysMessage(CypherStrings.PlayerNotFound); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint spell = handler.ExtractSpellIdFromLink(args); if (spell == 0 || !Global.SpellMgr.HasSpellInfo(spell, Difficulty.None)) return false; string all = args.NextString(); bool allRanks = !string.IsNullOrEmpty(all) && all == "all"; SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell, Difficulty.None); if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer())) { handler.SendSysMessage(CypherStrings.CommandSpellBroken, spell); return false; } if (!allRanks && targetPlayer.HasSpell(spell)) { if (targetPlayer == handler.GetSession().GetPlayer()) handler.SendSysMessage(CypherStrings.YouKnownSpell); else handler.SendSysMessage(CypherStrings.TargetKnownSpell, handler.GetNameLink(targetPlayer)); return false; } if (allRanks) targetPlayer.LearnSpellHighestRank(spell); else targetPlayer.LearnSpell(spell, false); return true; } [CommandGroup("all")] class LearnAllCommands { [Command("gm", RBACPermissions.CommandLearnAllGm)] static bool HandleLearnAllGMCommand(CommandHandler handler, StringArguments args) { foreach (var skillSpell in Global.SpellMgr.GetSkillLineAbilityMapBounds((uint)SkillType.Internal)) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(skillSpell.Spell, Difficulty.None); if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer(), false)) continue; handler.GetSession().GetPlayer().LearnSpell(skillSpell.Spell, false); } handler.SendSysMessage(CypherStrings.LearningGmSkills); return true; } [Command("lang", RBACPermissions.CommandLearnAllLang)] static bool HandleLearnAllLangCommand(CommandHandler handler, StringArguments args) { // skipping UNIVERSAL language (0) Global.LanguageMgr.ForEachLanguage((lang, languageDesc) => { if (languageDesc.SpellId != 0) handler.GetSession().GetPlayer().LearnSpell(languageDesc.SpellId, false); return true; }); handler.SendSysMessage(CypherStrings.CommandLearnAllLang); return true; } [Command("default", RBACPermissions.CommandLearnAllDefault)] static bool HandleLearnAllDefaultCommand(CommandHandler handler, StringArguments args) { Player target; if (!handler.ExtractPlayerTarget(args, out target)) return false; target.LearnDefaultSkills(); target.LearnCustomSpells(); target.LearnQuestRewardedSpells(); handler.SendSysMessage(CypherStrings.CommandLearnAllDefaultAndQuest, handler.GetNameLink(target)); return true; } [Command("crafts", RBACPermissions.CommandLearnAllCrafts)] static bool HandleLearnAllCraftsCommand(CommandHandler handler, StringArguments args) { Player target; if (!handler.ExtractPlayerTarget(args, out target)) return false; foreach (var skillInfo in CliDB.SkillLineStorage.Values) { if ((skillInfo.CategoryID == SkillCategory.Profession || skillInfo.CategoryID == SkillCategory.Secondary) && skillInfo.CanLink != 0) // only prof. with recipes have { HandleLearnSkillRecipesHelper(target, skillInfo.Id); } } handler.SendSysMessage(CypherStrings.CommandLearnAllCraft); return true; } [Command("recipes", RBACPermissions.CommandLearnAllRecipes)] static bool HandleLearnAllRecipesCommand(CommandHandler handler, StringArguments 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(CypherStrings.PlayerNotFound); return false; } if (args.Empty()) return false; // converting string that we try to find to lower case string namePart = args.NextString().ToLower(); string name = ""; uint skillId = 0; foreach (var skillInfo in CliDB.SkillLineStorage.Values) { if ((skillInfo.CategoryID != SkillCategory.Profession && skillInfo.CategoryID != SkillCategory.Secondary) || skillInfo.CanLink == 0) // only prof with recipes have set continue; Locale locale = handler.GetSessionDbcLocale(); name = skillInfo.DisplayName[locale]; if (string.IsNullOrEmpty(name)) continue; if (!name.Like(namePart)) { locale = 0; for (; locale < Locale.Total; ++locale) { if (locale == handler.GetSessionDbcLocale()) continue; name = skillInfo.DisplayName[locale]; if (name.IsEmpty()) continue; if (name.Like(namePart)) break; } } if (locale < Locale.Total) { skillId = skillInfo.Id; break; } } if (skillId == 0) return false; HandleLearnSkillRecipesHelper(target, skillId); ushort maxLevel = target.GetPureMaxSkillValue((SkillType)skillId); target.SetSkill(skillId, target.GetSkillStep((SkillType)skillId), maxLevel, maxLevel); handler.SendSysMessage(CypherStrings.CommandLearnAllRecipes, name); return true; } static void HandleLearnSkillRecipesHelper(Player player, uint skillId) { uint classmask = player.GetClassMask(); foreach (var skillLine in CliDB.SkillLineAbilityStorage.Values) { // wrong skill if (skillLine.SkillLine != skillId) continue; // not high rank if (skillLine.SupercedesSpell != 0) continue; // skip racial skills if (skillLine.RaceMask != 0) continue; // skip wrong class skills if (skillLine.ClassMask != 0 && (skillLine.ClassMask & classmask) == 0) continue; SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(skillLine.Spell, Difficulty.None); if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, player, false)) continue; player.LearnSpell(skillLine.Spell, false); } } [CommandGroup("my")] class LearnAllMyCommands { [Command("class", RBACPermissions.CommandLearnAllMyClass)] static bool HandleLearnAllMyClassCommand(CommandHandler handler, StringArguments args) { HandleLearnAllMySpellsCommand(handler, args); HandleLearnAllMyTalentsCommand(handler, args); return true; } [Command("spells", RBACPermissions.CommandLearnAllMySpells)] static bool HandleLearnAllMySpellsCommand(CommandHandler handler, StringArguments args) { ChrClassesRecord classEntry = CliDB.ChrClassesStorage.LookupByKey(handler.GetSession().GetPlayer().GetClass()); if (classEntry == null) return true; uint family = classEntry.SpellClassSet; foreach (var entry in CliDB.SkillLineAbilityStorage.Values) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(entry.Spell, Difficulty.None); if (spellInfo == null) 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 ((uint)spellInfo.SpellFamilyName != family) continue; // skip broken spells if (!Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer(), false)) continue; handler.GetSession().GetPlayer().LearnSpell(spellInfo.Id, false); } handler.SendSysMessage(CypherStrings.CommandLearnClassSpells); return true; } [Command("talents", RBACPermissions.CommandLearnAllMyTalents)] static bool HandleLearnAllMyTalentsCommand(CommandHandler handler, StringArguments args) { Player player = handler.GetSession().GetPlayer(); uint playerClass = (uint)player.GetClass(); foreach (var talentInfo in CliDB.TalentStorage.Values) { if (playerClass != talentInfo.ClassID) continue; SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None); if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer(), false)) continue; // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) player.LearnSpellHighestRank(talentInfo.SpellID); player.AddTalent(talentInfo, player.GetActiveTalentGroup(), true); } handler.SendSysMessage(CypherStrings.CommandLearnClassTalents); return true; } [Command("pettalents", RBACPermissions.CommandLearnAllMyPettalents)] static bool HandleLearnAllMyPetTalentsCommand(CommandHandler handler, StringArguments args) { return true; } } } [CommandNonGroup("unlearn", RBACPermissions.CommandUnlearn)] static bool HandleUnLearnCommand(CommandHandler handler, StringArguments args) { if (args.Empty()) return false; // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r uint spellId = handler.ExtractSpellIdFromLink(args); if (spellId == 0) return false; string allStr = args.NextString(); bool allRanks = !string.IsNullOrEmpty(allStr) && allStr == "all"; Player target = handler.GetSelectedPlayer(); if (!target) { handler.SendSysMessage(CypherStrings.NoCharSelected); return false; } if (allRanks) spellId = Global.SpellMgr.GetFirstSpellInChain(spellId); if (target.HasSpell(spellId)) target.RemoveSpell(spellId, false, !allRanks); else handler.SendSysMessage(CypherStrings.ForgetSpell); return true; } } }