AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
LootMgr.cpp File Reference
#include "LootMgr.h"
#include "Containers.h"
#include "DisableMgr.h"
#include "Group.h"
#include "ItemEnchantmentMgr.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "SharedDefines.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "Util.h"
#include "World.h"

Go to the source code of this file.

Classes

struct  LootGroupInvalidSelector
 
class  LootTemplate::LootGroup
 

Functions

ByteBufferoperator<< (ByteBuffer &b, LootItem const &li)
 
ByteBufferoperator<< (ByteBuffer &b, LootView const &lv)
 
void LoadLootTemplates_Creature ()
 
void LoadLootTemplates_Disenchant ()
 
void LoadLootTemplates_Fishing ()
 
void LoadLootTemplates_Gameobject ()
 
void LoadLootTemplates_Item ()
 
void LoadLootTemplates_Milling ()
 
void LoadLootTemplates_Pickpocketing ()
 
void LoadLootTemplates_Prospecting ()
 
void LoadLootTemplates_Mail ()
 
void LoadLootTemplates_Skinning ()
 
void LoadLootTemplates_Spell ()
 
void LoadLootTemplates_Player ()
 
void LoadLootTemplates_Reference ()
 

Variables

static Rates const qualityToRate [MAX_ITEM_QUALITY]
 
LootStore LootTemplates_Creature ("creature_loot_template", "creature entry", true)
 
LootStore LootTemplates_Disenchant ("disenchant_loot_template", "item disenchant id", true)
 
LootStore LootTemplates_Fishing ("fishing_loot_template", "area id", true)
 
LootStore LootTemplates_Gameobject ("gameobject_loot_template", "gameobject entry", true)
 
LootStore LootTemplates_Item ("item_loot_template", "item entry", true)
 
LootStore LootTemplates_Mail ("mail_loot_template", "mail template id", false)
 
LootStore LootTemplates_Milling ("milling_loot_template", "item entry (herb)", true)
 
LootStore LootTemplates_Pickpocketing ("pickpocketing_loot_template", "creature pickpocket lootid", true)
 
LootStore LootTemplates_Prospecting ("prospecting_loot_template", "item entry (ore)", true)
 
LootStore LootTemplates_Reference ("reference_loot_template", "reference id", false)
 
LootStore LootTemplates_Skinning ("skinning_loot_template", "creature skinning id", true)
 
LootStore LootTemplates_Spell ("spell_loot_template", "spell id (random item creating)", false)
 
LootStore LootTemplates_Player ("player_loot_template", "team id", true)
 

Function Documentation

◆ LoadLootTemplates_Creature()

void LoadLootTemplates_Creature ( )
1964{
1965 LOG_INFO("server.loading", "Loading Creature Loot Templates...");
1966
1967 uint32 oldMSTime = getMSTime();
1968
1969 LootIdSet lootIdSet, lootIdSetUsed;
1971
1972 // Remove real entries and check loot existence
1973 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
1974 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
1975 {
1976 if (uint32 lootid = itr->second.lootid)
1977 {
1978 if (lootIdSet.find(lootid) == lootIdSet.end())
1979 LootTemplates_Creature.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
1980 else
1981 lootIdSetUsed.insert(lootid);
1982 }
1983 }
1984
1985 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
1986 lootIdSet.erase(*itr);
1987
1988 // output error for any still listed (not referenced from appropriate table) ids
1990
1991 if (count)
1992 LOG_INFO("server.loading", ">> Loaded {} Creature Loot Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1993 else
1994 LOG_WARN("server.loading", ">> Loaded 0 creature loot templates. DB table `creature_loot_template` is empty");
1995
1996 LOG_INFO("server.loading", " ");
1997}
#define LOG_INFO(filterType__,...)
Definition: Log.h:165
#define LOG_WARN(filterType__,...)
Definition: Log.h:161
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
std::uint32_t uint32
Definition: Define.h:107
#define sObjectMgr
Definition: ObjectMgr.h:1635
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition: CreatureData.h:292
LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true)
std::set< uint32 > LootIdSet
Definition: LootMgr.h:204
uint32 LoadAndCollectLootIds(LootIdSet &ids_set)
Definition: LootMgr.cpp:267
void ReportNonExistingId(uint32 lootId) const
Definition: LootMgr.cpp:290
void ReportUnusedIds(LootIdSet const &ids_set) const
Definition: LootMgr.cpp:283

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Creature, LootStore::ReportNonExistingId(), LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesCreatureCommand(), and LoadLootTables().

