Index: src/game/inv_shared.c =================================================================== --- src/game/inv_shared.c (Revision 12046) +++ src/game/inv_shared.c (Arbeitskopie) @@ -97,7 +97,7 @@ } } -static int cache_Com_CheckToInventory = 0; +static int cache_Com_CheckToInventory = INV_DOES_NOT_FIT; /** * @brief Checks if an item-shape can be put into a container at a certain position... ignores any 'special' types. @@ -147,55 +147,54 @@ */ int Com_CheckToInventory (const inventory_t * const i, const int item, const int container, int x, int y) { - assert(i); assert((container >= 0) && (container < CSI->numIDs)); /* armor vs item */ if (!Q_strncmp(CSI->ods[item].type, "armor", MAX_VAR)) { if (!CSI->ids[container].armor && !CSI->ids[container].all) { - return 0; + return INV_DOES_NOT_FIT; } } else if (!CSI->ods[item].extension && CSI->ids[container].extension) { - return 0; + return INV_DOES_NOT_FIT; } else if (!CSI->ods[item].headgear && CSI->ids[container].headgear) { - return 0; + return INV_DOES_NOT_FIT; } else if (CSI->ids[container].armor) { - return 0; + return INV_DOES_NOT_FIT; } /* twohanded item */ if (CSI->ods[item].holdTwoHanded) { if ((container == CSI->idRight && i->c[CSI->idLeft]) || container == CSI->idLeft) - return 0; + return INV_DOES_NOT_FIT; } /* left hand is busy if right wields twohanded */ if (container == CSI->idLeft) { if (i->c[CSI->idRight] && CSI->ods[i->c[CSI->idRight]->item.t].holdTwoHanded) - return 0; + return INV_DOES_NOT_FIT; /* can't put an item that is 'fireTwoHanded' into the left hand */ if (CSI->ods[item].fireTwoHanded) - return 0; + return INV_DOES_NOT_FIT; } /* Single item containers, e.g. hands, extension or headgear. */ if (CSI->ids[container].single) { if (i->c[container]) { /* There is already an item. */ - return 0; + return INV_DOES_NOT_FIT; } else { if (Com_CheckToInventory_shape(i, container,CSI->ods[item].shape, x, y)) { /* Looks good. */ - return 1; + return INV_FITS; } else if (Com_CheckToInventory_shape(i, container, Com_ShapeRotate(CSI->ods[item].shape), x, y)) { - return 2; /* Return status "fits, but only rotated". */ + return INV_FITS_ONLY_ROTATED; /* Return status "fits, but only rotated". */ } Com_DPrintf(DEBUG_SHARED, "Com_CheckToInventory: INFO: Moving to 'single' container but item would not fit normally.\n"); - return 1; /* We are returning with status qtrue (1) if the item does not fit at all - unlikely but not impossible. */ + return INV_FITS; /* We are returning with status qtrue (1) if the item does not fit at all - unlikely but not impossible. */ } } @@ -239,6 +238,8 @@ * @param[in] container Container in given inventory definition, where the new item will be stored. * @param[in] x The x location in the container. * @param[in] y The x location in the container. + * @sa Com_RemoveFromInventory + * @sa Com_RemoveFromInventoryIgnore */ invList_t *Com_AddToInventory (inventory_t * const i, item_t item, int container, int x, int y) { @@ -276,7 +277,17 @@ * After that we can easily add the item (item.t, x and y positions) to our [t] being ic. */ + if (container == CSI->idEquip || container == CSI->idFloor) { + ic = i->c[container]; + for (; ic && ic->next; ic = ic->next) + if (ic->next->item.t == item.t) { + ic->next->item.amount++; + return ic; + } + } + /* Temporary store the pointer to the first item in this list. */ + /* not found - add a new one */ ic = i->c[container]; /* Set/overwrite first item-entry in the container to a yet empty one. */ @@ -295,6 +306,7 @@ /* Set the data in the new entry to the data we got via function-parameters.*/ ic->item = item; + ic->item.amount = 1; ic->x = x; ic->y = y; return ic; @@ -308,6 +320,7 @@ * @return qtrue If removal was successful. * @return qfalse If nothing was removed or an error occured. * @sa Com_RemoveFromInventoryIgnore + * @sa Com_AddToInventory */ qboolean Com_RemoveFromInventory (inventory_t* const i, int container, int x, int y) { @@ -340,9 +353,13 @@ } if (!ignore_type && (CSI->ids[container].single || (ic->x == x && ic->y == y))) { + cacheItem = ic->item; + if (ic->item.amount > 1) { + ic->item.amount--; + return qtrue; + } old = invUnused; invUnused = ic; - cacheItem = ic->item; i->c[container] = ic->next; if (CSI->ids[container].single && ic->next) @@ -354,6 +371,10 @@ for (; ic->next; ic = ic->next) if (ic->next->x == x && ic->next->y == y) { + if (ic->next->item.amount > 1) { + ic->next->item.amount--; + return qtrue; + } old = invUnused; invUnused = ic->next; cacheItem = ic->next->item; @@ -412,7 +433,7 @@ { invList_t *ic; int time; - int checkedTo = 0; + int checkedTo = INV_DOES_NOT_FIT; assert(to >= 0 && to < CSI->numIDs); assert(from >= 0 && from < CSI->numIDs); @@ -559,7 +580,7 @@ if (TU) *TU -= time; - if (checkedTo == 2) { + if (checkedTo == INV_FITS_ONLY_ROTATED) { /* Set rotated tag */ /** @todo remove this again when moving out of a container. */ Com_DPrintf(DEBUG_SHARED, "Com_MoveInInventoryIgnore: setting rotate tag.\n"); @@ -664,22 +685,22 @@ for (x = 0; x < SHAPE_BIG_MAX_WIDTH; x++) { checkedTo = Com_CheckToInventory(inv, item->t, container, x, y); if (checkedTo) { - if (checkedTo == 2) { + if (checkedTo == INV_FITS_ONLY_ROTATED) { /* Set rotated tag */ /** @todo remove this again when moving out of a container. */ Com_DPrintf(DEBUG_SHARED, "Com_FindSpace: setting rotate tag (%s: %s in %s)\n", CSI->ods[item->t].type, CSI->ods[item->t].id, CSI->ids[container].name); item->rotated = 1; } - cache_Com_CheckToInventory = 0; + cache_Com_CheckToInventory = INV_DOES_NOT_FIT; *px = x; *py = y; return; } else { - cache_Com_CheckToInventory = 1; + cache_Com_CheckToInventory = INV_FITS; } } } - cache_Com_CheckToInventory = 0; + cache_Com_CheckToInventory = INV_DOES_NOT_FIT; #ifdef PARANOID Com_DPrintf(DEBUG_SHARED, "Com_FindSpace: no space for %s: %s in %s\n", CSI->ods[item->t].type, CSI->ods[item->t].id, CSI->ids[container].name); Index: src/game/inv_shared.h =================================================================== --- src/game/inv_shared.h (Revision 12046) +++ src/game/inv_shared.h (Arbeitskopie) @@ -266,6 +266,12 @@ craftitem_t craftitem; } objDef_t; +enum { + INV_DOES_NOT_FIT, + INV_FITS, + INV_FITS_ONLY_ROTATED +}; + #define MAX_INVDEFS 16 /** @brief inventory definition for our menus */ @@ -290,7 +296,8 @@ int a; /**< number of ammo rounds left - see NONE_AMMO */ int m; /**< unique index of ammo type on csi->ods - see NONE */ int t; /**< unique index of weapon in csi.ods array - see NONE */ - int rotated; /**< If the item is curerntly displayed rotated (1) or not (0) */ + int amount; /**< the amount of items of this type */ + int rotated; /**< If the item is currently displayed rotated (1) or not (0) */ } item_t; /** @brief container/inventory list (linked list) with items */ Index: src/client/cl_team.c =================================================================== --- src/client/cl_team.c (Revision 12046) +++ src/client/cl_team.c (Arbeitskopie) @@ -89,7 +89,7 @@ { assert(item.t != NONE); /* Com_Printf("Add item %s to container %i (t=%i:a=%i:m=%i) (x=%i:y=%i)\n", csi.ods[item.t].id, container, item.t, item.a, item.m, x, y);*/ - MSG_WriteFormat(buf, "bbbbb", item.a, container, x, y, item.rotated); + MSG_WriteFormat(buf, "bbbbbl", item.a, container, x, y, item.rotated, item.amount); MSG_WriteString(buf, csi.ods[item.t].id); if (item.a > NONE_AMMO) MSG_WriteString(buf, csi.ods[item.m].id); @@ -126,7 +126,7 @@ item->t = item->m = NONE; item->a = NONE_AMMO; - MSG_ReadFormat(buf, "bbbbb", &item->a, container, x, y, &item->rotated); + MSG_ReadFormat(buf, "bbbbbl", &item->a, container, x, y, &item->rotated, &item->amount); itemID = MSG_ReadString(buf); item->t = INVSH_GetItemByID(itemID); if (item->a > NONE_AMMO) {