OregonCore  revision fb2a440-git
Your Favourite TBC server
SkillHandler.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "Opcodes.h"
20 #include "Log.h"
21 #include "Player.h"
22 #include "World.h"
23 #include "WorldPacket.h"
24 #include "WorldSession.h"
25 #include "ObjectAccessor.h"
26 #include "SpellAuras.h"
27 
29 {
30  uint32 talent_id, requested_rank;
31  recv_data >> talent_id >> requested_rank;
32 
33  uint32 CurTalentPoints = GetPlayer()->GetFreeTalentPoints();
34 
35  if (CurTalentPoints == 0)
36  return;
37 
38  if (requested_rank > 4)
39  return;
40 
41  TalentEntry const* talentInfo = sTalentStore.LookupEntry(talent_id);
42 
43  if (!talentInfo)
44  return;
45 
46  TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
47 
48  if (!talentTabInfo)
49  return;
50 
51  Player* player = GetPlayer();
52 
53  // prevent learn talent for different class (cheating)
54  if ((player->getClassMask() & talentTabInfo->ClassMask) == 0)
55  return;
56 
57  // prevent skip talent ranks (cheating)
58  if (requested_rank > 0 && !player->HasSpell(talentInfo->RankID[requested_rank - 1]))
59  return;
60 
61  // Check if it requires another talent
62  if (talentInfo->DependsOn > 0)
63  {
64  if (TalentEntry const* depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
65  {
66  bool hasEnoughRank = false;
67  for (int i = talentInfo->DependsOnRank; i <= 4; i++)
68  {
69  if (depTalentInfo->RankID[i] != 0)
70  if (player->HasSpell(depTalentInfo->RankID[i]))
71  hasEnoughRank = true;
72  }
73  if (!hasEnoughRank)
74  return;
75  }
76  }
77 
78  // Check if it requires spell
79  if (talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell))
80  return;
81 
82  // Find out how many points we have in this field
83  uint32 spentPoints = 0;
84 
85  uint32 tTab = talentInfo->TalentTab;
86  if (talentInfo->Row > 0)
87  {
88  unsigned int numRows = sTalentStore.GetNumRows();
89  for (unsigned int i = 0; i < numRows; i++) // Loop through all talents.
90  {
91  // Someday, someone needs to revamp
92  const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i);
93  if (tmpTalent) // the way talents are tracked
94  {
95  if (tmpTalent->TalentTab == tTab)
96  {
97  for (int j = 0; j <= 4; j++)
98  {
99  if (tmpTalent->RankID[j] != 0)
100  {
101  if (player->HasSpell(tmpTalent->RankID[j]))
102  spentPoints += j + 1;
103  }
104  }
105  }
106  }
107  }
108  }
109 
110  // not have required min points spent in talent tree
111  if (spentPoints < (talentInfo->Row * 5))
112  return;
113 
114  // spell not set in talent.dbc
115  uint32 spellid = talentInfo->RankID[requested_rank];
116  if (spellid == 0)
117  {
118  sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank);
119  return;
120  }
121 
122  // already known
123  if (GetPlayer()->HasSpell(spellid))
124  return;
125 
126  // learn! (other talent ranks will unlearned at learning)
127  GetPlayer()->LearnSpell(spellid);
128  sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
129 
130  // update free talent points
131  GetPlayer()->SetFreeTalentPoints(CurTalentPoints - 1);
132 }
133 
135 {
136  sLog.outDetail("MSG_TALENT_WIPE_CONFIRM");
137  uint64 guid;
138  recv_data >> guid;
139 
141  if (!unit)
142  {
143  sLog.outDebug("WORLD: HandleTalentWipeOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
144  return;
145  }
146 
147  // remove fake death
150 
151  if (!(_player->ResetTalents()))
152  {
153  WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8 + 4); //you have not any talent
154  data << uint64(0);
155  data << uint32(0);
156  SendPacket(&data);
157  return;
158  }
159 
160  unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect"
161 }
162 
164 {
165  uint32 skill_id;
166  recv_data >> skill_id;
167  GetPlayer()->SetSkill(skill_id, 0, 0);
168 }
169 
uint32 DependsOnRank
Definition: DBCStructure.h:938
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
bool ResetTalents(bool no_cost=false)
Definition: Player.cpp:3465
uint32 DependsOnSpell
Definition: DBCStructure.h:940
void HandleLearnTalentOpcode(WorldPacket &recvPacket)
void SetFreeTalentPoints(uint32 points)
Definition: Player.h:1661
uint32 DependsOn
Definition: DBCStructure.h:936
void RemoveSpellsCausingAura(AuraType auraType)
Definition: Unit.cpp:697
#define sLog
Log class singleton.
Definition: Log.h:187
Player * GetPlayer() const
Definition: WorldSession.h:104
void SendPacket(WorldPacket const *packet)
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3755
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
uint32 TalentTab
Definition: DBCStructure.h:931
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1223
ACE_UINT64 uint64
Definition: Define.h:70
uint32 getClassMask() const
Definition: Unit.h:1063
uint32 RankID[5]
Definition: DBCStructure.h:934
DBCStorage< TalentTabEntry > sTalentTabStore(TalentTabEntryfmt)
Player * _player
Definition: WorldSession.h:730
void HandleTalentWipeOpcode(WorldPacket &recvPacket)
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1030
void SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5374
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition: Player.cpp:2130
ACE_UINT32 uint32
Definition: Define.h:71
Definition: Player.h:922
void LearnSpell(uint32 spell_id)
Definition: Player.cpp:3140
void HandleUnlearnSkillOpcode(WorldPacket &recvPacket)
uint32 GetFreeTalentPoints() const
Definition: Player.h:1657