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