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