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 ( )
1531{
1532 while (!Entries.empty())
1533 {
1534 delete Entries.back();
1535 Entries.pop_back();
1536 }
1537
1538 for (size_t i = 0; i < Groups.size(); ++i)
1539 delete Groups[i];
1540 Groups.clear();
1541}
Groups
Definition: boss_moroes.cpp:55
Entries
Definition: zone_howling_fjord.cpp:177

◆ LootTemplate() [2/2]

LootTemplate::LootTemplate ( LootTemplate const &  )
private

Member Function Documentation

◆ addConditionItem()

bool LootTemplate::addConditionItem ( Condition cond)
1877{
1878 if (!cond || !cond->isLoaded())//should never happen, checked at loading
1879 {
1880 LOG_ERROR("condition", "LootTemplate::addConditionItem: condition is null");
1881 return false;
1882 }
1883
1884 if (!Entries.empty())
1885 {
1886 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1887 {
1888 if ((*i)->itemid == uint32(cond->SourceEntry))
1889 {
1890 (*i)->conditions.push_back(cond);
1891 return true;
1892 }
1893 }
1894 }
1895
1896 if (!Groups.empty())
1897 {
1898 for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1899 {
1900 LootGroup* group = *groupItr;
1901 if (!group)
1902 continue;
1903
1904 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1905 if (!itemList->empty())
1906 {
1907 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1908 {
1909 if ((*i)->itemid == uint32(cond->SourceEntry))
1910 {
1911 (*i)->conditions.push_back(cond);
1912 return true;
1913 }
1914 }
1915 }
1916
1917 itemList = group->GetEqualChancedItemList();
1918 if (!itemList->empty())
1919 {
1920 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1921 {
1922 if ((*i)->itemid == uint32(cond->SourceEntry))
1923 {
1924 (*i)->conditions.push_back(cond);
1925 return true;
1926 }
1927 }
1928 }
1929 }
1930 }
1931 return false;
1932}
std::uint32_t uint32
Definition: Define.h:108
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
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)
1545{
1546 // `item->reference` > 0 --> Reference is counted as a normal and non grouped entry
1547 // `item->reference` < 0 --> Reference is counted as grouped entry within shared groupid
1548 if (item->groupid > 0 && item->reference <= 0) // Group and grouped reference
1549 {
1550 if (item->groupid >= Groups.size())
1551 {
1552 Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed
1553 }
1554
1555 if (!Groups[item->groupid - 1])
1556 {
1557 Groups[item->groupid - 1] = new LootGroup();
1558 }
1559
1560 Groups[item->groupid - 1]->AddEntry(item); // Adds new entry to the group
1561 }
1562 else // Non-grouped entries
1563 Entries.push_back(item);
1564}
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
1854{
1855 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1856 {
1857 LootStoreItem* item = *ieItr;
1858 if (item->reference)
1859 {
1860 if (!LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1861 {
1862 LootTemplates_Reference.ReportNonExistingId(std::abs(item->reference), "Reference", item->itemid);
1863 }
1864 else if (ref_set)
1865 {
1866 ref_set->erase(std::abs(item->reference));
1867 }
1868 }
1869 }
1870
1871 for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
1872 if (LootGroup* group = *grItr)
1873 group->CheckLootRefs(store, ref_set);
1874}
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)
1567{
1568 for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
1569 (*i)->conditions.clear();
1570
1571 for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
1572 if (LootGroup* group = *i)
1573 group->CopyConditions(conditions);
1574}

◆ CopyConditions() [2/2]

