00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "client.h"
00028 #include "cl_inventory.h"
00029 #include "cl_inventory_callbacks.h"
00030 #include "../shared/parse.h"
00031
00041 const equipDef_t *INV_GetEquipmentDefinitionByID (const char *name)
00042 {
00043 int i;
00044
00045 for (i = 0, csi.eds; i < csi.numEDs; i++)
00046 if (!strcmp(name, csi.eds[i].name))
00047 return &csi.eds[i];
00048
00049 Com_Error(ERR_DROP, "Could not find equipment %s", name);
00050 }
00051
00064 qboolean INV_MoveItem (inventory_t* inv, const invDef_t * toContainer, int px, int py,
00065 const invDef_t * fromContainer, invList_t *fItem)
00066 {
00067 int moved;
00068
00069 if (px >= SHAPE_BIG_MAX_WIDTH || py >= SHAPE_BIG_MAX_HEIGHT)
00070 return qfalse;
00071
00072 if (!fItem)
00073 return qfalse;
00074
00075
00076 moved = cls.i.MoveInInventory(&cls.i, inv, fromContainer, fItem, toContainer, px, py, NULL, NULL);
00077
00078 switch (moved) {
00079 case IA_MOVE:
00080 case IA_ARMOUR:
00081 return qtrue;
00082 default:
00083 return qfalse;
00084 }
00085 }
00086
00094 void INV_LoadWeapon (invList_t *weapon, inventory_t *inv, const invDef_t *srcContainer, const invDef_t *destContainer)
00095 {
00096 int equipType;
00097 invList_t *ic = NULL;
00098 int i = 0;
00099
00100 assert(weapon);
00101
00102 equipType = INV_GetFilterFromItem(weapon->item.t);
00103
00104 while (i < weapon->item.t->numAmmos && !ic) {
00105 ic = INVSH_SearchInInventoryWithFilter(inv, srcContainer, NONE, NONE, weapon->item.t->ammos[i], equipType);
00106 i++;
00107 }
00108 if (ic)
00109 INV_MoveItem(inv, destContainer, weapon->x, weapon->y, srcContainer, ic);
00110 }
00111
00119 qboolean INV_UnloadWeapon (invList_t *weapon, inventory_t *inv, const invDef_t *container)
00120 {
00121 assert(weapon);
00122 if (container && inv) {
00123 const item_t item = {NONE_AMMO, NULL, weapon->item.m, 0, 0};
00124 if (cls.i.AddToInventory(&cls.i, inv, item, container, NONE, NONE, 1) != NULL) {
00125 weapon->item.m = NULL;
00126 weapon->item.a = 0;
00127 return qtrue;
00128 }
00129 }
00130 return qfalse;
00131 }
00132
00133 #ifdef DEBUG
00134
00138 static void INV_InventoryList_f (void)
00139 {
00140 int i;
00141
00142 for (i = 0; i < csi.numODs; i++) {
00143 objDef_t *od = INVSH_GetItemByIDX(i);
00144 Com_Printf("Item: %s\n", od->id);
00145 Com_Printf("... name -> %s\n", od->name);
00146 Com_Printf("... type -> %s\n", od->type);
00147 Com_Printf("... category -> %i\n", od->animationIndex);
00148 Com_Printf("... weapon -> %i\n", od->weapon);
00149 Com_Printf("... holdtwohanded -> %i\n", od->holdTwoHanded);
00150 Com_Printf("... firetwohanded -> %i\n", od->fireTwoHanded);
00151 Com_Printf("... thrown -> %i\n", od->thrown);
00152 Com_Printf("... usable for weapon (if type is ammo):\n");
00153 for (i = 0; i < od->numWeapons; i++) {
00154 if (od->weapons[i])
00155 Com_Printf(" ... %s\n", od->weapons[i]->name);
00156 }
00157 Com_Printf("\n");
00158 }
00159 }
00160 #endif
00161
00167 static qboolean INV_EquipmentDefSanityCheck (void)
00168 {
00169 int i, j;
00170 int sum;
00171 qboolean result = qtrue;
00172
00173 for (i = 0; i < csi.numEDs; i++) {
00174 const equipDef_t const *ed = &csi.eds[i];
00175
00176 if (strncmp(ed->name, "alien", 5) && strncmp(ed->name, "phalanx", 7))
00177 continue;
00178
00179
00180 sum = 0;
00181 for (j = 0; j < csi.numODs; j++) {
00182 const objDef_t const *obj = INVSH_GetItemByIDX(j);
00183 if (obj->weapon && obj->fireTwoHanded
00184 && (INV_ItemMatchesFilter(obj, FILTER_S_PRIMARY) || INV_ItemMatchesFilter(obj, FILTER_S_HEAVY)))
00185 sum += ed->numItems[j];
00186 }
00187 if (sum > 100) {
00188 Com_Printf("INV_EquipmentDefSanityCheck: Equipment Def '%s' has a total probability for primary weapons greater than 100\n", ed->name);
00189 result = qfalse;
00190 }
00191
00192
00193 sum = 0;
00194 for (j = 0; j < csi.numODs; j++) {
00195 const objDef_t const *obj = INVSH_GetItemByIDX(j);
00196 if (obj->weapon && obj->reload && !obj->deplete && INV_ItemMatchesFilter(obj, FILTER_S_SECONDARY))
00197 sum += ed->numItems[j];
00198 }
00199 if (sum > 100) {
00200 Com_Printf("INV_EquipmentDefSanityCheck: Equipment Def '%s' has a total probability for secondary weapons greater than 100\n", ed->name);
00201 result = qfalse;
00202 }
00203
00204
00205 sum = 0;
00206 for (j = 0; j < csi.numODs; j++) {
00207 const objDef_t const *obj = INVSH_GetItemByIDX(j);
00208 if (INV_ItemMatchesFilter(obj, FILTER_S_ARMOUR))
00209 sum += ed->numItems[j];
00210 }
00211 if (sum > 100) {
00212 Com_Printf("INV_EquipmentDefSanityCheck: Equipment Def '%s' has a total probability for armours greater than 100\n", ed->name);
00213 result = qfalse;
00214 }
00215
00216
00217 }
00218
00219 return result;
00220 }
00221
00222 itemFilterTypes_t INV_GetFilterFromItem (const objDef_t *obj)
00223 {
00224 assert(obj);
00225
00226
00227 if (obj->isHeavy)
00228 return FILTER_S_HEAVY;
00229 else if (obj->isPrimary)
00230 return FILTER_S_PRIMARY;
00231 else if (obj->isSecondary)
00232 return FILTER_S_SECONDARY;
00233 else if (obj->isMisc)
00234 return FILTER_S_MISC;
00235 else if (INV_IsArmour(obj))
00236 return FILTER_S_ARMOUR;
00237
00239 Sys_Error("INV_GetFilterFromItem: unknown filter category for item '%s'", obj->id);
00240 }
00241
00248 qboolean INV_ItemMatchesFilter (const objDef_t *obj, const itemFilterTypes_t filterType)
00249 {
00250 int i;
00251
00252 if (!obj)
00253 return qfalse;
00254
00255 switch (filterType) {
00256 case FILTER_S_PRIMARY:
00257 if (obj->isPrimary && !obj->isHeavy)
00258 return qtrue;
00259
00260
00261 for (i = 0; i < obj->numWeapons; i++) {
00262 if (obj->weapons[i] && obj->weapons[i] != obj && INV_ItemMatchesFilter(obj->weapons[i], filterType))
00263 return qtrue;
00264 }
00265 break;
00266
00267 case FILTER_S_SECONDARY:
00268 if (obj->isSecondary && !obj->isHeavy)
00269 return qtrue;
00270
00271
00272 for (i = 0; i < obj->numWeapons; i++) {
00273 if (obj->weapons[i] && obj->weapons[i] != obj && INV_ItemMatchesFilter(obj->weapons[i], filterType))
00274 return qtrue;
00275 }
00276 break;
00277
00278 case FILTER_S_HEAVY:
00279 if (obj->isHeavy)
00280 return qtrue;
00281
00282
00283 for (i = 0; i < obj->numWeapons; i++) {
00284 if (obj->weapons[i] && obj->weapons[i] != obj && INV_ItemMatchesFilter(obj->weapons[i], filterType))
00285 return qtrue;
00286 }
00287 break;
00288
00289 case FILTER_S_ARMOUR:
00290 return INV_IsArmour(obj);
00291
00292 case FILTER_S_MISC:
00293 return obj->isMisc;
00294
00295 case FILTER_CRAFTITEM:
00297 return INV_IsCraftItem(obj);
00298
00299 case FILTER_UGVITEM:
00300 return obj->isUGVitem;
00301
00302 case FILTER_DUMMY:
00303 return obj->isDummy;
00304
00305 case FILTER_AIRCRAFT:
00306 return !strcmp(obj->type, "aircraft");
00307
00308 case FILTER_DISASSEMBLY:
00310 break;
00311
00312 case MAX_SOLDIER_FILTERTYPES:
00313 case MAX_FILTERTYPES:
00314 case FILTER_ENSURE_32BIT:
00315 Com_Printf("INV_ItemMatchesFilter: Unknown filter type for items: %i\n", filterType);
00316 break;
00317 }
00318
00319
00320 return qfalse;
00321 }
00322
00334 invList_t *INVSH_SearchInInventoryWithFilter (const inventory_t* const i, const invDef_t * container, int x, int y, objDef_t *item, const itemFilterTypes_t filterType)
00335 {
00336 invList_t *ic;
00337
00338 if (item == NULL)
00339 return NULL;
00340
00341 for (ic = i->c[container->id]; ic; ic = ic->next) {
00342
00343 if (ic && ic->item.t && (INV_ItemMatchesFilter(ic->item.t, filterType) || filterType == MAX_FILTERTYPES)) {
00344
00345 if (item == ic->item.t)
00346 return ic;
00347 }
00348 }
00349
00350
00351 return NULL;
00352 }
00353
00356 static const char *filterTypeNames[MAX_FILTERTYPES] = {
00357 "primary",
00358 "secondary",
00359 "heavy",
00360 "misc",
00361 "armour",
00362 "",
00363 "craftitem",
00364 "ugvitem",
00365 "aircraft",
00366 "dummy",
00367 "disassembly"
00368 };
00369 CASSERT(lengthof(filterTypeNames) == MAX_FILTERTYPES);
00370
00375 itemFilterTypes_t INV_GetFilterTypeID (const char * filterTypeID)
00376 {
00377 itemFilterTypes_t i;
00378
00379 if (!filterTypeID)
00380 return MAX_FILTERTYPES;
00381
00382
00383 if (filterTypeID[0] == '\0')
00384 return FILTER_S_PRIMARY;
00385
00386 for (i = 0; i < MAX_FILTERTYPES; i++) {
00387 if (filterTypeNames[i] && !strcmp(filterTypeNames[i], filterTypeID))
00388 return i;
00389 }
00390
00391
00392 return MAX_FILTERTYPES;
00393 }
00394
00398 const char *INV_GetFilterType (const int id)
00399 {
00400 assert(id >= 0);
00401 assert(id < MAX_FILTERTYPES);
00402 return filterTypeNames[id];
00403 }
00404
00405 void INV_InitStartup (void)
00406 {
00407 #ifdef DEBUG
00408 Cmd_AddCommand("debug_listinventory", INV_InventoryList_f, "Print the current inventory to the game console");
00409 #endif
00410 INV_InitCallbacks();
00411
00412 INV_EquipmentDefSanityCheck();
00413 }
00414