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) const
 
void CopyConditions (ConditionList conditions)
 
bool CopyConditions (LootItem *li, uint32 conditionLootId=0) const
 
bool HasQuestDrop (LootTemplateMap const &store, uint8 groupId=0) const
 
bool HasQuestDropForPlayer (LootTemplateMap const &store, Player const *player, uint8 groupId=0) const
 
void Verify (LootStore const &store, uint32 Id) const
 
void CheckLootRefs (LootTemplateMap const &store, 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 ( )
1518{
1519 while (!Entries.empty())
1520 {
1521 delete Entries.back();
1522 Entries.pop_back();
1523 }
1524
1525 for (size_t i = 0; i < Groups.size(); ++i)
1526 delete Groups[i];
1527 Groups.clear();
1528}
Entries
Definition: zone_howling_fjord.cpp:177
LootGroups Groups
Definition: LootMgr.h:273

References Groups.

◆ LootTemplate() [2/2]

LootTemplate::LootTemplate ( LootTemplate const &  )
private

Member Function Documentation

◆ addConditionItem()

bool LootTemplate::addConditionItem ( Condition cond)
1844{
1845 if (!cond || !cond->isLoaded())//should never happen, checked at loading
1846 {
1847 LOG_ERROR("condition", "LootTemplate::addConditionItem: condition is null");
1848 return false;
1849 }
1850
1851 if (!Entries.empty())
1852 {
1853 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1854 {
1855 if ((*i)->itemid == uint32(cond->SourceEntry))
1856 {
1857 (*i)->conditions.push_back(cond);
1858 return true;
1859 }
1860 }
1861 }
1862
1863 if (!Groups.empty())
1864 {
1865 for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1866 {
1867 LootGroup* group = *groupItr;
1868 if (!group)
1869 continue;
1870
1871 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1872 if (!itemList->empty())
1873 {
1874 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1875 {
1876 if ((*i)->itemid == uint32(cond->SourceEntry))
1877 {
1878 (*i)->conditions.push_back(cond);
1879 return true;
1880 }
1881 }
1882 }
1883
1884 itemList = group->GetEqualChancedItemList();
1885 if (!itemList->empty())
1886 {
1887 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1888 {
1889 if ((*i)->itemid == uint32(cond->SourceEntry))
1890 {
1891 (*i)->conditions.push_back(cond);
1892 return true;
1893 }
1894 }
1895 }
1896 }
1897 }
1898 return false;
1899}
std::uint32_t uint32
Definition: Define.h:108
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
std::list< LootStoreItem * > LootStoreItemList
Definition: LootMgr.h:202
bool isLoaded() const
Definition: ConditionMgr.h:232
int32 SourceEntry
Definition: ConditionMgr.h:197

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

Referenced by ConditionMgr::addToLootTemplate().

◆ AddEntry()

void LootTemplate::AddEntry ( LootStoreItem item)
1532{
1533 // `item->reference` > 0 --> Reference is counted as a normal and non grouped entry
1534 // `item->reference` < 0 --> Reference is counted as grouped entry within shared groupid
1535 if (item->groupid > 0 && item->reference <= 0) // Group and grouped reference
1536 {
1537 if (item->groupid >= Groups.size())
1538 {
1539 Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed
1540 }
1541
1542 if (!Groups[item->groupid - 1])
1543 {
1544 Groups[item->groupid - 1] = new LootGroup();
1545 }
1546
1547 Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group
1548 }
1549 else // Non-grouped entries
1550 Entries.push_back(item);
1551}
int32 reference
Definition: LootMgr.h:131
uint8 groupid
Definition: LootMgr.h:135

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

◆ CheckLootRefs()

void LootTemplate::CheckLootRefs ( LootTemplateMap const &  store,
LootIdSet ref_set 
) const
1821{
1822 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1823 {
1824 LootStoreItem* item = *ieItr;
1825 if (item->reference)
1826 {
1827 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1828 {
1829 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), "Reference", item->itemid);
1830 }
1831 else if (ref_set)
1832 {
1833 ref_set->erase(std::abs(item->reference));
1834 }
1835 }
1836 }
1837
1838 for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
1839 if (LootGroup* group = *grItr)
1840 group->CheckLootRefs(store, ref_set);
1841}
LootStore LootTemplates_Reference
Definition: LootMgr.h:129
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(), Groups, LootStoreItem::itemid, LootTemplates_Reference, LootStoreItem::reference, and LootStore::ReportNonExistingId().

◆ CopyConditions() [1/2]

void LootTemplate::CopyConditions ( ConditionList  conditions)
1554{
1555 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1556 (*i)->conditions.clear();
1557
1558 for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
1559 if (LootGroup* group = *i)
1560 group->CopyConditions(conditions);
1561}

References Groups.

◆ CopyConditions() [2/2]

