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 "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 ( )
1915{
1916 LOG_INFO("server.loading", "Loading Creature Loot Templates...");
1917
1918 uint32 oldMSTime = getMSTime();
1919
1920 LootIdSet lootIdSet, lootIdSetUsed;
1922
1923 // Remove real entries and check loot existence
1924 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
1925 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
1926 {
1927 if (uint32 lootid = itr->second.lootid)
1928 {
1929 if (lootIdSet.find(lootid) == lootIdSet.end())
1930 LootTemplates_Creature.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
1931 else
1932 lootIdSetUsed.insert(lootid);
1933 }
1934 }
1935
1936 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
1937 lootIdSet.erase(*itr);
1938
1939 // output error for any still listed (not referenced from appropriate table) ids
1941
1942 if (count)
1943 LOG_INFO("server.loading", ">> Loaded {} Creature Loot Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1944 else
1945 LOG_WARN("server.loading", ">> Loaded 0 creature loot templates. DB table `creature_loot_template` is empty");
1946
1947 LOG_INFO("server.loading", " ");
1948}
std::uint32_t uint32
Definition: Define.h:108
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
#define LOG_WARN(filterType__,...)
Definition: Log.h:163
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition: CreatureData.h:281
#define sObjectMgr
Definition: ObjectMgr.h:1640
LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true)
std::set< uint32 > LootIdSet
Definition: LootMgr.h:205
uint32 LoadAndCollectLootIds(LootIdSet &ids_set)
Definition: LootMgr.cpp:266
void ReportNonExistingId(uint32 lootId) const
Definition: LootMgr.cpp:289
void ReportUnusedIds(LootIdSet const &ids_set) const
Definition: LootMgr.cpp:282

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 ( )
1951{
1952 LOG_INFO("server.loading", "Loading Disenchanting Loot Templates...");
1953
1954 uint32 oldMSTime = getMSTime();
1955
1956 LootIdSet lootIdSet, lootIdSetUsed;
1958
1959 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
1960 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
1961 {
1962 if (uint32 lootid = itr->second.DisenchantID)
1963 {
1964 if (lootIdSet.find(lootid) == lootIdSet.end())
1966 else
1967 lootIdSetUsed.insert(lootid);
1968 }
1969 }
1970
1971 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
1972 lootIdSet.erase(*itr);
1973
1974 // output error for any still listed (not referenced from appropriate table) ids
1976
1977 if (count)
1978 LOG_INFO("server.loading", ">> Loaded {} disenchanting loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1979 else
1980 LOG_WARN("server.loading", ">> Loaded 0 disenchanting loot templates. DB table `disenchant_loot_template` is empty");
1981 LOG_INFO("server.loading", " ");
1982}
std::unordered_map< uint32, ItemTemplate > ItemTemplateContainer
Definition: ItemTemplate.h:838
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 ( )
1985{
1986 LOG_INFO("server.loading", "Loading Fishing Loot Templates...");
1987
1988 uint32 oldMSTime = getMSTime();
1989
1990 LootIdSet lootIdSet;
1992
1993 // remove real entries and check existence loot
1994 for (uint32 i = 1; i < sAreaTableStore.GetNumRows(); ++i)
1995 if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i))
1996 if (lootIdSet.find(areaEntry->ID) != lootIdSet.end())
1997 lootIdSet.erase(areaEntry->ID);
1998
1999 // output error for any still listed (not referenced from appropriate table) ids
2001
2002 if (count)
2003 LOG_INFO("server.loading", ">> Loaded {} Fishing Loot Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2004 else
2005 LOG_WARN("server.loading", ">> Loaded 0 fishing loot templates. DB table `fishing_loot_template` is empty");
2006
2007 LOG_INFO("server.loading", " ");
2008}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true)
Definition: DBCStructure.h:519

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 ( )
2011{
2012 LOG_INFO("server.loading", "Loading Gameobject Loot Templates...");
2013
2014 uint32 oldMSTime = getMSTime();
2015
2016 LootIdSet lootIdSet, lootIdSetUsed;
2018
2019 // remove real entries and check existence loot
2020 GameObjectTemplateContainer const* gotc = sObjectMgr->GetGameObjectTemplates();
2021 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
2022 {
2023 if (uint32 lootid = itr->second.GetLootId())
2024 {
2025 if (lootIdSet.find(lootid) == lootIdSet.end())
2026 LootTemplates_Gameobject.ReportNonExistingId(lootid, "Gameobject", itr->second.entry);
2027 else
2028 lootIdSetUsed.insert(lootid);
2029 }
2030 }
2031
2032 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2033 lootIdSet.erase(*itr);
2034
2035 // output error for any still listed (not referenced from appropriate table) ids
2037
2038 if (count)
2039 LOG_INFO("server.loading", ">> Loaded {} Gameobject Loot Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2040 else
2041 LOG_WARN("server.loading", ">> Loaded 0 gameobject loot templates. DB table `gameobject_loot_template` is empty");
2042
2043 LOG_INFO("server.loading", " ");
2044}
std::unordered_map< uint32, GameObjectTemplate > GameObjectTemplateContainer
Definition: GameObject.h:44
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 ( )
2047{
2048 LOG_INFO("server.loading", "Loading Item Loot Templates...");
2049
2050 uint32 oldMSTime = getMSTime();
2051
2052 LootIdSet lootIdSet;
2054
2055 // remove real entries and check existence loot
2056 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2057 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2058 if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end() && itr->second.Flags & ITEM_FLAG_HAS_LOOT)
2059 lootIdSet.erase(itr->second.ItemId);
2060
2061 // output error for any still listed (not referenced from appropriate table) ids
2063
2064 if (count)
2065 LOG_INFO("server.loading", ">> Loaded {} item loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2066 else
2067 LOG_WARN("server.loading", ">> Loaded 0 item loot templates. DB table `item_loot_template` is empty");
2068
2069 LOG_INFO("server.loading", " ");
2070}
@ ITEM_FLAG_HAS_LOOT
Definition: ItemTemplate.h:150
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 ( )
2171{
2172 LOG_INFO("server.loading", "Loading Mail Loot Templates...");
2173
2174 uint32 oldMSTime = getMSTime();
2175
2176 LootIdSet lootIdSet;
2178
2179 // remove real entries and check existence loot
2180 for (uint32 i = 1; i < sMailTemplateStore.GetNumRows(); ++i)
2181 if (sMailTemplateStore.LookupEntry(i))
2182 if (lootIdSet.find(i) != lootIdSet.end())
2183 lootIdSet.erase(i);
2184
2185 // output error for any still listed (not referenced from appropriate table) ids
2187
2188 if (count)
2189 LOG_INFO("server.loading", ">> Loaded {} mail loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2190 else
2191 LOG_WARN("server.loading", ">> Loaded 0 mail loot templates. DB table `mail_loot_template` is empty");
2192
2193 LOG_INFO("server.loading", " ");
2194}
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)

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 ( )
2073{
2074 LOG_INFO("server.loading", "Loading Milling Loot Templates...");
2075
2076 uint32 oldMSTime = getMSTime();
2077
2078 LootIdSet lootIdSet;
2080
2081 // remove real entries and check existence loot
2082 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2083 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2084 {
2085 if (!(itr->second.Flags & ITEM_FLAG_IS_MILLABLE))
2086 continue;
2087
2088 if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end())
2089 lootIdSet.erase(itr->second.ItemId);
2090 }
2091
2092 // output error for any still listed (not referenced from appropriate table) ids
2094
2095 if (count)
2096 LOG_INFO("server.loading", ">> Loaded {} milling loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2097 else
2098 LOG_WARN("server.loading", ">> Loaded 0 milling loot templates. DB table `milling_loot_template` is empty");
2099
2100 LOG_INFO("server.loading", " ");
2101}
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:177
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 ( )
2104{
2105 LOG_INFO("server.loading", "Loading Pickpocketing Loot Templates...");
2106
2107 uint32 oldMSTime = getMSTime();
2108
2109 LootIdSet lootIdSet, lootIdSetUsed;
2111
2112 // Remove real entries and check loot existence
2113 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2114 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2115 {
2116 if (uint32 lootid = itr->second.pickpocketLootId)
2117 {
2118 if (lootIdSet.find(lootid) == lootIdSet.end())
2119 LootTemplates_Pickpocketing.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
2120 else
2121 lootIdSetUsed.insert(lootid);
2122 }
2123 }
2124
2125 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2126 lootIdSet.erase(*itr);
2127
2128 // output error for any still listed (not referenced from appropriate table) ids
2130
2131 if (count)
2132 LOG_INFO("server.loading", ">> Loaded {} pickpocketing loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2133 else
2134 LOG_WARN("server.loading", ">> Loaded 0 pickpocketing loot templates. DB table `pickpocketing_loot_template` is empty");
2135
2136 LOG_INFO("server.loading", " ");
2137}
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 ( )
2276{
2277 LOG_INFO("server.loading", "Loading Player Loot Templates...");
2278
2279 uint32 oldMSTime = getMSTime();
2280
2281 LootIdSet lootIdSet;
2283
2284 if (count)
2285 {
2286 LOG_INFO("server.loading", ">> Loaded {} player loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2287 }
2288 else
2289 {
2290 LOG_WARN("server.loading", ">> Loaded 0 player loot templates. DB table `player_loot_template` is empty");
2291 }
2292
2293 LOG_INFO("server.loading", " ");
2294}
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 ( )
2140{
2141 LOG_INFO("server.loading", "Loading Prospecting Loot Templates...");
2142
2143 uint32 oldMSTime = getMSTime();
2144
2145 LootIdSet lootIdSet;
2147
2148 // remove real entries and check existence loot
2149 ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
2150 for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
2151 {
2152 if (!(itr->second.Flags & ITEM_FLAG_IS_PROSPECTABLE))
2153 continue;
2154
2155 if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end())
2156 lootIdSet.erase(itr->second.ItemId);
2157 }
2158
2159 // output error for any still listed (not referenced from appropriate table) ids
2161
2162 if (count)
2163 LOG_INFO("server.loading", ">> Loaded {} prospecting loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2164 else
2165 LOG_WARN("server.loading", ">> Loaded 0 prospecting loot templates. DB table `prospecting_loot_template` is empty");
2166
2167 LOG_INFO("server.loading", " ");
2168}
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:166
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 ( )
2297{
2298 LOG_INFO("server.loading", "Loading Reference Loot Templates...");
2299
2300 uint32 oldMSTime = getMSTime();
2301
2302 LootIdSet lootIdSet;
2304
2305 // check references and remove used
2317
2318 // output error for any still listed ids (not referenced from any loot table)
2320
2321 LOG_INFO("server.loading", ">> Loaded refence loot templates in {} ms", GetMSTimeDiffToNow(oldMSTime));
2322 LOG_INFO("server.loading", " ");
2323}
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:276

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 ( )
2197{
2198 LOG_INFO("server.loading", "Loading Skinning Loot Templates...");
2199
2200 uint32 oldMSTime = getMSTime();
2201
2202 LootIdSet lootIdSet, lootIdSetUsed;
2204
2205 // remove real entries and check existence loot
2206 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
2207 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
2208 {
2209 if (uint32 lootid = itr->second.SkinLootId)
2210 {
2211 if (lootIdSet.find(lootid) == lootIdSet.end())
2212 LootTemplates_Skinning.ReportNonExistingId(lootid, "Creature", itr->second.Entry);
2213 else
2214 lootIdSetUsed.insert(lootid);
2215 }
2216 }
2217
2218 for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
2219 lootIdSet.erase(*itr);
2220
2221 // output error for any still listed (not referenced from appropriate table) ids
2223
2224 if (count)
2225 LOG_INFO("server.loading", ">> Loaded {} skinning loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2226 else
2227 LOG_WARN("server.loading", ">> Loaded 0 skinning loot templates. DB table `skinning_loot_template` is empty");
2228
2229 LOG_INFO("server.loading", " ");
2230}

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 ( )
2233{
2234 LOG_INFO("server.loading", "Loading Spell Loot Templates...");
2235
2236 uint32 oldMSTime = getMSTime();
2237
2238 LootIdSet lootIdSet;
2240
2241 // remove real entries and check existence loot
2242 for (uint32 spell_id = 1; spell_id < sSpellMgr->GetSpellInfoStoreSize(); ++spell_id)
2243 {
2244 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2245 if (!spellInfo)
2246 continue;
2247
2248 // possible cases
2249 if (!spellInfo->IsLootCrafting())
2250 continue;
2251
2252 if (lootIdSet.find(spell_id) == lootIdSet.end())
2253 {
2254 // not report about not trainable spells (optionally supported by DB)
2255 // ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example
2257 {
2258 LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id);
2259 }
2260 }
2261 else
2262 lootIdSet.erase(spell_id);
2263 }
2264
2265 // output error for any still listed (not referenced from appropriate table) ids
2267
2268 if (count)
2269 LOG_INFO("server.loading", ">> Loaded {} spell loot templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2270 else
2271 LOG_WARN("server.loading", ">> Loaded 0 spell loot templates. DB table `spell_loot_template` is empty");
2272 LOG_INFO("server.loading", " ");
2273}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
#define sSpellMgr
Definition: SpellMgr.h:818
@ SPELL_ATTR0_IS_TRADESKILL
Definition: SharedDefines.h:359
@ SPELL_ATTR0_NOT_SHAPESHIFTED
Definition: SharedDefines.h:370
Definition: SpellInfo.h:314
uint32 Id
Definition: SpellInfo.h:318
bool IsLootCrafting() const
Definition: SpellInfo.cpp:909
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412

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 
)
971{
972 b << uint32(li.itemid);
973 b << uint32(li.count); // nr of items of this type
974 b << uint32(sObjectMgr->GetItemTemplate(li.itemid)->DisplayInfoID);
975 b << uint32(li.randomSuffix);
976 b << uint32(li.randomPropertyId);
977 //b << uint8(0); // slot type - will send after this function call
978 return b;
979}

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

◆ operator<<() [2/2]

ByteBuffer & operator<< ( ByteBuffer b,
LootView const &  lv 
)
982{
983 if (lv.permission == NONE_PERMISSION)
984 {
985 b << uint32(0); //gold
986 b << uint8(0); // item count
987 return b; // nothing output more
988 }
989
990 Loot& l = lv.loot;
991
992 uint8 itemsShown = 0;
993
994 b << uint32(l.gold); //gold
995
996 size_t count_pos = b.wpos(); // pos of item count byte
997 b << uint8(0); // item count placeholder
998
999 switch (lv.permission)
1000 {
1001 case GROUP_PERMISSION:
1002 case MASTER_PERMISSION:
1004 {
1005 bool isMasterLooter = lv.viewer->GetGroup() && lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID();
1006
1007 // if you are not the round-robin group looter, you can only see
1008 // blocked rolled items and quest items, and !ffa items
1009 for (uint8 i = 0; i < l.items.size(); ++i)
1010 {
1011 if (!l.items[i].is_looted && !l.items[i].freeforall && (l.items[i].conditions.empty() || isMasterLooter) && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1012 {
1013 uint8 slot_type = 0;
1014
1015 if (l.items[i].is_blocked) // for ML & restricted is_blocked = !is_underthreshold
1016 {
1017 switch (lv.permission)
1018 {
1019 case GROUP_PERMISSION:
1020 slot_type = LOOT_SLOT_TYPE_ROLL_ONGOING;
1021 break;
1022 case MASTER_PERMISSION:
1023 {
1024 if (lv.viewer->GetGroup())
1025 {
1026 if (lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID())
1027 slot_type = LOOT_SLOT_TYPE_MASTER;
1028 else
1029 slot_type = LOOT_SLOT_TYPE_LOCKED;
1030 }
1031 break;
1032 }
1034 slot_type = LOOT_SLOT_TYPE_LOCKED;
1035 break;
1036 default:
1037 continue;
1038 }
1039 }
1040 else if (l.items[i].rollWinnerGUID)
1041 {
1042 if (l.items[i].rollWinnerGUID == lv.viewer->GetGUID())
1043 slot_type = LOOT_SLOT_TYPE_OWNER;
1044 else
1045 continue;
1046 }
1047 else if (!l.roundRobinPlayer || lv.viewer->GetGUID() == l.roundRobinPlayer || !l.items[i].is_underthreshold)
1048 {
1049 // no round robin owner or he has released the loot
1050 // or it IS the round robin group owner
1051 // => item is lootable
1052 slot_type = LOOT_SLOT_TYPE_ALLOW_LOOT;
1053 }
1054 else
1055 // item shall not be displayed.
1056 continue;
1057
1058 b << uint8(i) << l.items[i];
1059 b << uint8(slot_type);
1060 ++itemsShown;
1061 }
1062 }
1063 break;
1064 }
1066 {
1067 for (uint8 i = 0; i < l.items.size(); ++i)
1068 {
1069 if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1070 {
1071 if (l.roundRobinPlayer && lv.viewer->GetGUID() != l.roundRobinPlayer)
1072 // item shall not be displayed.
1073 continue;
1074
1075 b << uint8(i) << l.items[i];
1077 ++itemsShown;
1078 }
1079 }
1080 break;
1081 }
1082 case ALL_PERMISSION:
1083 case OWNER_PERMISSION:
1084 {
1086 for (uint8 i = 0; i < l.items.size(); ++i)
1087 {
1088 if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1089 {
1090 b << uint8(i) << l.items[i];
1091 b << uint8(slot_type);
1092 ++itemsShown;
1093 }
1094 }
1095 break;
1096 }
1097 default:
1098 return b;
1099 }
1100
1102
1103 // Xinef: items that do not follow loot rules need this
1104 LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : slotType;
1105
1106 QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
1107 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID());
1108 if (q_itr != lootPlayerQuestItems.end())
1109 {
1110 QuestItemList* q_list = q_itr->second;
1111 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
1112 {
1113 LootItem& item = l.quest_items[qi->index];
1114 if (!qi->is_looted && !item.is_looted)
1115 {
1116 bool showInLoot = true;
1117 bool hasQuestForItem = lv.viewer->HasQuestForItem(item.itemid, 0, false, &showInLoot);
1118 if (!hasQuestForItem)
1119 {
1120 if (!showInLoot)
1121 {
1122 const_cast<QuestItem*>(&(*qi))->is_looted = true;
1123 if (!item.freeforall)
1124 {
1125 item.is_looted = true;
1126 }
1127 continue;
1128 }
1129
1130 b << uint8(l.items.size() + (qi - q_list->begin()));
1131 b << item;
1133 }
1134 else
1135 {
1136 b << uint8(l.items.size() + (qi - q_list->begin()));
1137 b << item;
1138
1139 if (item.follow_loot_rules)
1140 {
1141 switch (lv.permission)
1142 {
1143 case MASTER_PERMISSION:
1145 break;
1147 b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
1148 break;
1149 case GROUP_PERMISSION:
1151 if (!item.is_blocked)
1153 else
1155 break;
1156 default:
1157 b << uint8(slotType);
1158 break;
1159 }
1160 }
1161 else if (!item.freeforall)
1162 b << uint8(partySlotType);
1163 else
1164 b << uint8(slotType);
1165 }
1166
1167 ++itemsShown;
1168 }
1169 }
1170 }
1171
1172 QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems();
1173 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID());
1174 if (ffa_itr != lootPlayerFFAItems.end())
1175 {
1176 QuestItemList* ffa_list = ffa_itr->second;
1177 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
1178 {
1179 LootItem& item = l.items[fi->index];
1180 if (!fi->is_looted && !item.is_looted)
1181 {
1182 b << uint8(fi->index);
1183 b << item;
1184 // Xinef: Here are FFA items, so dont use owner permision
1185 b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT /*slotType*/);
1186 ++itemsShown;
1187 }
1188 }
1189 }
1190
1191 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
1192 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID());
1193 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
1194 {
1195 QuestItemList* conditional_list = nn_itr->second;
1196 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
1197 {
1198 LootItem& item = l.items[ci->index];
1199 if (!ci->is_looted && !item.is_looted)
1200 {
1201 b << uint8(ci->index);
1202 b << item;
1203 if (item.follow_loot_rules)
1204 {
1205 switch (lv.permission)
1206 {
1207 case MASTER_PERMISSION:
1209 break;
1211 b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
1212 break;
1213 case GROUP_PERMISSION:
1215 if (!item.is_blocked)
1217 else
1219 break;
1220 default:
1221 b << uint8(slotType);
1222 break;
1223 }
1224 }
1225 else if (!item.freeforall)
1226 b << uint8(partySlotType);
1227 else
1228 b << uint8(slotType);
1229 ++itemsShown;
1230 }
1231 }
1232 }
1233
1234 //update number of items shown
1235 b.put<uint8>(count_pos, itemsShown);
1236
1237 return b;
1238}
std::uint8_t uint8
Definition: Define.h:110
@ OWNER_PERMISSION
Definition: LootMgr.h:73
@ ALL_PERMISSION
Definition: LootMgr.h:68
@ RESTRICTED_PERMISSION
Definition: LootMgr.h:71
@ NONE_PERMISSION
Definition: LootMgr.h:74
@ ROUND_ROBIN_PERMISSION
Definition: LootMgr.h:72
@ MASTER_PERMISSION
Definition: LootMgr.h:70
@ GROUP_PERMISSION
Definition: LootMgr.h:69
std::map< ObjectGuid, QuestItemList * > QuestItemMap
Definition: LootMgr.h:201
LootSlotType
Definition: LootMgr.h:114
@ LOOT_SLOT_TYPE_MASTER
Definition: LootMgr.h:117
@ LOOT_SLOT_TYPE_ROLL_ONGOING
Definition: LootMgr.h:116
@ LOOT_SLOT_TYPE_ALLOW_LOOT
Definition: LootMgr.h:115
@ LOOT_SLOT_TYPE_OWNER
Definition: LootMgr.h:119
@ LOOT_SLOT_TYPE_LOCKED
Definition: LootMgr.h:118
std::vector< QuestItem > QuestItemList
Definition: LootMgr.h:199
Definition: LootMgr.h:155
uint32 itemid
Definition: LootMgr.h:156
bool is_looted
Definition: LootMgr.h:164
bool freeforall
Definition: LootMgr.h:166
Definition: LootMgr.h:186
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
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:433
@ RATE_DROP_ITEM_LEGENDARY
Definition: IWorld.h:435
@ RATE_DROP_ITEM_POOR
Definition: IWorld.h:430
@ RATE_DROP_ITEM_UNCOMMON
Definition: IWorld.h:432
@ RATE_DROP_ITEM_EPIC
Definition: IWorld.h:434
@ RATE_DROP_ITEM_ARTIFACT
Definition: IWorld.h:436
@ RATE_DROP_ITEM_NORMAL
Definition: IWorld.h:431