TrinityCore
ItemEnchantmentMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore 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 "ItemEnchantmentMgr.h"
19#include "Containers.h"
20#include "DatabaseEnv.h"
21#include "DB2Stores.h"
22#include "ItemBonusMgr.h"
23#include "ItemTemplate.h"
24#include "Log.h"
25#include "ObjectMgr.h"
26#include "Timer.h"
27#include <list>
28#include <vector>
29
30namespace
31{
32 struct RandomBonusListIds
33 {
34 std::vector<int32> BonusListIDs;
35 std::vector<double> Chances;
36 };
37
38 std::unordered_map<uint32, RandomBonusListIds> _storage;
39}
40
42{
43 uint32 oldMSTime = getMSTime();
44
45 _storage.clear();
46
47 // 0 1 2
48 QueryResult result = WorldDatabase.Query("SELECT Id, BonusListID, Chance FROM item_random_bonus_list_template");
49
50 if (result)
51 {
52 uint32 count = 0;
53
54 do
55 {
56 Field* fields = result->Fetch();
57
58 uint32 id = fields[0].GetUInt32();
59 uint32 bonusListId = fields[1].GetUInt32();
60 float chance = fields[2].GetFloat();
61
62 if (ItemBonusMgr::GetItemBonuses(bonusListId).empty())
63 {
64 TC_LOG_ERROR("sql.sql", "Bonus list {} used in `item_random_bonus_list_template` by id {} doesn't have exist in ItemBonus.db2", bonusListId, id);
65 continue;
66 }
67
68 if (chance < 0.000001f || chance > 100.0f)
69 {
70 TC_LOG_ERROR("sql.sql", "Bonus list {} used in `item_random_bonus_list_template` by id {} has invalid chance {}", bonusListId, id, chance);
71 continue;
72 }
73
74 RandomBonusListIds& ids = _storage[id];
75 ids.BonusListIDs.push_back(bonusListId);
76 ids.Chances.push_back(chance);
77
78 ++count;
79 } while (result->NextRow());
80
81 TC_LOG_INFO("server.loading", ">> Loaded {} Random item bonus list definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
82 }
83 else
84 TC_LOG_INFO("server.loading", ">> Loaded 0 Random item bonus list definitions. DB table `item_random_bonus_list_template` is empty.");
85}
86
88{
89 ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
90 if (!itemProto)
91 return 0;
92
93 // item must have one from this field values not null if it can have random enchantments
94 if (!itemProto->RandomBonusListTemplateId)
95 return 0;
96
97 auto tab = _storage.find(itemProto->RandomBonusListTemplateId);
98 if (tab == _storage.end())
99 {
100 TC_LOG_ERROR("sql.sql", "Item RandomBonusListTemplateId id #{} used in `item_template_addon` but it does not have records in `item_random_bonus_list_template` table.", itemProto->RandomBonusListTemplateId);
101 return 0;
102 }
103
104 return *Trinity::Containers::SelectRandomWeightedContainerElement(tab->second.BonusListIDs, std::span(tab->second.Chances));
105}
106
107TC_GAME_API float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
108{
109 uint32 propIndex;
110
111 switch (inventoryType)
112 {
113 case INVTYPE_HEAD:
114 case INVTYPE_BODY:
115 case INVTYPE_CHEST:
116 case INVTYPE_LEGS:
117 case INVTYPE_RANGED:
118 case INVTYPE_2HWEAPON:
119 case INVTYPE_ROBE:
120 case INVTYPE_THROWN:
121 propIndex = 0;
122 break;
124 if (subClass == ITEM_SUBCLASS_WEAPON_WAND)
125 propIndex = 3;
126 else
127 propIndex = 0;
128 break;
129 case INVTYPE_WEAPON:
132 propIndex = 3;
133 break;
135 case INVTYPE_WAIST:
136 case INVTYPE_FEET:
137 case INVTYPE_HANDS:
138 case INVTYPE_TRINKET:
139 propIndex = 1;
140 break;
141 case INVTYPE_NECK:
142 case INVTYPE_WRISTS:
143 case INVTYPE_FINGER:
144 case INVTYPE_SHIELD:
145 case INVTYPE_CLOAK:
146 case INVTYPE_HOLDABLE:
147 propIndex = 2;
148 break;
149 case INVTYPE_RELIC:
150 propIndex = 4;
151 break;
152 default:
153 return 0;
154 }
155
156 RandPropPointsEntry const* randPropPointsEntry = sRandPropPointsStore.LookupEntry(itemLevel);
157 if (!randPropPointsEntry)
158 return 0;
159
160 switch (quality)
161 {
163 return randPropPointsEntry->GoodF[propIndex];
166 return randPropPointsEntry->SuperiorF[propIndex];
170 return randPropPointsEntry->EpicF[propIndex];
171 }
172
173 return 0;
174}
DB2Storage< RandPropPointsEntry > sRandPropPointsStore("RandPropPoints.db2", &RandPropPointsLoadInfo::Instance)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
#define TC_GAME_API
Definition: Define.h:123
uint32_t uint32
Definition: Define.h:142
TC_GAME_API float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
void LoadItemRandomBonusListTemplates()
ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id)
uint32 ItemRandomBonusListId
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:499
@ INVTYPE_BODY
Definition: ItemTemplate.h:383
@ INVTYPE_FINGER
Definition: ItemTemplate.h:390
@ INVTYPE_HEAD
Definition: ItemTemplate.h:380
@ INVTYPE_CLOAK
Definition: ItemTemplate.h:395
@ INVTYPE_ROBE
Definition: ItemTemplate.h:399
@ INVTYPE_HOLDABLE
Definition: ItemTemplate.h:402
@ INVTYPE_TRINKET
Definition: ItemTemplate.h:391
@ INVTYPE_RELIC
Definition: ItemTemplate.h:407
@ INVTYPE_RANGED
Definition: ItemTemplate.h:394
@ INVTYPE_THROWN
Definition: ItemTemplate.h:404
@ INVTYPE_WAIST
Definition: ItemTemplate.h:385
@ INVTYPE_RANGEDRIGHT
Definition: ItemTemplate.h:405
@ INVTYPE_WRISTS
Definition: ItemTemplate.h:388
@ INVTYPE_WEAPON
Definition: ItemTemplate.h:392
@ INVTYPE_WEAPONMAINHAND
Definition: ItemTemplate.h:400
@ INVTYPE_WEAPONOFFHAND
Definition: ItemTemplate.h:401
@ INVTYPE_2HWEAPON
Definition: ItemTemplate.h:396
@ INVTYPE_NECK
Definition: ItemTemplate.h:381
@ INVTYPE_SHOULDERS
Definition: ItemTemplate.h:382
@ INVTYPE_FEET
Definition: ItemTemplate.h:387
@ INVTYPE_SHIELD
Definition: ItemTemplate.h:393
@ INVTYPE_LEGS
Definition: ItemTemplate.h:386
@ INVTYPE_CHEST
Definition: ItemTemplate.h:384
@ INVTYPE_HANDS
Definition: ItemTemplate.h:389
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
#define sObjectMgr
Definition: ObjectMgr.h:1946
@ ITEM_QUALITY_UNCOMMON
@ ITEM_QUALITY_RARE
@ ITEM_QUALITY_LEGENDARY
@ ITEM_QUALITY_HEIRLOOM
@ ITEM_QUALITY_ARTIFACT
@ ITEM_QUALITY_EPIC
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:57
uint32 getMSTime()
Definition: Timer.h:33
Class used to access individual fields of database query result.
Definition: Field.h:90
float GetFloat() const
Definition: Field.cpp:94
uint32 GetUInt32() const
Definition: Field.cpp:62
std::span< ItemBonusEntry const * > GetItemBonuses(uint32 bonusListId)
auto SelectRandomWeightedContainerElement(C const &container, std::span< double > const &weights) -> decltype(std::begin(container))
Definition: Containers.h:126
uint32 RandomBonusListTemplateId
Definition: ItemTemplate.h:837
std::array< float, 5 > SuperiorF
std::array< float, 5 > GoodF
std::array< float, 5 > EpicF