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