mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[9653] Correctly update talent free points in diff cases.
Before at .unlearn or .learn all_mytalents commands free talent points not updated correctly. Same for .learn all_mypettalents.
This commit is contained in:
parent
d004549fd4
commit
daaeb0a998
8 changed files with 86 additions and 49 deletions
|
|
@ -665,14 +665,19 @@ TalentSpellPos const* GetTalentSpellPos(uint32 spellId)
|
|||
return &itr->second;
|
||||
}
|
||||
|
||||
uint32 GetTalentSpellCost(uint32 spellId)
|
||||
uint32 GetTalentSpellCost(TalentSpellPos const* pos)
|
||||
{
|
||||
if(TalentSpellPos const* pos = GetTalentSpellPos(spellId))
|
||||
if (pos)
|
||||
return pos->rank+1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 GetTalentSpellCost(uint32 spellId)
|
||||
{
|
||||
return GetTalentSpellCost(GetTalentSpellPos(spellId));
|
||||
}
|
||||
|
||||
int32 GetAreaFlagByAreaID(uint32 area_id)
|
||||
{
|
||||
AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ typedef std::list<uint32> SimpleFactionsList;
|
|||
SimpleFactionsList const* GetFactionTeamList(uint32 faction);
|
||||
char* GetPetName(uint32 petfamily, uint32 dbclang);
|
||||
uint32 GetTalentSpellCost(uint32 spellId);
|
||||
uint32 GetTalentSpellCost(TalentSpellPos const* pos);
|
||||
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
|
||||
|
||||
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
|
||||
|
|
|
|||
|
|
@ -1953,6 +1953,8 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
|
|||
player->learnSpellHighRank(spellid);
|
||||
}
|
||||
|
||||
player->SendTalentsInfoData(false);
|
||||
|
||||
SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2029,6 +2031,8 @@ bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
|
|||
pet->learnSpellHighRank(spellid);
|
||||
}
|
||||
|
||||
player->SendTalentsInfoData(true);
|
||||
|
||||
SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1380,11 +1380,8 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
|||
uint32 talentCost = GetTalentSpellCost(spell_id);
|
||||
if (talentCost)
|
||||
{
|
||||
int32 free_points = GetMaxTalentPointsForLevel(getLevel());
|
||||
m_usedTalentCount+=talentCost;
|
||||
// update free talent points
|
||||
free_points-=m_usedTalentCount;
|
||||
SetFreeTalentPoints(free_points > 0 ? free_points : 0);
|
||||
UpdateFreeTalentPoints(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1493,9 +1490,8 @@ bool Pet::removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
|
|||
m_usedTalentCount-=talentCost;
|
||||
else
|
||||
m_usedTalentCount = 0;
|
||||
// update free talent points
|
||||
int32 free_points = GetMaxTalentPointsForLevel(getLevel()) - m_usedTalentCount;
|
||||
SetFreeTalentPoints(free_points > 0 ? free_points : 0);
|
||||
|
||||
UpdateFreeTalentPoints(false);
|
||||
}
|
||||
|
||||
if (learn_prev)
|
||||
|
|
@ -1720,17 +1716,33 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/)
|
|||
CharacterDatabase.Execute(ss.str().c_str());
|
||||
}
|
||||
|
||||
void Pet::InitTalentForLevel()
|
||||
void Pet::UpdateFreeTalentPoints(bool resetIfNeed)
|
||||
{
|
||||
uint32 level = getLevel();
|
||||
uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
|
||||
// Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent)
|
||||
if (talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel)
|
||||
{
|
||||
// Remove all talent points
|
||||
// Remove all talent points (except for admin pets)
|
||||
if (resetIfNeed)
|
||||
{
|
||||
Unit *owner = GetOwner();
|
||||
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || ((Player*)owner)->GetSession()->GetSecurity() < SEC_ADMINISTRATOR)
|
||||
resetTalents(true);
|
||||
else
|
||||
SetFreeTalentPoints(0);
|
||||
}
|
||||
else
|
||||
SetFreeTalentPoints(0);
|
||||
}
|
||||
else
|
||||
SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
|
||||
}
|
||||
|
||||
|
||||
void Pet::InitTalentForLevel()
|
||||
{
|
||||
UpdateFreeTalentPoints();
|
||||
|
||||
Unit *owner = GetOwner();
|
||||
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ class Pet : public Creature
|
|||
uint8 GetMaxTalentPointsForLevel(uint32 level);
|
||||
uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
|
||||
void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); }
|
||||
void UpdateFreeTalentPoints(bool resetIfNeed = true);
|
||||
|
||||
uint32 m_resetTalentsCost;
|
||||
time_t m_resetTalentsTime;
|
||||
|
|
|
|||
|
|
@ -2518,7 +2518,7 @@ void Player::GiveLevel(uint32 level)
|
|||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
|
||||
}
|
||||
|
||||
void Player::InitTalentForLevel()
|
||||
void Player::UpdateFreeTalentPoints(bool resetIfNeed)
|
||||
{
|
||||
uint32 level = getLevel();
|
||||
// talents base at level diff ( talents = level - 9 but some can be used already)
|
||||
|
|
@ -2527,6 +2527,7 @@ void Player::InitTalentForLevel()
|
|||
// Remove all talent points
|
||||
if (m_usedTalentCount > 0) // Free any used talents
|
||||
{
|
||||
if (resetIfNeed)
|
||||
resetTalents(true);
|
||||
SetFreeTalentPoints(0);
|
||||
}
|
||||
|
|
@ -2538,7 +2539,7 @@ void Player::InitTalentForLevel()
|
|||
// if used more that have then reset
|
||||
if (m_usedTalentCount > talentPointsForLevel)
|
||||
{
|
||||
if (GetSession()->GetSecurity() < SEC_ADMINISTRATOR)
|
||||
if (resetIfNeed && GetSession()->GetSecurity() < SEC_ADMINISTRATOR)
|
||||
resetTalents(true);
|
||||
else
|
||||
SetFreeTalentPoints(0);
|
||||
|
|
@ -2547,6 +2548,11 @@ void Player::InitTalentForLevel()
|
|||
else
|
||||
SetFreeTalentPoints(talentPointsForLevel-m_usedTalentCount);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::InitTalentForLevel()
|
||||
{
|
||||
UpdateFreeTalentPoints();
|
||||
|
||||
if (!GetSession()->PlayerLoading())
|
||||
SendTalentsInfoData(false); // update at client
|
||||
|
|
@ -2996,10 +3002,12 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
}
|
||||
}
|
||||
|
||||
TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id);
|
||||
|
||||
if(!disabled_case) // skip new spell adding if spell already known (disabled spells case)
|
||||
{
|
||||
// talent: unlearn all other talent ranks (high and low)
|
||||
if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
|
||||
if (talentPos)
|
||||
{
|
||||
if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
||||
{
|
||||
|
|
@ -3085,11 +3093,23 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32 talentCost = GetTalentSpellCost(spell_id);
|
||||
if (talentPos)
|
||||
{
|
||||
// update used talent points count
|
||||
m_usedTalentCount += GetTalentSpellCost(talentPos);
|
||||
UpdateFreeTalentPoints(false);
|
||||
}
|
||||
|
||||
// update free primary prof.points (if any, can be none in case GM .learn prof. learning)
|
||||
if (uint32 freeProfs = GetFreePrimaryProfessionPoints())
|
||||
{
|
||||
if(sSpellMgr.IsPrimaryProfessionFirstRankSpell(spell_id))
|
||||
SetFreePrimaryProfessions(freeProfs-1);
|
||||
}
|
||||
|
||||
// cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned)
|
||||
// note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive
|
||||
if (talentCost > 0 && IsSpellHaveEffect(spellInfo,SPELL_EFFECT_LEARN_SPELL))
|
||||
if (talentPos && IsSpellHaveEffect(spellInfo,SPELL_EFFECT_LEARN_SPELL))
|
||||
{
|
||||
// ignore stance requirement for talent learn spell (stance set for spell only for client spell description show)
|
||||
CastSpell(this, spell_id, true);
|
||||
|
|
@ -3106,16 +3126,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
return false;
|
||||
}
|
||||
|
||||
// update used talent points count
|
||||
m_usedTalentCount += talentCost;
|
||||
|
||||
// update free primary prof.points (if any, can be none in case GM .learn prof. learning)
|
||||
if (uint32 freeProfs = GetFreePrimaryProfessionPoints())
|
||||
{
|
||||
if(sSpellMgr.IsPrimaryProfessionFirstRankSpell(spell_id))
|
||||
SetFreePrimaryProfessions(freeProfs-1);
|
||||
}
|
||||
|
||||
// add dependent skills
|
||||
uint16 maxskill = GetMaxSkillValueForLevel();
|
||||
|
||||
|
|
@ -3286,14 +3296,18 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank, bo
|
|||
if(PetAura const* petSpell = sSpellMgr.GetPetAura(spell_id, SpellEffectIndex(i)))
|
||||
RemovePetAura(petSpell);
|
||||
|
||||
// free talent points
|
||||
uint32 talentCosts = GetTalentSpellCost(spell_id);
|
||||
if(talentCosts > 0)
|
||||
TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id);
|
||||
if (talentPos)
|
||||
{
|
||||
// free talent points
|
||||
uint32 talentCosts = GetTalentSpellCost(talentPos);
|
||||
|
||||
if(talentCosts < m_usedTalentCount)
|
||||
m_usedTalentCount -= talentCosts;
|
||||
else
|
||||
m_usedTalentCount = 0;
|
||||
|
||||
UpdateFreeTalentPoints(false);
|
||||
}
|
||||
|
||||
// update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning)
|
||||
|
|
@ -3381,7 +3395,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank, bo
|
|||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
|
||||
|
||||
// if talent then lesser rank also talent and need learn
|
||||
if (talentCosts)
|
||||
if (talentPos)
|
||||
{
|
||||
if(learn_low_rank)
|
||||
learnSpell (prev_id,false);
|
||||
|
|
@ -5632,10 +5646,10 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const
|
|||
|
||||
void Player::SendInitialActionButtons() const
|
||||
{
|
||||
sLog.outDetail( "Initializing Action Buttons for '%u'", GetGUIDLow() );
|
||||
sLog.outDetail( "Initializing Action Buttons for '%u' spec '%u'", GetGUIDLow(), m_activeSpec);
|
||||
|
||||
WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4));
|
||||
data << uint8(1); // can be 0, 1, 2 (talent spec)
|
||||
data << uint8(m_activeSpec); // can be 0, 1, 2 (talent spec)
|
||||
ActionButtonList const& currentActionButtonList = m_actionButtons[m_activeSpec];
|
||||
for(uint8 button = 0; button < MAX_ACTION_BUTTONS; ++button)
|
||||
{
|
||||
|
|
@ -5647,7 +5661,7 @@ void Player::SendInitialActionButtons() const
|
|||
}
|
||||
|
||||
GetSession()->SendPacket( &data );
|
||||
sLog.outDetail( "Action Buttons for '%u' Initialized", GetGUIDLow() );
|
||||
sLog.outDetail( "Action Buttons for '%u' spec '%u' Initialized", GetGUIDLow(), m_activeSpec );
|
||||
}
|
||||
|
||||
bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type, Player* player, bool msg)
|
||||
|
|
@ -15874,7 +15888,9 @@ void Player::_LoadSpells(QueryResult *result)
|
|||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
addSpell(fields[0].GetUInt32(), fields[1].GetBool(), false, false, fields[2].GetBool());
|
||||
uint32 spell_id = fields[0].GetUInt32();
|
||||
|
||||
addSpell(spell_id, fields[1].GetBool(), false, false, fields[2].GetBool());
|
||||
}
|
||||
while( result->NextRow() );
|
||||
|
||||
|
|
@ -20892,9 +20908,6 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
|||
// learn! (other talent ranks will unlearned at learning)
|
||||
learnSpell(spellid, false);
|
||||
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
|
||||
|
||||
// update free talent points
|
||||
SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
|
||||
}
|
||||
|
||||
void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
|
||||
|
|
|
|||
|
|
@ -1544,6 +1544,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
|
||||
void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); }
|
||||
void UpdateFreeTalentPoints(bool resetIfNeed = true);
|
||||
bool resetTalents(bool no_cost = false);
|
||||
uint32 resetTalentsCost() const;
|
||||
void InitTalentForLevel();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9652"
|
||||
#define REVISION_NR "9653"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue