[2] | 1 | /* |
---|
[44] | 2 | * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> |
---|
[2] | 3 | * |
---|
[44] | 4 | * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/> |
---|
| 5 | * |
---|
[2] | 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 |
---|
[44] | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
[2] | 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 |
---|
[44] | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
[2] | 19 | */ |
---|
| 20 | |
---|
[44] | 21 | #ifndef TRINITY_LOOTMGR_H |
---|
| 22 | #define TRINITY_LOOTMGR_H |
---|
[2] | 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 HM_NAMESPACE::hash_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 |
---|