root/trunk/src/game/SkillHandler.cpp @ 242

Revision 102, 5.5 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed copyright notices to comply with GPL.

Original author: w12x
Date: 2008-10-23 03:29:52-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Common.h"
22#include "Database/DatabaseEnv.h"
23#include "Opcodes.h"
24#include "Log.h"
25#include "Player.h"
26#include "World.h"
27#include "WorldPacket.h"
28#include "WorldSession.h"
29#include "ObjectAccessor.h"
30#include "UpdateMask.h"
31#include "SpellAuras.h"
32
33void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
34{
35    CHECK_PACKET_SIZE(recv_data,4+4);
36
37    uint32 talent_id, requested_rank;
38    recv_data >> talent_id >> requested_rank;
39
40    uint32 CurTalentPoints =  GetPlayer()->GetFreeTalentPoints();
41
42    if(CurTalentPoints == 0)
43        return;
44
45    if (requested_rank > 4)
46        return;
47
48    TalentEntry const *talentInfo = sTalentStore.LookupEntry( talent_id );
49
50    if(!talentInfo)
51        return;
52
53    TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
54
55    if(!talentTabInfo)
56        return;
57
58    Player * player = GetPlayer();
59
60    // prevent learn talent for different class (cheating)
61    if( (player->getClassMask() & talentTabInfo->ClassMask) == 0 )
62        return;
63
64    // prevent skip talent ranks (cheating)
65    if(requested_rank > 0 && !player->HasSpell(talentInfo->RankID[requested_rank-1]))
66        return;
67
68    // Check if it requires another talent
69    if (talentInfo->DependsOn > 0)
70    {
71        if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
72        {
73            bool hasEnoughRank = false;
74            for (int i = talentInfo->DependsOnRank; i <= 4; i++)
75            {
76                if (depTalentInfo->RankID[i] != 0)
77                    if (player->HasSpell(depTalentInfo->RankID[i]))
78                        hasEnoughRank = true;
79            }
80            if (!hasEnoughRank)
81                return;
82        }
83    }
84
85    // Check if it requires spell
86    if( talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) )
87        return;
88
89    // Find out how many points we have in this field
90    uint32 spentPoints = 0;
91
92    uint32 tTab = talentInfo->TalentTab;
93    if (talentInfo->Row > 0)
94    {
95        unsigned int numRows = sTalentStore.GetNumRows();
96        for (unsigned int i = 0; i < numRows; i++)          // Loop through all talents.
97        {
98            // Someday, someone needs to revamp
99            const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
100            if (tmpTalent)                                  // the way talents are tracked
101            {
102                if (tmpTalent->TalentTab == tTab)
103                {
104                    for (int j = 0; j <= 4; j++)
105                    {
106                        if (tmpTalent->RankID[j] != 0)
107                        {
108                            if (player->HasSpell(tmpTalent->RankID[j]))
109                            {
110                                spentPoints += j + 1;
111                            }
112                        }
113                    }
114                }
115            }
116        }
117    }
118
119    // not have required min points spent in talent tree
120    if(spentPoints < (talentInfo->Row * 5))
121        return;
122
123    // spell not set in talent.dbc
124    uint32 spellid = talentInfo->RankID[requested_rank];
125    if( spellid == 0 )
126    {
127        sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank);
128        return;
129    }
130
131    // already known
132    if(GetPlayer( )->HasSpell(spellid))
133        return;
134
135    // learn! (other talent ranks will unlearned at learning)
136    GetPlayer( )->learnSpell(spellid);
137    sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
138
139    // update free talent points
140    GetPlayer()->SetFreeTalentPoints(CurTalentPoints - 1);
141}
142
143void WorldSession::HandleTalentWipeOpcode( WorldPacket & recv_data )
144{
145    CHECK_PACKET_SIZE(recv_data,8);
146
147    sLog.outDetail("MSG_TALENT_WIPE_CONFIRM");
148    uint64 guid;
149    recv_data >> guid;
150
151    Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TRAINER);
152    if (!unit)
153    {
154        sLog.outDebug( "WORLD: HandleTalentWipeOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
155        return;
156    }
157
158    // remove fake death
159    if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
160        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
161
162    if(!(_player->resetTalents()))
163    {
164        WorldPacket data( MSG_TALENT_WIPE_CONFIRM, 8+4);    //you have not any talent
165        data << uint64(0);
166        data << uint32(0);
167        SendPacket( &data );
168        return;
169    }
170
171    unit->CastSpell(_player, 14867, true);                  //spell: "Untalent Visual Effect"
172}
173
174void WorldSession::HandleUnlearnSkillOpcode(WorldPacket & recv_data)
175{
176    CHECK_PACKET_SIZE(recv_data,4);
177
178    uint32 skill_id;
179    recv_data >> skill_id;
180    GetPlayer()->SetSkill(skill_id, 0, 0);
181}
Note: See TracBrowser for help on using the browser.