[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / src / game / ItemEnchantmentMgr.cpp
blobea9e7ef18e0c1609c54ae20e5f9bdab49bfd8111
1 /*
2 * Copyright (C) 2005-2009 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
19 #include <stdlib.h>
20 #include <functional>
21 #include "ItemEnchantmentMgr.h"
22 #include "Database/DatabaseEnv.h"
23 #include "Log.h"
24 #include "ObjectMgr.h"
25 #include "ProgressBar.h"
26 #include <list>
27 #include <vector>
28 #include "Util.h"
30 struct EnchStoreItem
32 uint32 ench;
33 float chance;
35 EnchStoreItem()
36 : ench(0), chance(0) {}
38 EnchStoreItem(uint32 _ench, float _chance)
39 : ench(_ench), chance(_chance) {}
42 typedef std::vector<EnchStoreItem> EnchStoreList;
43 typedef UNORDERED_MAP<uint32, EnchStoreList> EnchantmentStore;
45 static EnchantmentStore RandomItemEnch;
47 void LoadRandomEnchantmentsTable()
49 RandomItemEnch.clear(); // for reload case
51 EnchantmentStore::iterator tab;
52 uint32 entry, ench;
53 float chance;
54 uint32 count = 0;
56 QueryResult *result = WorldDatabase.Query("SELECT entry, ench, chance FROM item_enchantment_template");
58 if (result)
60 barGoLink bar(result->GetRowCount());
64 Field *fields = result->Fetch();
65 bar.step();
67 entry = fields[0].GetUInt32();
68 ench = fields[1].GetUInt32();
69 chance = fields[2].GetFloat();
71 if (chance > 0.000001f && chance <= 100.0f)
72 RandomItemEnch[entry].push_back( EnchStoreItem(ench, chance) );
74 ++count;
75 } while (result->NextRow());
77 delete result;
79 sLog.outString();
80 sLog.outString( ">> Loaded %u Item Enchantment definitions", count );
82 else
84 sLog.outString();
85 sLog.outErrorDb( ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
89 uint32 GetItemEnchantMod(uint32 entry)
91 if (!entry) return 0;
93 EnchantmentStore::iterator tab = RandomItemEnch.find(entry);
95 if (tab == RandomItemEnch.end())
97 sLog.outErrorDb("Item RandomProperty / RandomSuffix id #%u used in `item_template` but it doesn't have records in `item_enchantment_template` table.",entry);
98 return 0;
101 double dRoll = rand_chance();
102 float fCount = 0;
104 for(EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
106 fCount += ench_iter->chance;
108 if (fCount > dRoll) return ench_iter->ench;
111 //we could get here only if sum of all enchantment chances is lower than 100%
112 dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
113 fCount = 0;
115 for(EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
117 fCount += ench_iter->chance;
119 if (fCount > dRoll) return ench_iter->ench;
122 return 0;
125 uint32 GenerateEnchSuffixFactor(uint32 item_id)
127 ItemPrototype const *itemProto = objmgr.GetItemPrototype(item_id);
129 if(!itemProto)
130 return 0;
131 if(!itemProto->RandomSuffix)
132 return 0;
134 RandomPropertiesPointsEntry const *randomProperty = sRandomPropertiesPointsStore.LookupEntry(itemProto->ItemLevel);
135 if(!randomProperty)
136 return 0;
138 uint32 suffixFactor;
139 switch(itemProto->InventoryType)
141 // Items of that type don`t have points
142 case INVTYPE_NON_EQUIP:
143 case INVTYPE_BAG:
144 case INVTYPE_TABARD:
145 case INVTYPE_AMMO:
146 case INVTYPE_QUIVER:
147 case INVTYPE_RELIC:
148 return 0;
149 // Select point coefficient
150 case INVTYPE_HEAD:
151 case INVTYPE_BODY:
152 case INVTYPE_CHEST:
153 case INVTYPE_LEGS:
154 case INVTYPE_2HWEAPON:
155 case INVTYPE_ROBE:
156 suffixFactor = 0;
157 break;
158 case INVTYPE_SHOULDERS:
159 case INVTYPE_WAIST:
160 case INVTYPE_FEET:
161 case INVTYPE_HANDS:
162 case INVTYPE_TRINKET:
163 suffixFactor = 1;
164 break;
165 case INVTYPE_NECK:
166 case INVTYPE_WRISTS:
167 case INVTYPE_FINGER:
168 case INVTYPE_SHIELD:
169 case INVTYPE_CLOAK:
170 case INVTYPE_HOLDABLE:
171 suffixFactor = 2;
172 break;
173 case INVTYPE_WEAPON:
174 case INVTYPE_WEAPONMAINHAND:
175 case INVTYPE_WEAPONOFFHAND:
176 suffixFactor = 3;
177 break;
178 case INVTYPE_RANGED:
179 case INVTYPE_THROWN:
180 case INVTYPE_RANGEDRIGHT:
181 suffixFactor = 4;
182 break;
183 default:
184 return 0;
186 // Select rare/epic modifier
187 switch (itemProto->Quality)
189 case ITEM_QUALITY_UNCOMMON:
190 return randomProperty->UncommonPropertiesPoints[suffixFactor];
191 case ITEM_QUALITY_RARE:
192 return randomProperty->RarePropertiesPoints[suffixFactor];
193 case ITEM_QUALITY_EPIC:
194 return randomProperty->EpicPropertiesPoints[suffixFactor];
195 case ITEM_QUALITY_LEGENDARY:
196 case ITEM_QUALITY_ARTIFACT:
197 return 0; // not have random properties
198 default:
199 break;
201 return 0;