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, 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 (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 ( )
1548{
1549 while (!Entries.empty())
1550 {
1551 delete Entries.back();
1552 Entries.pop_back();
1553 }
1554
1555 for (std::size_t i = 0; i < Groups.size(); ++i)
1556 delete Groups[i];
1557 Groups.clear();
1558}
Entries
Definition: zone_howling_fjord.cpp:177
Groups
Definition: boss_moroes.cpp:55

◆ LootTemplate() [2/2]

LootTemplate::LootTemplate ( LootTemplate const &  )
private

Member Function Documentation

◆ addConditionItem()

bool LootTemplate::addConditionItem ( Condition cond)
1893{
1894 if (!cond || !cond->isLoaded())//should never happen, checked at loading
1895 {
1896 LOG_ERROR("condition", "LootTemplate::addConditionItem: condition is null");
1897 return false;
1898 }
1899
1900 if (!Entries.empty())
1901 {
1902 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1903 {
1904 if ((*i)->itemid == uint32(cond->SourceEntry))
1905 {
1906 (*i)->conditions.push_back(cond);
1907 return true;
1908 }
1909 }
1910 }
1911
1912 if (!Groups.empty())
1913 {
1914 for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1915 {
1916 LootGroup* group = *groupItr;
1917 if (!group)
1918 continue;
1919
1920 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1921 if (!itemList->empty())
1922 {
1923 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1924 {
1925 if ((*i)->itemid == uint32(cond->SourceEntry))
1926 {
1927 (*i)->conditions.push_back(cond);
1928 return true;
1929 }
1930 }
1931 }
1932
1933 itemList = group->GetEqualChancedItemList();
1934 if (!itemList->empty())
1935 {
1936 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1937 {
1938 if ((*i)->itemid == uint32(cond->SourceEntry))
1939 {
1940 (*i)->conditions.push_back(cond);
1941 return true;
1942 }
1943 }
1944 }
1945 }
1946 }
1947 return false;
1948}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
std::uint32_t uint32
Definition: Define.h:107
std::list< LootStoreItem * > LootStoreItemList
Definition: LootMgr.h:201
bool isLoaded() const
Definition: ConditionMgr.h:233
int32 SourceEntry
Definition: ConditionMgr.h:198

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

Referenced by ConditionMgr::addToLootTemplate().

◆ AddEntry()

void LootTemplate::AddEntry ( LootStoreItem item)
1562{
1563 // `item->reference` > 0 --> Reference is counted as a normal and non grouped entry
1564 // `item->reference` < 0 --> Reference is counted as grouped entry within shared groupid
1565 if (item->groupid > 0 && item->reference <= 0) // Group and grouped reference
1566 {
1567 if (item->groupid >= Groups.size())
1568 {
1569 Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed
1570 }
1571
1572 if (!Groups[item->groupid - 1])
1573 {
1574 Groups[item->groupid - 1] = new LootGroup();
1575 }
1576
1577 Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group
1578 }
1579 else // Non-grouped entries
1580 Entries.push_back(item);
1581}
int32 reference
Definition: LootMgr.h:130
uint8 groupid
Definition: LootMgr.h:134

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

◆ CheckLootRefs()

void LootTemplate::CheckLootRefs ( LootStore const &  lootstore,
uint32  Id,
LootIdSet ref_set 
) const
1871{
1872 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1873 {
1874 LootStoreItem* item = *ieItr;
1875 if (item->reference)
1876 {
1877 if (item->mincount != item->maxcount)
1878 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1879
1880 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1881 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1882 else if (ref_set)
1883 ref_set->erase(std::abs(item->reference));
1884 }
1885 }
1886
1887 for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
1888 if (LootGroup* group = *grItr)
1889 group->CheckLootRefs(lootstore, Id, ref_set);
1890}
LootStore LootTemplates_Reference
Definition: LootMgr.h:128
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().

◆ CopyConditions() [1/2]

void LootTemplate::CopyConditions ( ConditionList  conditions)
1584{
1585 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1586 (*i)->conditions.clear();
1587
1588 for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
1589 if (LootGroup* group = *i)
1590 group->CopyConditions(conditions);
1591}

◆ CopyConditions() [2/2]

bool LootTemplate::CopyConditions ( LootItem li,
uint32  conditionLootId = 0 
) const
1594{
1595 for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter)
1596 {
1597 LootStoreItem* item = *_iter;
1598 if (item->reference)
1599 {
1600 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1601 {
1602 if (Referenced->CopyConditions(li, conditionLootId))
1603 {
1604 return true;
1605 }
1606 }
1607 }
1608 else
1609 {
1610 if (item->itemid != li->itemid)
1611 {
1612 continue;
1613 }
1614
1615 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1616 {
1617 continue;
1618 }
1619
1620 li->conditions = item->conditions;
1621 return true;
1622 }
1623 }
1624
1625 for (LootGroups::const_iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1626 {
1627 LootGroup* group = *groupItr;
1628 if (!group)
1629 continue;
1630
1631 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1632 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1633 {
1634 LootStoreItem* item = *i;
1635 if (item->reference)
1636 {
1637 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1638 {
1639 if (Referenced->CopyConditions(li, conditionLootId))
1640 {
1641 return true;
1642 }
1643 }
1644 }
1645 else
1646 {
1647 if (item->itemid != li->itemid)
1648 {
1649 continue;
1650 }
1651
1652 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1653 {
1654 continue;
1655 }
1656
1657 li->conditions = item->conditions;
1658 return true;
1659 }
1660 }
1661
1662 itemList = group->GetEqualChancedItemList();
1663 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1664 {
1665 LootStoreItem* item = *i;
1666 if (item->reference)
1667 {
1668 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1669 {
1670 if (Referenced->CopyConditions(li, conditionLootId))
1671 {
1672 return true;
1673 }
1674 }
1675 }
1676 else
1677 {
1678 if (item->itemid != li->itemid)
1679 {
1680 continue;
1681 }
1682
1683 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1684 {
1685 continue;
1686 }
1687
1688 li->conditions = item->conditions;
1689 return true;
1690 }
1691 }
1692 }
1693
1694 return false;
1695}
ConditionList conditions
Definition: LootMgr.h:137
uint32 itemid
Definition: LootMgr.h:155
ConditionList conditions
Definition: LootMgr.h:159
Definition: LootMgr.h:245

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,
uint8  groupId = 0 
) const
1771{
1772 if (groupId) // Group reference
1773 {
1774 if (groupId > Groups.size())
1775 return false; // Error message [should be] already printed at loading stage
1776
1777 if (!Groups[groupId - 1])
1778 return false;
1779
1780 return Groups[groupId - 1]->HasQuestDrop(store);
1781 }
1782
1783 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1784 {
1785 LootStoreItem* item = *i;
1786 if (item->reference) // References
1787 {
1788 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1789 if (Referenced == store.end())
1790 continue; // Error message [should be] already printed at loading stage
1791
1792 if (Referenced->second->HasQuestDrop(store, item->groupid))
1793 return true;
1794 }
1795 else if (item->needs_quest)
1796 return true; // quest drop found
1797 }
1798
1799 // Now processing groups
1800 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1801 {
1802 if (LootGroup* group = *i)
1803 {
1804 if (group->HasQuestDrop(store))
1805 {
1806 return true;
1807 }
1808 }
1809 }
1810
1811 return false;
1812}
bool needs_quest
Definition: LootMgr.h:132

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

