root/trunk/src/game/LootMgr.h @ 240

Revision 206, 12.4 kB (checked in by yumileroy, 17 years ago)

[svn] * Switch from hashmap to unordered map. - cleanup source - mangos. Help - Aokromes

Original author: KingPin?
Date: 2008-11-10 06:53:00-06:00

Line 
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
31enum 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
43enum 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
52enum PermissionTypes
53{
54    ALL_PERMISSION    = 0,
55    GROUP_PERMISSION  = 1,
56    MASTER_PERMISSION = 2,
57    NONE_PERMISSION   = 3
58};
59
60class Player;
61class LootStore;
62
63struct 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
85struct 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
107struct 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
119struct Loot;
120class LootTemplate;
121
122typedef std::vector<QuestItem> QuestItemList;
123typedef std::map<uint32, QuestItemList *> QuestItemMap;
124typedef std::vector<LootStoreItem> LootStoreItemList;
125typedef UNORDERED_MAP<uint32, LootTemplate*> LootTemplateMap;
126
127typedef std::set<uint32> LootIdSet;
128
129class 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
159class 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
185class LootValidatorRef :  public Reference<Loot, LootValidatorRef>
186{
187    public:
188        LootValidatorRef() {}
189        void targetObjectDestroyLink() {}
190        void sourceObjectDestroyLink() {}
191};
192
193//=====================================================
194
195class 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
211struct 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
284struct 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
296extern LootStore LootTemplates_Creature;
297extern LootStore LootTemplates_Fishing;
298extern LootStore LootTemplates_Gameobject;
299extern LootStore LootTemplates_Item;
300extern LootStore LootTemplates_Pickpocketing;
301extern LootStore LootTemplates_Skinning;
302extern LootStore LootTemplates_Disenchant;
303extern LootStore LootTemplates_Prospecting;
304extern LootStore LootTemplates_QuestMail;
305
306void LoadLootTemplates_Creature();
307void LoadLootTemplates_Fishing();
308void LoadLootTemplates_Gameobject();
309void LoadLootTemplates_Item();
310void LoadLootTemplates_Pickpocketing();
311void LoadLootTemplates_Skinning();
312void LoadLootTemplates_Disenchant();
313void LoadLootTemplates_Prospecting();
314void LoadLootTemplates_QuestMail();
315void LoadLootTemplates_Reference();
316
317inline 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
331ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
332ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
333#endif
Note: See TracBrowser for help on using the browser.