AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
LootTemplate::LootGroup Class Reference

Public Member Functions

 LootGroup ()
 
 ~LootGroup ()
 
void AddEntry (LootStoreItem *item)
 
bool HasQuestDrop (LootTemplateMap const &store) const
 
bool HasQuestDropForPlayer (Player const *player, LootTemplateMap const &store) const
 
void Process (Loot &loot, Player const *player, LootStore const &lootstore, uint16 lootMode, uint16 nonRefIterationsLeft) const
 
float RawTotalChance () const
 
float TotalChance () const
 
void Verify (LootStore const &lootstore, uint32 id, uint8 group_id) const
 
void CollectLootIds (LootIdSet &set) const
 
void CheckLootRefs (LootStore const &lootstore, uint32 Id, LootIdSet *ref_set) const
 
LootStoreItemListGetExplicitlyChancedItemList ()
 
LootStoreItemListGetEqualChancedItemList ()
 
void CopyConditions (ConditionList conditions)
 

Private Member Functions

LootStoreItem const * Roll (Loot &loot, Player const *player, LootStore const &store, uint16 lootMode) const
 
 LootGroup (LootGroup const &)
 
LootGroupoperator= (LootGroup const &)
 

Private Attributes

LootStoreItemList ExplicitlyChanced
 
LootStoreItemList EqualChanced
 

Detailed Description

Constructor & Destructor Documentation

◆ LootGroup() [1/2]

LootTemplate::LootGroup::LootGroup ( )
inline
97{ }

◆ ~LootGroup()

LootTemplate::LootGroup::~LootGroup ( )
1238{
1239 while (!ExplicitlyChanced.empty())
1240 {
1241 delete ExplicitlyChanced.back();
1242 ExplicitlyChanced.pop_back();
1243 }
1244
1245 while (!EqualChanced.empty())
1246 {
1247 delete EqualChanced.back();
1248 EqualChanced.pop_back();
1249 }
1250}
LootStoreItemList ExplicitlyChanced
Definition LootMgr.cpp:115
LootStoreItemList EqualChanced
Definition LootMgr.cpp:116

References EqualChanced, and ExplicitlyChanced.

◆ LootGroup() [2/2]

LootTemplate::LootGroup::LootGroup ( LootGroup const &  )
private

Member Function Documentation

◆ AddEntry()

void LootTemplate::LootGroup::AddEntry ( LootStoreItem item)
1254{
1255 if (item->chance != 0)
1256 ExplicitlyChanced.push_back(item);
1257 else
1258 EqualChanced.push_back(item);
1259}
float chance
Definition LootMgr.h:131

References LootStoreItem::chance.

◆ CheckLootRefs()

void LootTemplate::LootGroup::CheckLootRefs ( LootStore const &  lootstore,
uint32  Id,
LootIdSet ref_set 
) const
1482{
1483 for (LootStoreItemList::const_iterator ieItr = ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr)
1484 {
1485 LootStoreItem* item = *ieItr;
1486 if (item->reference)
1487 {
1488 if (item->mincount != item->maxcount)
1489 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1490
1491 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1492 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1493 else if (ref_set)
1494 ref_set->erase(std::abs(item->reference));
1495 }
1496 }
1497
1498 for (LootStoreItemList::const_iterator ieItr = EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr)
1499 {
1500 LootStoreItem* item = *ieItr;
1501 if (item->reference)
1502 {
1503 if (item->mincount != item->maxcount)
1504 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1505
1506 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1507 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1508 else if (ref_set)
1509 ref_set->erase(std::abs(item->reference));
1510 }
1511 }
1512}
LootStore LootTemplates_Reference
LootTemplate const * GetLootFor(uint32 loot_id) const
Definition LootMgr.cpp:247
void ReportInvalidCount(uint32 lootId, const char *ownerType, uint32 ownerId, uint32 itemId, uint8 minCount, uint8 maxCount) const
Definition LootMgr.cpp:300
void ReportNonExistingId(uint32 lootId) const
Definition LootMgr.cpp:290
Definition LootMgr.h:128
int32 reference
Definition LootMgr.h:130
uint32 itemid
Definition LootMgr.h:129
uint8 maxcount
Definition LootMgr.h:136
uint8 mincount
Definition LootMgr.h:135

References LootStore::GetLootFor(), LootStore::GetName(), LootStoreItem::itemid, LootTemplates_Reference, LootStoreItem::maxcount, LootStoreItem::mincount, LootStoreItem::reference, LootStore::ReportInvalidCount(), and LootStore::ReportNonExistingId().

◆ CollectLootIds()