◆ LoadLootTemplates_Disenchant()

void LoadLootTemplates_Disenchant ( )
2000{
2001 LOG_INFO("server.loading", "Loading Disenchanting Loot Templates...");
2002
2003 uint32 oldMSTime = getMSTime();
2004
2005 LootIdSet lootIdSet, lootIdSetUsed;
2007
2008 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2009 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2010 {
2011 if (uint32 lootid = itr->second.DisenchantID)
2012 {
2013 if (lootIdSet.find(lootid) == lootIdSet.end())
2015 else
2016 lootIdSetUsed.insert(lootid);
2017 }
2018 }
2019
2020 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2021 lootIdSet.erase(*itr);
2022
2023 // output error for any still listed (not referenced from appropriate table) ids
2025
2026 if (count)
2027 LOG_INFO("server.loading", ">> Loaded {} disenchanting loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2028 else
2029 LOG_WARN("server.loading", ">> Loaded 0 disenchanting loot templates. DB table `disenchant_loot_template` is empty");
2030 LOG_INFO("server.loading", " ");
2031}
std::unordered_map< uint32, ItemTemplate > ItemTemplateContainer
Definition: ItemTemplate.h:835
LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true)

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Disenchant, LootStore::ReportNonExistingId(), LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesDisenchantCommand(), and LoadLootTables().

◆ LoadLootTemplates_Fishing()

void LoadLootTemplates_Fishing ( )
2034{
2035 LOG_INFO("server.loading", "Loading Fishing Loot Templates...");
2036
2037 uint32 oldMSTime = getMSTime();
2038
2039 LootIdSet lootIdSet;
2041
2042 // remove real entries and check existence loot
2043 for (uint32 i = 1; i < sAreaTableStore.GetNumRows(); ++i)
2044 if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i))
2045 if (lootIdSet.find(areaEntry->ID) != lootIdSet.end())
2046 lootIdSet.erase(areaEntry->ID);
2047
2048 // output error for any still listed (not referenced from appropriate table) ids
2050
2051 if (count)
2052 LOG_INFO("server.loading", ">> Loaded {} Fishing Loot Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2053 else
2054 LOG_WARN("server.loading", ">> Loaded 0 fishing loot templates. DB table `fishing_loot_template` is empty");
2055
2056 LOG_INFO("server.loading", " ");
2057}
LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
Definition: DBCStructure.h:518

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Fishing, LootStore::ReportUnusedIds(), and sAreaTableStore.

Referenced by reload_commandscript::HandleReloadLootTemplatesFishingCommand(), and LoadLootTables().

◆ LoadLootTemplates_Gameobject()

