1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 * Declares Inventory, class implementing creatures' and containers'
24 * inventory and item management
25 * @author The GemRB Project
35 #include "Item.h" //needs item for itmextheader
42 //AddSlotItem return values
46 #define ASI_SWAPPED 3 //not returned normally, but Gui uses this value
48 //AddSlotItem extra slot ID's
49 #define SLOT_AUTOEQUIP -1
50 #define SLOT_ONLYINVENTORY -3
52 //slottypes (bitfield)
58 #define SLOT_AMULET 32
61 #define SLOT_WEAPON 256
62 #define SLOT_QUIVER 512
63 #define SLOT_CLOAK 1024
64 #define SLOT_ITEM 2048 //quick item
65 #define SLOT_SCROLL 4096
67 #define SLOT_POTION 16384
68 #define SLOT_ANY 32767
69 #define SLOT_INVENTORY 32768
72 //weapon slot types (1000==not equipped)
73 #define IW_NO_EQUIPPED 1000
75 /** Inventory types */
76 typedef enum ieInventoryType
{
78 INVENTORY_CREATURE
= 1
81 // !!! Keep these synchronized with GUIDefines.py !!!
82 typedef enum ieCREItemFlagBits
{
83 IE_INV_ITEM_IDENTIFIED
= 1,
84 IE_INV_ITEM_UNSTEALABLE
= 2,
85 IE_INV_ITEM_STOLEN
= 4,
86 //in iwd/iwd2 this flag means 'magical', some hack is needed
87 IE_INV_ITEM_UNDROPPABLE
=8,
88 //just recently acquired
89 IE_INV_ITEM_ACQUIRED
= 0x10, //this is a gemrb extension
90 //is this item destructible normally?
91 IE_INV_ITEM_DESTRUCTIBLE
= 0x20,//this is a gemrb extension
92 //is this item already equipped?
93 IE_INV_ITEM_EQUIPPED
= 0x40, //this is a gemrb extension
94 //selected for sale, using the same bit, hope it is ok
95 IE_INV_ITEM_SELECTED
= 0x40, //this is a gemrb extension
96 //is this item stackable?
97 IE_INV_ITEM_STACKED
= 0x80, //this is a gemrb extension
98 //these flags are coming from the original item, but these are immutable
99 IE_INV_ITEM_CRITICAL
= 0x100, //coming from original item
100 IE_INV_ITEM_TWOHANDED
= 0x200,
101 IE_INV_ITEM_MOVABLE
= 0x400, //same as undroppable
102 IE_INV_ITEM_RESELLABLE
= 0x800, //item will appear in shop when sold
103 IE_INV_ITEM_CURSED
= 0x1000, //item is cursed
104 IE_INV_ITEM_UNKNOWN2000
= 0x2000, //totally unknown
105 IE_INV_ITEM_MAGICAL
= 0x4000, //magical
106 IE_INV_ITEM_BOW
= 0x8000, //
107 IE_INV_ITEM_SILVER
= 0x10000,
108 IE_INV_ITEM_COLDIRON
= 0x20000,
109 IE_INV_ITEM_STOLEN2
= 0x40000, //same as 4
110 IE_INV_ITEM_CONVERSIBLE
= 0x80000,
111 IE_INV_ITEM_PULSATING
= 0x100000
114 #define IE_INV_DEPLETABLE (IE_INV_ITEM_MAGICAL|IE_INV_ITEM_DESTRUCTIBLE)
118 #define EQUIP_MELEE 1
119 #define EQUIP_RANGED 2
122 //actually this header shouldn't be THIS large, i was just
123 //lazy to pick the interesting elements
124 //it could be possible that some elements need to be added from the
126 struct ItemExtHeader
{
138 ieWord ProjectileType
;
146 ieWord FeatureOffset
;
148 ieWord ChargeDepletion
;
149 ieDword RechargeFlags
; //this is a bitfield with many bits
150 ieWord ProjectileAnimation
;
151 ieWord MeleeAnimation
[3];
152 int ProjectileQualifier
; //this is a derived value determined on load time
159 * Class holding Item instance specific values and providing link between
160 * an Inventory and a stack of Items.
161 * It's keeping info on whether Item was identified, for example.
164 class GEM_EXPORT CREItem
{
167 //recent research showed that this field is used by the create item
168 //for days effect. This field shows the expiration in gametime hours
170 ieWord Usages
[CHARGE_COUNTERS
];
172 // 2 cached values from associated item. LEAVE IT SIGNED!
173 /** Weight of items in the stack */
175 /** Amount of items in this stack */
180 Weight
=-1; //invalid weight
187 * Class implementing creatures' and containers' inventory and item management
190 class GEM_EXPORT Inventory
{
192 std::vector
<CREItem
*> Slots
;
196 /** Total weight of all items in Inventory */
199 ieWordSigned Equipped
;
200 ieWord EquippedHeader
;
201 /** this isn't saved */
205 virtual ~Inventory();
207 /** Removes an item from the inventory, destroys slot.
208 * Use it for containers only */
209 CREItem
*GetItem(unsigned int idx
);
210 /** adds an item to the inventory */
211 void AddItem(CREItem
*item
);
212 /** Returns number of items in the inventory */
213 int CountItems(const char *resref
, bool charges
) const;
214 /** looks for a particular item in a slot */
215 bool HasItemInSlot(const char *resref
, unsigned int slot
) const;
216 /** Looks for a particular item in the inventory. */
217 /* flags: see ieCREItemFlagBits */
218 bool HasItem(const char *resref
, ieDword flags
) const;
220 void CalculateWeight(void);
221 void SetInventoryType(int arg
);
222 void SetOwner(Actor
* act
) { Owner
= act
; }
224 /** returns number of all slots in the inventory */
225 int GetSlotCount() const { return (int)Slots
.size(); }
227 /** sets inventory size, for the first time */
228 void SetSlotCount(unsigned int size
);
231 /** Returns CREItem in specified slot.
232 * If count !=0 it splits the item and returns only requested amount */
233 CREItem
* RemoveItem(unsigned int slot
, unsigned int count
= 0);
234 /** returns slot of removed item, you can delete the removed item */
235 int RemoveItem(const char* resref
, unsigned int flags
, CREItem
**res_item
);
237 /** adds CREItem to the inventory. If slot == -1, finds
238 ** first eligible slot, eventually splitting the item to
239 ** more slots. If slot == -3 then finds the first empty inventory slot
240 ** Returns 2 if completely successful, 1 if partially, 0 else.
241 ** slottype is an optional filter for searching eligible slots */
242 int AddSlotItem(CREItem
* item
, int slot
, int slottype
=-1);
243 /** Adds STOItem to the inventory, it is never wielded, action might be STA_STEAL or STA_BUY */
244 /** The amount of items is stored in PurchasedAmount */
245 int AddStoreItem(STOItem
* item
, int action
);
247 /** flags: see ieCREItemFlagBits */
248 /** count == ~0 means to destroy all */
249 /** returns the number of destroyed items */
250 unsigned int DestroyItem(const char *resref
, ieDword flags
, ieDword count
);
251 /** flags: see ieCREItemFlagBits */
252 void SetItemFlags(CREItem
* item
, ieDword flags
);
253 void SetSlotItem(CREItem
* item
, unsigned int slot
);
254 int GetWeight() const {return Weight
;}
256 bool ItemsAreCompatible(CREItem
* target
, CREItem
* source
) const;
257 //depletes charged items
258 int DepleteItem(ieDword flags
);
259 //charges recharging items
260 void ChargeAllItems(int hours
);
261 /** Finds the first slot of named item, if resref is empty, finds the first filled! slot */
262 int FindItem(const char *resref
, unsigned int flags
) const;
263 bool DropItemAtLocation(unsigned int slot
, unsigned int flags
, Map
*map
, const Point
&loc
);
264 bool DropItemAtLocation(const char *resref
, unsigned int flags
, Map
*map
, const Point
&loc
);
265 bool SetEquippedSlot(ieWordSigned slotcode
, ieWord header
);
266 int GetEquipped() const;
267 int GetEquippedHeader() const;
269 int GetEquippedSlot() const;
271 int GetShieldSlot() const;
272 void AddSlotEffects( ieDword slot
);
273 //void AddAllEffects();
274 /** Returns item in specified slot. Does NOT change inventory */
275 CREItem
* GetSlotItem(ieDword slot
) const;
276 /** Returns the item's inventory flags */
277 ieDword
GetItemFlag(unsigned int slot
) const;
278 /** Changes the inventory flags */
279 bool ChangeItemFlag(ieDword slot
, ieDword value
, int mode
);
280 /** Equips the item, don't use it directly for weapons */
281 bool EquipItem(ieDword slot
);
282 bool UnEquipItem(ieDword slot
, bool removecurse
);
283 /** Returns equipped weapon, also its slot */
284 CREItem
*GetUsedWeapon(bool leftorright
, int &slot
) const;
285 /** returns slot of launcher weapon currently equipped */
286 int FindRangedWeapon() const;
287 /** returns slot of launcher weapon for specified projectile type */
288 int FindTypedRangedWeapon(unsigned int type
) const;
289 /** returns slot of launcher weapon for projectile in specified slot */
290 int FindSlotRangedWeapon(ieDword slot
) const;
291 /** Returns a slot which might be empty, or capable of holding item (or part of it) */
292 int FindCandidateSlot(int slottype
, size_t first_slot
, const char *resref
= NULL
);
293 /** Creates an item in the slot*/
294 void SetSlotItemRes(const ieResRef ItemResRef
, int Slot
, int Charge0
=1, int Charge1
=0, int Charge2
=0);
295 /** Adds item to slot*/
296 void AddSlotItemRes(const ieResRef ItemResRef
, int Slot
, int Charge0
=1, int Charge1
=0, int Charge2
=0);
297 /** breaks the item (weapon) in slot */
298 void BreakItemSlot(ieDword slot
);
299 /** Lists all items in the Inventory on terminal for debugging */
301 /** Equips best weapon */
302 void EquipBestWeapon(int flags
);
303 /** returns the struct of the usable items, returns true if there are more */
304 bool GetEquipmentInfo(ItemExtHeader
*array
, int startindex
, int count
);
305 /** returns the exclusion bits */
306 ieDword
GetEquipExclusion(int index
) const;
307 /** returns if a slot is temporarily blocked */
308 bool IsSlotBlocked(int slot
) const;
309 /** returns true if a two handed weapon is in slot */
310 inline bool TwoHandedInSlot(int slot
) const;
311 /** returns the strref for the reason why the item cannot be equipped */
312 int WhyCantEquip(int slot
, int twohanded
) const;
313 //setting important constants
314 static void Init(int mb
);
315 static void SetHeadSlot(int arg
);
316 static void SetFistSlot(int arg
);
317 static void SetMagicSlot(int arg
);
318 static void SetWeaponSlot(int arg
);
319 static void SetRangedSlot(int arg
);
320 static void SetQuickSlot(int arg
);
321 static void SetInventorySlot(int arg
);
322 static void SetShieldSlot(int arg
);
323 static int GetHeadSlot();
324 static int GetFistSlot();
325 static int GetMagicSlot();
326 static int GetWeaponSlot();
327 static int GetRangedSlot();
328 static int GetQuickSlot();
329 static int GetInventorySlot();
331 int FindRangedProjectile(unsigned int type
) const;
332 // called by KillSlot
333 void RemoveSlotEffects( /*CREItem* slot*/ ieDword slot
);
334 void KillSlot(ieDword index
);
335 inline Item
*GetItemPointer(ieDword slot
, CREItem
*&Slot
) const;
336 void UpdateWeaponAnimation();
337 void UpdateShieldAnimation(Item
*it
);