Core/Players: Minor skill loading improvements

* Fix initializing skill slots after they were increased from 256 to 300
* Improve skill step detection during loading from db
* Add safeguard for invalid data saved in character_skill (value = 0)
This commit is contained in:
Shauren
2026-02-16 11:40:48 +01:00
parent dfc7c0382d
commit 9b79ef5d4b
2 changed files with 30 additions and 14 deletions

View File

@@ -5725,7 +5725,7 @@ void Player::InitializeSkillFields()
{
SetSkillLineId(i, skillLine->ID);
SetSkillStartingRank(i, 1);
mSkillStatus.insert(SkillStatusMap::value_type(skillLine->ID, SkillStatusData(i, SKILL_UNCHANGED)));
mSkillStatus.try_emplace(skillLine->ID, i, SKILL_UNCHANGED);
if (++i >= PLAYER_MAX_SKILLS)
break;
}
@@ -5880,7 +5880,7 @@ void Player::SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
else
{
// We are about to learn a skill that has been added outside of normal circumstances (Game Master command, scripts etc.)
uint8 skillSlot = 0;
uint32 skillSlot = 0;
// Find a free skill slot
for (uint32 i = 0; i < PLAYER_MAX_SKILLS; ++i)
@@ -5939,7 +5939,7 @@ void Player::SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
UpdateSkillEnchantments(id, 0, newVal);
mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(skillSlot, SKILL_NEW)));
mSkillStatus.try_emplace(id, skillSlot, SKILL_NEW);
if (newVal)
{
@@ -26949,10 +26949,12 @@ void Player::_LoadSkills(PreparedQueryResult result)
TC_LOG_ERROR("entities.player", "Player::_LoadSkills: Player '{}' ({}, Race: {}, Class: {}) has forbidden skill {} for his race/class combination",
GetName(), GetGUID().ToString(), uint32(race), uint32(GetClass()), skill);
mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(mSkillStatus.size(), SKILL_DELETED)));
mSkillStatus.try_emplace(skill, mSkillStatus.size(), SKILL_DELETED);
continue;
}
uint16 step = 0;
// set fixed skill ranges
switch (GetSkillRangeType(rcEntry))
{
@@ -26965,24 +26967,31 @@ void Player::_LoadSkills(PreparedQueryResult result)
case SKILL_RANGE_LEVEL:
max = GetMaxSkillValueForLevel();
break;
case SKILL_RANGE_RANK:
{
SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcEntry->SkillTierID);
auto tierItr = std::ranges::find(tier->Value, max);
if (tierItr != std::ranges::end(tier->Value))
step = std::ranges::distance(std::ranges::begin(tier->Value), tierItr) + 1;
break;
}
default:
break;
}
auto skillItr = mSkillStatus.find(skill);
if (skillItr == mSkillStatus.end())
skillItr = mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(mSkillStatus.size(), SKILL_UNCHANGED))).first;
uint16 step = 0;
skillItr = mSkillStatus.try_emplace(skill, mSkillStatus.size(), SKILL_UNCHANGED).first;
if (SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(rcEntry->SkillID))
{
if (skillLine->CategoryID == SKILL_CATEGORY_SECONDARY)
if (!step && skillLine->CategoryID == SKILL_CATEGORY_SECONDARY)
step = max / 75;
if (skillLine->CategoryID == SKILL_CATEGORY_PROFESSION)
{
step = max / 75;
if (!step)
step = max / 75;
if (!skillLine->ParentSkillLineID)
{
@@ -26995,6 +27004,13 @@ void Player::_LoadSkills(PreparedQueryResult result)
}
SetSkillLineId(skillItr->second.pos, skill);
if (!value)
{
skillItr->second.uState = SKILL_DELETED;
continue;
}
SetSkillStep(skillItr->second.pos, step);
SetSkillRank(skillItr->second.pos, value);
SetSkillStartingRank(skillItr->second.pos, 1);
@@ -27014,7 +27030,7 @@ void Player::_LoadSkills(PreparedQueryResult result)
// enable parent skill line if missing
SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(skillId);
if (skillEntry->ParentSkillLineID && skillEntry->ParentTierIndex > 0 && GetSkillStep(skillEntry->ParentSkillLineID) < skillEntry->ParentTierIndex)
if (skillEntry->ParentSkillLineID && skillEntry->ParentTierIndex > 0 && int32(GetSkillStep(skillEntry->ParentSkillLineID)) < skillEntry->ParentTierIndex)
if (SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skillEntry->ParentSkillLineID, GetRace(), GetClass()))
if (SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcEntry->SkillTierID))
SetSkill(skillEntry->ParentSkillLineID, skillEntry->ParentTierIndex, std::max<uint16>(GetPureSkillValue(skillEntry->ParentSkillLineID), 1), tier->GetValueForTierIndex(skillEntry->ParentTierIndex - 1));
@@ -27023,12 +27039,12 @@ void Player::_LoadSkills(PreparedQueryResult result)
{
for (auto childItr = childSkillLines->begin(); childItr != childSkillLines->end() && mSkillStatus.size() < PLAYER_MAX_SKILLS; ++childItr)
{
if (mSkillStatus.find((*childItr)->ID) == mSkillStatus.end())
if (!mSkillStatus.contains((*childItr)->ID))
{
uint32 pos = mSkillStatus.size();
SetSkillLineId(pos, (*childItr)->ID);
SetSkillStartingRank(pos, 1);
mSkillStatus.insert(SkillStatusMap::value_type((*childItr)->ID, SkillStatusData(pos, SKILL_UNCHANGED)));
mSkillStatus.try_emplace((*childItr)->ID, pos, SKILL_UNCHANGED);
}
}
}

View File

@@ -653,10 +653,10 @@ enum SkillUpdateState
struct SkillStatusData
{
SkillStatusData(uint8 _pos, SkillUpdateState _uState) : pos(_pos), uState(_uState)
SkillStatusData(uint32 _pos, SkillUpdateState _uState) : pos(_pos), uState(_uState)
{
}
uint8 pos;
uint32 pos;
SkillUpdateState uState;
};