aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp36
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp17
-rw-r--r--src/server/game/Globals/ObjectMgr.h8
-rw-r--r--src/server/game/Spells/SpellEffects.cpp4
4 files changed, 47 insertions, 18 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4fc2bdd5bb8..b3258b28756 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3152,7 +3152,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
case SKILL_RANGE_RANK:
{
SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcInfo->SkillTierID);
- new_skill_max_value = tier->Value[spellLearnSkill->step - 1];
+ new_skill_max_value = tier->GetValueForTierIndex(spellLearnSkill->step - 1);
break;
}
default:
@@ -3427,7 +3427,7 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled /*= false*/, bool learn_
case SKILL_RANGE_RANK:
{
SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcInfo->SkillTierID);
- new_skill_max_value = tier->Value[prevSkill->step - 1];
+ new_skill_max_value = tier->GetValueForTierIndex(prevSkill->step - 1);
break;
}
default:
@@ -5886,6 +5886,12 @@ void Player::SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
// Activate and update skill line
if (newVal)
{
+ // enable parent skill line if missing
+ if (skillEntry->ParentSkillLineID && skillEntry->ParentTierIndex > 0 && 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));
+
// if skill value is going down, update enchantments before setting the new value
if (newVal < currVal)
UpdateSkillEnchantments(id, currVal, newVal);
@@ -6015,7 +6021,7 @@ void Player::SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
if (SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcEntry->SkillTierID))
{
uint16 skillval = GetPureSkillValue(skillEntry->ParentSkillLineID);
- SetSkill(skillEntry->ParentSkillLineID, skillEntry->ParentTierIndex, std::max<uint16>(skillval, 1), tier->Value[skillEntry->ParentTierIndex - 1]);
+ SetSkill(skillEntry->ParentSkillLineID, skillEntry->ParentTierIndex, std::max<uint16>(skillval, 1), tier->GetValueForTierIndex(skillEntry->ParentTierIndex - 1));
}
}
}
@@ -24354,7 +24360,7 @@ void Player::LearnDefaultSkill(SkillRaceClassInfoEntry const* rcInfo)
case SKILL_RANGE_RANK:
{
SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcInfo->SkillTierID);
- uint16 maxValue = tier->Value[0];
+ uint16 maxValue = tier->GetValueForTierIndex(0);
uint16 skillValue = 1;
if (rcInfo->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
skillValue = maxValue;
@@ -26201,7 +26207,6 @@ void Player::_LoadSkills(PreparedQueryResult result)
// SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max, professionSlot FROM character_skills WHERE guid = '{}'", GUID_LOPART(m_guid));
Races race = Races(GetRace());
- uint32 count = 0;
std::unordered_map<uint32, uint32> loadedSkillValues;
std::vector<uint16> loadedProfessionsWithoutSlot; // fixup old characters
if (result)
@@ -26286,18 +26291,27 @@ void Player::_LoadSkills(PreparedQueryResult result)
}
// Learn skill rewarded spells after all skills have been loaded to prevent learning a skill from them before its loaded with proper value from DB
- for (auto const& skill : loadedSkillValues)
+ for (auto const& [skillId, skillValue] : loadedSkillValues)
{
- LearnSkillRewardedSpells(skill.first, skill.second, race);
- if (std::vector<SkillLineEntry const*> const* childSkillLines = sDB2Manager.GetSkillLinesForParentSkill(skill.first))
+ LearnSkillRewardedSpells(skillId, skillValue, race);
+
+ // enable parent skill line if missing
+ SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(skillId);
+ if (skillEntry->ParentSkillLineID && skillEntry->ParentTierIndex > 0 && 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));
+
+ if (std::vector<SkillLineEntry const*> const* childSkillLines = sDB2Manager.GetSkillLinesForParentSkill(skillId))
{
for (auto childItr = childSkillLines->begin(); childItr != childSkillLines->end() && mSkillStatus.size() < PLAYER_MAX_SKILLS; ++childItr)
{
if (mSkillStatus.find((*childItr)->ID) == mSkillStatus.end())
{
- SetSkillLineId(count, (*childItr)->ID);
- SetSkillStartingRank(count, 1);
- mSkillStatus.insert(SkillStatusMap::value_type((*childItr)->ID, SkillStatusData(count, SKILL_UNCHANGED)));
+ uint32 pos = mSkillStatus.size();
+ SetSkillLineId(pos, (*childItr)->ID);
+ SetSkillStartingRank(pos, 1);
+ mSkillStatus.insert(SkillStatusMap::value_type((*childItr)->ID, SkillStatusData(pos, SKILL_UNCHANGED)));
}
}
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 5dc45d50536..27456a6e6d3 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7907,6 +7907,23 @@ int32 ObjectMgr::GetFishingBaseSkillLevel(AreaTableEntry const* areaEntry) const
return 0;
}
+SkillTiersEntry const* ObjectMgr::GetSkillTier(uint32 skillTierId) const
+{
+ auto itr = _skillTiers.find(skillTierId);
+ return itr != _skillTiers.end() ? &itr->second : nullptr;
+}
+
+uint32 SkillTiersEntry::GetValueForTierIndex(uint32 tierIndex) const
+{
+ if (tierIndex >= MAX_SKILL_STEP)
+ tierIndex = MAX_SKILL_STEP - 1;
+
+ while (Value[tierIndex] == 0 && tierIndex > 0)
+ --tierIndex;
+
+ return Value[tierIndex];
+}
+
void ObjectMgr::LoadPetNames()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 5a86448d870..bf90e20bb6a 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -969,6 +969,8 @@ struct SkillTiersEntry
{
uint32 ID; // 0
uint32 Value[MAX_SKILL_STEP]; // 1-16
+
+ uint32 GetValueForTierIndex(uint32 tierIndex) const;
};
SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const* rcEntry);
@@ -1409,11 +1411,7 @@ class TC_GAME_API ObjectMgr
int32 GetFishingBaseSkillLevel(AreaTableEntry const* areaEntry) const;
- SkillTiersEntry const* GetSkillTier(uint32 skillTierId) const
- {
- auto itr = _skillTiers.find(skillTierId);
- return itr != _skillTiers.end() ? &itr->second : nullptr;
- }
+ SkillTiersEntry const* GetSkillTier(uint32 skillTierId) const;
void ReturnOrDeleteOldMails(bool serverUp);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index d81288454fc..1895edd06b1 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2318,7 +2318,7 @@ void Spell::EffectLearnSkill()
return;
uint16 skillval = std::max<uint16>(1, playerTarget->GetPureSkillValue(skillid));
- uint16 maxSkillVal = tier->Value[damage - 1];
+ uint16 maxSkillVal = tier->GetValueForTierIndex(damage - 1);
if (rcEntry->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
skillval = maxSkillVal;
@@ -4566,7 +4566,7 @@ void Spell::EffectSkill()
return;
uint16 skillval = std::max<uint16>(1, playerTarget->GetPureSkillValue(skillid));
- uint16 maxSkillVal = tier->Value[damage - 1];
+ uint16 maxSkillVal = tier->GetValueForTierIndex(damage - 1);
if (rcEntry->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
skillval = maxSkillVal;