bool LootTemplate::CopyConditions ( LootItem li,
uint32  conditionLootId = 0 
) const
1577{
1578 for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter)
1579 {
1580 LootStoreItem* item = *_iter;
1581 if (item->reference)
1582 {
1583 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1584 {
1585 if (Referenced->CopyConditions(li, conditionLootId))
1586 {
1587 return true;
1588 }
1589 }
1590 }
1591 else
1592 {
1593 if (item->itemid != li->itemid)
1594 {
1595 continue;
1596 }
1597
1598 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1599 {
1600 continue;
1601 }
1602
1603 li->conditions = item->conditions;
1604 return true;
1605 }
1606 }
1607
1608 for (LootGroups::const_iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
1609 {
1610 LootGroup* group = *groupItr;
1611 if (!group)
1612 continue;
1613
1614 LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
1615 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1616 {
1617 LootStoreItem* item = *i;
1618 if (item->reference)
1619 {
1620 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1621 {
1622 if (Referenced->CopyConditions(li, conditionLootId))
1623 {
1624 return true;
1625 }
1626 }
1627 }
1628 else
1629 {
1630 if (item->itemid != li->itemid)
1631 {
1632 continue;
1633 }
1634
1635 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1636 {
1637 continue;
1638 }
1639
1640 li->conditions = item->conditions;
1641 return true;
1642 }
1643 }
1644
1645 itemList = group->GetEqualChancedItemList();
1646 for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
1647 {
1648 LootStoreItem* item = *i;
1649 if (item->reference)
1650 {
1651 if (LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(std::abs(item->reference)))
1652 {
1653 if (Referenced->CopyConditions(li, conditionLootId))
1654 {
1655 return true;
1656 }
1657 }
1658 }
1659 else
1660 {
1661 if (item->itemid != li->itemid)
1662 {
1663 continue;
1664 }
1665
1666 if (!item->conditions.empty() && conditionLootId && conditionLootId != item->conditions.front()->SourceGroup)
1667 {
1668 continue;
1669 }
1670
1671 li->conditions = item->conditions;
1672 return true;
1673 }
1674 }
1675 }
1676
1677 return false;
1678}
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
1754{
1755 if (groupId) // Group reference
1756 {
1757 if (groupId > Groups.size())
1758 return false; // Error message [should be] already printed at loading stage
1759
1760 if (!Groups[groupId - 1])
1761 return false;
1762
1763 return Groups[groupId - 1]->HasQuestDrop(store);
1764 }
1765
1766 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1767 {
1768 LootStoreItem* item = *i;
1769 if (item->reference) // References
1770 {
1771 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1772 if (Referenced == store.end())
1773 continue; // Error message [should be] already printed at loading stage
1774
1775 if (Referenced->second->HasQuestDrop(store, item->groupid))
1776 return true;
1777 }
1778 else if (item->needs_quest)
1779 return true; // quest drop found
1780 }
1781
1782 // Now processing groups
1783 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1784 {
1785 if (LootGroup* group = *i)
1786 {
1787 if (group->HasQuestDrop(store))
1788 {
1789 return true;
1790 }
1791 }
1792 }
1793
1794 return false;
1795}
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
1799{
1800 if (groupId) // Group reference
1801 {
1802 if (groupId > Groups.size())
1803 return false; // Error message already printed at loading stage
1804
1805 if (!Groups[groupId - 1])
1806 return false;
1807
1808 return Groups[groupId - 1]->HasQuestDropForPlayer(player, store);
1809 }
1810
1811 // Checking non-grouped entries
1812 for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i)
1813 {
1814 LootStoreItem* item = *i;
1815 if (item->reference) // References processing
1816 {
1817 LootTemplateMap::const_iterator Referenced = store.find(std::abs(item->reference));
1818 if (Referenced == store.end())
1819 continue; // Error message already printed at loading stage
1820 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
1821 return true;
1822 }
1823 else if (player->HasQuestForItem(item->itemid))
1824 return true; // active quest drop found
1825 }
1826
1827 // Now checking groups
1828 for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
1829 {
1830 if (LootGroup* group = *i)
1831 {
1832 if (group->HasQuestDropForPlayer(player, store))
1833 {
1834 return true;
1835 }
1836 }
1837 }
1838
1839 return false;
1840}

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

◆ isReference()

bool LootTemplate::isReference ( uint32  id) const
1935{
1936 for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
1937 {
1938 if ((*ieItr)->itemid == id && (*ieItr)->reference)
1939 {
1940 return true;
1941 }
1942 }
1943
1944 return false;//not found or not reference
1945}

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

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
1844{
1845 // Checking group chances
1846 for (uint32 i = 0; i < Groups.size(); ++i)
1847 if (Groups[i])
1848 Groups[i]->Verify(lootstore, id, i + 1);
1849
1851}

Member Data Documentation

◆ Entries

LootStoreItemList LootTemplate::Entries
private

◆ Groups

LootGroups LootTemplate::Groups
private