diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Accounts/RBAC.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Trainer.h | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 14 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_learn.cpp | 229 |
8 files changed, 131 insertions, 141 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 4895fba28fa..5ea0062d7bc 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -286,9 +286,9 @@ enum RBACPermissions // 418 previously used, do not reuse RBAC_PERM_COMMAND_LEARN_ALL_MY = 419, RBAC_PERM_COMMAND_LEARN_ALL_MY_CLASS = 420, - RBAC_PERM_COMMAND_LEARN_ALL_MY_PETTALENTS = 421, + RBAC_PERM_COMMAND_LEARN_MY_PETTALENTS = 421, RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS = 422, - RBAC_PERM_COMMAND_LEARN_ALL_MY_TALENTS = 423, + RBAC_PERM_COMMAND_LEARN_ALL_TALENTS = 423, RBAC_PERM_COMMAND_LEARN_ALL_GM = 424, RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS = 425, RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT = 426, diff --git a/src/server/game/Entities/Creature/Trainer.h b/src/server/game/Entities/Creature/Trainer.h index 6aa58bc9b7e..dc7b199ad54 100644 --- a/src/server/game/Entities/Creature/Trainer.h +++ b/src/server/game/Entities/Creature/Trainer.h @@ -50,7 +50,7 @@ namespace Trainer NotEnoughSkill = 2 }; - struct Spell + struct TC_GAME_API Spell { uint32 SpellId = 0; uint32 MoneyCost = 0; @@ -62,12 +62,15 @@ namespace Trainer bool IsCastable() const; }; - class Trainer + class TC_GAME_API Trainer { public: Trainer(uint32 trainerId, Type type, uint32 requirement, std::string greeting, std::vector<Spell> spells); + Spell const* GetSpell(uint32 spellId) const; + std::vector<Spell> const& GetSpells() const { return _spells; } void SendSpells(Creature const* npc, Player const* player, LocaleConstant locale) const; + bool CanTeachSpell(Player const* player, Spell const* trainerSpell) const; void TeachSpell(Creature const* npc, Player* player, uint32 spellId) const; Type GetTrainerType() const { return _type; } @@ -75,8 +78,6 @@ namespace Trainer bool IsTrainerValidForPlayer(Player const* player) const; private: - Spell const* GetSpell(uint32 spellId) const; - bool CanTeachSpell(Player const* player, Spell const* trainerSpell) const; SpellState GetSpellState(Player const* player, Spell const* trainerSpell) const; void SendTeachFailure(Creature const* npc, Player const* player, uint32 spellId, FailReason reason) const; void SendTeachSucceeded(Creature const* npc, Player const* player, uint32 spellId) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index df1c2e9ca86..a029ccb8ad5 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -24941,14 +24941,6 @@ bool Player::CanFlyInZone(uint32 mapid, uint32 zone, SpellInfo const* bySpell) c return true; } -void Player::LearnSpellHighestRank(uint32 spellid) -{ - LearnSpell(spellid, false); - - if (uint32 next = sSpellMgr->GetNextSpellInChain(spellid)) - LearnSpellHighestRank(next); -} - void Player::_LoadSkills(PreparedQueryResult result) { // 0 1 2 diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 5cdaa5d3df3..de224434c24 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1428,7 +1428,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void LearnDefaultSkill(uint32 skillId, uint16 rank); void LearnQuestRewardedSpells(); void LearnQuestRewardedSpells(Quest const* quest); - void LearnSpellHighestRank(uint32 spellid); void AddTemporarySpell(uint32 spellId); void RemoveTemporarySpell(uint32 spellId); void SetReputation(uint32 factionentry, uint32 value); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9c1db9e87d7..bb20dadc9b0 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -9208,7 +9208,10 @@ void ObjectMgr::LoadTrainers() break; } - _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells))); + auto [it, isNew] = _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells))); + ASSERT(isNew); + if (trainerType == Trainer::Type::Class) + _classTrainers[requirement].push_back(&it->second); } while (trainersResult->NextRow()); } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 2c611d58aa4..70e9844a89c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1492,6 +1492,7 @@ class TC_GAME_API ObjectMgr bool DeleteGameTele(std::string_view name); Trainer::Trainer const* GetTrainer(uint32 creatureId) const; + std::vector<Trainer::Trainer const*> const& GetClassTrainers(uint8 classId) const { return _classTrainers.at(classId); } VendorItemData const* GetNpcVendorItemList(uint32 entry) const { @@ -1729,6 +1730,7 @@ class TC_GAME_API ObjectMgr CacheVendorItemContainer _cacheVendorItemStore; std::unordered_map<uint32, Trainer::Trainer> _trainers; + std::unordered_map<uint8, std::vector<Trainer::Trainer const*>> _classTrainers; std::unordered_map<uint32, Trainer::Trainer const*> _creatureDefaultTrainers; std::set<uint32> _difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 643699317eb..ebcf71d765c 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -428,7 +428,19 @@ enum TrinityStrings LANG_COMMAND_ACC_LOCK_IP_HELP = 380, LANG_COMMAND_ACC_PASSWORD_HELP = 381, LANG_COMMAND_ACCOUNT_HELP = 382, - // Room for more level 2 383-399 not used + LANG_COMMAND_LEARN_HELP = 383, + LANG_COMMAND_UNLEARN_HELP = 384, + LANG_COMMAND_LEARN_MY_QUESTS_HELP = 385, + LANG_COMMAND_LEARN_MY_TRAINER_HELP = 386, + LANG_COMMAND_LEARN_ALL_BLIZZARD_HELP = 387, + LANG_COMMAND_LEARN_ALL_DEBUG_HELP = 388, + LANG_COMMAND_LEARN_ALL_CRAFTS_HELP = 389, + LANG_COMMAND_LEARN_ALL_DEFAULT_HELP = 390, + LANG_COMMAND_LEARN_ALL_LANGUAGES_HELP = 391, + LANG_COMMAND_LEARN_ALL_RECIPES_HELP = 392, + LANG_COMMAND_LEARN_ALL_TALENTS_HELP = 393, + LANG_COMMAND_LEARN_ALL_PETTALENT_HELP = 394, + // Room for more level 2 395-399 not used // level 3 chat LANG_SCRIPTS_RELOADED = 400, diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index b91e2052692..de6358ac65f 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -34,10 +34,6 @@ EndScriptData */ #include "SpellMgr.h" #include "WorldSession.h" -#if TRINITY_COMPILER == TRINITY_COMPILER_GNU -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - using namespace Trinity::ChatCommands; class learn_commandscript : public CommandScript { @@ -46,39 +42,40 @@ public: ChatCommandTable GetCommands() const override { - static ChatCommandTable learnAllMyCommandTable = + static ChatCommandTable learnAllCommandTable = { - { "class", HandleLearnAllMyClassCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_CLASS, Console::No }, - { "pettalents", HandleLearnAllMyPetTalentsCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_PETTALENTS, Console::No }, - { "spells", HandleLearnAllMySpellsCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS, Console::No }, - { "talents", HandleLearnAllMyTalentsCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_TALENTS, Console::No }, + { "blizzard", HandleLearnAllGMCommand, LANG_COMMAND_LEARN_ALL_BLIZZARD_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_GM, Console::No }, + { "debug", HandleLearnDebugSpellsCommand, LANG_COMMAND_LEARN_ALL_DEBUG_HELP, rbac::RBAC_PERM_COMMAND_LEARN, Console::No }, + { "crafts", HandleLearnAllCraftsCommand, LANG_COMMAND_LEARN_ALL_CRAFTS_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS, Console::No }, + { "default", HandleLearnAllDefaultCommand, LANG_COMMAND_LEARN_ALL_DEFAULT_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT, Console::No }, + { "languages", HandleLearnAllLangCommand, LANG_COMMAND_LEARN_ALL_LANGUAGES_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_LANG, Console::No }, + { "recipes", HandleLearnAllRecipesCommand, LANG_COMMAND_LEARN_ALL_RECIPES_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_RECIPES, Console::No }, + { "talents", HandleLearnAllTalentsCommand, LANG_COMMAND_LEARN_ALL_TALENTS_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_TALENTS, Console::No }, + { "pettalents", HandleLearnAllPetTalentsCommand, LANG_COMMAND_LEARN_ALL_PETTALENT_HELP, rbac::RBAC_PERM_COMMAND_LEARN_MY_PETTALENTS, Console::No }, }; - static ChatCommandTable learnAllCommandTable = + static ChatCommandTable learnMyCommandTable = { - { "my", learnAllMyCommandTable }, - { "gm", HandleLearnAllGMCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_GM, Console::No }, - { "crafts", HandleLearnAllCraftsCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS, Console::No }, - { "default", HandleLearnAllDefaultCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT, Console::No }, - { "lang", HandleLearnAllLangCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_LANG, Console::No }, - { "recipes", HandleLearnAllRecipesCommand, rbac::RBAC_PERM_COMMAND_LEARN_ALL_RECIPES, Console::No }, + { "trainer", HandleLearnMySpellsCommand, LANG_COMMAND_LEARN_MY_TRAINER_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS, Console::No }, + { "quests", HandleLearnMyQuestsCommand, LANG_COMMAND_LEARN_MY_QUESTS_HELP, rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS, Console::No }, }; static ChatCommandTable learnCommandTable = { - { "", HandleLearnCommand, rbac::RBAC_PERM_COMMAND_LEARN, Console::No }, + { "", HandleLearnCommand, LANG_COMMAND_LEARN_HELP, rbac::RBAC_PERM_COMMAND_LEARN, Console::No }, { "all", learnAllCommandTable }, + { "my", learnMyCommandTable } }; static ChatCommandTable commandTable = { { "learn", learnCommandTable }, - { "unlearn", HandleUnLearnCommand, rbac::RBAC_PERM_COMMAND_UNLEARN, Console::No }, + { "unlearn", HandleUnLearnCommand, LANG_COMMAND_UNLEARN_HELP, rbac::RBAC_PERM_COMMAND_UNLEARN, Console::No }, }; return commandTable; } - static bool HandleLearnCommand(ChatHandler* handler, char const* args) + static bool HandleLearnCommand(ChatHandler* handler, SpellInfo const* spell, Optional<EXACT_SEQUENCE("all")> allRanks) { Player* targetPlayer = handler->getSelectedPlayerOrSelf(); @@ -89,25 +86,16 @@ public: 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 || !sSpellMgr->GetSpellInfo(spell)) - return false; - - char const* all = strtok(nullptr, " "); - bool allRanks = all ? (strncmp(all, "all", strlen(all)) == 0) : false; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); - if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) + if (!SpellMgr::IsSpellValid(spell, handler->GetSession()->GetPlayer())) { - handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell->Id); handler->SetSentErrorMessage(true); return false; } - if (!allRanks && targetPlayer->HasSpell(spell)) + if (!allRanks && targetPlayer->HasSpell(spell->Id)) { - if (targetPlayer == handler->GetSession()->GetPlayer()) + if (targetPlayer == handler->GetPlayer()) handler->SendSysMessage(LANG_YOU_KNOWN_SPELL); else handler->PSendSysMessage(LANG_TARGET_KNOWN_SPELL, handler->GetNameLink(targetPlayer).c_str()); @@ -115,18 +103,21 @@ public: return false; } + targetPlayer->LearnSpell(spell->Id, false); if (allRanks) - targetPlayer->LearnSpellHighestRank(spell); - else - targetPlayer->LearnSpell(spell, false); + { + uint32 spellId = spell->Id; + while ((spellId = sSpellMgr->GetNextSpellInChain(spellId))) + targetPlayer->LearnSpell(spellId, false); + } - if (GetTalentSpellCost(spellInfo->GetFirstRankSpell()->Id)) + if (GetTalentSpellCost(spell->GetFirstRankSpell()->Id)) targetPlayer->SendTalentsInfoData(false); return true; } - static bool HandleLearnAllGMCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnAllGMCommand(ChatHandler* handler) { for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) { @@ -144,58 +135,54 @@ public: return true; } - static bool HandleLearnAllMyClassCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnMyQuestsCommand(ChatHandler* handler) { - HandleLearnAllMySpellsCommand(handler, ""); - HandleLearnAllMyTalentsCommand(handler, ""); + Player* player = handler->GetPlayer(); + for (auto const& [id, quest] : sObjectMgr->GetQuestTemplates()) + { + if (quest.GetRequiredClasses() && player->SatisfyQuestClass(&quest, false)) + player->LearnQuestRewardedSpells(&quest); + } return true; } - static bool HandleLearnAllMySpellsCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnMySpellsCommand(ChatHandler* handler) { - ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(handler->GetSession()->GetPlayer()->GetClass()); + ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(handler->GetPlayer()->GetClass()); if (!classEntry) return true; - uint32 family = classEntry->SpellClassSet; - - for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i) - { - SkillLineAbilityEntry const* entry = sSkillLineAbilityStore.LookupEntry(i); - if (!entry) - continue; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Spell); - if (!spellInfo) - continue; - // skip server-side/triggered spells - if (spellInfo->SpellLevel == 0) - continue; + Player* player = handler->GetPlayer(); + std::vector<Trainer::Trainer const*> const& trainers = sObjectMgr->GetClassTrainers(player->GetClass()); - // 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) - if (GetTalentSpellCost(spellInfo->GetFirstRankSpell()->Id) > 0) - continue; + bool hadNew; + do + { + hadNew = false; + for (Trainer::Trainer const* trainer : trainers) + { + if (!trainer->IsTrainerValidForPlayer(player)) + continue; + for (Trainer::Spell const& trainerSpell : trainer->GetSpells()) + { + if (!trainer->CanTeachSpell(player, &trainerSpell)) + continue; - // skip broken spells - if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false)) - continue; + if (trainerSpell.IsCastable()) + player->CastSpell(player, trainerSpell.SpellId, true); + else + player->LearnSpell(trainerSpell.SpellId, false); - handler->GetSession()->GetPlayer()->LearnSpell(spellInfo->Id, false); - } + hadNew = true; + } + } + } while (hadNew); handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); return true; } - static bool HandleLearnAllMyTalentsCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnAllTalentsCommand(ChatHandler* handler) { Player* player = handler->GetSession()->GetPlayer(); uint32 classMask = player->GetClassMask(); @@ -231,18 +218,18 @@ public: if (!spellInfo || !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(spellId); + player->LearnSpell(spellId, false); player->AddTalent(spellId, player->GetActiveSpec(), true); } player->SetFreeTalentPoints(0); + player->SendTalentsInfoData(false); handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); return true; } - static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnAllPetTalentsCommand(ChatHandler* handler) { Player* player = handler->GetSession()->GetPlayer(); @@ -320,22 +307,37 @@ public: return true; } - static bool HandleLearnAllLangCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnAllLangCommand(ChatHandler* handler) { for (LanguageDesc const& langDesc : lang_description) if (uint32 langSpellId = langDesc.spell_id) - handler->GetSession()->GetPlayer()->LearnSpell(langSpellId, false); + handler->GetPlayer()->LearnSpell(langSpellId, false); handler->SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); return true; } - static bool HandleLearnAllDefaultCommand(ChatHandler* handler, char const* args) + static bool HandleLearnDebugSpellsCommand(ChatHandler* handler) { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) + Player* const player = handler->GetPlayer(); + player->LearnSpell(63364, false); /* 63364 - Saronite Barrier (reduces damage taken by 99%) */ + player->LearnSpell(1908, false); /* 1908 - Uber Heal Over Time (heals target to full constantly) */ + player->LearnSpell(27680, false); /* 27680 - Berserk (+500% damage, +150% speed, 10m duration) */ + player->LearnSpell(62555, false); /* 62555 - Berserk (+500% damage, +150% melee haste, 10m duration) */ + player->LearnSpell(64238, false); /* 64238 - Berserk (+900% damage, +150% melee haste, 30m duration) */ + player->LearnSpell(72525, false); /* 72525 - Berserk (+240% damage, +160% haste, infinite duration) */ + player->LearnSpell(66776, false); /* 66776 - Rage (+300% damage, -95% damage taken, +100% speed, infinite duration) */ + return true; + } + + static bool HandleLearnAllDefaultCommand(ChatHandler* handler, Optional<PlayerIdentifier> player) + { + if (!player) + player = PlayerIdentifier::FromTargetOrSelf(handler); + if (!player || !player->IsConnected()) return false; + Player* target = player->GetConnectedPlayer(); target->LearnDefaultSkills(); target->LearnCustomSpells(); target->LearnQuestRewardedSpells(); @@ -344,12 +346,14 @@ public: return true; } - static bool HandleLearnAllCraftsCommand(ChatHandler* handler, char const* args) + static bool HandleLearnAllCraftsCommand(ChatHandler* handler, Optional<PlayerIdentifier> player) { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) + if (!player) + player = PlayerIdentifier::FromTargetOrSelf(handler); + if (!player || !player->IsConnected()) return false; + Player* target = player->GetConnectedPlayer(); for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) { SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i); @@ -367,7 +371,7 @@ public: return true; } - static bool HandleLearnAllRecipesCommand(ChatHandler* handler, char const* args) + static bool HandleLearnAllRecipesCommand(ChatHandler* handler, WTail namePart) { // Learns all recipes of specified profession and sets skill to max // Example: .learn all_recipes enchanting @@ -379,20 +383,14 @@ public: return false; } - if (!*args) - return false; - - std::wstring namePart; - - if (!Utf8toWStr(args, namePart)) + if (namePart.empty()) return false; // converting string that we try to find to lower case wstrToLower(namePart); - std::string name; - SkillLineEntry const* targetSkillInfo = nullptr; + char const* name = nullptr; for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i) { SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i); @@ -404,26 +402,18 @@ public: !skillInfo->CanLink) // only prof with recipes have set continue; - int locale = handler->GetSessionDbcLocale(); - name = skillInfo->DisplayName[locale]; - if (name.empty()) - continue; - - if (!Utf8FitTo(name, namePart)) + uint8 locale = 0; + for (; locale < TOTAL_LOCALES; ++locale) { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; + if (locale == handler->GetSessionDbcLocale()) + continue; - name = skillInfo->DisplayName[locale]; - if (name.empty()) - continue; + name = skillInfo->DisplayName[locale]; + if (!name || !*name) + continue; - if (Utf8FitTo(name, namePart)) - break; - } + if (Utf8FitTo(name, namePart)) + break; } if (locale < TOTAL_LOCALES) @@ -433,14 +423,14 @@ public: } } - if (!targetSkillInfo) + if (!(name && 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()); + handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name); return true; } @@ -478,20 +468,10 @@ public: } } - static bool HandleUnLearnCommand(ChatHandler* handler, char const* args) + static bool HandleUnLearnCommand(ChatHandler* handler, SpellInfo const* spell, Optional<EXACT_SEQUENCE("all")> allRanks) { - 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(nullptr, " "); - bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; - Player* target = handler->getSelectedPlayer(); + if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -499,6 +479,7 @@ public: return false; } + uint32 spellId = spell->Id; if (allRanks) spellId = sSpellMgr->GetFirstSpellInChain(spellId); |