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 ( )
1267{
1268 while (!ExplicitlyChanced.empty())
1269 {
1270 delete ExplicitlyChanced.back();
1271 ExplicitlyChanced.pop_back();
1272 }
1273
1274 while (!EqualChanced.empty())
1275 {
1276 delete EqualChanced.back();
1277 EqualChanced.pop_back();
1278 }
1279}
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)
1283{
1284 if (item->chance != 0)
1285 ExplicitlyChanced.push_back(item);
1286 else
1287 EqualChanced.push_back(item);
1288}
float chance
Definition: LootMgr.h:131

References LootStoreItem::chance.

◆ CheckLootRefs()

void LootTemplate::LootGroup::CheckLootRefs ( LootStore const &  lootstore,
uint32  Id,
LootIdSet ref_set 
) const
1511{
1512 for (LootStoreItemList::const_iterator ieItr = ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr)
1513 {
1514 LootStoreItem* item = *ieItr;
1515 if (item->reference)
1516 {
1517 if (item->mincount != item->maxcount)
1518 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1519
1520 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1521 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1522 else if (ref_set)
1523 ref_set->erase(std::abs(item->reference));
1524 }
1525 }
1526
1527 for (LootStoreItemList::const_iterator ieItr = EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr)
1528 {
1529 LootStoreItem* item = *ieItr;
1530 if (item->reference)
1531 {
1532 if (item->mincount != item->maxcount)
1533 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1534
1535 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1536 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1537 else if (ref_set)
1538 ref_set->erase(std::abs(item->reference));
1539 }
1540 }
1541}
LootStore LootTemplates_Reference
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
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

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)
1429{
1430 for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1431 (*i)->conditions.clear();
1432
1433 for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1434 (*i)->conditions.clear();
1435}

◆ GetEqualChancedItemList()

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

◆ GetExplicitlyChancedItemList()

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

◆ HasQuestDrop()

