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

#include "LootMgr.h"

Classes

class  LootGroup
 

Public Member Functions

 LootTemplate ()=default
 
 ~LootTemplate ()
 
void AddEntry (LootStoreItem *item)
 
void Process (Loot &loot, LootStore const &store, uint16 lootMode, Player const *player, uint8 groupId=0, bool isTopLevel=true) const
 
void CopyConditions (ConditionList conditions)
 
bool CopyConditions (LootItem *li, uint32 conditionLootId=0) const
 
bool HasQuestDrop (LootTemplateMap const &store) const
 
bool HasQuestDropForPlayer (LootTemplateMap const &store, Player const *player) const
 
void Verify (LootStore const &store, uint32 Id) const
 
void CheckLootRefs (LootStore const &lootstore, uint32 Id, LootIdSet *ref_set) const
 
bool addConditionItem (Condition *cond)
 
bool isReference (uint32 id) const
 

Private Types

typedef std::vector< LootGroup * > LootGroups
 

Private Member Functions

 LootTemplate (LootTemplate const &)
 
LootTemplateoperator= (LootTemplate const &)
 

Private Attributes

LootStoreItemList Entries
 
LootGroups Groups
 

Detailed Description

Member Typedef Documentation

◆ LootGroups

typedef std::vector<LootGroup*> LootTemplate::LootGroups
private

Constructor & Destructor Documentation

◆ LootTemplate() [1/2]

LootTemplate::LootTemplate ( )
default

◆ ~LootTemplate()

LootTemplate::~LootTemplate ( )
1501{
1502 while (!Entries.empty())
1503 {
1504 delete Entries.back();
1505 Entries.pop_back();
1506 }
1507
1508 for (std::size_t i = 0; i < Groups.size(); ++i)
1509 delete Groups[i];
1510 Groups.clear();
1511}
Groups
Definition boss_moroes.cpp:55
Entries
Definition zone_howling_fjord.cpp:73

◆ LootTemplate() [2/2]

LootTemplate::LootTemplate ( LootTemplate const &  )
private

Member Function Documentation

◆ addConditionItem()

bool LootTemplate::addConditionItem ( Condition cond)
1822{
1823 if (!cond || !cond->isLoaded())//should never happen, checked at loading
1824 {
1825 LOG_ERROR("condition", "LootTemplate::addConditionItem: condition is null");
1826 return false;
1827 }
1828
1829 if (!Entries.empty())
1830 {
1831 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1832 {
1833 if ((*i)->itemid == uint32(cond->SourceEntry))
1834 {
1835 (*i)->conditions.push_back(cond);
1836 return true;
1837 }
1838 }
1839 }
1840
1841 if (!Groups.empty())
1842 {
1843 for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1844 {
1845 LootGroup* group = *groupItr;
1846 if (!group)
1847 continue;
1848
1849 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1850 if (!itemList->empty())
1851 {
1852 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1853 {
1854 if ((*i)->itemid == uint32(cond->SourceEntry))
1855 {
1856 (*i)->conditions.push_back(cond);
1857 return true;
1858 }
1859 }
1860 }
1861
1862 itemList = group->GetEqualChancedItemList();
1863 if (!itemList->empty())
1864 {
1865 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1866 {
1867 if ((*i)->itemid == uint32(cond->SourceEntry))
1868 {
1869 (*i)->conditions.push_back(cond);
1870 return true;
1871 }
1872 }
1873 }
1874 }
1875 }
1876 return false;
1877}
std::uint32_t uint32
Definition Define.h:107
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
std::list< LootStoreItem * > LootStoreItemList
Definition LootMgr.h:201
bool isLoaded() const
Definition ConditionMgr.h:235
int32 SourceEntry
Definition ConditionMgr.h:200

References LootTemplate::LootGroup::GetEqualChancedItemList(), LootTemplate::LootGroup::GetExplicitlyChancedItemList(), Condition::isLoaded(), LOG_ERROR, and Condition::SourceEntry.

Referenced by ConditionMgr::addToLootTemplate().

◆ AddEntry()

void LootTemplate::AddEntry ( LootStoreItem item)
1515{
1516 if (item->groupid > 0) // Group and grouped reference
1517 {
1518 if (item->groupid >= Groups.size())
1519 {
1520 Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed
1521 }
1522
1523 if (!Groups[item->groupid - 1])
1524 {
1525 Groups[item->groupid - 1] = new LootGroup();
1526 }
1527
1528 Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group
1529 }
1530 else // Non-grouped entries
1531 Entries.push_back(item);
1532}
uint8 groupid
Definition LootMgr.h:134

References LootStoreItem::groupid.

◆ CheckLootRefs()

