Skip to content

Commit

Permalink
Update Player.cpp
Browse files Browse the repository at this point in the history
Restore changes
  • Loading branch information
FlagFlayer authored Jul 21, 2023
1 parent 771ecfe commit c9df904
Showing 1 changed file with 77 additions and 138 deletions.
215 changes: 77 additions & 138 deletions src/game/Objects/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5982,127 +5982,102 @@ void Player::UpdateSkillsToMaxSkillsForLevel()

// This functions sets a skill line value (and adds if doesn't exist yet)
// To "remove" a skill line, set it's values to zero
void Player::SetSkill(uint16 id, uint16 currVal, uint16 maxVal, uint16 step /*=0*/)
void Player::SetSkill(SkillStatusMap::iterator itr, uint16 currVal, uint16 maxVal, uint16 step/* = 0*/)
{
if (!id)
if (itr == mSkillStatus.end())
return;

SkillStatusMap::iterator itr = mSkillStatus.find(id);
const uint16 id = uint16(itr->first);
SkillStatusData& status = itr->second;

//has skill
if (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED)
if (status.uState == SKILL_DELETED)
return;

if (currVal) // Update
{
if (currVal)
{
if (step) // need update step
SetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos), MAKE_PAIR32(id, step));
// update value
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), MAKE_SKILL_VALUE(currVal, maxVal));
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_CHANGED;
if (step)
SetUInt32Value(PLAYER_SKILL_INDEX(status.pos), MAKE_PAIR32(id, step));

// Learn all spells auto-trained by this skill on change
UpdateSkillTrainedSpells(id, currVal);
}
else //remove
{
// Unapply skill bonuses
// temporary bonuses
AuraList const& lModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL);
for (const auto j : lModSkill)
if (j->GetModifier()->m_miscvalue == int32(id))
j->ApplyModifier(false);
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(status.pos), MAKE_SKILL_VALUE(currVal, maxVal));

// permanent bonuses
AuraList const& lModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT);
for (const auto j : lModSkillTalent)
if (j->GetModifier()->m_miscvalue == int32(id))
j->ApplyModifier(false);
if (status.uState != SKILL_NEW)
status.uState = SKILL_CHANGED;
}
else // Remove
{
SetUInt32Value(PLAYER_SKILL_INDEX(status.pos), 0);
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(status.pos), 0);
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(status.pos), 0);

// clear skill fields
SetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos), 0);
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), 0);
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos), 0);
if (status.uState == SKILL_NEW)
mSkillStatus.erase(itr);
else
status.uState = SKILL_DELETED;
}

// mark as deleted or simply remove from map if not saved yet
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_DELETED;
else
mSkillStatus.erase(itr);
// Learn/unlearn all spells auto-trained by this skill on change
UpdateSkillTrainedSpells(id, currVal);

// Remove all spells dependent on this skill unconditionally
UpdateSkillTrainedSpells(id, 0);
// On updating specific skills values
switch (id)
{
case SKILL_DEFENSE: UpdateDefenseBonusesMod(); break;
}
}

// remove all quests related to this skill (else the spell will be automatically learned at next login, cf Player::LearnQuestRewardedSpells)
for (auto& itr : mQuestStatus)
{
if (Quest const* quest = sObjectMgr.GetQuestTemplate(itr.first))
{
if (quest->GetRequiredSkill() == id)
{
// remove all quest entries for 'entry' from quest log
for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
{
if (GetQuestSlotQuestId(slot) == itr.first)
{
SetQuestSlot(slot, 0);
TakeOrReplaceQuestStartItems(itr.first, false, false);
break;
}
}
void Player::SetSkill(uint16 id, uint16 currVal, uint16 maxVal, uint16 step/* = 0*/)
{
if (!id)
return;

// set quest status to not started (will updated in DB at next save)
SetQuestStatus(itr.first, QUEST_STATUS_NONE); // Does not invalidate the iterator
itr.second.uState = QUEST_DELETED;
}
}
SkillStatusMap::iterator itr = mSkillStatus.find(id);

if (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED) // Update/remove existing
SetSkill(itr, currVal, maxVal, step);
else if (currVal) // Add new
{
if (itr == mSkillStatus.end())
{
SkillLineEntry const* entry = sSkillLineStore.LookupEntry(id);
if (!entry)
{
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "Skill not found in SkillLineStore: skill #%u", id);
return;
}
}
}
else if (currVal) // add
{
for (int i = 0; i < PLAYER_MAX_SKILLS; ++i)

for (uint8 pos = 0; pos < PLAYER_MAX_SKILLS; ++pos)
{
if (!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
if (GetUInt32Value(PLAYER_SKILL_INDEX(pos)))
continue;

if (itr != mSkillStatus.end()) // Re-use and move data for old status entry if not deleted yet
{
SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id);
if (!pSkill)
{
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "Skill not found in SkillLineStore: skill #%u", id);
itr->second.pos = pos;
itr->second.uState = SKILL_CHANGED;
}
else // Add a completely new status entry
{
auto result = mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(pos, SKILL_NEW)));

if (!result.second) // Insert failed
return;
}

SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step));
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(currVal, maxVal));
itr = result.first;
}

