[9581] Fixed apply damage reduction to melee/ranged damage.
[getmangos.git] / src / game / LootMgr.h
blob0b7914dffe0755710ac85ad3dd18a4ca73a5cccd
1 /*
2 * Copyright (C) 2005-2010 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,
34 ROLL_DISENCHANT = 3,
35 MAX_ROLL_TYPE = 4
38 #define ALL_ROLL_TYPE_MASK 0x0F
40 #define MAX_NR_LOOT_ITEMS 16
41 // note: the client cannot show more than 16 items total
42 #define MAX_NR_QUEST_ITEMS 32
43 // unrelated to the number of quest items shown, just for reserve
45 enum LootMethod
47 FREE_FOR_ALL = 0,
48 ROUND_ROBIN = 1,
49 MASTER_LOOT = 2,
50 GROUP_LOOT = 3,
51 NEED_BEFORE_GREED = 4
54 enum PermissionTypes
56 ALL_PERMISSION = 0,
57 GROUP_PERMISSION = 1,
58 MASTER_PERMISSION = 2,
59 NONE_PERMISSION = 3
62 enum LootType
64 LOOT_CORPSE = 1,
65 LOOT_PICKPOCKETING = 2,
66 LOOT_FISHING = 3,
67 LOOT_DISENCHANTING = 4,
68 // ignored always by client
69 LOOT_SKINNING = 6,
70 LOOT_PROSPECTING = 7,
71 LOOT_MILLING = 8,
73 LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead
74 LOOT_INSIGNIA = 21 // unsupported by client, sending LOOT_CORPSE instead
77 class Player;
78 class LootStore;
80 struct LootStoreItem
82 uint32 itemid; // id of the item
83 float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs
84 int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative)
85 uint8 group :7;
86 bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
87 uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
88 uint16 conditionId :16; // additional loot condition Id
90 // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
91 // displayid is filled in IsValid() which must be called after
92 LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint16 _conditionId, int32 _mincountOrRef, uint8 _maxcount)
93 : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
94 group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId)
97 bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
98 bool IsValid(LootStore const& store, uint32 entry) const;
99 // Checks correctness of values
102 struct LootItem
104 uint32 itemid;
105 uint32 randomSuffix;
106 int32 randomPropertyId;
107 uint16 conditionId :16; // allow compiler pack structure
108 uint8 count : 8;
109 bool is_looted : 1;
110 bool is_blocked : 1;
111 bool freeforall : 1; // free for all
112 bool is_underthreshold : 1;
113 bool is_counted : 1;
114 bool needs_quest : 1; // quest drop
116 // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties
117 // Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0)
118 explicit LootItem(LootStoreItem const& li);
120 // Basic checks for player/item compatibility - if false no chance to see the item in the loot
121 bool AllowedForPlayer(Player const * player) const;
124 struct QuestItem
126 uint8 index; // position in quest_items;
127 bool is_looted;
129 QuestItem()
130 : index(0), is_looted(false) {}
132 QuestItem(uint8 _index, bool _islooted = false)
133 : index(_index), is_looted(_islooted) {}
136 struct Loot;
137 class LootTemplate;
139 typedef std::vector<QuestItem> QuestItemList;
140 typedef std::map<uint32, QuestItemList *> QuestItemMap;
141 typedef std::vector<LootStoreItem> LootStoreItemList;
142 typedef UNORDERED_MAP<uint32, LootTemplate*> LootTemplateMap;
144 typedef std::set<uint32> LootIdSet;
146 class LootStore
148 public:
149 explicit LootStore(char const* name, char const* entryName, bool ratesAllowed)
150 : m_name(name), m_entryName(entryName), m_ratesAllowed(ratesAllowed) {}
151 virtual ~LootStore() { Clear(); }
153 void Verify() const;
155 void LoadAndCollectLootIds(LootIdSet& ids_set);
156 void CheckLootRefs(LootIdSet* ref_set = NULL) const;// check existence reference and remove it from ref_set
157 void ReportUnusedIds(LootIdSet const& ids_set) const;
158 void ReportNotExistedId(uint32 id) const;
160 bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); }
161 bool HaveQuestLootFor(uint32 loot_id) const;
162 bool HaveQuestLootForPlayer(uint32 loot_id,Player* player) const;
164 LootTemplate const* GetLootFor(uint32 loot_id) const;
166 char const* GetName() const { return m_name; }
167 char const* GetEntryName() const { return m_entryName; }
168 bool IsRatesAllowed() const { return m_ratesAllowed; }
169 protected:
170 void LoadLootTable();
171 void Clear();
172 private:
173 LootTemplateMap m_LootTemplates;
174 char const* m_name;
175 char const* m_entryName;
176 bool m_ratesAllowed;
179 class LootTemplate
181 class LootGroup; // A set of loot definitions for items (refs are not allowed inside)
182 typedef std::vector<LootGroup> LootGroups;
184 public:
185 // Adds an entry to the group (at loading stage)
186 void AddEntry(LootStoreItem& item);
187 // Rolls for every item in the template and adds the rolled items the the loot
188 void Process(Loot& loot, LootStore const& store, bool rate, uint8 GroupId = 0) const;
190 // True if template includes at least 1 quest drop entry
191 bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const;
192 // True if template includes at least 1 quest drop for an active quest of the player
193 bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const * player, uint8 GroupId = 0) const;
195 // Checks integrity of the template
196 void Verify(LootStore const& store, uint32 Id) const;
197 void CheckLootRefs(LootIdSet* ref_set) const;
198 private:
199 LootStoreItemList Entries; // not grouped only
200 LootGroups Groups; // groups have own (optimised) processing, grouped entries go there
203 //=====================================================
205 class LootValidatorRef : public Reference<Loot, LootValidatorRef>
207 public:
208 LootValidatorRef() {}
209 void targetObjectDestroyLink() {}
210 void sourceObjectDestroyLink() {}
213 //=====================================================
215 class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef>
217 public:
218 typedef LinkedListHead::Iterator< LootValidatorRef > iterator;
220 LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); }
221 LootValidatorRef* getLast() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getLast(); }
223 iterator begin() { return iterator(getFirst()); }
224 iterator end() { return iterator(NULL); }
225 iterator rbegin() { return iterator(getLast()); }
226 iterator rend() { return iterator(NULL); }
229 //=====================================================
230 struct LootView;
232 ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
233 ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
235 struct Loot
237 friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
239 QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; }
240 QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; }
241 QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; }
243 std::vector<LootItem> items;
244 uint32 gold;
245 uint8 unlootedCount;
246 LootType loot_type; // required for achievement system
248 Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE) {}
249 ~Loot() { clear(); }
251 // if loot becomes invalid this reference is used to inform the listener
252 void addLootValidatorRef(LootValidatorRef* pLootValidatorRef)
254 i_LootValidatorRefManager.insertFirst(pLootValidatorRef);
257 // void clear();
258 void clear()
260 for (QuestItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
261 delete itr->second;
262 PlayerQuestItems.clear();
264 for (QuestItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
265 delete itr->second;
266 PlayerFFAItems.clear();
268 for (QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
269 delete itr->second;
270 PlayerNonQuestNonFFAConditionalItems.clear();
272 PlayersLooting.clear();
273 items.clear();
274 quest_items.clear();
275 gold = 0;
276 unlootedCount = 0;
277 i_LootValidatorRefManager.clearReferences();
280 bool empty() const { return items.empty() && gold == 0; }
281 bool isLooted() const { return gold == 0 && unlootedCount == 0; }
283 void NotifyItemRemoved(uint8 lootIndex);
284 void NotifyQuestItemRemoved(uint8 questIndex);
285 void NotifyMoneyRemoved();
286 void AddLooter(uint64 GUID) { PlayersLooting.insert(GUID); }
287 void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
289 void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
290 bool FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, bool noEmptyError = false);
292 // Inserts the item into the loot (called by LootTemplate processors)
293 void AddItem(LootStoreItem const & item);
295 LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
296 uint32 GetMaxSlotInLootFor(Player* player) const;
298 private:
299 void FillNotNormalLootFor(Player* player);
300 QuestItemList* FillFFALoot(Player* player);
301 QuestItemList* FillQuestLoot(Player* player);
302 QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
304 std::vector<LootItem> quest_items;
305 std::set<uint64> PlayersLooting;
306 QuestItemMap PlayerQuestItems;
307 QuestItemMap PlayerFFAItems;
308 QuestItemMap PlayerNonQuestNonFFAConditionalItems;
310 // All rolls are registered here. They need to know, when the loot is not valid anymore
311 LootValidatorRefManager i_LootValidatorRefManager;
314 struct LootView
316 Loot &loot;
317 Player *viewer;
318 PermissionTypes permission;
319 LootView(Loot &_loot, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
320 : loot(_loot), viewer(_viewer), permission(_permission) {}
323 extern LootStore LootTemplates_Creature;
324 extern LootStore LootTemplates_Fishing;
325 extern LootStore LootTemplates_Gameobject;
326 extern LootStore LootTemplates_Item;
327 extern LootStore LootTemplates_Mail;
328 extern LootStore LootTemplates_Milling;
329 extern LootStore LootTemplates_Pickpocketing;
330 extern LootStore LootTemplates_Skinning;
331 extern LootStore LootTemplates_Disenchant;
332 extern LootStore LootTemplates_Prospecting;
333 extern LootStore LootTemplates_Spell;
335 void LoadLootTemplates_Creature();
336 void LoadLootTemplates_Fishing();
337 void LoadLootTemplates_Gameobject();
338 void LoadLootTemplates_Item();
339 void LoadLootTemplates_Mail();
340 void LoadLootTemplates_Milling();
341 void LoadLootTemplates_Pickpocketing();
342 void LoadLootTemplates_Skinning();
343 void LoadLootTemplates_Disenchant();
344 void LoadLootTemplates_Prospecting();
346 void LoadLootTemplates_Spell();
347 void LoadLootTemplates_Reference();
349 inline void LoadLootTables()
351 LoadLootTemplates_Creature();
352 LoadLootTemplates_Fishing();
353 LoadLootTemplates_Gameobject();
354 LoadLootTemplates_Item();
355 LoadLootTemplates_Mail();
356 LoadLootTemplates_Milling();
357 LoadLootTemplates_Pickpocketing();
358 LoadLootTemplates_Skinning();
359 LoadLootTemplates_Disenchant();
360 LoadLootTemplates_Prospecting();
361 LoadLootTemplates_Spell();
363 LoadLootTemplates_Reference();
366 #endif