2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
25 #include "WorldPacket.h"
26 #include "WorldSession.h"
27 #include "ObjectAccessor.h"
28 #include "UpdateMask.h"
29 #include "SpellAuras.h"
31 void WorldSession::HandleLearnTalentOpcode( WorldPacket
& recv_data
)
33 CHECK_PACKET_SIZE(recv_data
,4+4);
35 uint32 talent_id
, requested_rank
;
36 recv_data
>> talent_id
>> requested_rank
;
38 uint32 CurTalentPoints
= GetPlayer()->GetFreeTalentPoints();
40 if(CurTalentPoints
== 0)
43 if (requested_rank
> 4)
46 TalentEntry
const *talentInfo
= sTalentStore
.LookupEntry( talent_id
);
51 TalentTabEntry
const *talentTabInfo
= sTalentTabStore
.LookupEntry( talentInfo
->TalentTab
);
56 Player
* player
= GetPlayer();
58 // prevent learn talent for different class (cheating)
59 if( (player
->getClassMask() & talentTabInfo
->ClassMask
) == 0 )
62 // prevent skip talent ranks (cheating)
63 if(requested_rank
> 0 && !player
->HasSpell(talentInfo
->RankID
[requested_rank
-1]))
66 // Check if it requires another talent
67 if (talentInfo
->DependsOn
> 0)
69 if(TalentEntry
const *depTalentInfo
= sTalentStore
.LookupEntry(talentInfo
->DependsOn
))
71 bool hasEnoughRank
= false;
72 for (int i
= talentInfo
->DependsOnRank
; i
<= 4; i
++)
74 if (depTalentInfo
->RankID
[i
] != 0)
75 if (player
->HasSpell(depTalentInfo
->RankID
[i
]))
83 // Find out how many points we have in this field
84 uint32 spentPoints
= 0;
86 uint32 tTab
= talentInfo
->TalentTab
;
87 if (talentInfo
->Row
> 0)
89 unsigned int numRows
= sTalentStore
.GetNumRows();
90 for (unsigned int i
= 0; i
< numRows
; i
++) // Loop through all talents.
92 // Someday, someone needs to revamp
93 const TalentEntry
*tmpTalent
= sTalentStore
.LookupEntry(i
);
94 if (tmpTalent
) // the way talents are tracked
96 if (tmpTalent
->TalentTab
== tTab
)
98 for (int j
= 0; j
<= 4; j
++)
100 if (tmpTalent
->RankID
[j
] != 0)
102 if (player
->HasSpell(tmpTalent
->RankID
[j
]))
104 spentPoints
+= j
+ 1;
113 // not have required min points spent in talent tree
114 if(spentPoints
< (talentInfo
->Row
* 5))
117 // spell not set in talent.dbc
118 uint32 spellid
= talentInfo
->RankID
[requested_rank
];
121 sLog
.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id
, requested_rank
);
126 if(GetPlayer( )->HasSpell(spellid
))
129 // learn! (other talent ranks will unlearned at learning)
130 GetPlayer( )->learnSpell(spellid
);
131 sLog
.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id
, requested_rank
, spellid
);
133 // update free talent points
134 GetPlayer()->SetFreeTalentPoints(CurTalentPoints
- 1);
137 void WorldSession::HandleTalentWipeOpcode( WorldPacket
& recv_data
)
139 CHECK_PACKET_SIZE(recv_data
,8);
141 sLog
.outDetail("MSG_TALENT_WIPE_CONFIRM");
145 Creature
*unit
= ObjectAccessor::GetNPCIfCanInteractWith(*_player
, guid
,UNIT_NPC_FLAG_TRAINER
);
148 sLog
.outDebug( "WORLD: HandleTalentWipeOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid
)) );
153 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED
))
154 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH
);
156 if(!(_player
->resetTalents()))
158 WorldPacket
data( MSG_TALENT_WIPE_CONFIRM
, 8+4); //you have not any talent
165 unit
->CastSpell(_player
, 14867, true); //spell: "Untalent Visual Effect"
168 void WorldSession::HandleUnlearnSkillOpcode(WorldPacket
& recv_data
)
170 CHECK_PACKET_SIZE(recv_data
,4);
173 recv_data
>> skill_id
;
174 GetPlayer()->SetSkill(skill_id
, 0, 0);