diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DBCStructure.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 94 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 53 |
3 files changed, 69 insertions, 80 deletions
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index f3b6355091e..2556c141d8d 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -2139,7 +2139,7 @@ struct SummonPropertiesEntry uint32 Flags; // 5 }; -#define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK +#define MAX_TALENT_TIERS 7 struct TalentEntry { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 016666e2945..ad870f0262b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3310,7 +3310,6 @@ void DeleteSpellFromAllPlayers(uint32 spellId) bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) { - /* TODO: 6.x update talent system SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { @@ -3342,37 +3341,25 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) return false; } - PlayerTalentMap::iterator itr = GetTalentMap(spec)->find(spellId); - if (itr != GetTalentMap(spec)->end()) - itr->second->state = PLAYERSPELL_UNCHANGED; - else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId)) - { - if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id)) - { - for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank) - { - // skip learning spell and no rank spell case - uint32 rankSpellId = talentInfo->RankID[rank]; - if (!rankSpellId || rankSpellId == spellId) - continue; + TalentEntry const* talentEntry = GetTalentBySpellID(spellId); - itr = GetTalentMap(spec)->find(rankSpellId); - if (itr != GetTalentMap(spec)->end()) - itr->second->state = PLAYERSPELL_REMOVED; - } - } + // Check if talent exists in Talent.dbc + if (!talentEntry) { + TC_LOG_ERROR("spells", "Player::addTalent: Learning non-talent spell %u not allowed.", spellId); + return false; + } + + TalentSpecInfo* talentSpecInfo = GetTalentSpecInfo(spec); - PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED; - PlayerTalent* newtalent = new PlayerTalent(); + // Check if player already has this talent + if (talentSpecInfo->HasTalent(spellId)) + return false; - newtalent->state = state; - newtalent->spec = spec; + talentSpecInfo->Talents[talentEntry->TierID].SpellID = spellId; + if (learning) + talentSpecInfo->Talents[talentEntry->TierID].State = PLAYERSPELL_NEW; - (*GetTalentMap(spec))[spellId] = newtalent; - return true; - } - */ - return false; + return true; } bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, bool fromSkill /*= false*/) @@ -4133,6 +4120,8 @@ bool Player::ResetTalents(bool no_cost) } RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + + uint8 spec = GetActiveSpec(); for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId) { @@ -4159,10 +4148,8 @@ bool Player::ResetTalents(bool no_cost) if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL) RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true); - // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted - PlayerTalentMap::iterator plrTalent = GetTalentMap(GetActiveSpec())->find(talentInfo->SpellID); - if (plrTalent != GetTalentMap(GetActiveSpec())->end()) - plrTalent->second->state = PLAYERSPELL_REMOVED; + // Reset talents store + GetTalentSpecInfo(spec)->Reset(); } // Remove all specialization specific spells and give default ones which were overriden @@ -4181,12 +4168,12 @@ bool Player::ResetTalents(bool no_cost) } // Unlearn masteries - ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(GetActiveSpec())); + ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(spec)); for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i) if (uint32 mastery = chrSpec->MasterySpellID[i]) RemoveAurasDueToSpell(mastery); - SetTalentSpec(GetActiveSpec(), 0); + SetTalentSpec(spec, 0); SQLTransaction trans = CharacterDatabase.BeginTransaction(); _SaveTalents(trans); @@ -4278,10 +4265,9 @@ bool Player::HasSpell(uint32 spell) const !itr->second->disabled); } -bool Player::HasTalent(uint32 spell, uint8 spec) const +bool Player::HasTalent(uint32 spell, uint8 spec) { - PlayerTalentMap::const_iterator itr = GetTalentMap(spec)->find(spell); - return (itr != GetTalentMap(spec)->end() && itr->second->state != PLAYERSPELL_REMOVED); + return GetTalentSpecInfo(spec)->HasTalent(spell); } bool Player::HasActiveSpell(uint32 spell) const @@ -26142,38 +26128,36 @@ void Player::_SaveTalents(SQLTransaction& trans) { PreparedStatement* stmt = NULL; - for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + for (uint8 spec = 0; spec < MAX_TALENT_SPECS; ++spec) { - for (PlayerTalentMap::iterator itr = GetTalentMap(i)->begin(); itr != GetTalentMap(i)->end();) + TalentSpecInfo* talentSpecInfo = GetTalentSpecInfo(spec); + + for (uint32 tier = 0; tier < MAX_TALENT_TIERS; ++tier) { - if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) + PlayerTalent* talent = &talentSpecInfo->Talents[tier]; + + if (talent->State == PLAYERSPELL_REMOVED || talent->State == PLAYERSPELL_CHANGED) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC); stmt->setUInt64(0, GetGUID().GetCounter()); - stmt->setUInt32(1, itr->first); - stmt->setUInt8(2, itr->second->spec); + stmt->setUInt32(1, talent->SpellID); + stmt->setUInt8(2, spec); trans->Append(stmt); } - if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED) + if (talent->State == PLAYERSPELL_NEW || talent->State == PLAYERSPELL_CHANGED) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_TALENT); stmt->setUInt64(0, GetGUID().GetCounter()); - stmt->setUInt32(1, itr->first); - stmt->setUInt8(2, itr->second->spec); + stmt->setUInt32(1, talent->SpellID); + stmt->setUInt8(2, spec); trans->Append(stmt); } - if (itr->second->state == PLAYERSPELL_REMOVED) - { - delete itr->second; - GetTalentMap(i)->erase(itr++); - } - else - { - itr->second->state = PLAYERSPELL_UNCHANGED; - ++itr; - } + if (talent->State == PLAYERSPELL_REMOVED) + talent->SpellID = 0; + + talent->State = PLAYERSPELL_UNCHANGED; } } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index d1a477ac5e1..19105f49add 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -117,8 +117,8 @@ struct PlayerSpell struct PlayerTalent { - PlayerSpellState state : 8; - uint8 spec : 8; + PlayerSpellState State : 8; + uint32 SpellID : 32; }; extern uint32 const MasterySpells[MAX_CLASSES]; @@ -189,7 +189,6 @@ struct PlayerCurrency uint32 weekCount; }; -typedef std::unordered_map<uint32, PlayerTalent*> PlayerTalentMap; typedef std::unordered_map<uint32, PlayerSpell*> PlayerSpellMap; typedef std::list<SpellModifier*> SpellModList; typedef std::unordered_map<uint32, PlayerCurrency> PlayerCurrenciesMap; @@ -1218,35 +1217,42 @@ private: bool _isPvP; }; -struct PlayerTalentInfo +struct TalentSpecInfo { - PlayerTalentInfo() : ResetTalentsCost(0), ResetTalentsTime(0), ActiveSpec(0), SpecsCount(1) + PlayerTalent Talents[MAX_TALENT_TIERS]; + uint32 Glyphs[MAX_GLYPH_SLOT_INDEX]; + uint32 TalentSpec; + + bool HasTalent(uint32 spellId) { - for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) - { - SpecInfo[i].Talents = new PlayerTalentMap(); - memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32)); - SpecInfo[i].TalentSpec = 0; + for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i) + if (Talents[i].SpellID == spellId) + return true; + return false; + } + + void Reset() + { + for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i) { + Talents[i].State = PLAYERSPELL_REMOVED; + Talents[i].SpellID = 0; } } +}; - ~PlayerTalentInfo() +struct PlayerTalentInfo +{ + PlayerTalentInfo() : ResetTalentsCost(0), ResetTalentsTime(0), ActiveSpec(0), SpecsCount(1) { for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) { - for (PlayerTalentMap::const_iterator itr = SpecInfo[i].Talents->begin(); itr != SpecInfo[i].Talents->end(); ++itr) - delete itr->second; - delete SpecInfo[i].Talents; + memset(SpecInfo[i].Talents, 0, sizeof(PlayerTalent)*MAX_TALENT_TIERS); + memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32)); + SpecInfo[i].TalentSpec = 0; } } - struct TalentSpecInfo - { - PlayerTalentMap* Talents; - uint32 Glyphs[MAX_GLYPH_SLOT_INDEX]; - uint32 TalentSpec; - } SpecInfo[MAX_TALENT_SPECS]; - + TalentSpecInfo SpecInfo[MAX_TALENT_SPECS]; uint32 ResetTalentsCost; time_t ResetTalentsTime; uint8 ActiveSpec; @@ -1835,7 +1841,7 @@ class Player : public Unit, public GridObject<Player> void SendTalentsInfoData(bool pet); bool LearnTalent(uint32 talentId); bool AddTalent(uint32 spellId, uint8 spec, bool learning); - bool HasTalent(uint32 spell_id, uint8 spec) const; + bool HasTalent(uint32 spell_id, uint8 spec); // Dual Spec void UpdateSpecCount(uint8 count); @@ -1848,8 +1854,7 @@ class Player : public Unit, public GridObject<Player> void SetGlyph(uint8 slot, uint32 glyph); uint32 GetGlyph(uint8 spec, uint8 slot) const { return _talentMgr->SpecInfo[spec].Glyphs[slot]; } - PlayerTalentMap const* GetTalentMap(uint8 spec) const { return _talentMgr->SpecInfo[spec].Talents; } - PlayerTalentMap* GetTalentMap(uint8 spec) { return _talentMgr->SpecInfo[spec].Talents; } + TalentSpecInfo* GetTalentSpecInfo(uint8 spec) { return &_talentMgr->SpecInfo[spec]; } ActionButtonList const& GetActionButtons() const { return m_actionButtons; } uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); } |