void LootTemplate::CheckLootRefs ( LootStore const &  lootstore,
uint32  Id,
LootIdSet ref_set 
) const
1800{
1801 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1802 {
1803 LootStoreItem* item = *ieItr;
1804 if (item->reference)
1805 {
1806 if (item->mincount != item->maxcount)
1807 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1808
1809 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1810 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1811 else if (ref_set)
1812 ref_set->erase(std::abs(item->reference));
1813 }
1814 }
1815
1816 for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
1817 if (LootGroup* group = *grItr)
1818 group->CheckLootRefs(lootstore, Id, ref_set);
1819}
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().

◆ CopyConditions() [1/2]

void LootTemplate::CopyConditions ( ConditionList  conditions)
1535{
1536 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1537 (*i)->conditions.clear();
1538
1539 for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
1540 if (LootGroup* group = *i)
1541 group->CopyConditions(conditions);
1542}

◆ CopyConditions() [2/2]

bool LootTemplate::CopyConditions ( LootItem li,
uint32  conditionLootId = 0 
) const
1545{
1546 for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter)
1547 {
1548 LootStoreItem* item = *_iter;
1549 if (item->reference)
1550 {
1551 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1552 {
1553 if (Referenced->CopyConditions(li, conditionLootId))
1554 {
1555 return true;
1556 }
1557 }
1558 }
1559 else
1560 {
1561 if (item->itemid != li->itemid)
1562 {
1563 continue;
1564 }
1565
1566 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1567 {
1568 continue;
1569 }
1570
1571 li->conditions = item->conditions;
1572 return true;
1573 }
1574 }
1575
1576 for (LootGroups::const_iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1577 {
1578 LootGroup* group = *groupItr;
1579 if (!group)
1580 continue;
1581
1582 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1583 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1584 {
1585 LootStoreItem* item = *i;
1586 if (item->reference)
1587 {
1588 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1589 {
1590 if (Referenced->CopyConditions(li, conditionLootId))
1591 {
1592 return true;
1593 }
1594 }
1595 }
1596 else
1597 {
1598 if (item->itemid != li->itemid)
1599 {
1600 continue;
1601 }
1602
1603 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1604 {
1605 continue;
1606 }
1607
1608 li->conditions = item->conditions;
1609 return true;
1610 }
1611 }
1612
1613 itemList = group->GetEqualChancedItemList();
1614 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1615 {
1616 LootStoreItem* item = *i;
1617 if (item->reference)
1618 {
1619 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1620 {
1621 if (Referenced->CopyConditions(li, conditionLootId))
1622 {
1623 return true;
1624 }
1625 }
1626 }
1627 else
1628 {
1629 if (item->itemid != li->itemid)
1630 {
1631 continue;
1632 }
1633
1634 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1635 {
1636 continue;
1637 }
1638
1639 li->conditions = item->conditions;
1640 return true;
1641 }
1642 }
1643 }
1644
1645 return false;
1646}
Definition LootMgr.h:245
uint32 itemid
Definition LootMgr.h:155
ConditionList conditions
Definition LootMgr.h:159
ConditionList conditions
Definition LootMgr.h:137

References LootStoreItem::conditions, LootItem::conditions, LootTemplate::LootGroup::GetEqualChancedItemList(), LootTemplate::LootGroup::GetExplicitlyChancedItemList(), LootStore::GetLootFor(), LootStoreItem::itemid, LootItem::itemid, LootTemplates_Reference, and LootStoreItem::reference.

◆ HasQuestDrop()

bool LootTemplate::HasQuestDrop ( LootTemplateMap const &  store) const
1722{
1723 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1724 {
1725 LootStoreItem* item = *i;
1726 if (item->reference) // References
1727 {
1728 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1729 if (Referenced == store.end())
1730 continue; // Error message [should be] already printed at loading stage
1731
1732 if (Referenced->second->HasQuestDrop(store))
1733 return true;
1734 }
1735 else if (item->needs_quest)
1736 return true; // quest drop found
1737 }
1738
1739 // Now processing groups
1740 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1741 {
1742 if (LootGroup* group = *i)
1743 {
1744 if (group->HasQuestDrop(store))
1745 {
1746 return true;
1747 }
1748 }
1749 }
1750
1751 return false;
1752}
bool needs_quest
Definition LootMgr.h:132

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

◆ HasQuestDropForPlayer()

bool LootTemplate::HasQuestDropForPlayer ( LootTemplateMap const &  store,
Player const *  player 
) const
1756{
1757 // Checking non-grouped entries
1758 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1759 {
1760 LootStoreItem* item = *i;
1761 if (item->reference) // References processing
1762 {
1763 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1764 if (Referenced == store.end())
1765 continue; // Error message already printed at loading stage
1766 if (Referenced->second->HasQuestDropForPlayer(store, player))
1767 return true;
1768 }
1769 else if (player->HasQuestForItem(item->itemid))
1770 return true; // active quest drop found
1771 }
1772
1773 // Now checking groups
1774 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1775 {
1776 if (LootGroup* group = *i)
1777 {
1778 if (group->HasQuestDropForPlayer(player, store))
1779 {
1780 return true;
1781 }
1782 }
1783 }
1784
1785 return false;
1786}

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

