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 (LootTemplateMap const &store, 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
96{ }

◆ ~LootGroup()

LootTemplate::LootGroup::~LootGroup ( )
1246{
1247 while (!ExplicitlyChanced.empty())
1248 {
1249 delete ExplicitlyChanced.back();
1250 ExplicitlyChanced.pop_back();
1251 }
1252
1253 while (!EqualChanced.empty())
1254 {
1255 delete EqualChanced.back();
1256 EqualChanced.pop_back();
1257 }
1258}
LootStoreItemList ExplicitlyChanced
Definition: LootMgr.cpp:114
LootStoreItemList EqualChanced
Definition: LootMgr.cpp:115

References EqualChanced, and ExplicitlyChanced.

◆ LootGroup() [2/2]

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

Member Function Documentation

◆ AddEntry()

void LootTemplate::LootGroup::AddEntry ( LootStoreItem item)
1262{
1263 if (item->chance != 0)
1264 ExplicitlyChanced.push_back(item);
1265 else
1266 EqualChanced.push_back(item);
1267}
float chance
Definition: LootMgr.h:132

References LootStoreItem::chance.

◆ CheckLootRefs()

void LootTemplate::LootGroup::CheckLootRefs ( LootTemplateMap const &  store,
LootIdSet ref_set 
) const
1490{
1491 for (LootStoreItemList::const_iterator ieItr = ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr)
1492 {
1493 LootStoreItem* item = *ieItr;
1494 if (item->reference)
1495 {
1496 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1497 {
1498 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), "Reference", item->itemid);
1499 }
1500 else if (ref_set)
1501 {
1502 ref_set->erase(std::abs(item->reference));
1503 }
1504 }
1505 }
1506
1507 for (LootStoreItemList::const_iterator ieItr = EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr)
1508 {
1509 LootStoreItem* item = *ieItr;
1510 if (item->reference)
1511 {
1512 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1513 {
1514 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), "Reference", item->itemid);
1515 }
1516 else if (ref_set)
1517 {
1518 ref_set->erase(std::abs(item->reference));
1519 }
1520 }
1521 }
1522}
LootStore LootTemplates_Reference
Definition: LootMgr.h:129
int32 reference
Definition: LootMgr.h:131
uint32 itemid
Definition: LootMgr.h:130
LootTemplate const * GetLootFor(uint32 loot_id) const
Definition: LootMgr.cpp:246
void ReportNonExistingId(uint32 lootId) const
Definition: LootMgr.cpp:289

References LootStore::GetLootFor(), LootStoreItem::itemid, LootTemplates_Reference, LootStoreItem::reference, and LootStore::ReportNonExistingId().

◆ CollectLootIds()

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

◆ CopyConditions()

void LootTemplate::LootGroup::CopyConditions ( ConditionList  conditions)
1408{
1409 for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1410 (*i)->conditions.clear();
1411
1412 for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
1413 (*i)->conditions.clear();
1414}

◆ GetEqualChancedItemList()

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

◆ GetExplicitlyChancedItemList()

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

◆ HasQuestDrop()

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

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

◆ HasQuestDropForPlayer()

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

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

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
1454{
1455 float result = 0;
1456
1457 for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
1458 if (!(*i)->needs_quest)
1459 result += (*i)->chance;
1460
1461 return result;
1462}

◆ Roll()

LootStoreItem const * LootTemplate::LootGroup::Roll ( Loot loot,
Player const *  player,
LootStore const &  store,
uint16  lootMode 
) const
private
1271{
1272 LootStoreItemList possibleLoot = ExplicitlyChanced;
1273 possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
1274
1275 if (!possibleLoot.empty()) // First explicitly chanced entries are checked
1276 {
1277 float roll = (float)rand_chance();
1278
1279 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.
1280 {
1281 LootStoreItem* item = *itr;
1282 float chance = item->chance;
1283
1284 if (!sScriptMgr->OnItemRoll(player, item, chance, loot, store))
1285 return nullptr;
1286
1287 if (chance >= 100.0f)
1288 return item;
1289
1290 roll -= chance;
1291 if (roll < 0)
1292 return item;
1293 }
1294 }
1295
1296 if (!sScriptMgr->OnBeforeLootEqualChanced(player, EqualChanced, loot, store))
1297 return nullptr;
1298
1299 possibleLoot = EqualChanced;
1300 possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
1301 if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part
1303
1304 return nullptr; // Empty drop from the group
1305}
double rand_chance()
Definition: Random.cpp:83
std::list< LootStoreItem * > LootStoreItemList
Definition: LootMgr.h:202
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:135
Definition: LootMgr.cpp:59

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

◆ TotalChance()

float LootTemplate::LootGroup::TotalChance ( ) const
1466{
1467 float result = RawTotalChance();
1468
1469 if (!EqualChanced.empty() && result < 100.0f)
1470 return 100.0f;
1471
1472 return result;
1473}
float RawTotalChance() const
Definition: LootMgr.cpp:1453

◆ Verify()

void LootTemplate::LootGroup::Verify ( LootStore const &  lootstore,
uint32  id,
uint8  group_id 
) const
Todo:
: replace with 100% when DBs will be ready
1476{
1477 float chance = RawTotalChance();
1478 if (chance > 101.0f)
1479 {
1480 LOG_ERROR("sql.sql", "Table '{}' entry {} group {} has total chance > 100% ({})", lootstore.GetName(), id, group_id, chance);
1481 }
1482
1483 if (chance >= 100.0f && !EqualChanced.empty())
1484 {
1485 LOG_ERROR("sql.sql", "Table '{}' entry {} group {} has items with chance=0% but group total chance >= 100% ({})", lootstore.GetName(), id, group_id, chance);
1486 }
1487}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159

References LootStore::GetName(), and LOG_ERROR.

Member Data Documentation

◆ EqualChanced

LootStoreItemList LootTemplate::LootGroup::EqualChanced
private

◆ ExplicitlyChanced

LootStoreItemList LootTemplate::LootGroup::ExplicitlyChanced
private