void LoadLootTemplates_Gameobject ( )
2060{
2061 LOG_INFO("server.loading", "Loading Gameobject Loot Templates...");
2062
2063 uint32 oldMSTime = getMSTime();
2064
2065 LootIdSet lootIdSet, lootIdSetUsed;
2067
2068 // remove real entries and check existence loot
2069 GameObjectTemplateContainer const* gotc = sObjectMgr->GetGameObjectTemplates();
2070 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
2071 {
2072 if (uint32 lootid = itr->second.GetLootId())
2073 {
2074 if (lootIdSet.find(lootid) == lootIdSet.end())
2075 LootTemplates_Gameobject.ReportNonExistingId(lootid, "Gameobject", itr->second.entry);
2076 else
2077 lootIdSetUsed.insert(lootid);
2078 }
2079 }
2080
2081 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2082 lootIdSet.erase(*itr);
2083
2084 // output error for any still listed (not referenced from appropriate table) ids
2086
2087 if (count)
2088 LOG_INFO("server.loading", ">> Loaded {} Gameobject Loot Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2089 else
2090 LOG_WARN("server.loading", ">> Loaded 0 gameobject loot templates. DB table `gameobject_loot_template` is empty");
2091
2092 LOG_INFO("server.loading", " ");
2093}
std::unordered_map< uint32, GameObjectTemplate > GameObjectTemplateContainer
Definition: GameObject.h:42
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Gameobject, LootStore::ReportNonExistingId(), LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesGameobjectCommand(), and LoadLootTables().

◆ LoadLootTemplates_Item()

void LoadLootTemplates_Item ( )
2096{
2097 LOG_INFO("server.loading", "Loading Item Loot Templates...");
2098
2099 uint32 oldMSTime = getMSTime();
2100
2101 LootIdSet lootIdSet;
2103
2104 // remove real entries and check existence loot
2105 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2106 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2107 if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end() && itr->second.HasFlag(ITEM_FLAG_HAS_LOOT))
2108 lootIdSet.erase(itr->second.ItemId);
2109
2110 // output error for any still listed (not referenced from appropriate table) ids
2112
2113 if (count)
2114 LOG_INFO("server.loading", ">> Loaded {} item loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2115 else
2116 LOG_WARN("server.loading", ">> Loaded 0 item loot templates. DB table `item_loot_template` is empty");
2117
2118 LOG_INFO("server.loading", " ");
2119}
@ ITEM_FLAG_HAS_LOOT
Definition: ItemTemplate.h:149
LootStore LootTemplates_Item("item_loot_template", "item entry", true)

References getMSTime(), GetMSTimeDiffToNow(), ITEM_FLAG_HAS_LOOT, LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Item, LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesItemCommand(), and LoadLootTables().

◆ LoadLootTemplates_Mail()

void LoadLootTemplates_Mail ( )
2220{
2221 LOG_INFO("server.loading", "Loading Mail Loot Templates...");
2222
2223 uint32 oldMSTime = getMSTime();
2224
2225 LootIdSet lootIdSet;
2227
2228 // remove real entries and check existence loot
2229 for (uint32 i = 1; i < sMailTemplateStore.GetNumRows(); ++i)
2230 if (sMailTemplateStore.LookupEntry(i))
2231 if (lootIdSet.find(i) != lootIdSet.end())
2232 lootIdSet.erase(i);
2233
2234 // output error for any still listed (not referenced from appropriate table) ids
2236
2237 if (count)
2238 LOG_INFO("server.loading", ">> Loaded {} mail loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2239 else
2240 LOG_WARN("server.loading", ">> Loaded 0 mail loot templates. DB table `mail_loot_template` is empty");
2241
2242 LOG_INFO("server.loading", " ");
2243}
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Mail, LootStore::ReportUnusedIds(), and sMailTemplateStore.

Referenced by reload_commandscript::HandleReloadLootTemplatesMailCommand(), and LoadLootTables().

◆ LoadLootTemplates_Milling()

void LoadLootTemplates_Milling ( )
2122{
2123 LOG_INFO("server.loading", "Loading Milling Loot Templates...");
2124
2125 uint32 oldMSTime = getMSTime();
2126
2127 LootIdSet lootIdSet;
2129
2130 // remove real entries and check existence loot
2131 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2132 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2133 {
2134 if (!itr->second.HasFlag(ITEM_FLAG_IS_MILLABLE))
2135 continue;
2136
2137 if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end())
2138 lootIdSet.erase(itr->second.ItemId);
2139 }
2140
2141 // output error for any still listed (not referenced from appropriate table) ids
2143
2144 if (count)
2145 LOG_INFO("server.loading", ">> Loaded {} milling loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2146 else
2147 LOG_WARN("server.loading", ">> Loaded 0 milling loot templates. DB table `milling_loot_template` is empty");
2148
2149 LOG_INFO("server.loading", " ");
2150}
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)

References getMSTime(), GetMSTimeDiffToNow(), ITEM_FLAG_IS_MILLABLE, LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Milling, LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesMillingCommand(), and LoadLootTables().

◆ LoadLootTemplates_Pickpocketing()

void LoadLootTemplates_Pickpocketing ( )
2153{
2154 LOG_INFO("server.loading", "Loading Pickpocketing Loot Templates...");
2155
2156 uint32 oldMSTime = getMSTime();
2157
2158 LootIdSet lootIdSet, lootIdSetUsed;
2160
2161 // Remove real entries and check loot existence
2162 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2163 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2164 {
2165 if (uint32 lootid = itr->second.pickpocketLootId)
2166 {
2167 if (lootIdSet.find(lootid) == lootIdSet.end())
2168 LootTemplates_Pickpocketing.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
2169 else
2170 lootIdSetUsed.insert(lootid);
2171 }
2172 }
2173
2174 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2175 lootIdSet.erase(*itr);
2176
2177 // output error for any still listed (not referenced from appropriate table) ids
2179
2180 if (count)
2181 LOG_INFO("server.loading", ">> Loaded {} pickpocketing loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2182 else
2183 LOG_WARN("server.loading", ">> Loaded 0 pickpocketing loot templates. DB table `pickpocketing_loot_template` is empty");
2184
2185 LOG_INFO("server.loading", " ");
2186}
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Pickpocketing, LootStore::ReportNonExistingId(), LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesPickpocketingCommand(), and LoadLootTables().

◆ LoadLootTemplates_Player()

void LoadLootTemplates_Player ( )
2325{
2326 LOG_INFO("server.loading", "Loading Player Loot Templates...");
2327
2328 uint32 oldMSTime = getMSTime();
2329
2330 LootIdSet lootIdSet;
2332
2333 if (count)
2334 {
2335 LOG_INFO("server.loading", ">> Loaded {} player loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2336 }
2337 else
2338 {
2339 LOG_WARN("server.loading", ">> Loaded 0 player loot templates. DB table `player_loot_template` is empty");
2340 }
2341
2342 LOG_INFO("server.loading", " ");
2343}
LootStore LootTemplates_Player("player_loot_template", "team id", true)

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, and LootTemplates_Player.

Referenced by reload_commandscript::HandleReloadLootTemplatesPlayerCommand(), and LoadLootTables().

◆ LoadLootTemplates_Prospecting()

void LoadLootTemplates_Prospecting ( )
2189{
2190 LOG_INFO("server.loading", "Loading Prospecting Loot Templates...");
2191
2192 uint32 oldMSTime = getMSTime();
2193
2194 LootIdSet lootIdSet;
2196
2197 // remove real entries and check existence loot
2198 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2199 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2200 {
2201 if (!itr->second.HasFlag(ITEM_FLAG_IS_PROSPECTABLE))
2202 continue;
2203
2204 if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end())
2205 lootIdSet.erase(itr->second.ItemId);
2206 }
2207
2208 // output error for any still listed (not referenced from appropriate table) ids
2210
2211 if (count)
2212 LOG_INFO("server.loading", ">> Loaded {} prospecting loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2213 else
2214 LOG_WARN("server.loading", ">> Loaded 0 prospecting loot templates. DB table `prospecting_loot_template` is empty");
2215
2216 LOG_INFO("server.loading", " ");
2217}
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)

References getMSTime(), GetMSTimeDiffToNow(), ITEM_FLAG_IS_PROSPECTABLE, LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Prospecting, LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesProspectingCommand(), and LoadLootTables().

◆ LoadLootTemplates_Reference()

void LoadLootTemplates_Reference ( )
2346{
2347 LOG_INFO("server.loading", "Loading Reference Loot Templates...");
2348
2349 uint32 oldMSTime = getMSTime();
2350
2351 LootIdSet lootIdSet;
2353
2354 // check references and remove used
2366
2367 // output error for any still listed ids (not referenced from any loot table)
2369
2370 LOG_INFO("server.loading", ">> Loaded reference loot templates in {} ms", GetMSTimeDiffToNow(oldMSTime));
2371 LOG_INFO("server.loading", " ");
2372}
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true)
LootStore LootTemplates_Reference("reference_loot_template", "reference id", false)
void CheckLootRefs(LootIdSet *ref_set=nullptr) const
Definition: LootMgr.cpp:277

References LootStore::CheckLootRefs(), getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LootTemplates_Creature, LootTemplates_Disenchant, LootTemplates_Fishing, LootTemplates_Gameobject, LootTemplates_Item, LootTemplates_Mail, LootTemplates_Milling, LootTemplates_Pickpocketing, LootTemplates_Prospecting, LootTemplates_Reference, LootTemplates_Skinning, and LootStore::ReportUnusedIds().

Referenced by reload_commandscript::HandleReloadLootTemplatesReferenceCommand(), and LoadLootTables().

◆ LoadLootTemplates_Skinning()

void LoadLootTemplates_Skinning ( )
2246{
2247 LOG_INFO("server.loading", "Loading Skinning Loot Templates...");
2248
2249 uint32 oldMSTime = getMSTime();
2250
2251 LootIdSet lootIdSet, lootIdSetUsed;
2253
2254 // remove real entries and check existence loot
2255 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2256 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2257 {
2258 if (uint32 lootid = itr->second.SkinLootId)
2259 {
2260 if (lootIdSet.find(lootid) == lootIdSet.end())
2261 LootTemplates_Skinning.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
2262 else
2263 lootIdSetUsed.insert(lootid);
2264 }
2265 }
2266
2267 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2268 lootIdSet.erase(*itr);
2269
2270 // output error for any still listed (not referenced from appropriate table) ids
2272
2273 if (count)
2274 LOG_INFO("server.loading", ">> Loaded {} skinning loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2275 else
2276 LOG_WARN("server.loading", ">> Loaded 0 skinning loot templates. DB table `skinning_loot_template` is empty");
2277
2278 LOG_INFO("server.loading", " ");
2279}

References getMSTime(), GetMSTimeDiffToNow(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Skinning, LootStore::ReportNonExistingId(), LootStore::ReportUnusedIds(), and sObjectMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesSkinningCommand(), and LoadLootTables().

◆ LoadLootTemplates_Spell()

void LoadLootTemplates_Spell ( )
2282{
2283 LOG_INFO("server.loading", "Loading Spell Loot Templates...");
2284
2285 uint32 oldMSTime = getMSTime();
2286
2287 LootIdSet lootIdSet;
2289
2290 // remove real entries and check existence loot
2291 for (uint32 spell_id = 1; spell_id < sSpellMgr->GetSpellInfoStoreSize(); ++spell_id)
2292 {
2293 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2294 if (!spellInfo)
2295 continue;
2296
2297 // possible cases
2298 if (!spellInfo->IsLootCrafting())
2299 continue;
2300
2301 if (lootIdSet.find(spell_id) == lootIdSet.end())
2302 {
2303 // not report about not trainable spells (optionally supported by DB)
2304 // ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example
2306 {
2307 LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id);
2308 }
2309 }
2310 else
2311 lootIdSet.erase(spell_id);
2312 }
2313
2314 // output error for any still listed (not referenced from appropriate table) ids
2316
2317 if (count)
2318 LOG_INFO("server.loading", ">> Loaded {} spell loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2319 else
2320 LOG_WARN("server.loading", ">> Loaded 0 spell loot templates. DB table `spell_loot_template` is empty");
2321 LOG_INFO("server.loading", " ");
2322}
@ SPELL_ATTR0_IS_TRADESKILL
Definition: SharedDefines.h:387
@ SPELL_ATTR0_NOT_SHAPESHIFTED
Definition: SharedDefines.h:398
#define sSpellMgr
Definition: SpellMgr.h:825
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
Definition: SpellInfo.h:316
uint32 Id
Definition: SpellInfo.h:320
bool IsLootCrafting() const
Definition: SpellInfo.cpp:925
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415

References getMSTime(), GetMSTimeDiffToNow(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootStore::LoadAndCollectLootIds(), LOG_INFO, LOG_WARN, LootTemplates_Spell, LootStore::ReportNonExistingId(), LootStore::ReportUnusedIds(), SPELL_ATTR0_IS_TRADESKILL, SPELL_ATTR0_NOT_SHAPESHIFTED, and sSpellMgr.

Referenced by reload_commandscript::HandleReloadLootTemplatesSpellCommand(), and LoadLootTables().

◆ operator<<() [1/2]

ByteBuffer & operator<< ( ByteBuffer b,
LootItem const &  li 
)
993{
994 b << uint32(li.itemid);
995 b << uint32(li.count); // nr of items of this type
996 b << uint32(sObjectMgr->GetItemTemplate(li.itemid)->DisplayInfoID);
997 b << uint32(li.randomSuffix);
998 b << uint32(li.randomPropertyId);
999 //b << uint8(0); // slot type - will send after this function call
1000 return b;
1001}

References LootItem::count, LootItem::itemid, LootItem::randomPropertyId, LootItem::randomSuffix, and sObjectMgr.

◆ operator<<() [2/2]

ByteBuffer & operator<< ( ByteBuffer b,
LootView const &  lv 
)
1004{
1005 if (lv.permission == NONE_PERMISSION)
1006 {
1007 b << uint32(0); //gold
1008 b << uint8(0); // item count
1009 return b; // nothing output more
1010 }
1011
1012 Loot& l = lv.loot;
1013
1014 uint8 itemsShown = 0;
1015
1016 b << uint32(l.gold); //gold
1017
1018 std::size_t count_pos = b.wpos(); // pos of item count byte
1019 b << uint8(0); // item count placeholder
1020
1021 switch (lv.permission)
1022 {
1023 case GROUP_PERMISSION:
1024 case MASTER_PERMISSION:
1026 {
1027 bool isMasterLooter = lv.viewer->GetGroup() && lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID();
1028
1029 // if you are not the round-robin group looter, you can only see
1030 // blocked rolled items and quest items, and !ffa items
1031 for (uint8 i = 0; i < l.items.size(); ++i)
1032 {
1033 if (!l.items[i].is_looted && !l.items[i].freeforall && (l.items[i].conditions.empty() || isMasterLooter) && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1034 {
1035 uint8 slot_type = 0;
1036
1037 if (l.items[i].is_blocked) // for ML & restricted is_blocked = !is_underthreshold
1038 {
1039 switch (lv.permission)
1040 {
1041 case GROUP_PERMISSION:
1042 slot_type = LOOT_SLOT_TYPE_ROLL_ONGOING;
1043 break;
1044 case MASTER_PERMISSION:
1045 {
1046 if (lv.viewer->GetGroup())
1047 {
1048 if (lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID())
1049 slot_type = LOOT_SLOT_TYPE_MASTER;
1050 else
1051 slot_type = LOOT_SLOT_TYPE_LOCKED;
1052 }
1053 break;
1054 }
1056 slot_type = LOOT_SLOT_TYPE_LOCKED;
1057 break;
1058 default:
1059 continue;
1060 }
1061 }
1062 else if (l.items[i].rollWinnerGUID)
1063 {
1064 if (l.items[i].rollWinnerGUID == lv.viewer->GetGUID())
1065 slot_type = LOOT_SLOT_TYPE_OWNER;
1066 else
1067 continue;
1068 }
1069 else if (!l.roundRobinPlayer || lv.viewer->GetGUID() == l.roundRobinPlayer || !l.items[i].is_underthreshold)
1070 {
1071 // no round robin owner or he has released the loot
1072 // or it IS the round robin group owner
1073 // => item is lootable
1074 slot_type = LOOT_SLOT_TYPE_ALLOW_LOOT;
1075 }
1076 else
1077 // item shall not be displayed.
1078 continue;
1079
1080 b << uint8(i) << l.items[i];
1081 b << uint8(slot_type);
1082 ++itemsShown;
1083 }
1084 }
1085 break;
1086 }
1088 {
1089 for (uint8 i = 0; i < l.items.size(); ++i)
1090 {
1091 if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1092 {
1093 if (l.roundRobinPlayer && lv.viewer->GetGUID() != l.roundRobinPlayer)
1094 // item shall not be displayed.
1095 continue;
1096
1097 b << uint8(i) << l.items[i];
1099 ++itemsShown;
1100 }
1101 }
1102 break;
1103 }
1104 case ALL_PERMISSION:
1105 case OWNER_PERMISSION:
1106 {
1108 for (uint8 i = 0; i < l.items.size(); ++i)
1109 {
1110 if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1111 {
1112 b << uint8(i) << l.items[i];
1113 b << uint8(slot_type);
1114 ++itemsShown;
1115 }
1116 }
1117 break;
1118 }
1119 default:
1120 return b;
1121 }
1122
1124
1125 // Xinef: items that do not follow loot rules need this
1126 LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : slotType;
1127
1128 QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
1129 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID());
1130 if (q_itr != lootPlayerQuestItems.end())
1131 {
1132 QuestItemList* q_list = q_itr->second;
1133 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
1134 {
1135 LootItem& item = l.quest_items[qi->index];
1136 if (!qi->is_looted && !item.is_looted)
1137 {
1138 bool showInLoot = true;
1139 bool hasQuestForItem = lv.viewer->HasQuestForItem(item.itemid, 0, false, &showInLoot);
1140 if (!hasQuestForItem)
1141 {
1142 if (!showInLoot)
1143 {
1144 const_cast<QuestItem*>(&(*qi))->is_looted = true;
1145 if (!item.freeforall)
1146 {
1147 item.is_looted = true;
1148 }
1149 continue;
1150 }
1151
1152 b << uint8(l.items.size() + (qi - q_list->begin()));
1153 b << item;
1155 }
1156 else
1157 {
1158 b << uint8(l.items.size() + (qi - q_list->begin()));
1159 b << item;
1160
1161 if (item.follow_loot_rules)
1162 {
1163 switch (lv.permission)
1164 {
1165 case MASTER_PERMISSION:
1167 break;
1169 b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
1170 break;
1171 case GROUP_PERMISSION:
1173 if (!item.is_blocked)
1175 else
1177 break;
1178 default:
1179 b << uint8(slotType);
1180 break;
1181 }
1182 }
1183 else if (!item.freeforall)
1184 b << uint8(partySlotType);
1185 else
1186 b << uint8(slotType);
1187 }
1188
1189 ++itemsShown;
1190 }
1191 }
1192 }
1193
1194 QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems();
1195 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID());
1196 if (ffa_itr != lootPlayerFFAItems.end())
1197 {
1198 QuestItemList* ffa_list = ffa_itr->second;
1199 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
1200 {
1201 LootItem& item = l.items[fi->index];
1202 if (!fi->is_looted && !item.is_looted)
1203 {
1204 b << uint8(fi->index);
1205 b << item;
1206 // Xinef: Here are FFA items, so dont use owner permision
1207 b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT /*slotType*/);
1208 ++itemsShown;
1209 }
1210 }
1211 }
1212
1213 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
1214 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID());
1215 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
1216 {
1217 QuestItemList* conditional_list = nn_itr->second;
1218 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
1219 {
1220 LootItem& item = l.items[ci->index];
1221 if (!ci->is_looted && !item.is_looted)
1222 {
1223 b << uint8(ci->index);
1224 b << item;
1225 if (item.follow_loot_rules)
1226 {
1227 switch (lv.permission)
1228 {
1229 case MASTER_PERMISSION:
1231 break;
1233 b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
1234 break;
1235 case GROUP_PERMISSION:
1237 if (!item.is_blocked)
1239 else
1241 break;
1242 default:
1243 b << uint8(slotType);
1244 break;
1245 }
1246 }
1247 else if (!item.freeforall)
1248 b << uint8(partySlotType);
1249 else
1250 b << uint8(slotType);
1251 ++itemsShown;
1252 }
1253 }
1254 }
1255
1256 //update number of items shown
1257 b.put<uint8>(count_pos, itemsShown);
1258
1259 return b;
1260}
std::uint8_t uint8
Definition: Define.h:109
@ OWNER_PERMISSION
Definition: LootMgr.h:72
@ ALL_PERMISSION
Definition: LootMgr.h:67
@ RESTRICTED_PERMISSION
Definition: LootMgr.h:70
@ NONE_PERMISSION
Definition: LootMgr.h:73
@ ROUND_ROBIN_PERMISSION
Definition: LootMgr.h:71
@ MASTER_PERMISSION
Definition: LootMgr.h:69
@ GROUP_PERMISSION
Definition: LootMgr.h:68
std::map< ObjectGuid, QuestItemList * > QuestItemMap
Definition: LootMgr.h:200
LootSlotType
Definition: LootMgr.h:113
@ LOOT_SLOT_TYPE_MASTER
Definition: LootMgr.h:116
@ LOOT_SLOT_TYPE_ROLL_ONGOING
Definition: LootMgr.h:115
@ LOOT_SLOT_TYPE_ALLOW_LOOT
Definition: LootMgr.h:114
@ LOOT_SLOT_TYPE_OWNER
Definition: LootMgr.h:118
@ LOOT_SLOT_TYPE_LOCKED
Definition: LootMgr.h:117
std::vector< QuestItem > QuestItemList
Definition: LootMgr.h:198
Definition: LootMgr.h:154
uint32 itemid
Definition: LootMgr.h:155
bool is_looted
Definition: LootMgr.h:163
bool freeforall
Definition: LootMgr.h:165
Definition: LootMgr.h:185
Definition: LootMgr.h:313
ObjectGuid sourceWorldObjectGUID
Definition: LootMgr.h:330
ObjectGuid roundRobinPlayer
Definition: LootMgr.h:324
uint32 gold
Definition: LootMgr.h:322
QuestItemMap const & GetPlayerQuestItems() const
Definition: LootMgr.h:316
std::vector< LootItem > items
Definition: LootMgr.h:320
QuestItemMap const & GetPlayerFFAItems() const
Definition: LootMgr.h:317
QuestItemMap const & GetPlayerNonQuestNonFFAConditionalItems() const
Definition: LootMgr.h:318
std::vector< LootItem > quest_items
Definition: LootMgr.h:321
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

Variable Documentation

◆ LootTemplates_Creature

◆ LootTemplates_Disenchant

LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true) ( "disenchant_loot_template"  ,
"item disenchant id"  ,
true   
)

◆ LootTemplates_Fishing

LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true) ( "fishing_loot_template"  ,
"area id"  ,
true   
)

