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 (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 ( )
1542{
1543 while (!Entries.empty())
1544 {
1545 delete Entries.back();
1546 Entries.pop_back();
1547 }
1548
1549 for (std::size_t i = 0; i < Groups.size(); ++i)
1550 delete Groups[i];
1551 Groups.clear();
1552}
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)
1888{
1889 if (!cond || !cond->isLoaded())//should never happen, checked at loading
1890 {
1891 LOG_ERROR("condition", "LootTemplate::addConditionItem: condition is null");
1892 return false;
1893 }
1894
1895 if (!Entries.empty())
1896 {
1897 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1898 {
1899 if ((*i)->itemid == uint32(cond->SourceEntry))
1900 {
1901 (*i)->conditions.push_back(cond);
1902 return true;
1903 }
1904 }
1905 }
1906
1907 if (!Groups.empty())
1908 {
1909 for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1910 {
1911 LootGroup* group = *groupItr;
1912 if (!group)
1913 continue;
1914
1915 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1916 if (!itemList->empty())
1917 {
1918 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1919 {
1920 if ((*i)->itemid == uint32(cond->SourceEntry))
1921 {
1922 (*i)->conditions.push_back(cond);
1923 return true;
1924 }
1925 }
1926 }
1927
1928 itemList = group->GetEqualChancedItemList();
1929 if (!itemList->empty())
1930 {
1931 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1932 {
1933 if ((*i)->itemid == uint32(cond->SourceEntry))
1934 {
1935 (*i)->conditions.push_back(cond);
1936 return true;
1937 }
1938 }
1939 }
1940 }
1941 }
1942 return false;
1943}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
std::uint32_t uint32
Definition: Define.h:107
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(), Condition::isLoaded(), LOG_ERROR, and Condition::SourceEntry.

Referenced by ConditionMgr::addToLootTemplate().

◆ AddEntry()

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

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

◆ CheckLootRefs()

void LootTemplate::CheckLootRefs ( LootTemplateMap const &  store,
LootIdSet ref_set 
) const
1865{
1866 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1867 {
1868 LootStoreItem* item = *ieItr;
1869 if (item->reference)
1870 {
1871 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1872 {
1873 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), "Reference", item->itemid);
1874 }
1875 else if (ref_set)
1876 {
1877 ref_set->erase(std::abs(item->reference));
1878 }
1879 }
1880 }
1881
1882 for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
1883 if (LootGroup* group = *grItr)
1884 group->CheckLootRefs(store, ref_set);
1885}
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(), LootStoreItem::itemid, LootTemplates_Reference, LootStoreItem::reference, and LootStore::ReportNonExistingId().

◆ CopyConditions() [1/2]

void LootTemplate::CopyConditions ( ConditionList  conditions)
1578{
1579 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1580 (*i)->conditions.clear();
1581
1582 for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
1583 if (LootGroup* group = *i)
1584 group->CopyConditions(conditions);
1585}

◆ CopyConditions() [2/2]

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

◆ HasQuestDrop()

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

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

◆ HasQuestDropForPlayer()

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

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

◆ isReference()

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

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

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
1855{
1856 // Checking group chances
1857 for (uint32 i = 0; i < Groups.size(); ++i)
1858 if (Groups[i])
1859 Groups[i]->Verify(lootstore, id, i + 1);
1860
1862}

Member Data Documentation

◆ Entries

LootStoreItemList LootTemplate::Entries
private

◆ Groups

LootGroups LootTemplate::Groups
private