// insert new entry or update if not deleted old entry yet
if (itr != mSkillStatus.end())
SetUInt32Value(PLAYER_SKILL_INDEX(pos), MAKE_PAIR32(id, step)); // Set/reset skill id and step
SetSkill(itr, currVal, maxVal); // Set current and max values
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(pos), 0); // Reset bonus data
for (auto type : { SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT }) // Set temporary, permanent bonuses
{
for (auto aura : GetAurasByType(type))
{
itr->second.pos = i;
itr->second.uState = SKILL_CHANGED;
if (aura->GetModifier()->m_miscvalue == int32(id))
aura->ApplyModifier(true);
}
else
mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW)));

// apply skill bonuses
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i), 0);

// temporary bonuses
AuraList const& lModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL);
for (const auto j : lModSkill)
if (j->GetModifier()->m_miscvalue == int32(id))
j->ApplyModifier(true);

// permanent bonuses
AuraList const& lModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT);
for (const auto j : lModSkillTalent)
if (j->GetModifier()->m_miscvalue == int32(id))
j->ApplyModifier(true);

// Learn all spells auto-trained by this skill
UpdateSkillTrainedSpells(id, currVal);
return;
}
break;
}
}
}
Expand Down Expand Up @@ -19414,46 +19389,10 @@ void Player::LearnQuestRewardedSpells(Quest const* quest)
if (!found)
return;

// prevent learn non first rank unknown profession and second specialization for same profession)
// Prevent learning profession specializations, because unlearning and re-learning a profession doesn't automatically re-add the specialization
uint32 learned_0 = spellInfo->EffectTriggerSpell[EFFECT_INDEX_0];
if (sSpellMgr.GetSpellRank(learned_0) > 1 && !HasSpell(learned_0))
{
// not have first rank learned (unlearned prof?)
uint32 first_spell = sSpellMgr.GetFirstSpellInChain(learned_0);
if (!HasSpell(first_spell))
return;

SpellEntry const* learnedInfo = sSpellMgr.GetSpellEntry(learned_0);
if (!learnedInfo)
return;

// specialization
if (learnedInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_TRADE_SKILL && learnedInfo->Effect[EFFECT_INDEX_1] == 0)
{
// search other specialization for same prof
for (const auto& itr : m_spells)
{
if (itr.second.state == PLAYERSPELL_REMOVED || itr.first == learned_0)
continue;

SpellEntry const* itrInfo = sSpellMgr.GetSpellEntry(itr.first);
if (!itrInfo)
return;

// compare only specializations
if (itrInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_TRADE_SKILL || itrInfo->Effect[EFFECT_INDEX_1] != 0)
continue;

// compare same chain spells
if (sSpellMgr.GetFirstSpellInChain(itr.first) != first_spell)
continue;

// now we have 2 specialization, learn possible only if found is lesser specialization rank
if (!sSpellMgr.IsHighRankOfSpell(learned_0, itr.first))
return;
}
}
}
if (sSpellMgr.GetSpellRank(learned_0) > 1)
return;

CastSpell(this, spellId, true);
}
Expand Down

0 comments on commit c9df904

Please sign in to comment.