root/trunk/src/game/SkillDiscovery.cpp @ 22

Revision 2, 5.9 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "Database/DatabaseEnv.h"
20#include "Log.h"
21#include "ProgressBar.h"
22#include "Policies/SingletonImp.h"
23#include "ObjectAccessor.h"
24#include "World.h"
25#include "Util.h"
26#include "SkillDiscovery.h"
27#include "SpellMgr.h"
28#include <map>
29
30struct SkillDiscoveryEntry
31{
32    uint32  spellId;
33    float   chance;
34
35    SkillDiscoveryEntry()
36        : spellId(0), chance(0) {}
37
38    SkillDiscoveryEntry(uint16 _spellId, float _chance)
39        : spellId(_spellId), chance(_chance) {}
40};
41
42typedef std::list<SkillDiscoveryEntry> SkillDiscoveryList;
43typedef HM_NAMESPACE::hash_map<int32, SkillDiscoveryList> SkillDiscoveryMap;
44
45static SkillDiscoveryMap SkillDiscoveryStore;
46
47void LoadSkillDiscoveryTable()
48{
49
50    SkillDiscoveryStore.clear();                            // need for reload
51
52    uint32 count = 0;
53
54    //                                                 0        1         2
55    QueryResult *result = WorldDatabase.PQuery("SELECT spellId, reqSpell, chance FROM skill_discovery_template");
56
57    if (result)
58    {
59        barGoLink bar(result->GetRowCount());
60
61        std::ostringstream ssNonDiscoverableEntries;
62
63        do
64        {
65            Field *fields = result->Fetch();
66            bar.step();
67
68            uint32 spellId         = fields[0].GetUInt32();
69            int32  reqSkillOrSpell = fields[1].GetInt32();
70            float  chance          = fields[2].GetFloat();
71
72            if( chance <= 0 )                               // chance
73            {
74                ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " chance = " << chance << "\n";
75                continue;
76            }
77
78            if(reqSkillOrSpell > 0)                         // spell case
79            {
80                SpellEntry const* spellEntry = sSpellStore.LookupEntry(reqSkillOrSpell);
81                if( !spellEntry )
82                {
83                    sLog.outErrorDb("Spell (ID: %u) have not existed spell (ID: %i) in `reqSpell` field in `skill_discovery_template` table",spellId,reqSkillOrSpell);
84                    continue;
85                }
86
87                if( spellEntry->Mechanic != MECHANIC_DISCOVERY )
88                {
89                    sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc but listed in `skill_discovery_template` table",spellId);
90                    continue;
91                }
92
93                SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, chance) );
94            }
95            else if( reqSkillOrSpell == 0 )                 // skill case
96            {
97                SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellId);
98                SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellId);
99
100                if(lower==upper)
101                {
102                    sLog.outErrorDb("Spell (ID: %u) not listed in `SkillLineAbility.dbc` but listed with `reqSpell`=0 in `skill_discovery_template` table",spellId);
103                    continue;
104                }
105
106                for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
107                {
108                    SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, chance) );
109                }
110            }
111            else
112            {
113                sLog.outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table",spellId);
114                continue;
115            }
116            ++count;
117        } while (result->NextRow());
118
119        delete result;
120
121        sLog.outString();
122        sLog.outString( ">> Loaded %u skill discovery definitions", count );
123        if(!ssNonDiscoverableEntries.str().empty())
124            sLog.outErrorDb("Some items can't be successfully discovered: have in chance field value < 0.000001 in `skill_discovery_template` DB table . List:\n%s",ssNonDiscoverableEntries.str().c_str());
125    }
126    else
127    {
128        sLog.outString();
129        sLog.outString( ">> Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty." );
130    }
131}
132
133uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
134{
135    // check spell case
136    SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId);
137
138    if(tab != SkillDiscoveryStore.end())
139    {
140        for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
141        {
142            if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))
143                && !player->HasSpell(item_iter->spellId) )
144                return item_iter->spellId;
145        }
146
147        return 0;
148    }
149
150    // check skill line case
151    tab = SkillDiscoveryStore.find(-(int32)skillId);
152    if(tab != SkillDiscoveryStore.end())
153    {
154        for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
155        {
156            if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))
157                && !player->HasSpell(item_iter->spellId) )
158                return item_iter->spellId;
159        }
160
161        return 0;
162    }
163
164    return 0;
165}
Note: See TracBrowser for help on using the browser.