diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-12-04 19:42:12 +0100 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2023-12-05 20:50:49 +0100 |
commit | 10544e4406858c79710ad12069ad35e0917823c8 (patch) | |
tree | cd734c943982c4fc21914201d4e29e5012098ab2 /src | |
parent | ecf714e93cff000683512e1d18c678e25200c60e (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.cpp | 36 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 8 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 4 |
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; |