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"
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
58 MASTER_PERMISSION
= 2,
65 LOOT_PICKPOCKETING
= 2,
67 LOOT_DISENCHANTING
= 4,
68 // ignored always by client
73 LOOT_FISHINGHOLE
= 20, // unsupported by client, sending LOOT_FISHING instead
74 LOOT_INSIGNIA
= 21 // unsupported by client, sending LOOT_CORPSE instead
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)
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
106 int32 randomPropertyId
;
107 uint16 conditionId
:16; // allow compiler pack structure
111 bool freeforall
: 1; // free for all
112 bool is_underthreshold
: 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;
126 uint8 index
; // position in quest_items;
130 : index(0), is_looted(false) {}
132 QuestItem(uint8 _index
, bool _islooted
= false)
133 : index(_index
), is_looted(_islooted
) {}
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
;
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(); }
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
; }
170 void LoadLootTable();
173 LootTemplateMap m_LootTemplates
;
175 char const* m_entryName
;
181 class LootGroup
; // A set of loot definitions for items (refs are not allowed inside)
182 typedef std::vector
<LootGroup
> LootGroups
;
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;
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
>
208 LootValidatorRef() {}
209 void targetObjectDestroyLink() {}
210 void sourceObjectDestroyLink() {}
213 //=====================================================
215 class LootValidatorRefManager
: public RefManager
<Loot
, LootValidatorRef
>
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 //=====================================================
232 ByteBuffer
& operator<<(ByteBuffer
& b
, LootItem
const& li
);
233 ByteBuffer
& operator<<(ByteBuffer
& b
, LootView
const& lv
);
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
;
246 LootType loot_type
; // required for achievement system
248 Loot(uint32 _gold
= 0) : gold(_gold
), unlootedCount(0), loot_type(LOOT_CORPSE
) {}
251 // if loot becomes invalid this reference is used to inform the listener
252 void addLootValidatorRef(LootValidatorRef
* pLootValidatorRef
)
254 i_LootValidatorRefManager
.insertFirst(pLootValidatorRef
);
260 for (QuestItemMap::const_iterator itr
= PlayerQuestItems
.begin(); itr
!= PlayerQuestItems
.end(); ++itr
)
262 PlayerQuestItems
.clear();
264 for (QuestItemMap::const_iterator itr
= PlayerFFAItems
.begin(); itr
!= PlayerFFAItems
.end(); ++itr
)
266 PlayerFFAItems
.clear();
268 for (QuestItemMap::const_iterator itr
= PlayerNonQuestNonFFAConditionalItems
.begin(); itr
!= PlayerNonQuestNonFFAConditionalItems
.end(); ++itr
)
270 PlayerNonQuestNonFFAConditionalItems
.clear();
272 PlayersLooting
.clear();
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;
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
;
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();