Core/Skills: ported master branch handling for learning skills on levelup
This commit is contained in:
1 parent
7cc3577d75
commit
6446541738
10 files changed
+54
-130
No files matched your search
@@ -0,0 +1 @@
|
||||
DELETE FROM `command` WHERE `permission`= 513;
|
||||
@@ -410,7 +410,7 @@ enum RBACPermissions
|
||||
RBAC_PERM_COMMAND_KICK = 510,
|
||||
RBAC_PERM_COMMAND_LINKGRAVE = 511,
|
||||
RBAC_PERM_COMMAND_LISTFREEZE = 512,
|
||||
RBAC_PERM_COMMAND_MAXSKILL = 513,
|
||||
RBAC_PERM_COMMAND_MAXSKILL = 513, // DEPRECATED: DON'T REUSE
|
||||
RBAC_PERM_COMMAND_MOVEGENS = 514,
|
||||
RBAC_PERM_COMMAND_MUTE = 515,
|
||||
RBAC_PERM_COMMAND_NEARGRAVE = 516,
|
||||
|
||||
@@ -283,6 +283,11 @@ static bool LoadDBC_assert_print(uint32 fsize, uint32 rsize, const std::string&
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::unordered_map<uint32, std::vector<SkillLineAbilityEntry const*>> _skillLineAbilitiesBySkillupSkill;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCStorage<T>& storage, std::string const& dbcPath, std::string const& filename, uint32 defaultLocale, std::string const& customFormat = std::string(), std::string const& customIndexName = std::string())
|
||||
{
|
||||
@@ -616,6 +621,9 @@ void DBCManager::LoadStores(const std::string& dataPath, uint32 defaultLocale)
|
||||
if (entry->RangeIndex > MAX_BATTLEGROUND_BRACKETS)
|
||||
ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data");
|
||||
|
||||
for (SkillLineAbilityEntry const* skillLineAbility : sSkillLineAbilityStore)
|
||||
_skillLineAbilitiesBySkillupSkill[skillLineAbility->SkillLine].push_back(skillLineAbility);
|
||||
|
||||
for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore)
|
||||
if (sSkillLineStore.LookupEntry(entry->SkillID))
|
||||
SkillRaceClassInfoBySkill.emplace(entry->SkillID, entry);
|
||||
@@ -1268,6 +1276,11 @@ uint32 DBCManager::GetDefaultMapLight(uint32 mapId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<SkillLineAbilityEntry const*> const* DBCManager::GetSkillLineAbilitiesBySkill(uint32 skillId) const
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_skillLineAbilitiesBySkillupSkill, skillId);
|
||||
}
|
||||
|
||||
SkillRaceClassInfoEntry const* DBCManager::GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_)
|
||||
{
|
||||
SkillRaceClassInfoBounds bounds = SkillRaceClassInfoBySkill.equal_range(skill);
|
||||
|
||||
@@ -244,7 +244,8 @@ public:
|
||||
uint32 GetPowerIndexByClass(Powers power, uint32 classId);
|
||||
static bool IsInArea(uint32 objectAreaId, uint32 areaId);
|
||||
static LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
|
||||
std::vector<uint32> const* GetPhasesForGroup(uint32 group);
|
||||
std::vector<uint32> const* GetPhasesForGroup(uint32 group);
|
||||
std::vector<SkillLineAbilityEntry const*> const* GetSkillLineAbilitiesBySkill(uint32 skillId) const;
|
||||
SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
|
||||
ResponseCodes ValidateName(std::wstring const& name, LocaleConstant locale);
|
||||
EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uint32 gender);
|
||||
|
||||
@@ -2337,6 +2337,8 @@ void Player::GiveLevel(uint8 level)
|
||||
|
||||
SetLevel(level);
|
||||
|
||||
UpdateSkillsForLevel();
|
||||
|
||||
// save base values (bonuses already included in stored stats
|
||||
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
||||
SetCreateStat(Stats(i), info.stats[i]);
|
||||
@@ -2350,9 +2352,6 @@ void Player::GiveLevel(uint8 level)
|
||||
|
||||
UpdateAllStats();
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_ALWAYS_MAXSKILL)) // Max weapon skill when leveling up
|
||||
UpdateWeaponsSkillsToMaxSkillsForLevel();
|
||||
|
||||
_ApplyAllLevelScaleItemMods(true); // Moved to above SetFullHealth so player will have full health from Heirlooms
|
||||
|
||||
// set current level health and mana/energy to maximum after applying all mods.
|
||||
@@ -2387,10 +2386,6 @@ void Player::GiveLevel(uint8 level)
|
||||
SetByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL, 0x01);
|
||||
}
|
||||
|
||||
// Leaning Running Wild
|
||||
if (getRace() == RACE_WORGEN && level == 20)
|
||||
CastSpell(this, SPELL_RUNNING_WILD_LEARN, true);
|
||||
|
||||
sScriptMgr->OnPlayerLevelChanged(this, oldLevel);
|
||||
}
|
||||
|
||||
@@ -3062,9 +3057,6 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
|
||||
if (skill_max_value < new_skill_max_value)
|
||||
skill_max_value = new_skill_max_value;
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_ALWAYS_MAXSKILL) && !IsProfessionOrRidingSkill(spellLearnSkill->skill))
|
||||
skill_value = skill_max_value;
|
||||
|
||||
SetSkill(spellLearnSkill->skill, spellLearnSkill->step, skill_value, skill_max_value);
|
||||
}
|
||||
}
|
||||
@@ -5403,55 +5395,18 @@ void Player::UpdateSkillsForLevel()
|
||||
if (GetSkillRangeType(rcEntry) != SKILL_RANGE_LEVEL)
|
||||
continue;
|
||||
|
||||
if (IsWeaponSkill(rcEntry->SkillID))
|
||||
continue;
|
||||
|
||||
uint16 field = itr->second.pos / 2;
|
||||
uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
|
||||
|
||||
uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
|
||||
|
||||
/// update only level dependent max skill values
|
||||
if (max != 1)
|
||||
if (GetSkillRangeType(rcEntry) == SKILL_RANGE_LEVEL)
|
||||
{
|
||||
SetSkillRank(itr->second.pos, maxSkill);
|
||||
if (rcEntry->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
|
||||
SetSkillRank(itr->second.pos, maxSkill);
|
||||
|
||||
SetSkillMaxRank(itr->second.pos, maxSkill);
|
||||
if (itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdateWeaponsSkillsToMaxSkillsForLevel()
|
||||
{
|
||||
for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end(); ++itr)
|
||||
{
|
||||
if (itr->second.uState == SKILL_DELETED || !GetSkillRank(itr->second.pos))
|
||||
continue;
|
||||
|
||||
uint32 pskill = itr->first;
|
||||
SkillRaceClassInfoEntry const* rcEntry = sDBCManager.GetSkillRaceClassInfo(pskill, getRace(), getClass());
|
||||
if (!rcEntry)
|
||||
continue;
|
||||
|
||||
if (IsProfessionOrRidingSkill(rcEntry->SkillID))
|
||||
continue;
|
||||
|
||||
if (IsWeaponSkill(rcEntry->SkillID))
|
||||
continue;
|
||||
|
||||
uint16 field = itr->second.pos / 2;
|
||||
uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
|
||||
|
||||
uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
|
||||
|
||||
if (max > 1)
|
||||
{
|
||||
SetSkillRank(itr->second.pos, max);
|
||||
|
||||
if (itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
}
|
||||
// Update level dependent skillline spells
|
||||
LearnSkillRewardedSpells(rcEntry->SkillID, GetSkillRank(itr->second.pos));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5542,9 +5497,9 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
|
||||
itr->second.uState = SKILL_UNCHANGED;
|
||||
|
||||
// remove all spells that related to this skill
|
||||
for (SkillLineAbilityEntry const* skillLineAbilities : sSkillLineAbilityStore)
|
||||
if (skillLineAbilities->SkillLine == id)
|
||||
RemoveSpell(sSpellMgr->GetFirstSpellInChain(skillLineAbilities->Spell));
|
||||
if (std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = sDBCManager.GetSkillLineAbilitiesBySkill(id))
|
||||
for (SkillLineAbilityEntry const* skillLineAbility : *skillLineAbilities)
|
||||
RemoveSpell(sSpellMgr->GetFirstSpellInChain(skillLineAbility->Spell));
|
||||
|
||||
// Clear profession lines
|
||||
if (GetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1) == id)
|
||||
@@ -23719,9 +23674,7 @@ void Player::LearnDefaultSkill(uint32 skillId, uint16 rank)
|
||||
{
|
||||
uint16 skillValue = 1;
|
||||
uint16 maxValue = GetMaxSkillValueForLevel();
|
||||
if (sWorld->getBoolConfig(CONFIG_ALWAYS_MAXSKILL) && !IsProfessionOrRidingSkill(skillId))
|
||||
skillValue = maxValue;
|
||||
else if (rcInfo->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
|
||||
if (rcInfo->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
|
||||
skillValue = maxValue;
|
||||
else if (getClass() == CLASS_DEATH_KNIGHT)
|
||||
skillValue = std::min(std::max<uint16>({ 1, uint16((getLevel() - 1) * 5) }), maxValue);
|
||||
@@ -23822,28 +23775,29 @@ void Player::LearnQuestRewardedSpells()
|
||||
|
||||
void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue)
|
||||
{
|
||||
// bad hack to work around data being suited only for the client - AcquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN for riding
|
||||
// client uses it to show riding in spellbook as trainable
|
||||
if (skillId == SKILL_RIDING)
|
||||
return;
|
||||
|
||||
uint32 raceMask = getRaceMask();
|
||||
uint32 classMask = getClassMask();
|
||||
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
|
||||
std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = sDBCManager.GetSkillLineAbilitiesBySkill(skillId);
|
||||
if (!skillLineAbilities)
|
||||
return;
|
||||
|
||||
for (SkillLineAbilityEntry const* ability : *skillLineAbilities)
|
||||
{
|
||||
SkillLineAbilityEntry const* ability = sSkillLineAbilityStore.LookupEntry(j);
|
||||
if (!ability || ability->SkillLine != skillId)
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(ability->Spell);
|
||||
if (!spellInfo)
|
||||
continue;
|
||||
|
||||
SpellInfo const* spell = sSpellMgr->GetSpellInfo(ability->Spell);
|
||||
if (!spell)
|
||||
continue;
|
||||
switch (ability->AcquireMethod)
|
||||
{
|
||||
case SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE:
|
||||
case SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if we fulfill the level requirement for the spell
|
||||
if (getLevel() < spell->SpellLevel)
|
||||
continue;
|
||||
|
||||
if (ability->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE && ability->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
|
||||
// AcquireMethod == 2 && NumSkillUps == 1 --> automatically learn riding skill spell, else we skip it (client shows riding in spellbook as trainable).
|
||||
if (skillId == SKILL_RIDING && (ability->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN || ability->NumSkillUps != 1))
|
||||
continue;
|
||||
|
||||
// Check race if set
|
||||
@@ -23854,35 +23808,19 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue)
|
||||
if (ability->ClassMask && !(ability->ClassMask & classMask))
|
||||
continue;
|
||||
|
||||
// check level, skip class spells if not high enough
|
||||
if (getLevel() < spellInfo->SpellLevel)
|
||||
continue;
|
||||
|
||||
// need unlearn spell
|
||||
if (skillValue < ability->MinSkillLineRank && ability->AcquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE)
|
||||
RemoveSpell(ability->Spell);
|
||||
|
||||
// need learn
|
||||
else if (!IsInWorld())
|
||||
AddSpell(ability->Spell, true, true, true, false, false, ability->SkillLine);
|
||||
else
|
||||
{
|
||||
// used to avoid double Seal of Righteousness on paladins, it's the only player spell which has both spell and forward spell in auto learn
|
||||
if (ability->AcquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && ability->SupercededBySpell)
|
||||
{
|
||||
bool skipCurrent = false;
|
||||
auto bounds = sSpellMgr->GetSkillLineAbilityMapBounds(ability->SupercededBySpell);
|
||||
for (auto itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
if (itr->second->AcquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && skillValue >= itr->second->MinSkillLineRank)
|
||||
{
|
||||
skipCurrent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipCurrent)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsInWorld())
|
||||
AddSpell(ability->Spell, true, true, true, false, false, ability->SkillLine);
|
||||
else
|
||||
LearnSpell(ability->Spell, true, ability->SkillLine);
|
||||
}
|
||||
LearnSpell(ability->Spell, true, ability->SkillLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1974,7 +1974,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
int32 CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus = false);
|
||||
|
||||
void UpdateSkillsForLevel();
|
||||
void UpdateWeaponsSkillsToMaxSkillsForLevel(); // for .levelup
|
||||
void ModifySkillBonus(uint32 skillid, int32 val, bool talent);
|
||||
|
||||
void SetLastSoulburnSpell(SpellInfo const* spell) { m_lastSoulburnSpell = spell; }
|
||||
|
||||
@@ -1463,7 +1463,6 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_bool_configs[CONFIG_RESET_DUEL_HEALTH_MANA] = sConfigMgr->GetBoolDefault("ResetDuelHealthMana", false);
|
||||
m_bool_configs[CONFIG_START_ALL_EXPLORED] = sConfigMgr->GetBoolDefault("PlayerStart.MapsExplored", false);
|
||||
m_bool_configs[CONFIG_START_ALL_REP] = sConfigMgr->GetBoolDefault("PlayerStart.AllReputation", false);
|
||||
m_bool_configs[CONFIG_ALWAYS_MAXSKILL] = sConfigMgr->GetBoolDefault("AlwaysMaxWeaponSkill", false);
|
||||
m_bool_configs[CONFIG_PVP_TOKEN_ENABLE] = sConfigMgr->GetBoolDefault("PvPToken.Enable", false);
|
||||
m_int_configs[CONFIG_PVP_TOKEN_MAP_TYPE] = sConfigMgr->GetIntDefault("PvPToken.MapAllowType", 4);
|
||||
m_int_configs[CONFIG_PVP_TOKEN_ID] = sConfigMgr->GetIntDefault("PvPToken.ItemID", 29434);
|
||||
|
||||
@@ -142,7 +142,6 @@ enum WorldBoolConfigs
|
||||
CONFIG_START_ALL_SPELLS,
|
||||
CONFIG_START_ALL_EXPLORED,
|
||||
CONFIG_START_ALL_REP,
|
||||
CONFIG_ALWAYS_MAXSKILL,
|
||||
CONFIG_PVP_TOKEN_ENABLE,
|
||||
CONFIG_NO_RESET_TALENT_COST,
|
||||
CONFIG_SHOW_KICK_IN_WORLD,
|
||||
|
||||
@@ -87,7 +87,6 @@ public:
|
||||
{ "kick", rbac::RBAC_PERM_COMMAND_KICK, true, &HandleKickPlayerCommand, "" },
|
||||
{ "linkgrave", rbac::RBAC_PERM_COMMAND_LINKGRAVE, false, &HandleLinkGraveCommand, "" },
|
||||
{ "listfreeze", rbac::RBAC_PERM_COMMAND_LISTFREEZE, false, &HandleListFreezeCommand, "" },
|
||||
{ "maxskill", rbac::RBAC_PERM_COMMAND_MAXSKILL, false, &HandleMaxSkillCommand, "" },
|
||||
{ "movegens", rbac::RBAC_PERM_COMMAND_MOVEGENS, false, &HandleMovegensCommand, "" },
|
||||
{ "mute", rbac::RBAC_PERM_COMMAND_MUTE, true, &HandleMuteCommand, "" },
|
||||
{ "mutehistory", rbac::RBAC_PERM_COMMAND_MUTEHISTORY, true, &HandleMuteInfoCommand, "" },
|
||||
@@ -1436,22 +1435,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
Player* player = handler->getSelectedPlayerOrSelf();
|
||||
if (!player)
|
||||
{
|
||||
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// each skills that have max skill value dependent from level seted to current level max skill value
|
||||
player->UpdateWeaponsSkillsToMaxSkillsForLevel();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleSetSkillCommand(ChatHandler* handler, char const* args)
|
||||
{
|
||||
// number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
|
||||
|
||||
@@ -3135,15 +3135,6 @@ ResetDuelCooldowns = 0
|
||||
|
||||
ResetDuelHealthMana = 0
|
||||
|
||||
#
|
||||
# AlwaysMaxWeaponSkill
|
||||
# Description: Players will automatically gain max weapon/defense skill when logging in,
|
||||
# or leveling.
|
||||
# Default: 0 - (Disabled)
|
||||
# 1 - (Enabled)
|
||||
|
||||
AlwaysMaxWeaponSkill = 0
|
||||
|
||||
#
|
||||
# PvPToken.Enable
|
||||
# Description: Character will receive a token after defeating another character that yields
|
||||
|
||||
Reference in new issue
Block a user