aboutsummaryrefslogtreecommitdiff
path: root/src/game/LootMgr.h
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-02 16:23:55 -0500
committerNeo2003 <none@none>2008-10-02 16:23:55 -0500
commit9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch)
treeb5d1ba94a656e6679f8737f9ea6bed1239b73b14 /src/game/LootMgr.h
[svn] * Proper SVN structureinit
--HG-- branch : trunk
Diffstat (limited to 'src/game/LootMgr.h')
-rw-r--r--src/game/LootMgr.h331
1 files changed, 331 insertions, 0 deletions
diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h
new file mode 100644
index 00000000000..fe063a447fc
--- /dev/null
+++ b/src/game/LootMgr.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_LOOTMGR_H
+#define MANGOS_LOOTMGR_H
+
+#include "ItemEnchantmentMgr.h"
+#include "ByteBuffer.h"
+#include "Utilities/LinkedReference/RefManager.h"
+
+#include <map>
+#include <vector>
+
+enum RollType
+{
+ ROLL_PASS = 0,
+ ROLL_NEED = 1,
+ ROLL_GREED = 2
+};
+
+#define MAX_NR_LOOT_ITEMS 16
+// note: the client cannot show more than 16 items total
+#define MAX_NR_QUEST_ITEMS 32
+// unrelated to the number of quest items shown, just for reserve
+
+enum LootMethod
+{
+ FREE_FOR_ALL = 0,
+ ROUND_ROBIN = 1,
+ MASTER_LOOT = 2,
+ GROUP_LOOT = 3,
+ NEED_BEFORE_GREED = 4
+};
+
+enum PermissionTypes
+{
+ ALL_PERMISSION = 0,
+ GROUP_PERMISSION = 1,
+ MASTER_PERMISSION = 2,
+ NONE_PERMISSION = 3
+};
+
+class Player;
+class LootStore;
+
+struct LootStoreItem
+{
+ uint32 itemid; // id of the item
+ float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs
+ int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative)
+ uint8 group :8;
+ uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
+ uint16 conditionId :16; // additional loot condition Id
+ bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
+
+ // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
+ // displayid is filled in IsValid() which must be called after
+ LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount)
+ : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
+ group(_group), maxcount(_maxcount), conditionId(_conditionId),
+ needs_quest(_chanceOrQuestChance < 0) {}
+
+ bool Roll() const; // Checks if the entry takes it's chance (at loot generation)
+ bool IsValid(LootStore const& store, uint32 entry) const;
+ // Checks correctness of values
+};
+
+struct LootItem
+{
+ uint32 itemid;
+ uint32 randomSuffix;
+ int32 randomPropertyId;
+ uint16 conditionId :16; // allow compiler pack structure
+ uint8 count : 8;
+ bool is_looted : 1;
+ bool is_blocked : 1;
+ bool freeforall : 1; // free for all
+ bool is_underthreshold : 1;
+ bool is_counted : 1;
+ bool needs_quest : 1; // quest drop
+
+ // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties
+ // Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0)
+ explicit LootItem(LootStoreItem const& li);
+
+ // Basic checks for player/item compatibility - if false no chance to see the item in the loot
+ bool AllowedForPlayer(Player const * player) const;
+};
+
+struct QuestItem
+{
+ uint8 index; // position in quest_items;
+ bool is_looted;
+
+ QuestItem()
+ : index(0), is_looted(false) {}
+
+ QuestItem(uint8 _index, bool _islooted = false)
+ : index(_index), is_looted(_islooted) {}
+};
+
+struct Loot;
+class LootTemplate;
+
+typedef std::vector<QuestItem> QuestItemList;
+typedef std::map<uint32, QuestItemList *> QuestItemMap;
+typedef std::vector<LootStoreItem> LootStoreItemList;
+typedef HM_NAMESPACE::hash_map<uint32, LootTemplate*> LootTemplateMap;
+
+typedef std::set<uint32> LootIdSet;
+
+class LootStore
+{
+ public:
+ explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {}
+ virtual ~LootStore() { Clear(); }
+
+ void Verify() const;
+
+ void LoadAndCollectLootIds(LootIdSet& ids_set);
+ void CheckLootRefs(LootIdSet* ref_set = NULL) const;// check existence reference and remove it from ref_set
+ void ReportUnusedIds(LootIdSet const& ids_set) const;
+ void ReportNotExistedId(uint32 id) const;
+
+ bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); }
+ bool HaveQuestLootFor(uint32 loot_id) const;
+ bool HaveQuestLootForPlayer(uint32 loot_id,Player* player) const;
+
+ LootTemplate const* GetLootFor(uint32 loot_id) const;
+
+ char const* GetName() const { return m_name; }
+ char const* GetEntryName() const { return m_entryName; }
+ protected:
+ void LoadLootTable();
+ void Clear();
+ private:
+ LootTemplateMap m_LootTemplates;
+ char const* m_name;
+ char const* m_entryName;
+};
+
+class LootTemplate
+{
+ class LootGroup; // A set of loot definitions for items (refs are not allowed inside)
+ typedef std::vector<LootGroup> LootGroups;
+
+ public:
+ // Adds an entry to the group (at loading stage)
+ void AddEntry(LootStoreItem& item);
+ // Rolls for every item in the template and adds the rolled items the the loot
+ void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const;
+
+ // True if template includes at least 1 quest drop entry
+ bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const;
+ // True if template includes at least 1 quest drop for an active quest of the player
+ bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const * player, uint8 GroupId = 0) const;
+
+ // Checks integrity of the template
+ void Verify(LootStore const& store, uint32 Id) const;
+ void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const;
+ private:
+ LootStoreItemList Entries; // not grouped only
+ LootGroups Groups; // groups have own (optimised) processing, grouped entries go there
+};
+
+//=====================================================
+
+class LootValidatorRef : public Reference<Loot, LootValidatorRef>
+{
+ public:
+ LootValidatorRef() {}
+ void targetObjectDestroyLink() {}
+ void sourceObjectDestroyLink() {}
+};
+
+//=====================================================
+
+class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef>
+{
+ public:
+ typedef LinkedListHead::Iterator< LootValidatorRef > iterator;
+
+ LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); }
+ LootValidatorRef* getLast() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getLast(); }
+
+ iterator begin() { return iterator(getFirst()); }
+ iterator end() { return iterator(NULL); }
+ iterator rbegin() { return iterator(getLast()); }
+ iterator rend() { return iterator(NULL); }
+};
+
+//=====================================================
+
+struct Loot
+{
+ QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; }
+ QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; }
+ QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; }
+
+ QuestItemList* FillFFALoot(Player* player);
+ QuestItemList* FillQuestLoot(Player* player);
+ QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
+
+ std::vector<LootItem> items;
+ std::vector<LootItem> quest_items;
+ uint32 gold;
+ uint8 unlootedCount;
+
+ Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0) {}
+ ~Loot() { clear(); }
+
+ // if loot becomes invalid this reference is used to inform the listener
+ void addLootValidatorRef(LootValidatorRef* pLootValidatorRef)
+ {
+ i_LootValidatorRefManager.insertFirst(pLootValidatorRef);
+ }
+
+ // void clear();
+ void clear()
+ {
+ items.clear(); gold = 0; PlayersLooting.clear();
+ for (QuestItemMap::iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
+ delete itr->second;
+ for (QuestItemMap::iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
+ delete itr->second;
+ for (QuestItemMap::iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
+ delete itr->second;
+
+ PlayerQuestItems.clear();
+ PlayerFFAItems.clear();
+ PlayerNonQuestNonFFAConditionalItems.clear();
+
+ items.clear();
+ quest_items.clear();
+ gold = 0;
+ unlootedCount = 0;
+ i_LootValidatorRefManager.clearReferences();
+ }
+
+ bool empty() const { return items.empty() && gold == 0; }
+ bool isLooted() const { return gold == 0 && unlootedCount == 0; }
+
+ void NotifyItemRemoved(uint8 lootIndex);
+ void NotifyQuestItemRemoved(uint8 questIndex);
+ void NotifyMoneyRemoved();
+ void AddLooter(uint64 GUID) { PlayersLooting.insert(GUID); }
+ void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
+
+ void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
+ void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner);
+
+ // Inserts the item into the loot (called by LootTemplate processors)
+ void AddItem(LootStoreItem const & item);
+
+ LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
+ private:
+ std::set<uint64> PlayersLooting;
+ QuestItemMap PlayerQuestItems;
+ QuestItemMap PlayerFFAItems;
+ QuestItemMap PlayerNonQuestNonFFAConditionalItems;
+
+ // All rolls are registered here. They need to know, when the loot is not valid anymore
+ LootValidatorRefManager i_LootValidatorRefManager;
+
+};
+
+struct LootView
+{
+ Loot &loot;
+ QuestItemList *qlist;
+ QuestItemList *ffalist;
+ QuestItemList *conditionallist;
+ Player *viewer;
+ PermissionTypes permission;
+ LootView(Loot &_loot, QuestItemList *_qlist, QuestItemList *_ffalist, QuestItemList *_conditionallist, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
+ : loot(_loot), qlist(_qlist), ffalist(_ffalist), conditionallist(_conditionallist), viewer(_viewer), permission(_permission) {}
+};
+
+extern LootStore LootTemplates_Creature;
+extern LootStore LootTemplates_Fishing;
+extern LootStore LootTemplates_Gameobject;
+extern LootStore LootTemplates_Item;
+extern LootStore LootTemplates_Pickpocketing;
+extern LootStore LootTemplates_Skinning;
+extern LootStore LootTemplates_Disenchant;
+extern LootStore LootTemplates_Prospecting;
+extern LootStore LootTemplates_QuestMail;
+
+void LoadLootTemplates_Creature();
+void LoadLootTemplates_Fishing();
+void LoadLootTemplates_Gameobject();
+void LoadLootTemplates_Item();
+void LoadLootTemplates_Pickpocketing();
+void LoadLootTemplates_Skinning();
+void LoadLootTemplates_Disenchant();
+void LoadLootTemplates_Prospecting();
+void LoadLootTemplates_QuestMail();
+void LoadLootTemplates_Reference();
+
+inline void LoadLootTables()
+{
+ LoadLootTemplates_Creature();
+ LoadLootTemplates_Fishing();
+ LoadLootTemplates_Gameobject();
+ LoadLootTemplates_Item();
+ LoadLootTemplates_Pickpocketing();
+ LoadLootTemplates_Skinning();
+ LoadLootTemplates_Disenchant();
+ LoadLootTemplates_Prospecting();
+ LoadLootTemplates_QuestMail();
+ LoadLootTemplates_Reference();
+}
+
+ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
+ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
+#endif