1 /**
2  * @file
3  * @brief common object-, inventory-, container- and firemode-related functions headers.
4  */
5 
6 /*
7 Copyright (C) 2002-2013 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23 
24 */
25 
26 #pragma once
27 
28 struct csi_s;
29 
30 /** @todo doesn't belong here, but AIRCRAFTTYPE_MAX is needed for the equipment definitions */
31 typedef enum {
32 	DROPSHIP_FIREBIRD,
33 	DROPSHIP_HERAKLES,
34 	DROPSHIP_RAPTOR,
35 
36 	INTERCEPTOR_STILETTO,
37 	INTERCEPTOR_SARACEN,
38 	INTERCEPTOR_DRAGON,
39 	INTERCEPTOR_STARCHASER,
40 	INTERCEPTOR_STINGRAY,
41 
42 	AIRCRAFTTYPE_MAX
43 } humanAircraftType_t;
44 
45 /* this is the absolute max for now */
46 #define MAX_OBJDEFS		128		/* Remember to adapt the "NONE" define (and similar) if this gets changed. */
47 #define MAX_IMPLANTS	16
48 #define MAX_MAPDEFS		256
49 #define MAX_WEAPONS_PER_OBJDEF 4
50 #define MAX_AMMOS_PER_OBJDEF 4
51 #define MAX_FIREDEFS_PER_WEAPON 8
52 #define WEAPON_BALANCE 0.5f
53 #define SKILL_BALANCE 1.0f
54 
55 typedef int32_t containerIndex_t;
56 #define CID_RIGHT		0
57 #define CID_LEFT		1
58 #define CID_IMPLANT		2
59 #define CID_HEADGEAR	3
60 #define CID_BACKPACK	4
61 #define CID_BELT		5
62 #define CID_HOLSTER		6
63 #define CID_ARMOUR		7
64 #define CID_FLOOR		8
65 #define CID_EQUIP		9
66 #define CID_MAX			10
67 
isValidContId(const containerIndex_t id)68 inline bool isValidContId(const containerIndex_t id)
69 {
70 	return (id >= 0 && id < CID_MAX);
71 }
72 
73 /** @brief Possible inventory actions for moving items between containers */
74 typedef enum {
75 	IA_NONE,			/**< no move possible */
76 
77 	IA_MOVE,			/**< normal inventory item move */
78 	IA_ARMOUR,			/**< move or swap armour */
79 	IA_RELOAD,			/**< reload weapon */
80 	IA_RELOAD_SWAP,		/**< switch loaded ammo */
81 
82 	IA_NOTIME,			/**< not enough TUs to make this inv move */
83 	IA_NORELOAD			/**< not loadable or already fully loaded */
84 } inventory_action_t;
85 
86 typedef int32_t weaponFireDefIndex_t;
87 typedef int32_t fireDefIndex_t;
88 
89 typedef enum {
90 	EFFECT_ACTIVE,
91 	EFFECT_INACTIVE,
92 	EFFECT_OVERDOSE,
93 	EFFECT_STRENGTHEN,
94 	EFFECT_MAX
95 } effectStages_t;
96 
97 typedef struct itemEffect_s {
98 	bool isPermanent;	/**< @c true if this effect does not expire */
99 	int duration;		/**< the turns that the effect is active */
100 	int period;			/**< Frequency to add attribute. This is for effects that are handled outside of the battlescape. */
101 
102 	/* all in percent */
103 	float accuracy;
104 	float TUs;
105 	float power;
106 	float mind;
107 	float morale;
108 } itemEffect_t;
109 
110 typedef struct implantDef_s {
111 	const char* id;
112 	int idx;
113 	const struct objDef_s* item;	/**< the assigned implant effect */
114 	int installationTime;	/**< the time that is needed in order to install the implant */
115 	int removeTime;			/**< the time that is needed in order to remove the implant */
116 } implantDef_t;
117 
118 /** @brief this is a fire definition for our weapons/ammo */
119 typedef struct fireDef_s {
120 	const char* name;			/**< fire definition name (translatable) */
121 	const char* projectile;		/**< projectile particle */
122 	const char* impact;			/**< impact particle */
123 	const char* impactSound;	/**< the sound that is played on impact */
124 	const char* hitBody;		/**< hit the body particles */
125 	const char* hitBodySound;	/**< the sound that is played on hitting a body */
126 	const char* fireSound;		/**< the sound when a recruits fires */
127 	const char* bounceSound;	/**< bouncing sound */
128 
129 	float fireAttenuation;		/**< attenuation of firing (less louder over distance), see S_PlaySample() */
130 	float impactAttenuation;	/**< attenuation of impact (less louder over distance), see S_PlaySample() */
131 
132 	/* These values are created in Com_ParseItem and Com_AddObjectLinks.
133 	 * They are used for self-referencing the firedef. */
134 	const struct objDef_s* obj;		/**< The weapon/ammo item this fd is located in. */
135 	weaponFireDefIndex_t weapFdsIdx;	/**< The index of the "weapon_mod" entry (objDef_t->fd[weapFdsIdx]) this fd is located in.
136 						 ** Depending on this value you can find out via objDef_t->weapIdx[weapFdsIdx] what weapon this firemode is used for.
137 						 ** This does _NOT_ equal the index of the weapon object in ods.
138 						 */
139 	fireDefIndex_t fdIdx;		/**< Self link of the fd in the objDef_t->fd[][fdIdx] array. */
140 	itemEffect_t* activeEffect;
141 	itemEffect_t* deactiveEffect;
142 	itemEffect_t* overdoseEffect;
143 
144 	bool soundOnce;		/**< when set, firing sound is played only once, see CL_ActorDoThrow() and CL_ActorShootHidden() */
145 	bool gravity;		/**< Does gravity have any influence on this item? */
146 	bool launched;		/**< used for calculating parabolas in Com_GrenadeTarget() */
147 	bool rolled;		/**< Can it be rolled - e.g. grenades - used in "Roll" firemodes, see Com_GrenadeTarget() */
148 	bool reaction;		/**< This firemode can be used/selected for reaction fire.*/
149 	bool irgoggles;		/**< Is this an irgoggle? */
150 	byte dmgweight;		/**< used in G_Damage() to apply damagetype effects - redundant with obj->dmgtype */
151 	int throughWall;	/**< allow the shooting through a wall */
152 	float speed;		/**< projectile-related; zero value means unlimited speed (most of the cases).
153 							 for that unlimited speed we use special particle (which cannot work with speed non-zero valued. */
154 	vec2_t shotOrg;		/**< This can shift a muzzle vertically (first value) and horizontally (second value) for the trace that is done on the server side. */
155 	vec2_t spread;		/**< used for accuracy calculations (G_ShootGrenade(), G_ShootSingle()) */
156 	int delay;			/**< applied on grenades and grenade launcher. If no delay is set, a touch with an actor will lead to
157 						 * an explosion or a hit of the projectile. If a delay is set, the (e.g. grenade) may bounce away again. */
158 	int bounce;			/**< amount of max possible bounces, for example grenades */
159 	float bounceFac;	/**< used in G_ShootGrenade() to apply VectorScale() effect */
160 	float crouch;		/**< used for accuracy calculations - must be greater than 0.0 */
161 	float range;		/**< range of the weapon ammunition, defined per firemode */
162 	int shots;			/**< how many shots this firemode will produce */
163 	int ammo;			/**< how many ammo this firemode will use */
164 	float delayBetweenShots;	/**< delay between shots (sounds and particles) for this firemode;
165 						 the higher the value, the less the delay (1000/delay) */
166 	int time;			/**< amount of TU used for this firemode */
167 	vec2_t damage;		/**< G_Damage(), damage[0] is min value of damage, damage[1] is used for randomized calculations
168 						 of additional damage; damage[0] < 0 means healing, not applying damage */
169 	vec2_t spldmg;		/**< G_SplashDamage(), currently we use only first value (spldmg[0]) for apply splashdamage effect */
170 	float splrad;		/**< splash damage radius */
171 	int weaponSkill;	/**< What weapon skill is needed to fire this weapon. */
172 	int rounds;			/**< e.g. for incendiary grenades */
173 } fireDef_t;
174 
175 /**
176  * @brief The max width and height of an item-shape
177  * @note these values depend on the usage of an uint32_t that has 32 bits and a width of 8bit => 4 rows
178  * @sa SHAPE_BIG_MAX_HEIGHT
179  * @sa SHAPE_BIG_MAX_WIDTH
180  * @note This is also used for bit shifting, so please don't change this until
181  * you REALLY know what you are doing
182  */
183 #define SHAPE_SMALL_MAX_WIDTH 8
184 #define SHAPE_SMALL_MAX_HEIGHT 4
185 
186 /**
187  * @brief defines the max height of an inventory container
188  * @note the max width is 32 - because uint32_t has 32 bits and we are
189  * using a bitmask for the x values
190  * @sa SHAPE_SMALL_MAX_WIDTH
191  * @sa SHAPE_SMALL_MAX_HEIGHT
192  * @note This is also used for bit shifting, so please don't change this until
193  * you REALLY know what you are doing
194  */
195 #define SHAPE_BIG_MAX_HEIGHT 16
196 /** @brief 32 bit mask */
197 #define SHAPE_BIG_MAX_WIDTH 32
198 
199 /**
200  * @brief All different types of craft items.
201  * @note must begin with weapons and end with ammos
202  * @todo move into campaign only structure
203  */
204 typedef enum {
205 	/* weapons */
206 	AC_ITEM_BASE_MISSILE,	/**< base weapon */
207 	AC_ITEM_BASE_LASER,		/**< base weapon */
208 	AC_ITEM_WEAPON,			/**< aircraft weapon */
209 
210 	/* misc */
211 	AC_ITEM_SHIELD,			/**< aircraft shield */
212 	AC_ITEM_ELECTRONICS,	/**< aircraft electronics */
213 
214 	/* Crew */
215 	AC_ITEM_PILOT,
216 
217 	/* ammos */
218 	AC_ITEM_AMMO,			/**< aircraft ammos */
219 	AC_ITEM_AMMO_MISSILE,	/**< base ammos */
220 	AC_ITEM_AMMO_LASER,		/**< base ammos */
221 
222 	MAX_ACITEMS
223 } aircraftItemType_t;
224 
225 /**
226  * @brief Aircraft parameters.
227  * @note This is a list of all aircraft parameters that depends on aircraft items.
228  * those values doesn't change with shield or weapon assigned to aircraft
229  * @note AIR_STATS_WRANGE must be the last parameter (see AII_UpdateAircraftStats)
230  * @todo move into campaign only structure
231  */
232 typedef enum {
233 	AIR_STATS_SPEED,	/**< Aircraft cruising speed. */
234 	AIR_STATS_MAXSPEED,	/**< Aircraft max speed. */
235 	AIR_STATS_SHIELD,	/**< Aircraft shield. */
236 	AIR_STATS_ECM,		/**< Aircraft electronic warfare level. */
237 	AIR_STATS_DAMAGE,	/**< Aircraft damage points (= hit points of the aircraft). */
238 	AIR_STATS_ACCURACY,	/**< Aircraft accuracy - base accuracy (without weapon). */
239 	AIR_STATS_FUELSIZE,	/**< Aircraft fuel capacity. */
240 	AIR_STATS_WRANGE,	/**< Aircraft weapon range - the maximum distance aircraft can open fire.
241 						 * for aircraft, the value is in millidegree (because this is an int) */
242 	AIR_STATS_ANTIMATTER,	/**< amount of antimatter needed for a full refill. */
243 
244 	AIR_STATS_MAX
245 } aircraftParams_t;
246 
247 /**
248  * @brief Aircraft items.
249  * @note This is a part of objDef, only filled for aircraft items (weapons, shield, electronics).
250  * @sa objDef_t
251  * @todo move into campaign only structure
252  */
253 typedef struct craftitem_s {
254 	aircraftItemType_t type;	/**< The type of the aircraft item. */
255 	float stats[AIR_STATS_MAX];	/**< All coefficient that can affect aircraft->stats */
256 	float weaponDamage;			/**< The base damage inflicted by an ammo */
257 	float weaponSpeed;			/**< The speed of the projectile on geoscape */
258 	float weaponDelay;			/**< The minimum delay between 2 shots */
259 	int installationTime;		/**< The time needed to install/remove the item on an aircraft */
260 	bool bullets;				/**< create bullets for the projectiles */
261 	bool beam;					/**< create (laser/particle) beam particles for the projectiles */
262 	vec4_t beamColor;
263 } craftItem;
264 
265 #define MAX_DAMAGETYPES 64
266 
267 /**
268  * @brief Defines all attributes of objects used in the inventory.
269  * @note See also http://ufoai.org/wiki/index.php/UFO-Scripts/weapon_%2A.ufo
270  */
271 typedef struct objDef_s {
272 	/* Common */
273 	int idx;				/**< Index of the objDef in the global item list (ods). */
274 	const char* name;		/**< Item name taken from scriptfile. */
275 	const char* id;			/**< Identifier of the item being item definition in scriptfile. */
276 	const char* model;		/**< Model name - relative to game dir. */
277 	const char* image;		/**< Object image file - relative to game dir. */
278 	const char* type;		/**< melee, rifle, ammo, armour. e.g. used in the ufopedia */
279 	const char* armourPath;
280 	uint32_t shape;			/**< The shape in inventory. */
281 
282 	float scale;			/**< scale value for images? and models */
283 	vec3_t center;			/**< origin for models */
284 	bool weapon;			/**< This item is a weapon or ammo. */
285 	bool holdTwoHanded;		/**< The soldier needs both hands to hold this object. */
286 	bool fireTwoHanded;		/**< The soldier needs both hands to fire using object. */
287 	bool headgear;			/**< This is a headgear. */
288 	bool thrown;			/**< This item can be thrown. */
289 	bool implant;			/**< This item can be implanted */
290 	itemEffect_t* strengthenEffect;
291 	bool isVirtual;			/**< virtual equipment don't show up in menus, if it's an ammo no item needed for reload */
292 	bool isPrimary;
293 	bool isSecondary;
294 	bool isHeavy;
295 	bool isMisc;
296 	bool isUGVitem;
297 	bool isDummy;
298 
299 	/* Weapon specific. */
300 	int ammo;			/**< This value is set for weapon and it says how many bullets currently loaded clip would
301 					     have, if that clip would be full. In other words, max bullets for this type of
302 					     weapon with currently loaded type of ammo. */
303 	int _reload;			/**< Time units (TUs) for reloading the weapon. */
304 	const char* reloadSound;	/**< Sound played when weapon is reloaded */
305 	float reloadAttenuation;	/**< Attenuation of reload sound - less louder over distance - */
306 	bool oneshot;		/**< This weapon contains its own ammo (it is loaded in the base).
307 						 * "int ammo" of objDef_s defines the amount of ammo used in oneshoot weapons. */
308 	bool deplete;		/**< This weapon is useless after all ("oneshot") ammo is used up.
309 						 * If true this item will not be collected on mission-end. (see INV_CollectinItems). */
310 
311 	int useable;		/**< Defines which team can use this item: TEAM_*.
312 						 * Used in checking the right team when filling the containers with available armour. */
313 
314 	const struct objDef_s* ammos[MAX_AMMOS_PER_OBJDEF];		/**< List of ammo-object pointers that can be used in this one. */
315 	int numAmmos;		/**< Number of ammos this weapon can be used with, which is <= MAX_AMMOS_PER_OBJDEF. */
316 
317 	/* Firemodes (per weapon). */
318 	const struct objDef_s* weapons[MAX_WEAPONS_PER_OBJDEF];	/**< List of weapon-object pointers where this item can be used in.
319 															 * Correct index for this array can be get from fireDef_t.weapFdsIdx. or
320 															 * getFiredefs(). */
321 	fireDef_t fd[MAX_WEAPONS_PER_OBJDEF][MAX_FIREDEFS_PER_WEAPON];	/**< List of firemodes per weapon (the ammo can be used in). */
322 	fireDefIndex_t numFiredefs[MAX_WEAPONS_PER_OBJDEF];	/**< Number of firemodes per weapon.
323 												 * Maximum value for fireDef_t.fdIdx <= MAX_FIREDEFS_PER_WEAPON. */
324 	int numWeapons;		/**< Number of weapons this ammo can be used in.
325 						 * Maximum value for fireDef_t.weapFdsIdx <= MAX_WEAPONS_PER_OBJDEF. */
326 
327 
328 	/* Armour specific */
329 	short protection[MAX_DAMAGETYPES];	/**< Protection values for each armour and every damage type. */
330 	short ratings[MAX_DAMAGETYPES];		/**< Rating values for each armour and every damage type to display in the menus. */
331 
332 	byte dmgtype;
333 	byte sx, sy;			/**< Size in x and y direction. */
334 	char animationIndex;	/**< The animation index for the character with the weapon. */
335 
336 	/**** @todo move into campaign only structure ****/
337 	/* Aircraft specific */
338 	craftItem craftitem;
339 	int price;				/**< Price for this item. */
340 	int productionCost;		/**< Production costs for this item. */
341 	int size;				/**< Size of an item, used in storage capacities. */
342 	float weight;			/**< The weight of the item */
343 	bool notOnMarket;		/**< True if this item should not be available on market. */
344 
345 
346 	uint32_t getShapeRotated () const;
347 	bool isCraftItem () const;
348 	bool isBaseDefenceItem () const;
349 	bool isLoadableInWeapon (const objDef_s* weapon) const;
isAmmoobjDef_s350 	inline bool isAmmo () const {
351 		return Q_streq(this->type, "ammo");
352 	}
isArmourobjDef_s353 	inline bool isArmour ()	const {
354 		return Q_streq(this->type, "armour");
355 	}
getReloadTimeobjDef_s356 	inline int getReloadTime () const {
357 		return _reload;
358 	}
isReloadableobjDef_s359 	inline bool isReloadable () const {
360 		return getReloadTime() > 0;
361 	}
362 
363 } objDef_t;
364 
365 /**
366  * @brief Return values for canHoldItem.
367  */
368 enum {
369 	INV_DOES_NOT_FIT		= 0,	/**< Item does not fit. */
370 	INV_FITS 				= 1,	/**< The item fits without rotation (only) */
371 	INV_FITS_ONLY_ROTATED	= 2,	/**< The item fits only when rotated (90! to the left) */
372 	INV_FITS_BOTH			= 3		/**< The item fits either rotated or not. */
373 };
374 
375 #define MAX_INVDEFS	16
376 
377 /** @brief inventory definition for our menus */
378 typedef struct invDef_s {
379 	char name[MAX_VAR];	/**< id from script files. */
380 	containerIndex_t id;				/**< Special container id. See csi_t for the values to compare it with. */
381 	/** Type of this container or inventory. */
382 	bool single;	/**< Just a single item can be stored in this container. */
383 	bool armour;	/**< Only armour can be stored in this container. */
384 	bool implant;	/**< Only implants can be stored in this container. */
385 	bool headgear;	/**< Only headgear items can be stored in this container. */
386 	bool all;		/**< Every item type can be stored in this container. */
387 	bool unique;	/**< Does not allow to put the same item more than once into the container */
388 	bool temp;		/**< This is only a pointer to another inventory definitions. */
389 	/** Scroll information. @sa Inventory */
390 	bool scroll;	/**< Set if the container is scrollable */
391 	uint32_t shape[SHAPE_BIG_MAX_HEIGHT];	/**< The inventory form/shape. */
392 	int in, out;	/**< parsed: TU costs for moving items in and out. */
393 
394 	bool isArmourDef () const;
395 	bool isFloorDef () const;
396 	bool isRightDef () const;
397 	bool isLeftDef () const;
398 	bool isEquipDef () const;
399 } invDef_t;
400 
401 #define MAX_CONTAINERS	MAX_INVDEFS
402 
403 /**
404  * @brief item instance data, with linked list capability
405  * @note the item and ammo indices are transfered as shorts over the net - a value of NONE means
406  * that there is no item - e.g. a value of NONE for the ammo means, that there is no
407  * ammo loaded or assigned to this weapon
408  */
409 class Item {
410 	const objDef_t* _itemDef;	/**< The weapon definition. */
411 	const objDef_t* _ammoDef;	/**< Pointer to ammo definition. */
412 	Item* _next;				/**< Next entry in this list. */
413 	int _x, _y;					/**< Position (aka origin location) of the item in the container/invlist.
414 								 * @note ATTENTION Do not use this to get an item by comparing it against a x/y value.
415 								 * The shape as defined in the Item may be empty at this location! */
416 	int _amount;				/**< The amount of items of this type on the same x and y location in the container */
417 	int _ammoLeft;				/**< Number of ammo rounds left - see NONE_AMMO */
418 public:
419 	int rotated;	/**< If the item is currently displayed rotated (true or 1) or not (false or 0)
420 					 * @note don't change this to anything smaller than 4 bytes - the network
421 					 * parsing functions are expecting this to be at least 4 bytes */
422 
423 
ammoDef(void)424 	inline const objDef_t* ammoDef (void) const {
425 		return _ammoDef;
426 	}
427 
setAmmoDef(const objDef_t * od)428 	inline void setAmmoDef (const objDef_t* od) {
429 		_ammoDef = od;
430 	}
431 
getAmount()432 	inline int getAmount () const {
433 		return _amount;
434 	}
435 
setAmount(int value)436 	inline void setAmount (int value) {
437 		_amount = value;
438 	}
439 
addAmount(int value)440 	inline void addAmount (int value) {
441 		_amount += value;
442 	}
443 
getAmmoLeft()444 	inline int getAmmoLeft () const {
445 		return _ammoLeft;
446 	}
447 
setAmmoLeft(int value)448 	inline void setAmmoLeft (int value) {
449 		_ammoLeft = value;
450 	}
451 
getNext()452 	inline Item* getNext () const {
453 		return _next;
454 	}
455 
setNext(Item * nx)456 	inline void setNext (Item* nx) {
457 		_next = nx;
458 	}
459 
460 	Item ();
461 	Item (const objDef_t* _itemDef, const objDef_t* ammo = nullptr, int ammoLeft = 0);
462 
getX()463 	inline int getX () const {
464 		return _x;
465 	}
466 
setX(const int val)467 	inline void setX (const int val) {
468 		_x = val;
469 	}
470 
getY()471 	inline int getY () const {
472 		return _y;
473 	}
474 
setY(const int val)475 	inline void setY (const int val) {
476 		_y = val;
477 	}
478 
setDef(const objDef_t * objDef)479 	inline void setDef(const objDef_t* objDef) {
480 		_itemDef = objDef;
481 	}
482 
def(void)483 	inline const objDef_t* def (void) const {
484 		return _itemDef;
485 	}
486 
isHeldTwoHanded()487 	inline bool isHeldTwoHanded() const {
488 		return _itemDef->holdTwoHanded;
489 	}
490 
isReloadable()491 	inline bool isReloadable() const {
492 		return _itemDef->getReloadTime() > 0;
493 	}
494 
495 	/** @todo is !mustReload() equivalent to 'usable' ?? e.g. grenades are certainly not reloadable, but do they have ammo ??? */
mustReload()496 	inline bool mustReload() const {
497 		return isReloadable() && getAmmoLeft() <= 0;
498 	}
499 
isWeapon()500 	inline bool isWeapon() const {
501 		return _itemDef->weapon;
502 	}
503 
isArmour()504 	inline bool isArmour() const {
505 		return _itemDef->isArmour();
506 	}
507 
508 	bool isSameAs (const Item* const other) const;
509 	float getWeight () const;
510 	void getFirstShapePosition (int* const x, int* const y) const;
511 	const objDef_t* getReactionFireWeaponType () const;
512 	const fireDef_t* getFiredefs () const;
513 	const fireDef_t* getSlowestFireDef () const;
514 };
515 
516 class Container
517 {
518 	const invDef_t* _def;	/* container attributes (invDef_t) */
519 public:
520 	int id;
521 	Item* _invList;	/* start of the list of items */
522 
523 	Container();
524 	const invDef_t* def () const;
525 	Item* getNextItem (const Item* prev) const;
526 	int countItems () const;
527 };
528 
529 /** @brief inventory definition with all its containers */
530 class Inventory {
531 protected:
532 	Container _containers[MAX_CONTAINERS];
533 
534 	/** @todo: convert into iterator */
535 	const Container* _getNextCont (const Container* prev) const;
536 
537 public:
538 	Inventory ();
~Inventory()539 	virtual ~Inventory() {}
540 	void init ();
541 
getContainer(const containerIndex_t idx)542 	inline const Container& getContainer (const containerIndex_t idx) const {
543 		return _containers[idx];
544 	}
545 
546 	/**
547 	 * @note temporary naming while migrating !!
548 	 * getContainer2 will return an item, while
549 	 * @todo this should return a reference - can't be null
550 	 */
getContainer2(const containerIndex_t idx)551 	inline Item* getContainer2 (const containerIndex_t idx) const {
552 		return getContainer(idx)._invList;
553 	}
554 
setContainer(const containerIndex_t idx,Item * cont)555 	inline void setContainer (const containerIndex_t idx, Item* cont) {
556 		_containers[idx]._invList = cont;
557 	}
558 
resetContainer(const containerIndex_t idx)559 	inline void resetContainer (const containerIndex_t idx) {
560 		_containers[idx]._invList = nullptr;
561 	}
resetTempContainers()562 	inline void resetTempContainers () {
563 		const Container* cont = nullptr;
564 		while ((cont = getNextCont(cont, true))) {
565 			/* CID_FLOOR and CID_EQUIP are temp */
566 			if (cont->def()->temp)
567 				resetContainer(cont->id);
568 		}
569 	}
570 
571 	/**
572 	 * @brief Searches if there is a specific item already in the inventory&container.
573 	 * @param[in] contId Container in the inventory.
574 	 * @param[in] item The item to search for.
575 	 * @return true if there already is at least one item of this type, otherwise false.
576 	 */
containsItem(const containerIndex_t contId,const Item * const item)577 	inline bool containsItem (const containerIndex_t contId, const Item* const item) const {
578 		return findInContainer(contId, item) ? true : false;
579 	}
580 
581 	Item* getArmour () const;
582 	Item* getHeadgear() const;
583 	/** @todo this should return a reference - can't be null */
584 	Item* getRightHandContainer() const;
585 	/** @todo this should return a reference - can't be null */
586 	Item* getLeftHandContainer () const;
587 	/** @todo this should return a reference - can't be null */
588 	Item* getHolsterContainer() const;
589 	/** @todo this should return a reference - can't be null */
590 	Item* getEquipContainer () const;
591 	/** @todo this should return a reference - can't be null */
592 	Item* getFloorContainer() const;
593 	void setFloorContainer(Item* cont);
594 
595 	void findSpace (const invDef_t* container, const Item* item, int* const px, int* const py, const Item* ignoredItem) const;
596 	Item* findInContainer (const containerIndex_t contId, const Item*  const item) const;
597 	Item* getItemAtPos (const invDef_t* container, const int x, const int y) const;
598 	float getWeight () const;
599 	int canHoldItem (const invDef_t* container, const objDef_t* od, const int x, const int y, const Item* ignoredItem) const;
600 	bool canHoldItemWeight (containerIndex_t from, containerIndex_t to, const Item &item, int maxWeight) const;
601 	bool holdsReactionFireWeapon () const;
602 	/** @todo convert into iterator */
603 	const Container* getNextCont (const Container* prev, bool inclTemp = false) const;
604 	int countItems () const;
605 };
606 
607 #define MAX_EQUIPDEFS   64
608 
609 typedef struct equipDef_s {
610 	char id[MAX_VAR];			/**< script id of the equipment definition */
611 	const char* name;			/**< translatable name of the equipment definition */
612 	int numItems[MAX_OBJDEFS];	/**< Number of item for each item type (see equipment_missions.ufo for more info) */
613 	byte numItemsLoose[MAX_OBJDEFS];	/**< currently only used for weapon ammo */
614 	int numAircraft[AIRCRAFTTYPE_MAX];
615 	int minInterest;			/**< Minimum overall interest to use this equipment definition (only for alien) */
616 	int maxInterest;			/**< Maximum overall interest to use this equipment definition (only for alien) */
617 
618 	void addClip(const Item* item);	/** Combine the rounds of partially used clips. */
619 } equipDef_t;
620 
621 /* Maximum number of alien teams per alien group */
622 #define MAX_TEAMS_PER_MISSION MAX_TEAMDEFS
623 
624 typedef struct damageType_s {
625 	char id[MAX_VAR];
626 	bool showInMenu;	/**< true for values that contains a translatable id */
627 } damageType_t;
628 
629 /** @todo remove this and use the container id - not every unit must have two hands */
630 typedef enum {
631 	ACTOR_HAND_NOT_SET = 0,
632 	ACTOR_HAND_RIGHT = 1,
633 	ACTOR_HAND_LEFT = 2,
634 
635 	ACTOR_HAND_ENSURE_32BIT = 0x7FFFFFFF
636 } actorHands_t;
637 
638 #define foreachhand(hand) for (int hand##__loop = 0; hand##__loop < 2; ++hand##__loop) \
639 	if (hand = (hand##__loop == 0 ? ACTOR_HAND_RIGHT : ACTOR_HAND_LEFT), false) {} else
640 
641 
642 /* ================================ */
643 /*  INVENTORY MANAGEMENT FUNCTIONS  */
644 /* ================================ */
645 
646 void INVSH_InitCSI(const struct csi_s* import) __attribute__((nonnull));
647 
648 const objDef_t* INVSH_GetItemByID(const char* id);
649 const objDef_t* INVSH_GetItemByIDX(int index);
650 const objDef_t* INVSH_GetItemByIDSilent(const char* id);
651 
652 const implantDef_t* INVSH_GetImplantForObjDef(const objDef_t* od);
653 const implantDef_t* INVSH_GetImplantByID(const char* id);
654 const implantDef_t* INVSH_GetImplantByIDSilent(const char* id);
655 
656 const invDef_t* INVSH_GetInventoryDefinitionByID(const char* id);
657 
658 #define THIS_FIREMODE(fm, HAND, fdIdx)	((fm)->getHand() == (HAND) && (fm)->getFmIdx() == (fdIdx))
659 
660 /* =============================== */
661 /*  FIREMODE MANAGEMENT FUNCTIONS  */
662 /* =============================== */
663 
664 const fireDef_t* FIRESH_GetFiredef(const objDef_t* obj, const weaponFireDefIndex_t weapFdsIdx, const fireDefIndex_t fdIdx);
665 #define FIRESH_IsMedikit(firedef) ((firedef)->damage[0] < 0)
666 void INVSH_MergeShapes(uint32_t* shape, const uint32_t itemShape, const int x, const int y);
667 bool INVSH_CheckShape(const uint32_t* shape, const int x, const int y);
668 int INVSH_ShapeSize(const uint32_t shape);
669