◆ isReference()

bool LootTemplate::isReference ( uint32  id) const
1880{
1881 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1882 {
1883 if ((*ieItr)->itemid == id && (*ieItr)->reference)
1884 {
1885 return true;
1886 }
1887 }
1888
1889 return false;//not found or not reference
1890}

Referenced by ConditionMgr::isSourceTypeValid().

◆ operator=()

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

◆ Process()

void LootTemplate::Process ( Loot loot,
LootStore const &  store,
uint16  lootMode,
Player const *  player,
uint8  groupId = 0,
bool  isTopLevel = true 
) const
1650{
1651 bool rate = store.IsRatesAllowed();
1652
1653 if (groupId) // Group reference uses own processing of the group
1654 {
1655 if (groupId > Groups.size())
1656 return; // Error message already printed at loading stage
1657
1658 if (!Groups[groupId - 1])
1659 return;
1660
1661 // Rate.Drop.Item.GroupAmount is only in effect for the top loot template level
1662 if (isTopLevel)
1663 {
1664 Groups[groupId - 1]->Process(loot, player, store, lootMode, sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT));
1665 }
1666 else
1667 {
1668 Groups[groupId - 1]->Process(loot, player, store, lootMode, 0);
1669 }
1670 return;
1671 }
1672
1673 // Rolling non-grouped items
1674 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1675 {
1676 LootStoreItem* item = *i;
1677 if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
1678 continue;
1679 if (!item->Roll(rate, player, loot, store))
1680 continue; // Bad luck for the entry
1681
1682 if (item->reference) // References processing
1683 {
1684 LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference));
1685 if (!Referenced)
1686 continue; // Error message already printed at loading stage
1687
1688 uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
1689 sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, item, maxcount, store);
1690 for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
1691 // we're no longer in the top level, so isTopLevel is false
1692 Referenced->Process(loot, store, lootMode, player, item->groupid, false);
1693 }
1694 else
1695 {
1696 // Plain entries (not a reference, not grouped)
1697 sScriptMgr->OnBeforeDropAddItem(player, loot, rate, lootMode, item, store);
1698 loot.AddItem(*item); // Chance is already checked, just add
1699 }
1700 }
1701
1702 // Now processing groups
1703 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1704 if (LootGroup* group = *i)
1705 {
1706 // Rate.Drop.Item.GroupAmount is only in effect for the top loot template level
1707 if (isTopLevel)
1708 {
1709 uint32 groupAmount = sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT);
1710 sScriptMgr->OnAfterCalculateLootGroupAmount(player, loot, lootMode, groupAmount, store);
1711 group->Process(loot, player, store, lootMode, groupAmount);
1712 }
1713 else
1714 {
1715 group->Process(loot, player, store, lootMode, 0);
1716 }
1717 }
1718}
#define sScriptMgr
Definition ScriptMgr.h:734
@ RATE_DROP_ITEM_REFERENCED_AMOUNT
Definition WorldConfig.h:410
@ RATE_DROP_ITEM_GROUP_AMOUNT
Definition WorldConfig.h:411
void Process(Loot &loot, LootStore const &store, uint16 lootMode, Player const *player, uint8 groupId=0, bool isTopLevel=true) const
Definition LootMgr.cpp:1649
#define sWorld
Definition World.h:316
bool Roll(bool rate, Player const *player, Loot &loot, LootStore const &store) const
Definition LootMgr.cpp:311
uint16 lootmode
Definition LootMgr.h:133
void AddItem(LootStoreItem const &item)
Definition LootMgr.cpp:463

References Loot::AddItem(), LootStore::GetLootFor(), LootStoreItem::groupid, LootStore::IsRatesAllowed(), LootStoreItem::lootmode, LootTemplates_Reference, LootStoreItem::maxcount, Process(), RATE_DROP_ITEM_GROUP_AMOUNT, RATE_DROP_ITEM_REFERENCED_AMOUNT, LootStoreItem::reference, LootStoreItem::Roll(), sScriptMgr, and sWorld.

Referenced by Loot::FillLoot(), debug_commandscript::GenerateLoot(), Process(), and LootTemplate::LootGroup::Process().

◆ Verify()

void LootTemplate::Verify ( LootStore const &  store,
uint32  Id 
) const
Todo:
: References validity checks
1790{
1791 // Checking group chances
1792 for (uint32 i = 0; i < Groups.size(); ++i)
1793 if (Groups[i])
1794 Groups[i]->Verify(lootstore, id, i + 1);
1795
1797}

Member Data Documentation

◆ Entries

LootStoreItemList LootTemplate::Entries
private

◆ Groups

LootGroups LootTemplate::Groups
private

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