OregonCore  revision fb2a440-git
Your Favourite TBC server
ItemEnchantmentMgr.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <stdlib.h>
19 #include <functional>
20 #include "ItemEnchantmentMgr.h"
21 #include "Database/DatabaseEnv.h"
22 #include "Log.h"
23 #include "ObjectMgr.h"
24 #include <list>
25 #include <vector>
26 #include "Utilities/Util.h"
27 
29 {
31  float chance;
32 
34  : ench(0), chance(0) {}
35 
36  EnchStoreItem(uint32 _ench, float _chance)
37  : ench(_ench), chance(_chance) {}
38 };
39 
40 typedef std::vector<EnchStoreItem> EnchStoreList;
41 typedef UNORDERED_MAP<uint32, EnchStoreList> EnchantmentStore;
42 
43 static EnchantmentStore RandomItemEnch;
44 
46 {
47  RandomItemEnch.clear(); // for reload case
48 
49  EnchantmentStore::iterator tab;
50  uint32 entry, ench;
51  float chance;
52  uint32 count = 0;
53 
54  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, ench, chance FROM item_enchantment_template");
55 
56  if (result)
57  {
58 
59  do
60  {
61  Field* fields = result->Fetch();
62 
63  entry = fields[0].GetUInt32();
64  ench = fields[1].GetUInt32();
65  chance = fields[2].GetFloat();
66 
67  if (chance > 0.000001f && chance <= 100.0f)
68  RandomItemEnch[entry].push_back(EnchStoreItem(ench, chance));
69 
70  ++count;
71  }
72  while (result->NextRow());
73 
74  sLog.outString(">> Loaded %u Item Enchantment definitions", count);
75  }
76  else
77  sLog.outErrorDb(">> Loaded 0 Item Enchantment definitions. DB table item_enchantment_template is empty.");
78 }
79 
81 {
82  if (!entry) return 0;
83 
84  EnchantmentStore::iterator tab = RandomItemEnch.find(entry);
85 
86  if (tab == RandomItemEnch.end())
87  {
88  sLog.outErrorDb("Item RandomProperty / RandomSuffix id #%u used in item_template but it doesn't have records in item_enchantment_template table.", entry);
89  return 0;
90  }
91 
92  double dRoll = rand_chance();
93  float fCount = 0;
94 
95  for (EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
96  {
97  fCount += ench_iter->chance;
98 
99  if (fCount > dRoll) return ench_iter->ench;
100  }
101 
102  //we could get here only if sum of all enchantment chances is lower than 100%
103  dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
104  fCount = 0;
105 
106  for (EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
107  {
108  fCount += ench_iter->chance;
109 
110  if (fCount > dRoll) return ench_iter->ench;
111  }
112 
113  return 0;
114 }
115 
117 {
118  ItemTemplate const* itemProto = sObjectMgr.GetItemTemplate(item_id);
119 
120  if (!itemProto)
121  return 0;
122  if (!itemProto->RandomSuffix)
123  return 0;
124 
125  RandomPropertiesPointsEntry const* randomProperty = sRandomPropertiesPointsStore.LookupEntry(itemProto->ItemLevel);
126  if (!randomProperty)
127  return 0;
128 
129  uint32 suffixFactor;
130  switch (itemProto->InventoryType)
131  {
132  // Items of that type don`t have points
133  case INVTYPE_NON_EQUIP:
134  case INVTYPE_BAG:
135  case INVTYPE_TABARD:
136  case INVTYPE_AMMO:
137  case INVTYPE_QUIVER:
138  case INVTYPE_RELIC:
139  return 0;
140  // Select point coefficient
141  case INVTYPE_HEAD:
142  case INVTYPE_BODY:
143  case INVTYPE_CHEST:
144  case INVTYPE_LEGS:
145  case INVTYPE_2HWEAPON:
146  case INVTYPE_ROBE:
147  suffixFactor = 0;
148  break;
149  case INVTYPE_SHOULDERS:
150  case INVTYPE_WAIST:
151  case INVTYPE_FEET:
152  case INVTYPE_HANDS:
153  case INVTYPE_TRINKET:
154  suffixFactor = 1;
155  break;
156  case INVTYPE_NECK:
157  case INVTYPE_WRISTS:
158  case INVTYPE_FINGER:
159  case INVTYPE_SHIELD:
160  case INVTYPE_CLOAK:
161  case INVTYPE_HOLDABLE:
162  suffixFactor = 2;
163  break;
164  case INVTYPE_WEAPON:
167  suffixFactor = 3;
168  break;
169  case INVTYPE_RANGED:
170  case INVTYPE_THROWN:
171  case INVTYPE_RANGEDRIGHT:
172  suffixFactor = 4;
173  break;
174  default:
175  return 0;
176  }
177  // Select rare/epic modifier
178  switch (itemProto->Quality)
179  {
181  return randomProperty->UncommonPropertiesPoints[suffixFactor];
182  case ITEM_QUALITY_RARE:
183  return randomProperty->RarePropertiesPoints[suffixFactor];
184  case ITEM_QUALITY_EPIC:
185  return randomProperty->EpicPropertiesPoints[suffixFactor];
188  return 0; // not have random properties
189  default:
190  break;
191  }
192  return 0;
193 }
194 
uint32 ItemLevel
uint32 GetItemEnchantMod(uint32 entry)
uint32 InventoryType
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
std::vector< EnchStoreItem > EnchStoreList
Definition: Field.h:24
int32 irand(int32 min, int32 max)
Definition: Util.cpp:28
#define sLog
Log class singleton.
Definition: Log.h:187
QueryResult_AutoPtr Query(const char *sql)
Definition: Database.cpp:383
#define sObjectMgr
Definition: ObjectMgr.h:1285
uint32 RandomSuffix
DBCStorage< RandomPropertiesPointsEntry > sRandomPropertiesPointsStore(RandomPropertiesPointsfmt)
UNORDERED_MAP< uint32, EnchStoreList > EnchantmentStore
EnchStoreItem(uint32 _ench, float _chance)
void LoadRandomEnchantmentsTable()
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
double rand_chance()
Definition: Util.cpp:53
uint32 GenerateEnchSuffixFactor(uint32 item_id)
ACE_UINT32 uint32
Definition: Define.h:71