Files
TCPlayerbotCore/src/server/scripts/Commands/cs_learn.cpp
T
Intel da52c8d54e Core/Talents:
Fixed SMSG_TALENTS_INFO packet
Fixed talents saving to DB
Renamed 'talent spec' to 'talent group' since this name was shadowing character specializations (and new name is correct according to JAM)
Enabled loading of MinorTalent.dbc (will be used later)
Added additional specialization check in LearnTalent
2014-11-12 21:43:48 +02:00

469 lines
17 KiB
C++

/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/* 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 override
{
static ChatCommand learnAllMyCommandTable[] =
{
{ "class", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_CLASS, false, &HandleLearnAllMyClassCommand, "", NULL },
{ "pettalents", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_PETTALENTS, false, &HandleLearnAllMyPetTalentsCommand, "", NULL },
{ "spells", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS, false, &HandleLearnAllMySpellsCommand, "", NULL },
{ "talents", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_TALENTS, false, &HandleLearnAllMyTalentsCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand learnAllCommandTable[] =
{
{ "my", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY, false, NULL, "", learnAllMyCommandTable },
{ "gm", rbac::RBAC_PERM_COMMAND_LEARN_ALL_GM, false, &HandleLearnAllGMCommand, "", NULL },
{ "crafts", rbac::RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS, false, &HandleLearnAllCraftsCommand, "", NULL },
{ "default", rbac::RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT, false, &HandleLearnAllDefaultCommand, "", NULL },
{ "lang", rbac::RBAC_PERM_COMMAND_LEARN_ALL_LANG, false, &HandleLearnAllLangCommand, "", NULL },
{ "recipes", rbac::RBAC_PERM_COMMAND_LEARN_ALL_RECIPES, false, &HandleLearnAllRecipesCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand learnCommandTable[] =
{
{ "all", rbac::RBAC_PERM_COMMAND_LEARN_ALL, false, NULL, "", learnAllCommandTable },
{ "", rbac::RBAC_PERM_COMMAND_LEARN, false, &HandleLearnCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "learn", rbac::RBAC_PERM_COMMAND_LEARN, false, NULL, "", learnCommandTable },
{ "unlearn", rbac::RBAC_PERM_COMMAND_UNLEARN, 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 || !sSpellMgr->GetSpellInfo(spell))
return false;
char const* all = strtok(NULL, " ");
bool allRanks = all ? (strncmp(all, "all", strlen(all)) == 0) : false;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
{
handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
handler->SetSentErrorMessage(true);
return 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->LearnSpellHighestRank(spell);
else
targetPlayer->LearnSpell(spell, 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, handler->GetSession()->GetPlayer(), false))
continue;
if (!spellInfo->IsAbilityOfSkillType(SKILL_INTERNAL))
continue;
handler->GetSession()->GetPlayer()->LearnSpell(i, false);
}
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->SpellClassSet;
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 broken spells
if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
continue;
handler->GetSession()->GetPlayer()->LearnSpell(spellInfo->Id, false);
}
handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
return true;
}
static bool HandleLearnAllMyTalentsCommand(ChatHandler* handler, char const* /*args*/)
{
Player* player = handler->GetSession()->GetPlayer();
uint32 playerClass = player->getClass();
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
{
TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
if (!talentInfo)
continue;
if (playerClass != talentInfo->ClassID)
continue;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
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(talentInfo->SpellID);
player->AddTalent(talentInfo->SpellID, player->GetActiveTalentGroup());
}
handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
return true;
}
static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/)
{
/* TODO: 6.x remove pet talents
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, handler->GetSession()->GetPlayer(), false))
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, false);
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->LearnDefaultSkills();
target->LearnCustomSpells();
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)
{
Player* target;
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
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(target, 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;
name = skillInfo->DisplayName_lang;
if (name.empty())
continue;
if (!Utf8FitTo(name, namePart))
continue;
targetSkillInfo = skillInfo;
}
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->SkillLine != skillId)
continue;
// not high rank
if (skillLine->SupercedesSpell)
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, player, false))
continue;
player->LearnSpell(skillLine->SpellID, false);
}
}
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, false, !allRanks);
else
handler->SendSysMessage(LANG_FORGET_SPELL);
return true;
}
};
void AddSC_learn_commandscript()
{
new learn_commandscript();
}