UFO: Alien Invasion
Loading...
Searching...
No Matches
inv_shared.cpp
Go to the documentation of this file.
1
7
8/*
9Copyright (C) 2002-2025 UFO: Alien Invasion.
10
11This program is free software; you can redistribute it and/or
12modify it under the terms of the GNU General Public License
13as published by the Free Software Foundation; either version 2
14of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20See the GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26*/
27
28#include "q_shared.h"
29
30static const csi_t* CSI;
31
39void INVSH_InitCSI (const csi_t* import)
40{
41 CSI = import;
42}
43
49{
50 return id == CID_FLOOR;
51}
52
58{
59 return id == CID_RIGHT;
60}
61
67{
68 return id == CID_LEFT;
69}
70
76{
77 return id == CID_EQUIP;
78}
79
85{
86 return id == CID_ARMOUR;
87}
88
90
99static bool INVSH_CheckShapeCollision (const uint32_t* shape, const uint32_t itemShape, const int x, const int y)
100{
101 /* Negative positions not allowed (all items are supposed to have at least one bit set in the first row and column) */
102 if (x < 0 || y < 0) {
103 Com_DPrintf(DEBUG_SHARED, "INVSH_CheckShapeCollision: x or y value negative: x=%i y=%i!\n", x, y);
104 return true;
105 }
106
107 for (int i = 0; i < SHAPE_SMALL_MAX_HEIGHT; i++) {
108 /* 0xFF is the length of one row in a "small shape" i.e. SHAPE_SMALL_MAX_WIDTH */
109 const int itemRow = (itemShape >> (i * SHAPE_SMALL_MAX_WIDTH)) & 0xFF;
110 /* Result has to be limited to 32bit (SHAPE_BIG_MAX_WIDTH) */
111 const uint32_t itemRowShifted = itemRow << x;
112
113 /* Check x maximum. */
114 if (itemRowShifted >> x != itemRow)
115 /* Out of bounds (32bit; a few bits of this row in itemShape were truncated) */
116 return true;
117
118 /* Check y maximum. */
119 if (y + i >= SHAPE_BIG_MAX_HEIGHT && itemRow)
120 /* This row (row "i" in itemShape) is outside of the max. bound and has bits in it. */
121 return true;
122
123 /* Check for collisions of the item with the big mask. */
124 if (itemRowShifted & shape[y + i])
125 return true;
126 }
127
128 return false;
129}
130
142static bool INVSH_CheckToInventory_shape (const Inventory* const inv, const invDef_t* container, const uint32_t itemShape, const int x, const int y, const Item* ignoredItem)
143{
144 static uint32_t mask[SHAPE_BIG_MAX_HEIGHT];
145
146 assert(container);
147
148 if (container->scroll)
149 Sys_Error("INVSH_CheckToInventory_shape: No scrollable container will ever use this. This type does not support grid-packing!");
150
151 /* check bounds */
152 if (x < 0 || y < 0 || x >= SHAPE_BIG_MAX_WIDTH || y >= SHAPE_BIG_MAX_HEIGHT)
153 return false;
154
156 /* extract shape info */
157 for (int j = 0; j < SHAPE_BIG_MAX_HEIGHT; j++)
158 mask[j] = ~container->shape[j];
159
160 /* Add other items to mask. (i.e. merge their shapes at their location into the generated mask) */
161 const Container& cont = inv->getContainer(container->id);
162 Item* item = nullptr;
163 while ((item = cont.getNextItem(item))) {
164 if (ignoredItem == item)
165 continue;
166
167 if (item->rotated)
168 INVSH_MergeShapes(mask, item->def()->getShapeRotated(), item->getX(), item->getY());
169 else
170 INVSH_MergeShapes(mask, item->def()->shape, item->getX(), item->getY());
171 }
172 }
173
174 /* Test for collisions with newly generated mask. */
175 if (INVSH_CheckShapeCollision(mask, itemShape, x, y))
176 return false;
177
178 /* Everything ok. */
179 return true;
180}
181
188static bool INVSH_CheckShapeSmall (const uint32_t shape, const int x, const int y)
189{
190 if (y >= SHAPE_SMALL_MAX_HEIGHT || x >= SHAPE_SMALL_MAX_WIDTH|| x < 0 || y < 0) {
191 return false;
192 }
193
194 return shape & (0x01 << (y * SHAPE_SMALL_MAX_WIDTH + x));
195}
196
203static bool INVSH_ShapeCheckPosition (const Item* item, const int x, const int y)
204{
205 assert(item);
206
207 /* Check if the position is inside the shape (depending on rotation value) of the item. */
208 uint32_t shape;
209 if (item->rotated) {
210 shape = item->def()->getShapeRotated();
211 } else {
212 shape = item->def()->shape;
213 }
214
215 return INVSH_CheckShapeSmall(shape, x - item->getX(), y - item->getY());
216}
217
227{
228 return craftitem.type != MAX_ACITEMS && !isDummy;
229}
230
240{
241 return craftitem.type != MAX_ACITEMS && isDummy;
242}
243
249const objDef_t* INVSH_GetItemByIDSilent (const char* id)
250{
251 if (!id)
252 return nullptr;
253
254 for (int i = 0; i < CSI->numODs; ++i) { /* i = item index */
255 const objDef_t* item = &CSI->ods[i];
256 if (Q_streq(id, item->id)) {
257 return item;
258 }
259 }
260 return nullptr;
261}
262
267{
268 if (index == NONE)
269 return nullptr;
270
271 if (index < 0 || index >= CSI->numODs)
272 Sys_Error("Invalid object index given: %i", index);
273
274 return &CSI->ods[index];
275}
276
282const objDef_t* INVSH_GetItemByID (const char* id)
283{
284 const objDef_t* od = INVSH_GetItemByIDSilent(id);
285 if (!od)
286 Com_Printf("INVSH_GetItemByID: Item \"%s\" not found.\n", id);
287
288 return od;
289}
290
292{
293 for (int i = 0; i < CSI->numImplants; i++) {
294 const implantDef_t* id = &CSI->implants[i];
295 if (id->item == od)
296 return id;
297 }
298 Com_Printf("INVSH_GetImplantForObjDef: could not get implant for %s\n", od->id);
299 return nullptr;
300}
301
308{
309 if (!id)
310 return nullptr;
311
312 for (int i = 0; i < CSI->numImplants; ++i) {
313 const implantDef_t* item = &CSI->implants[i];
314 if (Q_streq(id, item->id)) {
315 return item;
316 }
317 }
318 return nullptr;
319}
320
326const implantDef_t* INVSH_GetImplantByID (const char* id)
327{
328 const implantDef_t* implantDef = INVSH_GetImplantByIDSilent(id);
329 if (!implantDef)
330 Com_Printf("INVSH_GetImplantByID: Implant \"%s\" not found.\n", id);
331
332 return implantDef;
333}
334
341{
342 const invDef_t* container = CSI->ids;
343
344 for (containerIndex_t i = 0; i < CID_MAX; ++container, ++i)
345 if (Q_streq(id, container->name))
346 return container;
347
348 return nullptr;
349}
350
357{
358 assert(weapon);
359
360 /* check whether the weapon is only linked to itself. */
361 if (this->numWeapons == 1 && this->weapons[0] == this)
362 return false;
363
364 for (int i = 0; i < this->numWeapons; i++)
365 if (weapon == this->weapons[i])
366 return true;
367
368 return false;
369}
370
371/*
372===============================
373FIREMODE MANAGEMENT FUNCTIONS
374===============================
375*/
376
385const fireDef_t* FIRESH_GetFiredef (const objDef_t* obj, const weaponFireDefIndex_t weapFdsIdx, const fireDefIndex_t fdIdx)
386{
387 if (weapFdsIdx < 0 || weapFdsIdx >= MAX_WEAPONS_PER_OBJDEF)
388 Sys_Error("FIRESH_GetFiredef: weapFdsIdx out of bounds [%i] for item '%s'", weapFdsIdx, obj->id);
389 if (fdIdx < 0 || fdIdx >= MAX_FIREDEFS_PER_WEAPON)
390 Sys_Error("FIRESH_GetFiredef: fdIdx out of bounds [%i] for item '%s'", fdIdx, obj->id);
391 return &obj->fd[weapFdsIdx & (MAX_WEAPONS_PER_OBJDEF - 1)][fdIdx & (MAX_FIREDEFS_PER_WEAPON - 1)];
392}
393
402void INVSH_MergeShapes (uint32_t* shape, const uint32_t itemShape, const int x, const int y)
403{
404 for (int i = 0; (i < SHAPE_SMALL_MAX_HEIGHT) && (y + i < SHAPE_BIG_MAX_HEIGHT); ++i)
405 shape[y + i] |= ((itemShape >> i * SHAPE_SMALL_MAX_WIDTH) & 0xFF) << x;
406}
407
414bool INVSH_CheckShape (const uint32_t* shape, const int x, const int y)
415{
416 if (y >= SHAPE_BIG_MAX_HEIGHT || x >= SHAPE_BIG_MAX_WIDTH || x < 0 || y < 0) {
417 Com_Printf("INVSH_CheckShape: Bad x or y value: (x=%i, y=%i)\n", x, y);
418 return false;
419 }
420
421 const uint32_t row = shape[y];
422 const int position = powf(2.0f, (float)x);
423 if ((row & position) == 0)
424 return false;
425
426 return true;
427}
428
435int INVSH_ShapeSize (const uint32_t shape)
436{
437 int bitCounter = 0;
438
439 for (int i = 0; i < SHAPE_SMALL_MAX_HEIGHT * SHAPE_SMALL_MAX_WIDTH; ++i)
440 if (shape & (1 << i))
441 ++bitCounter;
442
443 return bitCounter;
444}
445
455static uint32_t INVSH_ShapeSetBit (uint32_t shape, const int x, const int y)
456{
457 if (x >= SHAPE_SMALL_MAX_WIDTH || y >= SHAPE_SMALL_MAX_HEIGHT || x < 0 || y < 0) {
458 Com_Printf("INVSH_ShapeSetBit: Bad x or y value: (x=%i, y=%i)\n", x,y);
459 return shape;
460 }
461
462 shape |= 0x01 << (y * SHAPE_SMALL_MAX_WIDTH + x);
463 return shape;
464}
465
466
473{
474 uint32_t shapeNew = 0;
475 int maxWidth = -1;
476
477 for (int w = SHAPE_SMALL_MAX_WIDTH - 1; w >= 0; w--) {
478 for (int h = 0; h < SHAPE_SMALL_MAX_HEIGHT; h++) {
479 if (!INVSH_CheckShapeSmall(shape, w, h))
480 continue;
481 if (w >= SHAPE_SMALL_MAX_HEIGHT) {
482 /* Object can't be rotated (code-wise), it is longer than SHAPE_SMALL_MAX_HEIGHT allows. */
483 return shape;
484 }
485
486 if (maxWidth < 0)
487 maxWidth = w;
488
489 shapeNew = INVSH_ShapeSetBit(shapeNew, h, maxWidth - w);
490 }
491 }
492
493 return shapeNew;
494}
495
498{
500 setAmount(0);
501 setAmmoDef(nullptr);
502 _itemDef = nullptr;
503 _x = _y = rotated = 0;
504 _next = nullptr;
505}
506
508Item::Item (const objDef_t* itemDef, const objDef_t* ammo, int ammoLeft)
509{
510 setAmmoLeft(ammoLeft);
511 setAmount(0);
512 setAmmoDef(ammo);
513 _itemDef = itemDef;
514 _x = _y = rotated = 0;
515 _next = nullptr;
516}
517
522int Item::getWeight () const
523{
524 int weight = def()->weight;
525 if (ammoDef() && ammoDef() != def() && getAmmoLeft() > 0) {
526 weight += ammoDef()->weight;
527 }
528 return weight;
529}
530
536bool Item::isSameAs (const Item* const other) const
537{
538 if (this == other)
539 return true;
540
541 if (other == nullptr)
542 return false;
543
544 if (this->def() == other->def() && this->ammoDef() == other->ammoDef() && this->getAmmoLeft() == other->getAmmoLeft())
545 return true;
546
547 return false;
548}
549
557void Item::getFirstShapePosition (int* const x, int* const y) const
558{
559 for (int tempX = 0; tempX < SHAPE_SMALL_MAX_HEIGHT; tempX++)
560 for (int tempY = 0; tempY < SHAPE_SMALL_MAX_HEIGHT; tempY++)
561 if (INVSH_ShapeCheckPosition(this, this->getX() + tempX, this->getY() + tempY)) {
562 *x = tempX;
563 *y = tempY;
564 return;
565 }
566
567 *x = *y = NONE;
568}
569
577{
578 const objDef_t* ammodef = ammoDef();
579 const objDef_t* weapon = def();
580
581 /* this weapon does not use ammo, check for
582 * existing firedefs in the weapon. */
583 if (weapon->numWeapons > 0)
584 ammodef = def();
585
586 if (!ammodef)
587 return nullptr;
588
589 for (int i = 0; i < ammodef->numWeapons; ++i) { /* search the weapons that this ammo supports */
590 if (weapon == ammodef->weapons[i]) /* found it ! */
591 return &ammodef->fd[i][0]; /* return the relevant part of the ammo's fireDef table */
592 }
593
594 return nullptr;
595}
596
598{
599 const fireDef_t* fdArray = getFiredefs();
600 if (!fdArray)
601 return 0;
602 const objDef_t* ammodef = this->def()->numWeapons > 0 ? def() : ammoDef();
603 return ammodef->numFiredefs[fdArray->weapFdsIdx];
604}
605
611{
612 const fireDef_t* fdArray = getFiredefs();
613 int slowest = 0;
614
615 if (fdArray == nullptr)
616 return nullptr;
617
618 for (int i = 0; i < MAX_FIREDEFS_PER_WEAPON; ++i)
619 if (fdArray[i].time > fdArray[slowest].time)
620 slowest = i;
621
622 return &fdArray[slowest];
623}
625{
626 const fireDef_t* fdArray = getFiredefs();
627 const int fdCount = getNumFiredefs();
628 int fastestTime = 999;
629 int fastest = -1;
630
631 if (fdArray == nullptr)
632 return nullptr;
633
634 for (int i = 0; i < fdCount; ++i)
635 if (fastestTime > fdArray[i].time) {
636 fastestTime = fdArray[i].time;
637 fastest = i;
638 }
639
640 return fastest == -1 ? nullptr : &fdArray[fastest];
641}
642
650{
651 if (def()) {
652 const fireDef_t* fd = getFiredefs();
653 if (fd && fd->reaction)
654 return def();
655 }
656
657 return nullptr;
658}
659
661{
662 _def = nullptr;
663 _invList = nullptr;
664 id = 0;
665}
666
668{
669 return &CSI->ids[id];
670}
671Item* Container::getNextItem (const Item* prev) const
672{
673 if (!prev)
674 return _invList; /* the first one */
675
676 return prev->getNext();
677}
678
682{
683 int nr = 0;
684 Item* item = nullptr;
685 while ((item = getNextItem(item))) {
687 ++nr;
688 }
689 return nr;
690}
691
693{
694 /* This (prototype-)constructor does not work as intended. Seems like the first inventory is created before CSI is set.
695 * There is the static game_inventory, static character_t, static le_t ...
696 * containers[CID_LEFT]._invList = nullptr;
697 * containers[CID_LEFT]._def = &CSI->ids[CID_LEFT]; */
698
699 /* Plan B: add an 'id' member to class Container and init it here */
700 init();
701}
702
704{
706 for (int i = 0; i < CID_MAX; ++i)
707 _containers[i].id = i;
708}
709
711{
712 if (!prev)
713 /* the first one */
714 return &_containers[0];
715 if (prev >= &_containers[CID_MAX - 1])
716 /* prev was the last one */
717 return nullptr;
718
719 return ++prev;
720}
721
722const Container* Inventory::getNextCont (const Container* prev, bool inclTemp) const
723{
724 const Container* cont = prev;
725
726 while ((cont = _getNextCont(cont))) {
727 /* if we don't want to include the temp containers ... */
728 if (!inclTemp) {
729 /* ...skip them ! */
730 if (cont == &_containers[CID_FLOOR])
731 continue;
732 if (cont == &_containers[CID_EQUIP])
733 continue;
734 }
735 break;
736 }
737 return cont;
738}
739
742{
743 int nr = 0;
744 const Container* cont = nullptr;
745 while ((cont = getNextCont(cont))) { /* skips the temp containers */
746 nr += cont->countItems();
747 }
748 return nr;
749}
750
761int Inventory::canHoldItem (const invDef_t* container, const objDef_t* od, const int x, const int y, const Item* ignoredItem) const
762{
763 assert(container);
764 assert(od);
765
766 /* armour vs item */
767 if (od->isArmour()) {
768 if (!container->armour && !container->all) {
769 return INV_DOES_NOT_FIT;
770 }
771 } else if (!od->implant && container->implant) {
772 return INV_DOES_NOT_FIT;
773 } else if (!od->headgear && container->headgear) {
774 return INV_DOES_NOT_FIT;
775 } else if (container->armour) {
776 return INV_DOES_NOT_FIT;
777 }
778
779 /* twohanded item */
780 if (od->holdTwoHanded) {
781 if ((container->isRightDef() && getContainer2(CID_LEFT)) || container->isLeftDef())
782 return INV_DOES_NOT_FIT;
783 }
784
785 /* left hand is busy if right wields twohanded */
786 if (container->isLeftDef()) {
787 if (getContainer2(CID_RIGHT) && getContainer2(CID_RIGHT)->isHeldTwoHanded())
788 return INV_DOES_NOT_FIT;
789
790 /* can't put an item that is 'fireTwoHanded' into the left hand */
791 if (od->fireTwoHanded)
792 return INV_DOES_NOT_FIT;
793 }
794
795 if (container->unique) {
796 const Item item(od);
797 if (containsItem(container->id, &item))
798 return INV_DOES_NOT_FIT;
799 }
800
801 /* Single item containers, e.g. hands or headgear. */
802 if (container->single) {
803 if (getContainer2(container->id)) {
804 /* There is already an item. */
805 return INV_DOES_NOT_FIT;
806 } else {
807 int fits = INV_DOES_NOT_FIT; /* equals 0 */
808
809 if (INVSH_CheckToInventory_shape(this, container, od->shape, x, y, ignoredItem))
810 fits |= INV_FITS;
811 if (INVSH_CheckToInventory_shape(this, container, od->getShapeRotated(), x, y, ignoredItem))
812 fits |= INV_FITS_ONLY_ROTATED;
813
814 if (fits != INV_DOES_NOT_FIT)
815 return fits;
816
817 Com_DPrintf(DEBUG_SHARED, "canHoldItem: INFO: Moving to 'single' container but item would not fit normally.\n");
818 return INV_FITS;
819 }
820 }
821
822 /* Scrolling container have endless room, the item always fits. */
823 if (container->scroll)
824 return INV_FITS;
825
826 /* Check 'grid' containers. */
827 int fits = INV_DOES_NOT_FIT; /* equals 0 */
828 if (INVSH_CheckToInventory_shape(this, container, od->shape, x, y, ignoredItem))
829 fits |= INV_FITS;
831 if (!container->isEquipDef() && !container->isFloorDef()
832 && INVSH_CheckToInventory_shape(this, container, od->getShapeRotated(), x, y, ignoredItem))
833 fits |= INV_FITS_ONLY_ROTATED;
834
835 return fits;
836}
837
844Item* Inventory::getItemAtPos (const invDef_t* container, const int x, const int y) const
845{
846 assert(container);
847
848 /* Only a single item. */
849 if (container->single)
850 return getContainer2(container->id);
851
852 if (container->scroll)
853 Sys_Error("getItemAtPos: Scrollable containers (%i:%s) are not supported by this function.", container->id, container->name);
854
855 /* More than one item - search for the item that is located at location x/y in this container. */
856 const Container& cont = getContainer(container->id);
857 Item* item = nullptr;
858 while ((item = cont.getNextItem(item)))
859 if (INVSH_ShapeCheckPosition(item, x, y))
860 return item;
861
862 /* Found nothing. */
863 return nullptr;
864}
865
876void Inventory::findSpace (const invDef_t* container, const Item* item, int* const px, int* const py, const Item* ignoredItem) const
877{
878 assert(container);
879 assert(!cacheCheckToInventory);
880
881 /* Scrollable container always have room. We return a dummy location. */
882 if (container->scroll) {
883 *px = *py = 0;
884 return;
885 }
886
888
889 for (int y = 0; y < SHAPE_BIG_MAX_HEIGHT; ++y) {
890 for (int x = 0; x < SHAPE_BIG_MAX_WIDTH; ++x) {
891 const int checkedTo = canHoldItem(container, item->def(), x, y, ignoredItem);
892 if (checkedTo) {
894 *px = x;
895 *py = y;
896 return;
897 } else {
899 }
900 }
901 }
903
904#ifdef PARANOID
905 Com_DPrintf(DEBUG_SHARED, "findSpace: no space for %s: %s in %s\n",
906 item->def()->type, item->def()->id, container->name);
907#endif
908 *px = *py = NONE;
909}
910
919bool Inventory::canHoldItemWeight (containerIndex_t from, containerIndex_t to, const Item& item, int maxWeight) const
920{
921 if (CSI->ids[to].temp || !CSI->ids[from].temp)
922 return true;
923
924 const int itemWeight = item.getWeight();
925 if (itemWeight < 1)
926 return true;
927 const bool swapArmour = item.isArmour() && getArmour();
928 const int invWeight = getWeight() - (swapArmour ? getArmour()->getWeight() : 0);
929
930 return (maxWeight < 0 || maxWeight * WEIGHT_FACTOR >= invWeight + itemWeight);
931}
932
938{
939 int weight = 0;
940 const Container* cont = nullptr;
941 while ((cont = getNextCont(cont))) {
942 Item* item = nullptr;
943 while ((item = cont->getNextItem(item))) {
944 weight += item->getWeight();
945 }
946 }
947 return weight;
948}
949
951{
952 setContainer(CID_FLOOR, cont);
953}
954
959
964
966{
968}
969
974
979
984
989
991{
993}
994
1001Item* Inventory::findInContainer (const containerIndex_t contId, const Item* const searchItem) const
1002{
1003 const Container& cont = getContainer(contId);
1004 Item* item = nullptr;
1005 while ((item = cont.getNextItem(item)))
1006 if (item->isSameAs(searchItem)) {
1007 return item;
1008 }
1009
1010 return nullptr;
1011}
1012
1017{
1018 if (getRightHandContainer() != nullptr && getRightHandContainer()->getReactionFireWeaponType())
1019 return true;
1020 if (getLeftHandContainer() != nullptr && getLeftHandContainer()->getReactionFireWeaponType())
1021 return true;
1022 return false;
1023}
1024
1028void equipDef_t::addClip (const Item* item)
1029{
1030 const int ammoIdx = item->ammoDef()->idx;
1031 numItemsLoose[ammoIdx] += item->getAmmoLeft();
1032 /* Accumulate loose ammo into clips */
1033 if (numItemsLoose[ammoIdx] >= item->def()->ammo) {
1034 numItemsLoose[ammoIdx] -= item->def()->ammo;
1035 numItems[ammoIdx]++;
1036 }
1037}
1038
1039void fireDef_t::getShotOrigin (const vec3_t from, const vec3_t dir, bool crouching, vec3_t shotOrigin) const
1040{
1041 const int dv = AngleToDir((int) (atan2(dir[1], dir[0]) * todeg));
1042 vec3_t dvec;
1043 VectorCopy(dvecs[dv], dvec);
1044 /* get weapon position */
1045 VectorCopy(from, shotOrigin);
1046 /* adjust height: */
1047 if (shotOrg[1] != 0) {
1048 shotOrigin[2] += shotOrg[1];
1049 if (crouching)
1050 shotOrigin[2] -= EYE_STAND - PLAYER_CROUCH - 1;
1051 }
1052 /* adjust horizontal: */
1053 if (shotOrg[0] != 0) {
1054 /* get "right" and "left" of a unit(rotate dir 90 on the x-y plane): */
1055 const float x = dvec[1];
1056 const float y = -dvec[0];
1057 const float length = sqrt(dvec[0] * dvec[0] + dvec[1] * dvec[1]);
1058 /* assign adjustments: */
1059 shotOrigin[0] += x * shotOrg[0] / length;
1060 shotOrigin[1] += y * shotOrg[0] / length;
1061 }
1062}
int countItems() const
Count the number of items in the Container.
Item * _invList
Definition inv_shared.h:516
const invDef_t * _def
Definition inv_shared.h:513
Item * getNextItem(const Item *prev) const
const invDef_t * def() const
inventory definition with all its containers
Definition inv_shared.h:525
Item * getLeftHandContainer() const
int countItems() const
Count the number of items in the inventory (without temp containers).
const Container * _getNextCont(const Container *prev) const
int canHoldItem(const invDef_t *container, const objDef_t *od, const int x, const int y, const Item *ignoredItem) const
bool canHoldItemWeight(containerIndex_t from, containerIndex_t to, const Item &item, int maxWeight) const
Check that adding an item to the inventory won't exceed the max permitted weight.
Item * getFloorContainer() const
bool holdsReactionFireWeapon() const
Checks if there is a weapon in the hands that can be used for reaction fire.
void findSpace(const invDef_t *container, const Item *item, int *const px, int *const py, const Item *ignoredItem) const
Finds space for item in inv at container.
Item * getRightHandContainer() const
bool containsItem(const containerIndex_t contId, const Item *const item) const
Searches if there is a specific item already in the inventory&container.
Definition inv_shared.h:572
Container _containers[MAX_CONTAINERS]
Definition inv_shared.h:527
Item * getEquipContainer() const
int getWeight() const
Get the weight of the items in the given inventory (excluding those in temp containers).
void setContainer(const containerIndex_t idx, Item *cont)
Definition inv_shared.h:550
Item * getHolsterContainer() const
Item * getArmour() const
Item * getImplantContainer() const
Item * getHeadgear() const
void setFloorContainer(Item *cont)
Item * getItemAtPos(const invDef_t *container, const int x, const int y) const
Searches if there is an item at location (x,y) in a container.
const Container & getContainer(const containerIndex_t idx) const
Definition inv_shared.h:537
Item * getContainer2(const containerIndex_t idx) const
Definition inv_shared.h:546
const Container * getNextCont(const Container *prev, bool inclTemp=false) const
Item * findInContainer(const containerIndex_t contId, const Item *const item) const
Searches a specific item in the inventory&container.
void init()
item instance data, with linked list capability
Definition inv_shared.h:402
bool isArmour() const
Definition inv_shared.h:489
const objDef_t * ammoDef(void) const
Definition inv_shared.h:460
int getAmmoLeft() const
Definition inv_shared.h:466
Item()
Item constructor with all default values.
int getX() const
Definition inv_shared.h:454
void setAmount(int value)
Definition inv_shared.h:438
void setAmmoDef(const objDef_t *od)
Definition inv_shared.h:435
int rotated
Definition inv_shared.h:412
const objDef_t * _itemDef
Definition inv_shared.h:403
int _x
Definition inv_shared.h:406
const fireDef_t * getFastestFireDef() const
const objDef_t * def(void) const
Definition inv_shared.h:469
const fireDef_t * getSlowestFireDef() const
Get the firedef that uses the most TU for this item.
int getY() const
Definition inv_shared.h:457
Item * _next
Definition inv_shared.h:405
int _y
Definition inv_shared.h:406
int getWeight() const
Return the weight of an item.
const fireDef_t * getFiredefs() const
Returns the firedefinitions for a given weapon/ammo.
bool isSameAs(const Item *const other) const
Check if the (physical) information of 2 items is exactly the same.
void getFirstShapePosition(int *const x, int *const y) const
Calculates the first "true" bit in the shape and returns its position in the item.
const objDef_t * getReactionFireWeaponType() const
Checks whether this item is a reaction fire enabled weapon.
int getNumFiredefs() const
void setAmmoLeft(int value)
Definition inv_shared.h:441
Item * getNext() const
Definition inv_shared.h:451
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
#define nullptr
Definition cxx.h:53
#define NONE_AMMO
Definition defines.h:69
#define NONE
Definition defines.h:68
#define DEBUG_SHARED
Definition defines.h:55
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
const objDef_t * INVSH_GetItemByIDX(int index)
Returns the item that belongs to the given index or nullptr if the index is invalid.
void INVSH_MergeShapes(uint32_t *shape, const uint32_t itemShape, const int x, const int y)
Will merge the second shape (=itemShape) into the first one (=big container shape) on the position x/...
const implantDef_t * INVSH_GetImplantByID(const char *id)
Returns the implant that belongs to the given id or nullptr if it wasn't found.
static bool INVSH_CheckToInventory_shape(const Inventory *const inv, const invDef_t *container, const uint32_t itemShape, const int x, const int y, const Item *ignoredItem)
Checks if an item-shape can be put into a container at a certain position... ignores any 'special' ty...
static const csi_t * CSI
bool INVSH_CheckShape(const uint32_t *shape, const int x, const int y)
Checks the shape if there is a 1-bit on the position x/y.
const implantDef_t * INVSH_GetImplantForObjDef(const objDef_t *od)
static int cacheCheckToInventory
static uint32_t INVSH_ShapeSetBit(uint32_t shape, const int x, const int y)
Sets one bit in a shape to true/1.
static bool INVSH_CheckShapeSmall(const uint32_t shape, const int x, const int y)
Checks the shape if there is a 1-bit on the position x/y.
const implantDef_t * INVSH_GetImplantByIDSilent(const char *id)
Returns the implant that belongs to the given id or nullptr if it wasn't found.
const fireDef_t * FIRESH_GetFiredef(const objDef_t *obj, const weaponFireDefIndex_t weapFdsIdx, const fireDefIndex_t fdIdx)
Get the fire definitions for a given object.
int INVSH_ShapeSize(const uint32_t shape)
Counts the used bits in a shape (item shape).
static bool INVSH_ShapeCheckPosition(const Item *item, const int x, const int y)
Check if a position in a container is used by an item (i.e. collides with the shape).
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
const invDef_t * INVSH_GetInventoryDefinitionByID(const char *id)
void INVSH_InitCSI(const csi_t *import)
Initializes client server shared data pointer. This works because the client and the server are both ...
static bool INVSH_CheckShapeCollision(const uint32_t *shape, const uint32_t itemShape, const int x, const int y)
Will check if the item-shape is colliding with something else in the container-shape at position x/y.
const objDef_t * INVSH_GetItemByIDSilent(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
#define CID_IMPLANT
Definition inv_shared.h:49
int32_t weaponFireDefIndex_t
Definition inv_shared.h:77
@ INV_FITS
Definition inv_shared.h:363
@ INV_DOES_NOT_FIT
Definition inv_shared.h:362
@ INV_FITS_ONLY_ROTATED
Definition inv_shared.h:364
int32_t fireDefIndex_t
Definition inv_shared.h:78
#define CID_MAX
Definition inv_shared.h:57
#define CID_ARMOUR
Definition inv_shared.h:54
#define CID_HEADGEAR
Definition inv_shared.h:50
@ MAX_ACITEMS
Definition inv_shared.h:215
int32_t containerIndex_t
Definition inv_shared.h:46
#define SHAPE_SMALL_MAX_WIDTH
The max width and height of an item-shape.
Definition inv_shared.h:176
#define MAX_FIREDEFS_PER_WEAPON
Definition inv_shared.h:42
#define SHAPE_BIG_MAX_WIDTH
32 bit mask
Definition inv_shared.h:190
#define SHAPE_BIG_MAX_HEIGHT
defines the max height of an inventory container
Definition inv_shared.h:188
#define SHAPE_SMALL_MAX_HEIGHT
Definition inv_shared.h:177
#define CID_EQUIP
Definition inv_shared.h:56
#define CID_FLOOR
Definition inv_shared.h:55
#define CID_LEFT
Definition inv_shared.h:48
#define MAX_WEAPONS_PER_OBJDEF
Definition inv_shared.h:40
#define CID_HOLSTER
Definition inv_shared.h:53
#define CID_RIGHT
Definition inv_shared.h:47
const vec4_t dvecs[PATHFINDING_DIRECTIONS]
Definition mathlib.cpp:58
int AngleToDir(int angle)
Returns the index of array directionAngles[DIRECTIONS] whose value is the closest to angle.
Definition mathlib.cpp:130
#define todeg
Definition mathlib.h:51
Common header file.
#define PLAYER_CROUCH
Definition q_sizes.h:7
#define EYE_STAND
Definition q_sizes.h:4
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition r_gl.h:110
QGL_EXTERN GLuint index
Definition r_gl.h:110
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint * id
Definition r_gl.h:86
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
The csi structure is the client-server-information structure which contains all the static data neede...
Definition q_shared.h:515
int numItems[MAX_OBJDEFS]
Definition inv_shared.h:608
byte numItemsLoose[MAX_OBJDEFS]
Definition inv_shared.h:609
void addClip(const Item *item)
Combine the rounds of partially used clips.
this is a fire definition for our weapons/ammo
Definition inv_shared.h:110
bool reaction
Definition inv_shared.h:139
vec2_t shotOrg
Definition inv_shared.h:145
weaponFireDefIndex_t weapFdsIdx
Definition inv_shared.h:126
void getShotOrigin(const vec3_t from, const vec3_t dir, bool crouching, vec3_t shotOrigin) const
const char * id
Definition inv_shared.h:102
inventory definition for our menus
Definition inv_shared.h:371
bool isFloorDef() const
Checks whether the inventory definition is the floor.
uint32_t shape[SHAPE_BIG_MAX_HEIGHT]
Definition inv_shared.h:384
bool scroll
Definition inv_shared.h:383
char name[MAX_VAR]
Definition inv_shared.h:372
bool isArmourDef() const
Checks whether a given inventory definition is of special type.
bool isLeftDef() const
Checks whether a given inventory definition is of special type.
bool unique
Definition inv_shared.h:380
bool headgear
Definition inv_shared.h:378
bool isEquipDef() const
Checks whether a given inventory definition is of special type.
containerIndex_t id
Definition inv_shared.h:373
bool single
Definition inv_shared.h:375
bool implant
Definition inv_shared.h:377
bool isRightDef() const
Checks whether the inventory definition is the right Hand.
bool armour
Definition inv_shared.h:376
Defines all attributes of objects used in the inventory.
Definition inv_shared.h:264
uint32_t getShapeRotated() const
Rotates a shape definition 90 degree to the left (CCW).
const char * type
Definition inv_shared.h:271
bool holdTwoHanded
Definition inv_shared.h:278
uint32_t shape
Definition inv_shared.h:273
bool isBaseDefenceItem() const
Checks whether the item is a basedefence item.
bool weapon
Definition inv_shared.h:277
bool headgear
Definition inv_shared.h:280
fireDef_t fd[MAX_WEAPONS_PER_OBJDEF][MAX_FIREDEFS_PER_WEAPON]
Definition inv_shared.h:314
bool isDummy
Definition inv_shared.h:290
fireDefIndex_t numFiredefs[MAX_WEAPONS_PER_OBJDEF]
Definition inv_shared.h:315
bool isLoadableInWeapon(const objDef_s *weapon) const
Checks if an item can be used to reload a weapon.
bool fireTwoHanded
Definition inv_shared.h:279
craftItem craftitem
Definition inv_shared.h:331
bool implant
Definition inv_shared.h:282
const char * id
Definition inv_shared.h:268
bool isArmour() const
Definition inv_shared.h:346
int numWeapons
Definition inv_shared.h:317
const struct objDef_s * weapons[MAX_WEAPONS_PER_OBJDEF]
Definition inv_shared.h:311
bool isCraftItem() const
Checks whether a given item is an aircraftitem item.
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorCopy(src, dest)
Definition vector.h:51