Updated Copyright year to 2013
[getmangos.git] / src / game / ItemEnchantmentMgr.cpp
blobe3ac804ae63e01a10db9bb9ea99cb06581a781cb
1 /*
2 * Copyright (C) 2005-2013 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::const_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;
76 while (result->NextRow());
78 delete result;
80 sLog.outString();
81 sLog.outString(">> Loaded %u Item Enchantment definitions", count);
83 else
85 sLog.outString();
86 sLog.outErrorDb(">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
90 uint32 GetItemEnchantMod(uint32 entry)
92 if (!entry) return 0;
94 EnchantmentStore::const_iterator tab = RandomItemEnch.find(entry);
96 if (tab == RandomItemEnch.end())
98 sLog.outErrorDb("Item RandomProperty / RandomSuffix id #%u used in `item_template` but it doesn't have records in `item_enchantment_template` table.", entry);
99 return 0;
102 double dRoll = rand_chance();
103 float fCount = 0;
105 for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
107 fCount += ench_iter->chance;
109 if (fCount > dRoll) return ench_iter->ench;
112 // we could get here only if sum of all enchantment chances is lower than 100%
113 dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
114 fCount = 0;
116 for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
118 fCount += ench_iter->chance;
120 if (fCount > dRoll) return ench_iter->ench;
123 return 0;
126 uint32 GenerateEnchSuffixFactor(uint32 item_id)
128 ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(item_id);
130 if (!itemProto)
131 return 0;
132 if (!itemProto->RandomSuffix)
133 return 0;
135 RandomPropertiesPointsEntry const* randomProperty = sRandomPropertiesPointsStore.LookupEntry(itemProto->ItemLevel);
136 if (!randomProperty)
137 return 0;
139 uint32 suffixFactor;
140 switch (itemProto->InventoryType)
142 // Items of that type don`t have points
143 case INVTYPE_NON_EQUIP:
144 case INVTYPE_BAG:
145 case INVTYPE_TABARD:
146 case INVTYPE_AMMO:
147 case INVTYPE_QUIVER:
148 case INVTYPE_RELIC:
149 return 0;
150 // Select point coefficient
151 case INVTYPE_HEAD:
152 case INVTYPE_BODY:
153 case INVTYPE_CHEST:
154 case INVTYPE_LEGS:
155 case INVTYPE_2HWEAPON:
156 case INVTYPE_ROBE:
157 suffixFactor = 0;
158 break;
159 case INVTYPE_SHOULDERS:
160 case INVTYPE_WAIST:
161 case INVTYPE_FEET:
162 case INVTYPE_HANDS:
163 case INVTYPE_TRINKET:
164 suffixFactor = 1;
165 break;
166 case INVTYPE_NECK:
167 case INVTYPE_WRISTS:
168 case INVTYPE_FINGER:
169 case INVTYPE_SHIELD:
170 case INVTYPE_CLOAK:
171 case INVTYPE_HOLDABLE:
172 suffixFactor = 2;
173 break;
174 case INVTYPE_WEAPON:
175 case INVTYPE_WEAPONMAINHAND:
176 case INVTYPE_WEAPONOFFHAND:
177 suffixFactor = 3;
178 break;
179 case INVTYPE_RANGED:
180 case INVTYPE_THROWN:
181 case INVTYPE_RANGEDRIGHT:
182 suffixFactor = 4;
183 break;
184 default:
185 return 0;
187 // Select rare/epic modifier
188 switch (itemProto->Quality)
190 case ITEM_QUALITY_UNCOMMON:
191 return randomProperty->UncommonPropertiesPoints[suffixFactor];
192 case ITEM_QUALITY_RARE:
193 return randomProperty->RarePropertiesPoints[suffixFactor];
194 case ITEM_QUALITY_EPIC:
195 return randomProperty->EpicPropertiesPoints[suffixFactor];
196 case ITEM_QUALITY_LEGENDARY:
197 case ITEM_QUALITY_ARTIFACT:
198 return 0; // not have random properties
199 default:
200 break;
202 return 0;