2 * Copyright (C) 2005,2006 MaNGOS <http://www.mangosproject.org/>
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 "ObjectMgr.h"
28 #include "UpdateMask.h"
29 #include "SpellAuras.h"
31 void WorldSession::HandleLearnTalentOpcode( WorldPacket
& recv_data
)
34 uint32 talent_id
, requested_rank
;
35 recv_data
>> talent_id
>> requested_rank
;
37 uint32 CurTalentPoints
= GetPlayer()->GetUInt32Value(PLAYER_CHARACTER_POINTS1
);
38 if(CurTalentPoints
== 0)
41 if (requested_rank
> 4)
44 TalentEntry
*talentInfo
= sTalentStore
.LookupEntry( talent_id
);
49 TalentTabEntry
*talentTabInfo
= sTalentTabStore
.LookupEntry( talentInfo
->TalentTab
);
54 Player
* player
= GetPlayer();
56 // prevent learn talent for different class (cheating)
57 if( (player
->getClassMask() & talentTabInfo
->ClassMask
) == 0 )
60 // prevent skip talent ranks (cheating)
61 if(requested_rank
> 0 && !player
->HasSpell(talentInfo
->RankID
[requested_rank
-1]))
64 // Check if it requires another talent
65 if (talentInfo
->DependsOn
> 0)
67 TalentEntry
*depTalentInfo
= sTalentStore
.LookupEntry(talentInfo
->DependsOn
);
68 bool hasEnoughRank
= false;
69 for (int i
= talentInfo
->DependsOnRank
; i
<= 4; i
++)
71 if (depTalentInfo
->RankID
[i
] != 0)
72 if (player
->HasSpell(depTalentInfo
->RankID
[i
]))
79 // Find out how many points we have in this field
80 uint32 spentPoints
= 0;
82 uint32 tTab
= talentInfo
->TalentTab
;
83 if (talentInfo
->Row
> 0)
85 unsigned int numRows
= sTalentStore
.GetNumRows();
86 for (unsigned int i
= 0; i
< numRows
; i
++) // Loop through all talents.
88 // Someday, someone needs to revamp
89 TalentEntry
*tmpTalent
= sTalentStore
.data
[i
];
90 if (tmpTalent
) // the way talents are tracked
92 if (tmpTalent
->TalentTab
== tTab
)
94 for (int j
= 0; j
<= 4; j
++)
96 if (tmpTalent
->RankID
[j
] != 0)
98 if (player
->HasSpell(tmpTalent
->RankID
[j
]))
100 spentPoints
+= j
+ 1;
109 uint32 spellid
= talentInfo
->RankID
[requested_rank
];
112 sLog
.outDetail("Talent: %u Rank: %u = 0", talent_id
, requested_rank
);
116 if(spentPoints
< (talentInfo
->Row
* 5)) // Min points spent
121 if(!(GetPlayer( )->HasSpell(spellid
)))
123 if(!GetPlayer( )->addSpell((uint16
)spellid
,1))
126 data
.Initialize(SMSG_LEARNED_SPELL
);
127 sLog
.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id
, requested_rank
, spellid
);
129 GetPlayer( )->GetSession()->SendPacket(&data
);
131 SpellEntry
*spellInfo
= sSpellStore
.LookupEntry( spellid
);
132 assert(spellInfo
); // checked in addSpell
134 // already apply in addSpell function
135 //for(uint32 i = 0;i<3;i++)
137 // uint8 eff = spellInfo->Effect[i];
138 // if (eff>=TOTAL_SPELL_EFFECTS)
141 // // Duration 21 = permanent
142 // if ((eff == 6) && (spellInfo->DurationIndex == 21) && (spellInfo->rangeIndex == 1))
144 // Aura *Aur = new Aura(spellInfo, i, GetPlayer());
145 // GetPlayer()->AddAura(Aur);
149 if(requested_rank
> 0 )
151 uint32 respellid
= talentInfo
->RankID
[requested_rank
-1];
152 GetPlayer( )->removeSpell((uint16
)respellid
);
153 GetPlayer()->RemoveAurasDueToSpell(respellid
);
155 GetPlayer()->SetUInt32Value(PLAYER_CHARACTER_POINTS1
, CurTalentPoints
- 1);
160 void WorldSession::HandleTalentWipeOpcode( WorldPacket
& recv_data
)
162 sLog
.outString("MSG_TALENT_WIPE_CONFIRM");
166 Creature
*unit
= ObjectAccessor::Instance().GetCreature(*_player
, guid
);
170 sLog
.outDebug( "WORLD: HandleTalentWipeOpcode - NO SUCH UNIT! (GUID: %u)", uint32(GUID_LOPART(guid
)) );
174 if( unit
->IsHostileTo(_player
)) // do not talk with enemies
177 if( !unit
->isTrainer()) // it's not trainer
180 if(!(_player
->resetTalents()))
183 data
.Initialize( MSG_TALENT_WIPE_CONFIRM
); //you have not any talent
190 data
.Initialize(SMSG_SPELL_START
);
191 data
.append(_player
->GetPackGUID());
192 data
.append(unit
->GetPackGUID());
193 data
<< uint16(14867) << uint16(0x00) << uint16(0x0F) << uint32(0x00)<< uint16(0x00);
196 data
.Initialize(SMSG_SPELL_GO
);
197 data
.append(_player
->GetPackGUID());
198 data
.append(unit
->GetPackGUID());
199 data
<< uint16(14867) << uint16(0x00) << uint8(0x0D) << uint8(0x01)<< uint8(0x01) << _player
->GetGUID();
200 data
<< uint32(0x00) << uint16(0x0200) << uint16(0x00);
204 void WorldSession::HandleUnlearnSkillOpcode(WorldPacket
& recv_data
)
207 recv_data
>> skill_id
;
208 GetPlayer()->SetSkill(skill_id
, 0, 0);