aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOvah <dreadkiller@gmx.de>2020-02-21 19:09:05 +0100
committerGitHub <noreply@github.com>2020-02-21 19:09:05 +0100
commit5860e128d687790c065c94adc8bacaf99db244fc (patch)
treeae694b79bf63451bc1580c730627af49e6b3135a
parenta6233982d22fe3a8c417c28897dcdb0b511df3ff (diff)
Core/Players: re-organize SetSkill method to handle initialized skills correctly (#24116)
-rw-r--r--src/server/game/Entities/Player/Player.cpp74
1 files changed, 39 insertions, 35 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index ce83f97ec96..f77044efab9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -579,6 +579,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
InitStatsForLevel();
InitTaxiNodesForLevel();
InitTalentForLevel();
+ InitializeSkillFields();
InitPrimaryProfessions(); // to max set before any spell added
// apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods()
@@ -5579,10 +5580,12 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
uint16 currVal;
SkillStatusMap::iterator itr = mSkillStatus.find(id);
- //has skill
- if (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED)
+ // Handle already stored skills
+ if (itr != mSkillStatus.end())
{
currVal = m_activePlayerData->Skill->SkillRank[itr->second.pos];
+
+ // Activate and update skill line
if (newVal)
{
// if skill value is going down, update enchantments before setting the new value
@@ -5595,9 +5598,6 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
SetSkillRank(itr->second.pos, newVal);
SetSkillMaxRank(itr->second.pos, maxVal);
- if (itr->second.uState != SKILL_NEW)
- itr->second.uState = SKILL_CHANGED;
-
LearnSkillRewardedSpells(id, newVal);
// if skill value is going up, update enchantments after setting the new value
if (newVal > currVal)
@@ -5605,8 +5605,17 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
UpdateCriteria(CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
UpdateCriteria(CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
+
+ // update skill state
+ if (itr->second.uState == SKILL_UNCHANGED)
+ {
+ if (currVal == 0) // activated skill, mark as new to save into database
+ itr->second.uState = SKILL_NEW;
+ else // updated skill, mark as changed to save into database
+ itr->second.uState = SKILL_CHANGED;
+ }
}
- else //remove
+ else if (currVal && !newVal) // Deactivate skill line
{
//remove enchantments needing this skill
UpdateSkillEnchantments(id, currVal, 0);
@@ -5618,9 +5627,11 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
SetSkillTempBonus(itr->second.pos, 0);
SetSkillPermBonus(itr->second.pos, 0);
- // mark as deleted or simply remove from map if not saved yet
+ // mark as deleted so the next save will delete the data from the database
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_DELETED;
+ else
+ itr->second.uState = SKILL_UNCHANGED;
// remove all spells that related to this skill
if (std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = sDB2Manager.GetSkillLineAbilitiesBySkill(id))
@@ -5638,25 +5649,24 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ProfessionSkillLine, 1), 0);
}
}
- else //add
+ else
{
- // Check if the player already has a skill, otherwise pick a empty skill slot if available
- uint8 skillSlot = itr != mSkillStatus.end() ? itr->second.pos : 0;
- if (!skillSlot)
+ // We are about to learn a skill that has been added outside of normal circumstances (Game Master command, scripts etc.)
+ uint8 skillSlot = 0;
+
+ // Find a free skill slot
+ for (uint32 i = 0; i < PLAYER_MAX_SKILLS; ++i)
{
- for (uint32 i = 0; i < PLAYER_MAX_SKILLS; ++i)
+ if (!m_activePlayerData->Skill->SkillLineID[i])
{
- if (!m_activePlayerData->Skill->SkillLineID[i])
- {
- skillSlot = i;
- break;
- }
+ skillSlot = i;
+ break;
}
}
if (!skillSlot)
{
- TC_LOG_ERROR("misc", "Tried to add skill #%u but the player cannot have additional skills", id);
+ TC_LOG_ERROR("misc", "Tried to add skill %u but player %s (%s) cannot have additional skills", id, GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -5712,11 +5722,7 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
UpdateSkillEnchantments(id, 0, newVal);
- // update or add entry
- if (itr != mSkillStatus.end())
- itr->second.uState = SKILL_CHANGED;
- else
- mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(skillSlot, SKILL_NEW)));
+ mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(skillSlot, SKILL_NEW)));
if (newVal)
{
@@ -5724,20 +5730,18 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
UpdateCriteria(CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
// temporary bonuses
- AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL);
- for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j)
- if ((*j)->GetMiscValue() == int32(id))
- (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
- AuraEffectList const& mModSkill2 = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_2);
- for (AuraEffectList::const_iterator j = mModSkill2.begin(); j != mModSkill2.end(); ++j)
- if ((*j)->GetMiscValue() == int32(id))
- (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
+ for (AuraEffect* effect : GetAuraEffectsByType(SPELL_AURA_MOD_SKILL))
+ if (effect->GetMiscValue() == int32(id))
+ effect->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
+
+ for (AuraEffect* effect : GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_2))
+ if (effect->GetMiscValue() == int32(id))
+ effect->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
// permanent bonuses
- AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT);
- for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j)
- if ((*j)->GetMiscValue() == int32(id))
- (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
+ for (AuraEffect* effect : GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT))
+ if (effect->GetMiscValue() == int32(id))
+ effect->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
// Learn all spells for skill
LearnSkillRewardedSpells(id, newVal);