◆ LootTemplates_Gameobject

LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true) ( "gameobject_loot_template"  ,
"gameobject entry"  ,
true   
)

◆ LootTemplates_Item

LootStore LootTemplates_Item("item_loot_template", "item entry", true) ( "item_loot_template"  ,
"item entry"  ,
true   
)

◆ LootTemplates_Mail

LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false) ( "mail_loot_template"  ,
"mail template id"  ,
false   
)

◆ LootTemplates_Milling

LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true) ( "milling_loot_template"  ,
"item entry (herb)"  ,
true   
)

◆ LootTemplates_Pickpocketing

LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true) ( "pickpocketing_loot_template"  ,
"creature pickpocket lootid"  ,
true   
)

◆ LootTemplates_Player

LootStore LootTemplates_Player("player_loot_template", "team id", true) ( "player_loot_template"  ,
"team id"  ,
true   
)

◆ LootTemplates_Prospecting

LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true) ( "prospecting_loot_template"  ,
"item entry (ore)"  ,
true   
)

◆ LootTemplates_Reference

LootStore LootTemplates_Reference("reference_loot_template", "reference id", false) ( "reference_loot_template"  ,
"reference id"  ,
false   
)

◆ LootTemplates_Skinning

LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true) ( "skinning_loot_template"  ,
"creature skinning id"  ,
true   
)

◆ LootTemplates_Spell

LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false) ( "spell_loot_template"  ,
"spell id (random item creating)"  ,
false   
)

◆ qualityToRate

Rates const qualityToRate[MAX_ITEM_QUALITY]
static
Initial value:
=
{
}
@ RATE_DROP_ITEM_RARE
Definition: IWorld.h:442
@ RATE_DROP_ITEM_LEGENDARY
Definition: IWorld.h:444
@ RATE_DROP_ITEM_POOR
Definition: IWorld.h:439
@ RATE_DROP_ITEM_UNCOMMON
Definition: IWorld.h:441
@ RATE_DROP_ITEM_EPIC
Definition: IWorld.h:443
@ RATE_DROP_ITEM_ARTIFACT
Definition: IWorld.h:445
@ RATE_DROP_ITEM_NORMAL
Definition: IWorld.h:440