◆ HasQuestDropForPlayer()

bool LootTemplate::HasQuestDropForPlayer ( LootTemplateMap const &  store,
Player const *  player,
uint8  groupId = 0 
) const
1816{
1817 if (groupId) // Group reference
1818 {
1819 if (groupId > Groups.size())
1820 return false; // Error message already printed at loading stage
1821
1822 if (!Groups[groupId - 1])
1823 return false;
1824
1825 return Groups[groupId - 1]->HasQuestDropForPlayer(player, store);
1826 }
1827
1828 // Checking non-grouped entries
1829 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1830 {
1831 LootStoreItem* item = *i;
1832 if (item->reference) // References processing
1833 {
1834 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1835 if (Referenced == store.end())
1836 continue; // Error message already printed at loading stage
1837 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
1838 return true;
1839 }
1840 else if (player->HasQuestForItem(item->itemid))
1841 return true; // active quest drop found
1842 }
1843
1844 // Now checking groups
1845 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1846 {
1847 if (LootGroup* group = *i)
1848 {
1849 if (group->HasQuestDropForPlayer(player, store))
1850 {
1851 return true;
1852 }
1853 }
1854 }
1855
1856 return false;
1857}

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

◆ isReference()

bool LootTemplate::isReference ( uint32  id) const
1951{
1952 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1953 {
1954 if ((*ieItr)->itemid == id && (*ieItr)->reference)
1955 {
1956 return true;
1957 }
1958 }
1959
1960 return false;//not found or not reference
1961}

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
1699{
1700 bool rate = store.IsRatesAllowed();
1701
1702 if (groupId) // Group reference uses own processing of the group
1703 {
1704 if (groupId > Groups.size())
1705 return; // Error message already printed at loading stage
1706
1707 if (!Groups[groupId - 1])
1708 return;
1709
1710 // Rate.Drop.Item.GroupAmount is only in effect for the top loot template level
1711 if (isTopLevel)
1712 {
1713 Groups[groupId - 1]->Process(loot, player, store, lootMode, sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT));
1714 }
1715 else
1716 {
1717 Groups[groupId - 1]->Process(loot, player, store, lootMode, 0);
1718 }
1719 return;
1720 }
1721
1722 // Rolling non-grouped items
1723 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1724 {
1725 LootStoreItem* item = *i;
1726 if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
1727 continue;
1728 if (!item->Roll(rate, player, loot, store))
1729 continue; // Bad luck for the entry
1730
1731 if (item->reference) // References processing
1732 {
1733 LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference));
1734 if (!Referenced)
1735 continue; // Error message already printed at loading stage
1736
1737 uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
1738 sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, item, maxcount, store);
1739 for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
1740 // we're no longer in the top level, so isTopLevel is false
1741 Referenced->Process(loot, store, lootMode, player, item->groupid, false);
1742 }
1743 else
1744 {
1745 // Plain entries (not a reference, not grouped)
1746 sScriptMgr->OnBeforeDropAddItem(player, loot, rate, lootMode, item, store);
1747 loot.AddItem(*item); // Chance is already checked, just add
1748 }
1749 }
1750
1751 // Now processing groups
1752 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1753 if (LootGroup* group = *i)
1754 {
1755 // Rate.Drop.Item.GroupAmount is only in effect for the top loot template level
1756 if (isTopLevel)
1757 {
1758 uint32 groupAmount = sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT);
1759 sScriptMgr->OnAfterCalculateLootGroupAmount(player, loot, lootMode, groupAmount, store);
1760 group->Process(loot, player, store, lootMode, groupAmount);
1761 }
1762 else
1763 {
1764 group->Process(loot, player, store, lootMode, 0);
1765 }
1766 }
1767}
@ RATE_DROP_ITEM_REFERENCED_AMOUNT
Definition: IWorld.h:447
@ RATE_DROP_ITEM_GROUP_AMOUNT
Definition: IWorld.h:448
#define sScriptMgr
Definition: ScriptMgr.h:709
#define sWorld
Definition: World.h:443
bool Roll(bool rate, Player const *player, Loot &loot, LootStore const &store) const
Definition: LootMgr.cpp:311
uint16 lootmode
Definition: LootMgr.h:133
void Process(Loot &loot, LootStore const &store, uint16 lootMode, Player const *player, uint8 groupId=0, bool isTopLevel=true) const
Definition: LootMgr.cpp:1698
void AddItem(LootStoreItem const &item)
Definition: LootMgr.cpp:511

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(), Process(), and LootTemplate::LootGroup::Process().

◆ Verify()

void LootTemplate::Verify ( LootStore const &  store,
uint32  Id 
) const
Todo:
: References validity checks
1861{
1862 // Checking group chances
1863 for (uint32 i = 0; i < Groups.size(); ++i)
1864 if (Groups[i])
1865 Groups[i]->Verify(lootstore, id, i + 1);
1866
1868}

Member Data Documentation

◆ Entries

LootStoreItemList LootTemplate::Entries
private

◆ Groups

LootGroups LootTemplate::Groups
private