void LootTemplate::LootGroup::CollectLootIds ( LootIdSet set) const

◆ CopyConditions()

void LootTemplate::LootGroup::CopyConditions ( ConditionList  conditions)
1400{
1401 for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1402 (*i)->conditions.clear();
1403
1404 for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1405 (*i)->conditions.clear();
1406}

References LootStoreItem::conditions.

◆ GetEqualChancedItemList()

LootStoreItemList * LootTemplate::LootGroup::GetEqualChancedItemList ( )
inline

◆ GetExplicitlyChancedItemList()

LootStoreItemList * LootTemplate::LootGroup::GetExplicitlyChancedItemList ( )
inline

◆ HasQuestDrop()

bool LootTemplate::LootGroup::HasQuestDrop ( LootTemplateMap const &  store) const
1301{
1302 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1303 {
1304 LootStoreItem* item = *i;
1305 if (item->reference) // References
1306 {
1307 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1308 if (Referenced == store.end())
1309 {
1310 continue; // Error message [should be] already printed at loading stage
1311 }
1312
1313 if (Referenced->second->HasQuestDrop(store))
1314 {
1315 return true;
1316 }
1317 }
1318 else if (item->needs_quest)
1319 {
1320 return true;
1321 }
1322 }
1323
1324 for (LootStoreItemList::const_iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1325 {
1326 LootStoreItem* item = *i;
1327 if (item->reference) // References
1328 {
1329 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1330 if (Referenced == store.end())
1331 {
1332 continue; // Error message [should be] already printed at loading stage
1333 }
1334
1335 if (Referenced->second->HasQuestDrop(store))
1336 {
1337 return true;
1338 }
1339 }
1340 else if (item->needs_quest)
1341 {
1342 return true;
1343 }
1344 }
1345
1346 return false;
1347}
bool needs_quest
Definition LootMgr.h:132

References LootStoreItem::needs_quest, and LootStoreItem::reference.

◆ HasQuestDropForPlayer()

bool LootTemplate::LootGroup::HasQuestDropForPlayer ( Player const *  player,
LootTemplateMap const &  store 
) const
1351{
1352 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1353 {
1354 LootStoreItem* item = *i;
1355 if (item->reference) // References processing
1356 {
1357 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1358 if (Referenced == store.end())
1359 {
1360 continue; // Error message already printed at loading stage
1361 }
1362
1363 if (Referenced->second->HasQuestDropForPlayer(store, player))
1364 {
1365 return true;
1366 }
1367 }
1368 else if (player->HasQuestForItem(item->itemid))
1369 {
1370 return true; // active quest drop found
1371 }
1372 }
1373
1374 for (LootStoreItemList::const_iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1375 {
1376 LootStoreItem* item = *i;
1377 if (item->reference) // References processing
1378 {
1379 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1380 if (Referenced == store.end())
1381 {
1382 continue; // Error message already printed at loading stage
1383 }
1384
1385 if (Referenced->second->HasQuestDropForPlayer(store, player))
1386 {
1387 return true;
1388 }
1389 }
1390 else if (player->HasQuestForItem(item->itemid))
1391 {
1392 return true; // active quest drop found
1393 }
1394 }
1395
1396 return false;
1397}

References Player::HasQuestForItem(), LootStoreItem::itemid, and LootStoreItem::reference.

◆ operator=()

LootGroup & LootTemplate::LootGroup::operator= ( LootGroup const &  )
private

◆ Process()

void LootTemplate::LootGroup::Process ( Loot loot,
Player const *  player,
LootStore const &  lootstore,
uint16  lootMode,
uint16  nonRefIterationsLeft 
) const
1410{
1411 if (LootStoreItem const* item = Roll(loot, player, store, lootMode))
1412 {
1413 bool rate = store.IsRatesAllowed();
1414
1415 if (item->reference) // References processing
1416 {
1417 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1418 {
1419 uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
1420 sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, const_cast<LootStoreItem*>(item), maxcount, store);
1421 for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
1422 // This reference needs to be processed further, but it is marked isTopLevel=false so that any groups inside
1423 // the reference are not multiplied by Rate.Drop.Item.GroupAmount
1424 Referenced->Process(loot, store, lootMode, player, 0, false);
1425 }
1426 }
1427 else
1428 {
1429 // Plain entries (not a reference, not grouped)
1430 sScriptMgr->OnBeforeDropAddItem(player, loot, rate, lootMode, const_cast<LootStoreItem*>(item), store);
1431 loot.AddItem(*item); // Chance is already checked, just add
1432
1433 // If we still have non-ref runs to do for this group AND this item wasn't a reference,
1434 // recursively call this function to produce more items for this group.
1435 // However, if this is a quest item we shouldn't multiply this group.
1436 if (nonRefIterationsLeft > 1 && !item->needs_quest)
1437 {
1438 this->Process(loot, player, store, lootMode, nonRefIterationsLeft-1);
1439 }
1440 }
1441 }
1442}
std::uint32_t uint32
Definition Define.h:107
#define sScriptMgr
Definition ScriptMgr.h:737
@ RATE_DROP_ITEM_REFERENCED_AMOUNT
Definition WorldConfig.h:408
void Process(Loot &loot, Player const *player, LootStore const &lootstore, uint16 lootMode, uint16 nonRefIterationsLeft) const
Definition LootMgr.cpp:1409
Definition LootMgr.h:245
Definition Group.h:143
#define sWorld
Definition World.h:317
void AddItem(LootStoreItem const &item)
Definition LootMgr.cpp:481

References Loot::AddItem(), LootStore::GetLootFor(), LootStore::IsRatesAllowed(), LootTemplates_Reference, LootTemplate::Process(), RATE_DROP_ITEM_REFERENCED_AMOUNT, sScriptMgr, and sWorld.

◆ RawTotalChance()

float LootTemplate::LootGroup::RawTotalChance ( ) const
1446{
1447 float result = 0;
1448
1449 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1450 if (!(*i)->needs_quest)
1451 result += (*i)->chance;
1452
1453 return result;
1454}

◆ Roll()

LootStoreItem const * LootTemplate::LootGroup::Roll ( Loot loot,
Player const *  player,
LootStore const &  store,
uint16  lootMode 
) const
private
1263{
1264 LootStoreItemList possibleLoot = ExplicitlyChanced;
1265 possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
1266
1267 if (!possibleLoot.empty()) // First explicitly chanced entries are checked
1268 {
1269 float roll = (float)rand_chance();
1270
1271 for (LootStoreItemList::const_iterator itr = possibleLoot.begin(); itr != possibleLoot.end(); ++itr) // check each explicitly chanced entry in the template and modify its chance based on quality.
1272 {
1273 LootStoreItem* item = *itr;
1274 float chance = item->chance;
1275
1276 if (!sScriptMgr->OnItemRoll(player, item, chance, loot, store))
1277 return nullptr;
1278
1279 if (chance >= 100.0f)
1280 return item;
1281
1282 roll -= chance;
1283 if (roll < 0)
1284 return item;
1285 }
1286 }
1287
1288 if (!sScriptMgr->OnBeforeLootEqualChanced(player, EqualChanced, loot, store))
1289 return nullptr;
1290
1291 possibleLoot = EqualChanced;
1292 possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
1293 if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part
1295
1296 return nullptr; // Empty drop from the group
1297}
std::list< LootStoreItem * > LootStoreItemList
Definition LootMgr.h:201
double rand_chance()
Definition Random.cpp:91
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:133
Definition LootMgr.cpp:60

References LootStoreItem::chance, rand_chance(), Acore::Containers::SelectRandomContainerElement(), and sScriptMgr.

◆ TotalChance()

float LootTemplate::LootGroup::TotalChance ( ) const
1458{
1459 float result = RawTotalChance();
1460
1461 if (!EqualChanced.empty() && result < 100.0f)
1462 return 100.0f;
1463
1464 return result;
1465}
float RawTotalChance() const
Definition LootMgr.cpp:1445

◆ Verify()

void LootTemplate::LootGroup::Verify ( LootStore const &  lootstore,
uint32  id,
uint8  group_id 
) const
Todo:
: replace with 100% when DBs will be ready
1468{
1469 float chance = RawTotalChance();
1470 if (chance > 101.0f)
1471 {
1472 LOG_ERROR("sql.sql", "Table '{}' entry {} group {} has total chance > 100% ({})", lootstore.GetName(), id, group_id, chance);
1473 }
1474
1475 if (chance >= 100.0f && !EqualChanced.empty())
1476 {
1477 LOG_ERROR("sql.sql", "Table '{}' entry {} group {} has items with chance=0% but group total chance >= 100% ({})", lootstore.GetName(), id, group_id, chance);
1478 }
1479}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145

References LootStore::GetName(), and LOG_ERROR.

Member Data Documentation

◆ EqualChanced

LootStoreItemList LootTemplate::LootGroup::EqualChanced
private

◆ ExplicitlyChanced

LootStoreItemList LootTemplate::LootGroup::ExplicitlyChanced
private

The documentation for this class was generated from the following file: