aboutsummaryrefslogtreecommitdiff
path: root/src/game/LootMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/LootMgr.cpp')
-rw-r--r--src/game/LootMgr.cpp150
1 files changed, 122 insertions, 28 deletions
diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp
index dcbb376208b..2137c8872b5 100644
--- a/src/game/LootMgr.cpp
+++ b/src/game/LootMgr.cpp
@@ -64,6 +64,9 @@ class LootTemplate::LootGroup // A set of loot def
void Verify(LootStore const& lootstore, uint32 id, uint8 group_id) const;
void CollectLootIds(LootIdSet& set) const;
void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const;
+ LootStoreItemList * GetExplicitlyChancedItemList() { return &ExplicitlyChanced; }
+ LootStoreItemList * GetEqualChancedItemList() { return &EqualChanced; }
+ void CopyConditions(ConditionList conditions);
private:
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
@@ -99,8 +102,8 @@ void LootStore::LoadLootTable()
sLog.outString("%s :", GetName());
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, lootmode, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2 FROM %s",GetName());
+ // 0 1 2 3 4 5 6
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, lootmode, groupid, mincountOrRef, maxcount FROM %s",GetName());
if (result)
{
@@ -118,9 +121,6 @@ void LootStore::LoadLootTable()
uint8 group = fields[4].GetUInt8();
int32 mincountOrRef = fields[5].GetInt32();
int32 maxcount = fields[6].GetInt32();
- ConditionType condition = (ConditionType)fields[7].GetUInt8();
- uint32 cond_value1 = fields[8].GetUInt32();
- uint32 cond_value2 = fields[9].GetUInt32();
if (maxcount > std::numeric_limits<uint8>::max())
{
@@ -128,16 +128,7 @@ void LootStore::LoadLootTable()
continue; // error already printed to log/console.
}
- if (!PlayerCondition::IsValid(condition,cond_value1, cond_value2))
- {
- sLog.outErrorDb("... in table '%s' entry %u item %u", GetName(), entry, item);
- continue; // error already printed to log/console.
- }
-
- // (condition + cond_value1/2) are converted into single conditionId
- uint16 conditionId = objmgr.GetConditionId(condition, cond_value1, cond_value2);
-
- LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, lootmode, group, conditionId, mincountOrRef, maxcount);
+ LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, lootmode, group, mincountOrRef, maxcount);
if (!storeitem.IsValid(*this,entry)) // Validity checks
continue;
@@ -195,6 +186,16 @@ bool LootStore::HaveQuestLootForPlayer(uint32 loot_id,Player* player) const
return false;
}
+void LootStore::ResetConditions()
+{
+ LootTemplateMap m_LootTemplates;
+ for (LootTemplateMap::iterator itr = m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr)
+ {
+ ConditionList empty;
+ (*itr).second->CopyConditions(empty);
+ }
+}
+
LootTemplate const* LootStore::GetLootFor(uint32 loot_id) const
{
LootTemplateMap::const_iterator tab = m_LootTemplates.find(loot_id);
@@ -205,6 +206,16 @@ LootTemplate const* LootStore::GetLootFor(uint32 loot_id) const
return tab->second;
}
+LootTemplate* LootStore::GetLootForConditionFill(uint32 loot_id)
+{
+ LootTemplateMap::iterator tab = m_LootTemplates.find(loot_id);
+
+ if (tab == m_LootTemplates.end())
+ return NULL;
+
+ return tab->second;
+}
+
void LootStore::LoadAndCollectLootIds(LootIdSet& ids_set)
{
LoadLootTable();
@@ -316,9 +327,9 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
// Constructor, copies most fields from LootStoreItem and generates random count
LootItem::LootItem(LootStoreItem const& li)
{
- itemid = li.itemid;
- conditionId = li.conditionId;
-
+ itemid = li.itemid;
+ conditions = li.conditions;
+
ItemPrototype const* proto = objmgr.GetItemPrototype(itemid);
freeforall = proto && (proto->Flags & ITEM_FLAGS_PARTY_LOOT);
@@ -336,8 +347,8 @@ LootItem::LootItem(LootStoreItem const& li)
// Basic checks for player/item compatibility - if false no chance to see the item in the loot
bool LootItem::AllowedForPlayer(Player const * player) const
{
- // DB conditions check
- if (!objmgr.IsPlayerMeetToCondition(player,conditionId))
+ // DB conditions check
+ if (!sConditionMgr.IsPlayerMeetToConditions(const_cast<Player*>(player), conditions))
return false;
if (needs_quest)
@@ -368,7 +379,7 @@ void Loot::AddItem(LootStoreItem const & item)
{
if (quest_items.size() < MAX_NR_QUEST_ITEMS)
quest_items.push_back(LootItem(item));
- }
+ }
else if (items.size() < MAX_NR_LOOT_ITEMS) // Non-quest drop
{
items.push_back(LootItem(item));
@@ -376,7 +387,7 @@ void Loot::AddItem(LootStoreItem const & item)
// non-conditional one-player only items are counted here,
// free for all items are counted in FillFFALoot(),
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
- if (!item.conditionId)
+ if (item.conditions.empty())
{
ItemPrototype const* proto = objmgr.GetItemPrototype(item.itemid);
if (!proto || (proto->Flags & ITEM_FLAGS_PARTY_LOOT) == 0)
@@ -512,7 +523,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
for (uint8 i = 0; i < items.size(); ++i)
{
LootItem &item = items[i];
- if (!item.is_looted && !item.freeforall && item.conditionId && item.AllowedForPlayer(player))
+ if (!item.is_looted && !item.freeforall && !item.conditions.empty() && item.AllowedForPlayer(player))
{
ql->push_back(QuestItem(i));
if (!item.is_counted)
@@ -649,7 +660,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qite
}
}
}
- else if (item->conditionId)
+ else if (!item->conditions.empty())
{
QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow());
if (itr != PlayerNonQuestNonFFAConditionalItems.end())
@@ -776,7 +787,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
// blocked rolled items and quest items, and !ffa items
for (uint8 i = 0; i < l.items.size(); ++i)
{
- if (!l.items[i].is_looted && !l.items[i].freeforall && !l.items[i].conditionId && l.items[i].AllowedForPlayer(lv.viewer))
+ if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer))
{
uint8 slot_type;
@@ -804,7 +815,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
for (uint8 i = 0; i < l.items.size(); ++i)
{
- if (!l.items[i].is_looted && !l.items[i].freeforall && !l.items[i].conditionId && l.items[i].AllowedForPlayer(lv.viewer))
+ if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer))
{
if (l.roundRobinPlayer != 0 && lv.viewer->GetGUID() != l.roundRobinPlayer)
// item shall not be displayed.
@@ -823,7 +834,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
uint8 slot_type = (lv.permission == MASTER_PERMISSION) ? LOOT_SLOT_TYPE_MASTER : LOOT_SLOT_TYPE_ALLOW_LOOT;
for (uint8 i = 0; i < l.items.size(); ++i)
{
- if (!l.items[i].is_looted && !l.items[i].freeforall && !l.items[i].conditionId && l.items[i].AllowedForPlayer(lv.viewer))
+ if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer))
{
b << uint8(i) << l.items[i];
b << uint8(slot_type);
@@ -954,6 +965,18 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const
return false;
}
+void LootTemplate::LootGroup::CopyConditions(ConditionList conditions)
+{
+ for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
+ {
+ i->conditions = conditions;
+ }
+ for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
+ {
+ i->conditions = conditions;
+ }
+}
+
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const
{
@@ -1078,7 +1101,7 @@ void LootTemplate::LootGroup::Verify(LootStore const& lootstore, uint32 id, uint
}
}
-void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, LootIdSet* ref_set) const
+void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const
{
for (LootStoreItemList::const_iterator ieItr=ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr)
{
@@ -1120,6 +1143,15 @@ void LootTemplate::AddEntry(LootStoreItem& item)
Entries.push_back(item);
}
+void LootTemplate::CopyConditions(ConditionList conditions)
+{
+ for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
+ i->conditions = conditions;
+
+ for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
+ i->CopyConditions(conditions);
+}
+
// Rolls for every item in the template and adds the rolled items the the loot
void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint16 lootMode, uint8 groupId) const
{
@@ -1165,6 +1197,8 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint16
if (!Referenced)
continue; // Error message already printed at loading stage
+ const_cast<LootTemplate*>(Referenced)->CopyConditions(i->conditions);//copy conditions from referer template
+
for (uint32 loop = 0; loop < i->maxcount; ++loop) // Ref multiplicator
Referenced->Process(loot, store, rate, lootMode, i->group);
}
@@ -1268,6 +1302,66 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se
for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr)
grItr->CheckLootRefs(store,ref_set);
}
+bool LootTemplate::addConditionItem(Condition* cond)
+{
+ if (!cond || !cond->isLoaded())//should never happen, checked at loading
+ {
+ sLog.outError("LootTemplate::addConditionItem: condition is null");
+ return false;
+ }
+ if (!Entries.empty())
+ {
+ for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
+ {
+ if (i->itemid == cond->mSourceEntry)
+ {
+ i->conditions.push_back(cond);
+ return true;
+ }
+ }
+ }
+ if (!Groups.empty())
+ {
+ for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
+ {
+ LootStoreItemList* itemList = (*groupItr).GetExplicitlyChancedItemList();
+ if (!itemList->empty())
+ {
+ for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
+ {
+ if ((*i).itemid == cond->mSourceEntry)
+ {
+ (*i).conditions.push_back(cond);
+ return true;
+ }
+ }
+ }
+ itemList = (*groupItr).GetEqualChancedItemList();
+ if (!itemList->empty())
+ {
+ for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
+ {
+ if ((*i).itemid == cond->mSourceEntry)
+ {
+ (*i).conditions.push_back(cond);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool LootTemplate::isReference(uint32 id)
+{
+ for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr)
+ {
+ if (ieItr->itemid == id && ieItr->mincountOrRef < 0)
+ return true;
+ }
+ return false;//not found or not reference
+}
void LoadLootTemplates_Creature()
{