bool LootTemplate::CopyConditions ( LootItem li,
uint32  conditionLootId = 0 
) const
1564{
1565 for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter)
1566 {
1567 LootStoreItem* item = *_iter;
1568 if (item->reference)
1569 {
1570 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1571 {
1572 if (Referenced->CopyConditions(li, conditionLootId))
1573 {
1574 return true;
1575 }
1576 }
1577 }
1578 else
1579 {
1580 if (item->itemid != li->itemid)
1581 {
1582 continue;
1583 }
1584
1585 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1586 {
1587 continue;
1588 }
1589
1590 li->conditions = item->conditions;
1591 return true;
1592 }
1593 }
1594
1595 for (LootGroups::const_iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1596 {
1597 LootGroup* group = *groupItr;
1598 if (!group)
1599 continue;
1600
1601 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1602 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1603 {
1604 LootStoreItem* item = *i;
1605 if (item->reference)
1606 {
1607 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1608 {
1609 if (Referenced->CopyConditions(li, conditionLootId))
1610 {
1611 return true;
1612 }
1613 }
1614 }
1615 else
1616 {
1617 if (item->itemid != li->itemid)
1618 {
1619 continue;
1620 }
1621
1622 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1623 {
1624 continue;
1625 }
1626
1627 li->conditions = item->conditions;
1628 return true;
1629 }
1630 }
1631
1632 itemList = group->GetEqualChancedItemList();
1633 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1634 {
1635 LootStoreItem* item = *i;
1636 if (item->reference)
1637 {
1638 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1639 {
1640 if (Referenced->CopyConditions(li, conditionLootId))
1641 {
1642 return true;
1643 }
1644 }
1645 }
1646 else
1647 {
1648 if (item->itemid != li->itemid)
1649 {
1650 continue;
1651 }
1652
1653 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1654 {
1655 continue;
1656 }
1657
1658 li->conditions = item->conditions;
1659 return true;
1660 }
1661 }
1662 }
1663
1664 return false;
1665}
ConditionList conditions
Definition: LootMgr.h:138
uint32 itemid
Definition: LootMgr.h:156
ConditionList conditions
Definition: LootMgr.h:160
Definition: LootMgr.h:245

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

◆ HasQuestDrop()

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

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

◆ HasQuestDropForPlayer()

bool LootTemplate::HasQuestDropForPlayer ( LootTemplateMap const &  store,
Player const *  player,
uint8  groupId = 0 
) const
1766{
1767 if (groupId) // Group reference
1768 {
1769 if (groupId > Groups.size())
1770 return false; // Error message already printed at loading stage
1771
1772 if (!Groups[groupId - 1])
1773 return false;
1774
1775 return Groups[groupId - 1]->HasQuestDropForPlayer(player, store);
1776 }
1777
1778 // Checking non-grouped entries
1779 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1780 {
1781 LootStoreItem* item = *i;
1782 if (item->reference) // References processing
1783 {
1784 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1785 if (Referenced == store.end())
1786 continue; // Error message already printed at loading stage
1787 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
1788 return true;
1789 }
1790 else if (player->HasQuestForItem(item->itemid))
1791 return true; // active quest drop found
1792 }
1793
1794 // Now checking groups
1795 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1796 {
1797 if (LootGroup* group = *i)
1798 {
1799 if (group->HasQuestDropForPlayer(player, store))
1800 {
1801 return true;
1802 }
1803 }
1804 }
1805
1806 return false;
1807}

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

◆ isReference()

bool LootTemplate::isReference ( uint32  id) const
1902{
1903 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1904 {
1905 if ((*ieItr)->itemid == id && (*ieItr)->reference)
1906 {
1907 return true;
1908 }
1909 }
1910
1911 return false;//not found or not reference
1912}

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 
) const
1669{
1670 bool rate = store.IsRatesAllowed();
1671
1672 if (groupId) // Group reference uses own processing of the group
1673 {
1674 if (groupId > Groups.size())
1675 return; // Error message already printed at loading stage
1676
1677 if (!Groups[groupId - 1])
1678 return;
1679
1680 Groups[groupId - 1]->Process(loot, player, store, lootMode);
1681 return;
1682 }
1683
1684 // Rolling non-grouped items
1685 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1686 {
1687 LootStoreItem* item = *i;
1688 if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
1689 continue;
1690
1691 if (!item->Roll(rate, player, loot, store))
1692 continue; // Bad luck for the entry
1693
1694 if (item->reference) // References processing
1695 {
1696 LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference));
1697 if (!Referenced)
1698 continue; // Error message already printed at loading stage
1699
1700 uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
1701 sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, item, maxcount, store);
1702 for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
1703 Referenced->Process(loot, store, lootMode, player, item->groupid);
1704 }
1705 else
1706 {
1707 // Plain entries (not a reference, not grouped)
1708 sScriptMgr->OnBeforeDropAddItem(player, loot, rate, lootMode, item, store);
1709 loot.AddItem(*item); // Chance is already checked, just add
1710 }
1711 }
1712
1713 // Now processing groups
1714 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1715 if (LootGroup* group = *i)
1716 group->Process(loot, player, store, lootMode);
1717}
#define sScriptMgr
Definition: ScriptMgr.h:2702
@ RATE_DROP_ITEM_REFERENCED_AMOUNT
Definition: IWorld.h:439
#define sWorld
Definition: World.h:451
bool Roll(bool rate, Player const *player, Loot &loot, LootStore const &store) const
Definition: LootMgr.cpp:305
uint8 maxcount
Definition: LootMgr.h:137
uint16 lootmode
Definition: LootMgr.h:134
void Process(Loot &loot, LootStore const &store, uint16 lootMode, Player const *player, uint8 groupId=0) const
Definition: LootMgr.cpp:1668
void AddItem(LootStoreItem const &item)
Definition: LootMgr.cpp:494

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

Referenced by Loot::FillLoot(), and Process().

◆ Verify()

void LootTemplate::Verify ( LootStore const &  store,
uint32  Id 
) const
Todo:
: References validity checks
1811{
1812 // Checking group chances
1813 for (uint32 i = 0; i < Groups.size(); ++i)
1814 if (Groups[i])
1815 Groups[i]->Verify(lootstore, id, i + 1);
1816
1818}

References Groups.

Member Data Documentation

◆ Entries

LootStoreItemList LootTemplate::Entries
private

◆ Groups