Fix debug message from last commit
[getmangos.git] / src / game / LootMgr.h
blob4d218f2dfa4833e4f6ed58c777c70358ae1c0c66
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOS_LOOTMGR_H
20 #define MANGOS_LOOTMGR_H
22 #include "ItemEnchantmentMgr.h"
23 #include "ByteBuffer.h"
24 #include "Utilities/LinkedReference/RefManager.h"
26 #include <map>
27 #include <vector>
29 enum RollType
31 ROLL_PASS = 0,
32 ROLL_NEED = 1,
33 ROLL_GREED = 2
36 #define MAX_NR_LOOT_ITEMS 16
37 // note: the client cannot show more than 16 items total
38 #define MAX_NR_QUEST_ITEMS 32
39 // unrelated to the number of quest items shown, just for reserve
41 enum LootMethod
43 FREE_FOR_ALL = 0,
44 ROUND_ROBIN = 1,
45 MASTER_LOOT = 2,
46 GROUP_LOOT = 3,
47 NEED_BEFORE_GREED = 4
50 enum PermissionTypes
52 ALL_PERMISSION = 0,
53 GROUP_PERMISSION = 1,
54 MASTER_PERMISSION = 2,
55 NONE_PERMISSION = 3
58 class Player;
59 class LootStore;
61 struct LootStoreItem
63 uint32 itemid; // id of the item
64 float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs
65 int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative)
66 uint8 group :8;
67 uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
68 uint16 conditionId :16; // additional loot condition Id
69 bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
71 // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
72 // displayid is filled in IsValid() which must be called after
73 LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount)
74 : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
75 group(_group), maxcount(_maxcount), conditionId(_conditionId),
76 needs_quest(_chanceOrQuestChance < 0) {}
78 bool Roll() const; // Checks if the entry takes it's chance (at loot generation)
79 bool IsValid(LootStore const& store, uint32 entry) const;
80 // Checks correctness of values
83 struct LootItem
85 uint32 itemid;
86 uint32 randomSuffix;
87 int32 randomPropertyId;
88 uint16 conditionId :16; // allow compiler pack structure
89 uint8 count : 8;
90 bool is_looted : 1;
91 bool is_blocked : 1;
92 bool freeforall : 1; // free for all
93 bool is_underthreshold : 1;
94 bool is_counted : 1;
95 bool needs_quest : 1; // quest drop
97 // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties
98 // Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0)
99 explicit LootItem(LootStoreItem const& li);
101 // Basic checks for player/item compatibility - if false no chance to see the item in the loot
102 bool AllowedForPlayer(Player const * player) const;
105 struct QuestItem
107 uint8 index; // position in quest_items;
108 bool is_looted;
110 QuestItem()
111 : index(0), is_looted(false) {}
113 QuestItem(uint8 _index, bool _islooted = false)
114 : index(_index), is_looted(_islooted) {}
117 struct Loot;
118 class LootTemplate;
120 typedef std::vector<QuestItem> QuestItemList;
121 typedef std::map<uint32, QuestItemList *> QuestItemMap;
122 typedef std::vector<LootStoreItem> LootStoreItemList;
123 typedef UNORDERED_MAP<uint32, LootTemplate*> LootTemplateMap;
125 typedef std::set<uint32> LootIdSet;
127 class LootStore
129 public:
130 explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {}
131 virtual ~LootStore() { Clear(); }
133 void Verify() const;
135 void LoadAndCollectLootIds(LootIdSet& ids_set);
136 void CheckLootRefs(LootIdSet* ref_set = NULL) const;// check existence reference and remove it from ref_set
137 void ReportUnusedIds(LootIdSet const& ids_set) const;
138 void ReportNotExistedId(uint32 id) const;
140 bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); }
141 bool HaveQuestLootFor(uint32 loot_id) const;
142 bool HaveQuestLootForPlayer(uint32 loot_id,Player* player) const;
144 LootTemplate const* GetLootFor(uint32 loot_id) const;
146 char const* GetName() const { return m_name; }
147 char const* GetEntryName() const { return m_entryName; }
148 protected:
149 void LoadLootTable();
150 void Clear();
151 private:
152 LootTemplateMap m_LootTemplates;
153 char const* m_name;
154 char const* m_entryName;
157 class LootTemplate
159 class LootGroup; // A set of loot definitions for items (refs are not allowed inside)
160 typedef std::vector<LootGroup> LootGroups;
162 public:
163 // Adds an entry to the group (at loading stage)
164 void AddEntry(LootStoreItem& item);
165 // Rolls for every item in the template and adds the rolled items the the loot
166 void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const;
168 // True if template includes at least 1 quest drop entry
169 bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const;
170 // True if template includes at least 1 quest drop for an active quest of the player
171 bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const * player, uint8 GroupId = 0) const;
173 // Checks integrity of the template
174 void Verify(LootStore const& store, uint32 Id) const;
175 void CheckLootRefs(LootIdSet* ref_set) const;
176 private:
177 LootStoreItemList Entries; // not grouped only
178 LootGroups Groups; // groups have own (optimised) processing, grouped entries go there
181 //=====================================================
183 class LootValidatorRef : public Reference<Loot, LootValidatorRef>
185 public:
186 LootValidatorRef() {}
187 void targetObjectDestroyLink() {}
188 void sourceObjectDestroyLink() {}
191 //=====================================================
193 class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef>
195 public:
196 typedef LinkedListHead::Iterator< LootValidatorRef > iterator;
198 LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); }
199 LootValidatorRef* getLast() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getLast(); }
201 iterator begin() { return iterator(getFirst()); }
202 iterator end() { return iterator(NULL); }
203 iterator rbegin() { return iterator(getLast()); }
204 iterator rend() { return iterator(NULL); }
207 //=====================================================
209 struct Loot
211 QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; }
212 QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; }
213 QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; }
215 QuestItemList* FillFFALoot(Player* player);
216 QuestItemList* FillQuestLoot(Player* player);
217 QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
219 std::vector<LootItem> items;
220 std::vector<LootItem> quest_items;
221 uint32 gold;
222 uint8 unlootedCount;
224 Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0) {}
225 ~Loot() { clear(); }
227 // if loot becomes invalid this reference is used to inform the listener
228 void addLootValidatorRef(LootValidatorRef* pLootValidatorRef)
230 i_LootValidatorRefManager.insertFirst(pLootValidatorRef);
233 // void clear();
234 void clear()
236 items.clear(); gold = 0; PlayersLooting.clear();
237 for (QuestItemMap::iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
238 delete itr->second;
239 for (QuestItemMap::iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
240 delete itr->second;
241 for (QuestItemMap::iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
242 delete itr->second;
244 PlayerQuestItems.clear();
245 PlayerFFAItems.clear();
246 PlayerNonQuestNonFFAConditionalItems.clear();
248 items.clear();
249 quest_items.clear();
250 gold = 0;
251 unlootedCount = 0;
252 i_LootValidatorRefManager.clearReferences();
255 bool empty() const { return items.empty() && gold == 0; }
256 bool isLooted() const { return gold == 0 && unlootedCount == 0; }
258 void NotifyItemRemoved(uint8 lootIndex);
259 void NotifyQuestItemRemoved(uint8 questIndex);
260 void NotifyMoneyRemoved();
261 void AddLooter(uint64 GUID) { PlayersLooting.insert(GUID); }
262 void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
264 void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
265 void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner);
267 // Inserts the item into the loot (called by LootTemplate processors)
268 void AddItem(LootStoreItem const & item);
270 LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
271 private:
272 std::set<uint64> PlayersLooting;
273 QuestItemMap PlayerQuestItems;
274 QuestItemMap PlayerFFAItems;
275 QuestItemMap PlayerNonQuestNonFFAConditionalItems;
277 // All rolls are registered here. They need to know, when the loot is not valid anymore
278 LootValidatorRefManager i_LootValidatorRefManager;
282 struct LootView
284 Loot &loot;
285 QuestItemList *qlist;
286 QuestItemList *ffalist;
287 QuestItemList *conditionallist;
288 Player *viewer;
289 PermissionTypes permission;
290 LootView(Loot &_loot, QuestItemList *_qlist, QuestItemList *_ffalist, QuestItemList *_conditionallist, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
291 : loot(_loot), qlist(_qlist), ffalist(_ffalist), conditionallist(_conditionallist), viewer(_viewer), permission(_permission) {}
294 extern LootStore LootTemplates_Creature;
295 extern LootStore LootTemplates_Fishing;
296 extern LootStore LootTemplates_Gameobject;
297 extern LootStore LootTemplates_Item;
298 extern LootStore LootTemplates_Milling;
299 extern LootStore LootTemplates_Pickpocketing;
300 extern LootStore LootTemplates_Skinning;
301 extern LootStore LootTemplates_Disenchant;
302 extern LootStore LootTemplates_Prospecting;
303 extern LootStore LootTemplates_QuestMail;
305 void LoadLootTemplates_Creature();
306 void LoadLootTemplates_Fishing();
307 void LoadLootTemplates_Gameobject();
308 void LoadLootTemplates_Item();
309 void LoadLootTemplates_Milling();
310 void LoadLootTemplates_Pickpocketing();
311 void LoadLootTemplates_Skinning();
312 void LoadLootTemplates_Disenchant();
313 void LoadLootTemplates_Prospecting();
314 void LoadLootTemplates_QuestMail();
315 void LoadLootTemplates_Reference();
317 inline void LoadLootTables()
319 LoadLootTemplates_Creature();
320 LoadLootTemplates_Fishing();
321 LoadLootTemplates_Gameobject();
322 LoadLootTemplates_Item();
323 LoadLootTemplates_Milling();
324 LoadLootTemplates_Pickpocketing();
325 LoadLootTemplates_Skinning();
326 LoadLootTemplates_Disenchant();
327 LoadLootTemplates_Prospecting();
328 LoadLootTemplates_QuestMail();
329 LoadLootTemplates_Reference();
332 ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
333 ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
334 #endif