bool LootTemplate::LootGroup::HasQuestDrop ( LootTemplateMap const &  store) const
1330{
1331 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1332 {
1333 LootStoreItem* item = *i;
1334 if (item->reference) // References
1335 {
1336 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1337 if (Referenced == store.end())
1338 {
1339 continue; // Error message [should be] already printed at loading stage
1340 }
1341
1342 if (Referenced->second->HasQuestDrop(store, item->groupid))
1343 {
1344 return true;
1345 }
1346 }
1347 else if (item->needs_quest)
1348 {
1349 return true;
1350 }
1351 }
1352
1353 for (LootStoreItemList::const_iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1354 {
1355 LootStoreItem* item = *i;
1356 if (item->reference) // References
1357 {
1358 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1359 if (Referenced == store.end())
1360 {
1361 continue; // Error message [should be] already printed at loading stage
1362 }
1363
1364 if (Referenced->second->HasQuestDrop(store, item->groupid))
1365 {
1366 return true;
1367 }
1368 }
1369 else if (item->needs_quest)
1370 {
1371 return true;
1372 }
1373 }
1374
1375 return false;
1376}
bool needs_quest
Definition: LootMgr.h:132
uint8 groupid
Definition: LootMgr.h:134

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

◆ HasQuestDropForPlayer()

bool LootTemplate::LootGroup::HasQuestDropForPlayer ( Player const *  player,
LootTemplateMap const &  store 
) const
1380{
1381 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1382 {
1383 LootStoreItem* item = *i;
1384 if (item->reference) // References processing
1385 {
1386 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1387 if (Referenced == store.end())
1388 {
1389 continue; // Error message already printed at loading stage
1390 }
1391
1392 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
1393 {
1394 return true;
1395 }
1396 }
1397 else if (player->HasQuestForItem(item->itemid))
1398 {
1399 return true; // active quest drop found
1400 }
1401 }
1402
1403 for (LootStoreItemList::const_iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1404 {
1405 LootStoreItem* item = *i;
1406 if (item->reference) // References processing
1407 {
1408 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1409 if (Referenced == store.end())
1410 {
1411 continue; // Error message already printed at loading stage
1412 }
1413
1414 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
1415 {
1416 return true;
1417 }
1418 }
1419 else if (player->HasQuestForItem(item->itemid))
1420 {
1421 return true; // active quest drop found
1422 }
1423 }
1424
1425 return false;
1426}

References LootStoreItem::groupid, 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
1439{
1440 if (LootStoreItem const* item = Roll(loot, player, store, lootMode))
1441 {
1442 bool rate = store.IsRatesAllowed();
1443
1444 if (item->reference) // References processing
1445 {
1446 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1447 {
1448 uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
1449 sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, const_cast<LootStoreItem*>(item), maxcount, store);
1450 for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
1451 // This reference needs to be processed further, but it is marked isTopLevel=false so that any groups inside
1452 // the reference are not multiplied by Rate.Drop.Item.GroupAmount
1453 Referenced->Process(loot, store, lootMode, player, item->groupid, false);
1454 }
1455 }
1456 else
1457 {
1458 // Plain entries (not a reference, not grouped)
1459 sScriptMgr->OnBeforeDropAddItem(player, loot, rate, lootMode, const_cast<LootStoreItem*>(item), store);
1460 loot.AddItem(*item); // Chance is already checked, just add
1461
1462 // If we still have non-ref runs to do for this group AND this item wasn't a reference,
1463 // recursively call this function to produce more items for this group.
1464 // However, if this is a quest item we shouldn't multiply this group.
1465 if (nonRefIterationsLeft > 1 && !item->needs_quest)
1466 {
1467 this->Process(loot, player, store, lootMode, nonRefIterationsLeft-1);
1468 }
1469 }
1470 }
1471}
std::uint32_t uint32
Definition: Define.h:107
@ RATE_DROP_ITEM_REFERENCED_AMOUNT
Definition: IWorld.h:447
#define sScriptMgr
Definition: ScriptMgr.h:709
#define sWorld
Definition: World.h:443
Definition: Group.h:143
void Process(Loot &loot, Player const *player, LootStore const &lootstore, uint16 lootMode, uint16 nonRefIterationsLeft) const
Definition: LootMgr.cpp:1438
Definition: LootMgr.h:245
void AddItem(LootStoreItem const &item)
Definition: LootMgr.cpp:511

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
1475{
1476 float result = 0;
1477
1478 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1479 if (!(*i)->needs_quest)
1480 result += (*i)->chance;
1481
1482 return result;
1483}

◆ Roll()

LootStoreItem const * LootTemplate::LootGroup::Roll ( Loot loot,
Player const *  player,
LootStore const &  store,
uint16  lootMode 
) const
private
1292{
1293 LootStoreItemList possibleLoot = ExplicitlyChanced;
1294 possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
1295
1296 if (!possibleLoot.empty()) // First explicitly chanced entries are checked
1297 {
1298 float roll = (float)rand_chance();
1299
1300 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.
1301 {
1302 LootStoreItem* item = *itr;
1303 float chance = item->chance;
1304
1305 if (!sScriptMgr->OnItemRoll(player, item, chance, loot, store))
1306 return nullptr;
1307
1308 if (chance >= 100.0f)
1309 return item;
1310
1311 roll -= chance;
1312 if (roll < 0)
1313 return item;
1314 }
1315 }
1316
1317 if (!sScriptMgr->OnBeforeLootEqualChanced(player, EqualChanced, loot, store))
1318 return nullptr;
1319
1320 possibleLoot = EqualChanced;
1321 possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
1322 if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part
1324
1325 return nullptr; // Empty drop from the group
1326}
double rand_chance()
Definition: Random.cpp:83
std::list< LootStoreItem * > LootStoreItemList
Definition: LootMgr.h:201
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
1487{
1488 float result = RawTotalChance();
1489
1490 if (!EqualChanced.empty() && result < 100.0f)
1491 return 100.0f;
1492
1493 return result;
1494}
float RawTotalChance() const
Definition: LootMgr.cpp:1474

◆ Verify()

void LootTemplate::LootGroup::Verify ( LootStore const &  lootstore,
uint32  id,
uint8  group_id 
) const
Todo:
: replace with 100% when DBs will be ready
1497{
1498 float chance = RawTotalChance();
1499 if (chance > 101.0f)
1500 {
1501 LOG_ERROR("sql.sql", "Table '{}' entry {} group {} has total chance > 100% ({})", lootstore.GetName(), id, group_id, chance);
1502 }
1503
1504 if (chance >= 100.0f && !EqualChanced.empty())
1505 {
1506 LOG_ERROR("sql.sql", "Table '{}' entry {} group {} has items with chance=0% but group total chance >= 100% ({})", lootstore.GetName(), id, group_id, chance);
1507 }
1508}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157

References LootStore::GetName(), and LOG_ERROR.

Member Data Documentation

◆ EqualChanced

LootStoreItemList LootTemplate::LootGroup::EqualChanced
private

◆ ExplicitlyChanced

LootStoreItemList LootTemplate::LootGroup::ExplicitlyChanced
private