aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-12-04 19:42:12 +0100
committerfunjoker <funjoker109@gmail.com>2023-12-05 20:50:49 +0100
commit10544e4406858c79710ad12069ad35e0917823c8 (patch)
treecd734c943982c4fc21914201d4e29e5012098ab2 /src
parentecf714e93cff000683512e1d18c678e25200c60e (diff)
Core/Players: Learn parent skilllines if they are missing while learning child skills
Closes #29482 (cherry picked from commit 9022f2374884b966c3ecf7199c52498140775668)
Diffstat (limited to 'src')
-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 e6080957e6a..7d5dcac9d74 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3137,7 +3137,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:
@@ -3412,7 +3412,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:
@@ -5744,6 +5744,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);
@@ -5873,7 +5879,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));
}
}
}
@@ -23669,7 +23675,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;
@@ -25554,7 +25560,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)
@@ -25639,18 +25644,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 6945f283f7d..f4f3b539681 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7883,6 +7883,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 bb6e6efda95..0a608f07607 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2315,7 +2315,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;
@@ -4581,7 +4581,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;