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

◆ LootTemplate() [2/2]

LootTemplate::LootTemplate ( LootTemplate const &  )
private

Member Function Documentation

◆ addConditionItem()

bool LootTemplate::addConditionItem ( Condition cond)
1894{
1895 if (!cond || !cond->isLoaded())//should never happen, checked at loading
1896 {
1897 LOG_ERROR("condition", "LootTemplate::addConditionItem: condition is null");
1898 return false;
1899 }
1900
1901 if (!Entries.empty())
1902 {
1903 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1904 {
1905 if ((*i)->itemid == uint32(cond->SourceEntry))
1906 {
1907 (*i)->conditions.push_back(cond);
1908 return true;
1909 }
1910 }
1911 }
1912
1913 if (!Groups.empty())
1914 {
1915 for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1916 {
1917 LootGroup* group = *groupItr;
1918 if (!group)
1919 continue;
1920
1921 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1922 if (!itemList->empty())
1923 {
1924 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1925 {
1926 if ((*i)->itemid == uint32(cond->SourceEntry))
1927 {
1928 (*i)->conditions.push_back(cond);
1929 return true;
1930 }
1931 }
1932 }
1933
1934 itemList = group->GetEqualChancedItemList();
1935 if (!itemList->empty())
1936 {
1937 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1938 {
1939 if ((*i)->itemid == uint32(cond->SourceEntry))
1940 {
1941 (*i)->conditions.push_back(cond);
1942 return true;
1943 }
1944 }
1945 }
1946 }
1947 }
1948 return false;
1949}
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: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)
1563{
1564 // `item->reference` > 0 --> Reference is counted as a normal and non grouped entry
1565 // `item->reference` < 0 --> Reference is counted as grouped entry within shared groupid
1566 if (item->groupid > 0 && item->reference <= 0) // Group and grouped reference
1567 {
1568 if (item->groupid >= Groups.size())
1569 {
1570 Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed
1571 }
1572
1573 if (!Groups[item->groupid - 1])
1574 {
1575 Groups[item->groupid - 1] = new LootGroup();
1576 }
1577
1578 Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group
1579 }
1580 else // Non-grouped entries
1581 Entries.push_back(item);
1582}
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
1872{
1873 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1874 {
1875 LootStoreItem* item = *ieItr;
1876 if (item->reference)
1877 {
1878 if (item->mincount != item->maxcount)
1879 LootTemplates_Reference.ReportInvalidCount(std::abs(item->reference), lootstore.GetName(), Id, item->itemid, item->mincount, item->maxcount);
1880
1881 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1882 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), lootstore.GetName(), item->itemid);
1883 else if (ref_set)
1884 ref_set->erase(std::abs(item->reference));
1885 }
1886 }
1887
1888 for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
1889 if (LootGroup* group = *grItr)
1890 group->CheckLootRefs(lootstore, Id, ref_set);
1891}
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
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)
1585{
1586 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1587 (*i)->conditions.clear();
1588
1589 for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
1590 if (LootGroup* group = *i)
1591 group->CopyConditions(conditions);
1592}

◆ CopyConditions() [2/2]

bool LootTemplate::CopyConditions ( LootItem li,
uint32  conditionLootId = 0 
) const
1595{
1596 for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter)
1597 {
1598 LootStoreItem* item = *_iter;
1599 if (item->reference)
1600 {
1601 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1602 {
1603 if (Referenced->CopyConditions(li, conditionLootId))
1604 {
1605 return true;
1606 }
1607 }
1608 }
1609 else
1610 {
1611 if (item->itemid != li->itemid)
1612 {
1613 continue;
1614 }
1615
1616 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1617 {
1618 continue;
1619 }
1620
1621 li->conditions = item->conditions;
1622 return true;
1623 }
1624 }
1625
1626 for (LootGroups::const_iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1627 {
1628 LootGroup* group = *groupItr;
1629 if (!group)
1630 continue;
1631
1632 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
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 itemList = group->GetEqualChancedItemList();
1664 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1665 {
1666 LootStoreItem* item = *i;
1667 if (item->reference)
1668 {
1669 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1670 {
1671 if (Referenced->CopyConditions(li, conditionLootId))
1672 {
1673 return true;
1674 }
1675 }
1676 }
1677 else
1678 {
1679 if (item->itemid != li->itemid)
1680 {
1681 continue;
1682 }
1683
1684 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1685 {
1686 continue;
1687 }
1688
1689 li->conditions = item->conditions;
1690 return true;
1691 }
1692 }
1693 }
1694
1695 return false;
1696}
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,
uint8  groupId = 0 
) const
1772{
1773 if (groupId) // Group reference
1774 {
1775 if (groupId > Groups.size())
1776 return false; // Error message [should be] already printed at loading stage
1777
1778 if (!Groups[groupId - 1])
1779 return false;
1780
1781 return Groups[groupId - 1]->HasQuestDrop(store);
1782 }
1783
1784 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1785 {
1786 LootStoreItem* item = *i;
1787 if (item->reference) // References
1788 {
1789 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1790 if (Referenced == store.end())
1791 continue; // Error message [should be] already printed at loading stage
1792
1793 if (Referenced->second->HasQuestDrop(store, item->groupid))
1794 return true;
1795 }
1796 else if (item->needs_quest)
1797 return true; // quest drop found
1798 }
1799
1800 // Now processing groups
1801 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1802 {
1803 if (LootGroup* group = *i)
1804 {
1805 if (group->HasQuestDrop(store))
1806 {
1807 return true;
1808 }
1809 }
1810 }
1811
1812 return false;
1813}
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
1817{
1818 if (groupId) // Group reference
1819 {
1820 if (groupId > Groups.size())
1821 return false; // Error message already printed at loading stage
1822
1823 if (!Groups[groupId - 1])
1824 return false;
1825
1826 return Groups[groupId - 1]->HasQuestDropForPlayer(player, store);
1827 }
1828
1829 // Checking non-grouped entries
1830 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1831 {
1832 LootStoreItem* item = *i;
1833 if (item->reference) // References processing
1834 {
1835 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1836 if (Referenced == store.end())
1837 continue; // Error message already printed at loading stage
1838 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
1839 return true;
1840 }
1841 else if (player->HasQuestForItem(item->itemid))
1842 return true; // active quest drop found
1843 }
1844
1845 // Now checking groups
1846 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1847 {
1848 if (LootGroup* group = *i)
1849 {
1850 if (group->HasQuestDropForPlayer(player, store))
1851 {
1852 return true;
1853 }
1854 }
1855 }
1856
1857 return false;
1858}

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

◆ isReference()

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

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

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
1862{
1863 // Checking group chances
1864 for (uint32 i = 0; i < Groups.size(); ++i)
1865 if (Groups[i])
1866 Groups[i]->Verify(lootstore, id, i + 1);
1867
1869}

Member Data Documentation

◆ Entries

LootStoreItemList LootTemplate::Entries
private

◆ Groups

LootGroups LootTemplate::Groups
private

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