#include #include "constants.h" #include "game/bondgun.h" #include "game/game_0b0fd0.h" #include "game/inv.h" #include "game/lang.h" #include "bss.h" #include "lib/main.h" #include "data.h" #include "types.h" void invClear(void) { s32 i; for (i = 0; i < g_Vars.currentplayer->equipmaxitems; i++) { g_Vars.currentplayer->equipment[i].type = -1; } g_Vars.currentplayer->weapons = NULL; g_Vars.currentplayer->equipcuritem = 0; } /** * Sorts subject into its correct position in the inventory list. * * Subject is expected to initially be at the head of the list. It works by * swapping the subject with the item to its right as many times as needed. */ void invSortItem(struct invitem *subject) { struct invitem *candidate; s32 subjweapon1 = -1; s32 subjweapon2 = -1; s32 candweapon1; s32 candweapon2; // Prepare subject's properties for comparisons if (subject->type == INVITEMTYPE_WEAP) { subjweapon1 = subject->type_weap.weapon1; } else if (subject->type == INVITEMTYPE_DUAL) { subjweapon1 = subject->type_dual.weapon1; subjweapon2 = subject->type_dual.weapon2; } else if (subject->type == INVITEMTYPE_PROP) { subjweapon1 = 2000; } candidate = subject->next; while (g_Vars.currentplayer->weapons != subject->next) { // Prepare candidate's properties for comparisons candweapon1 = -1; candweapon2 = -1; if (subject->next->type == INVITEMTYPE_WEAP) { candweapon1 = subject->next->type_weap.weapon1; } else if (subject->next->type == INVITEMTYPE_DUAL) { candweapon1 = subject->next->type_dual.weapon1; candweapon2 = subject->next->type_dual.weapon2; } else if (subject->next->type == INVITEMTYPE_PROP) { candweapon1 = 1000; } // If the candidate should sort ahead of subject // then subject is in the desired position. if (candweapon1 >= subjweapon1 && (subjweapon1 != candweapon1 || subjweapon2 <= candweapon2)) { return; } // If there's only two items in the list then there's no point swapping // them. Just set the list head to the candidate. if (candidate->next == subject) { g_Vars.currentplayer->weapons = candidate; } else { // Swap subject with candidate subject->next = candidate->next; candidate->prev = subject->prev; subject->prev = candidate; candidate->next = subject; subject->next->prev = subject; candidate->prev->next = candidate; // Set new list head if subject was the head if (subject == g_Vars.currentplayer->weapons) { g_Vars.currentplayer->weapons = candidate; } } candidate = subject->next; } } void invInsertItem(struct invitem *item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; if (prop && prop->obj) { struct textoverride *override = invGetTextOverrideForObj(prop->obj); bool setflag = true; if (override) { if (override->weapon >= WEAPON_UNARMED && override->weapon <= WEAPON_NECKLACE) { setflag = false; } if (override->weapon == WEAPON_MPSHIELD) { setflag = false; } if (override->weapon == WEAPON_SUICIDEPILL) { setflag = false; } if (override->weapon == WEAPON_BRIEFCASE2) { setflag = false; } } if (setflag && prop->type == PROPTYPE_OBJ) { struct defaultobj *obj = prop->obj; obj->flags2 |= OBJFLAG2_00040000; } } } // Place item at head of weapons list if (g_Vars.currentplayer->weapons) { item->next = g_Vars.currentplayer->weapons; item->prev = g_Vars.currentplayer->weapons->prev; item->next->prev = item; item->prev->next = item; } else { item->next = item; item->prev = item; } g_Vars.currentplayer->weapons = item; invSortItem(item); invCalculateCurrentIndex(); } void invRemoveItem(struct invitem *item) { struct invitem *next = item->next; struct invitem *prev = item->prev; if (g_Vars.currentplayer->weapons == item) { if (item == item->next) { g_Vars.currentplayer->weapons = NULL; } else { g_Vars.currentplayer->weapons = item->next; } } next->prev = prev; prev->next = next; item->type = -1; invCalculateCurrentIndex(); } struct invitem *invFindUnusedSlot(void) { s32 i; for (i = 0; i < g_Vars.currentplayer->equipmaxitems; i++) { if (g_Vars.currentplayer->equipment[i].type == -1) { return &g_Vars.currentplayer->equipment[i]; } } return NULL; } void invSetAllGuns(bool enable) { s32 weaponnum; g_Vars.currentplayer->equipallguns = enable; invCalculateCurrentIndex(); weaponnum = invGetWeaponNumByIndex(g_Vars.currentplayer->equipcuritem); bgunEquipWeapon(weaponnum); } bool invHasAllGuns(void) { return g_Vars.currentplayer->equipallguns; } struct invitem *invFindSingleWeapon(s32 weaponnum) { struct invitem *first = g_Vars.currentplayer->weapons; struct invitem *item = first; while (item) { if (item->type == INVITEMTYPE_WEAP && item->type_weap.weapon1 == weaponnum) { return item; } item = item->next; if (item == first) { break; } } return NULL; } bool invHasSingleWeaponExcAllGuns(s32 weaponnum) { return invFindSingleWeapon(weaponnum) != NULL; } struct invitem *invFindDoubleWeapon(s32 weapon1, s32 weapon2) { struct invitem *first = g_Vars.currentplayer->weapons; struct invitem *item = first; while (item) { if (item->type == INVITEMTYPE_DUAL && item->type_dual.weapon1 == weapon1 && item->type_dual.weapon2 == weapon2) { return item; } item = item->next; if (item == first) { break; } } return NULL; } bool invHasDoubleWeaponExcAllGuns(s32 weapon1, s32 weapon2) { return invFindDoubleWeapon(weapon1, weapon2) != NULL; } bool invHasSingleWeaponOrProp(s32 weaponnum) { struct invitem *item = g_Vars.currentplayer->weapons; while (item) { if (item->type == INVITEMTYPE_WEAP) { if (weaponnum == item->type_weap.weapon1) { return true; } } else if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; if (prop && prop->type == PROPTYPE_WEAPON) { struct defaultobj *obj = prop->obj; if (obj && obj->type == OBJTYPE_WEAPON) { struct weaponobj *weapon = (struct weaponobj *)prop->obj; if (weapon->weaponnum == weaponnum) { return true; } } } } item = item->next; if (item == g_Vars.currentplayer->weapons) { break; } } return false; } s32 invAddOneIfCantHaveSlayer(s32 index) { if (mainGetStageNum()); if (mainGetStageNum() != STAGE_ATTACKSHIP && mainGetStageNum() != STAGE_SKEDARRUINS && index >= WEAPON_SLAYER) { index++; } #if VERSION >= VERSION_JPN_FINAL if (index >= 26) { index++; } #endif return index; } s32 currentStageForbidsSlayer(void) { bool value = VERSION >= VERSION_JPN_FINAL ? 1 : 0; if (mainGetStageNum() != STAGE_ATTACKSHIP && mainGetStageNum() != STAGE_SKEDARRUINS) { value++; } return value; } bool invCanHaveAllGunsWeapon(s32 weaponnum) { bool canhave = true; #if VERSION == VERSION_JPN_FINAL if (weaponnum == WEAPON_COMBATKNIFE) { canhave = false; } #endif if (weaponnum == WEAPON_SLAYER) { canhave = false; } // @bug: The stage conditions need an OR. This condition can never pass. if ((mainGetStageNum() == STAGE_ATTACKSHIP && mainGetStageNum() == STAGE_SKEDARRUINS) && weaponnum == WEAPON_SLAYER) { canhave = true; } return canhave; } bool invHasSingleWeaponIncAllGuns(s32 weaponnum) { if (g_Vars.currentplayer->equipallguns && weaponnum && weaponnum <= WEAPON_PSYCHOSISGUN && invCanHaveAllGunsWeapon(weaponnum)) { return true; } return invHasSingleWeaponExcAllGuns(weaponnum); } bool invHasDoubleWeaponIncAllGuns(s32 weapon1, s32 weapon2) { if (weapon2 == WEAPON_NONE) { return true; } if (g_Vars.currentplayer->equipallguns && weapon1 <= WEAPON_PSYCHOSISGUN && weapon1 == weapon2 && weaponHasFlag(weapon1, WEAPONFLAG_DUALWIELD) && invCanHaveAllGunsWeapon(weapon1)) { return true; } return invHasDoubleWeaponExcAllGuns(weapon1, weapon2); } bool invGiveSingleWeapon(s32 weaponnum) { if (invHasSingleWeaponExcAllGuns(weaponnum) == 0) { struct invitem *item; if (g_Vars.currentplayer->equipallguns && weaponnum <= WEAPON_PSYCHOSISGUN && invCanHaveAllGunsWeapon(weaponnum)) { return false; } item = invFindUnusedSlot(); if (item) { item->type = INVITEMTYPE_WEAP; item->type_weap.weapon1 = weaponnum; item->type_weap.pickuppad = -1; invInsertItem(item); } return true; } return false; } bool invGiveDoubleWeapon(s32 weapon1, s32 weapon2) { if (invHasDoubleWeaponExcAllGuns(weapon1, weapon2) == 0) { if (weaponHasFlag(weapon1, WEAPONFLAG_DUALWIELD)) { struct invitem *item = invFindUnusedSlot(); if (item) { item->type = INVITEMTYPE_DUAL; item->type_dual.weapon1 = weapon1; item->type_dual.weapon2 = weapon2; invInsertItem(item); } return true; } else { return false; } } else { return false; } return false; } void invRemoveItemByNum(s32 weaponnum) { if (g_Vars.currentplayer->weapons) { // Begin iterating from the second item in the list. This is required // because the item might be removed from the list when iterating it, // and it needs to determine when the end of the list has been reached. struct invitem *item = g_Vars.currentplayer->weapons->next; while (true) { // Have to preload this because item->next shouldn't be trusted // after calling invRemoveItem() struct invitem *next = item->next; if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; struct textoverride *override = invGetTextOverrideForObj(prop->obj); if (override && override->weapon == weaponnum) { invRemoveItem(item); } } else if (item->type == INVITEMTYPE_WEAP) { if (item->type_weap.weapon1 == weaponnum) { invRemoveItem(item); } } else if (item->type == INVITEMTYPE_DUAL) { if (item->type_dual.weapon1 == weaponnum || item->type_dual.weapon2 == weaponnum) { invRemoveItem(item); } } if (item == g_Vars.currentplayer->weapons || !g_Vars.currentplayer->weapons) { break; } item = next; } } } bool invGiveProp(struct prop *prop) { struct invitem *item; item = invFindUnusedSlot(); if (item) { item->type = INVITEMTYPE_PROP; item->type_prop.prop = prop; invInsertItem(item); } return true; } void invRemoveProp(struct prop *prop) { if (g_Vars.currentplayer->weapons) { struct invitem *item = g_Vars.currentplayer->weapons->next; while (true) { struct invitem *next = item->next; if (item->type == INVITEMTYPE_PROP && item->type_prop.prop == prop) { invRemoveItem(item); } if (item == g_Vars.currentplayer->weapons || !g_Vars.currentplayer->weapons) { break; } item = next; } } } s32 invGiveWeaponsByProp(struct prop *prop) { s32 numgiven = 0; if (prop->type == PROPTYPE_WEAPON) { struct defaultobj *obj = prop->obj; struct weaponobj *weapon; struct weaponobj *otherweapon; s32 weaponnum; s32 otherweaponnum; if (obj->type == OBJTYPE_WEAPON) { weapon = prop->weapon; weaponnum = weapon->weaponnum; otherweaponnum; if (invGiveSingleWeapon(weaponnum)) { numgiven = 1; } if (g_Vars.normmplayerisrunning && weaponHasFlag(weaponnum, WEAPONFLAG_DUALWIELD) && !invHasDoubleWeaponExcAllGuns(weaponnum, weaponnum)) { struct invitem *invitem = invFindSingleWeapon(weaponnum); if (invitem) { if (invitem->type_weap.pickuppad < 0) { if (obj->pad >= 0) { invitem->type_weap.pickuppad = obj->pad; } } else if (obj->pad >= 0 && invitem->type_weap.pickuppad != obj->pad) { if (invGiveDoubleWeapon(weaponnum, weaponnum)) { numgiven = 2; } else { numgiven = 0; } } } } otherweapon = weapon->dualweapon; if (otherweapon) { if (weapon->base.flags & OBJFLAG_WEAPON_LEFTHANDED) { numgiven = invHasDoubleWeaponExcAllGuns(otherweapon->weaponnum, weaponnum) == 0; } else { numgiven = invHasDoubleWeaponExcAllGuns(weaponnum, otherweapon->weaponnum) == 0; } weapon->dualweapon->dualweaponnum = weaponnum; weapon->dualweapon->dualweapon = NULL; weapon->dualweapon = NULL; } else if (weapon->dualweaponnum >= 0) { if (weapon->base.flags & OBJFLAG_WEAPON_LEFTHANDED) { if (invGiveDoubleWeapon(weapon->dualweaponnum, weaponnum)) { numgiven = 2; } else { numgiven = 0; } } else { if (invGiveDoubleWeapon(weaponnum, weapon->dualweaponnum)) { numgiven = 2; } else { numgiven = 0; } } } } } return numgiven; } void invChooseCycleForwardWeapon(s32 *ptr1, s32 *ptr2, bool arg2) { s32 weapon1 = *ptr1; s32 weapon2 = *ptr2; if (g_Vars.currentplayer->equipallguns) { s32 candidate = *ptr1; if (weaponHasFlag(*ptr1, WEAPONFLAG_DUALWIELD) && *ptr2 != *ptr1) { // Switching to dual from single weapon1 = *ptr1; weapon2 = *ptr1; } else { // Find next weapon do { candidate = (candidate + 1) % NUM_CYCLEABLE_WEAPONS; if (candidate == WEAPON_NONE) { candidate = (candidate + 1) % NUM_CYCLEABLE_WEAPONS; } if ((!arg2 || bgun0f0a1a10(candidate)) && invCanHaveAllGunsWeapon(candidate)) { weapon1 = candidate; weapon2 = WEAPON_NONE; break; } } while (candidate != weapon1); } } else { struct invitem *item = g_Vars.currentplayer->weapons; while (item) { if (item->type == INVITEMTYPE_WEAP) { if (item->type_weap.weapon1 < NUM_CYCLEABLE_WEAPONS && item->type_weap.weapon1 > weapon1) { if (!arg2 || bgun0f0a1a10(item->type_weap.weapon1)) { weapon1 = item->type_weap.weapon1; weapon2 = WEAPON_NONE; break; } } } else if (item->type == INVITEMTYPE_DUAL) { if (item->type_dual.weapon1 > weapon1 || (weapon1 == item->type_dual.weapon1 && item->type_dual.weapon2 > weapon2)) { if (!arg2 || bgun0f0a1a10(item->type_dual.weapon1) || bgun0f0a1a10(item->type_dual.weapon2)) { weapon1 = item->type_dual.weapon1; weapon2 = item->type_dual.weapon2; break; } } } item = item->next; if (item == g_Vars.currentplayer->weapons) { if (arg2) { break; } weapon1 = -1; weapon2 = -1; } } } *ptr1 = weapon1; *ptr2 = weapon2; } void invChooseCycleBackWeapon(s32 *ptr1, s32 *ptr2, bool arg2) { s32 weapon1 = *ptr1; s32 weapon2 = *ptr2; if (g_Vars.currentplayer->equipallguns) { s32 candidate = *ptr1; if (weaponHasFlag(weapon1, WEAPONFLAG_DUALWIELD) && weapon1 == weapon2) { // Switching from dual to single weapon1 = candidate; weapon2 = WEAPON_NONE; } else { // Find prev weapon do { candidate = (candidate + NUM_CYCLEABLE_WEAPONS - 1) % NUM_CYCLEABLE_WEAPONS; if (candidate == WEAPON_NONE) { candidate = (candidate + NUM_CYCLEABLE_WEAPONS - 1) % NUM_CYCLEABLE_WEAPONS; } } while ((arg2 && !bgun0f0a1a10(candidate)) || !invCanHaveAllGunsWeapon(candidate)); if (weaponHasFlag(candidate, WEAPONFLAG_DUALWIELD)) { weapon1 = candidate; weapon2 = candidate; } else { weapon1 = candidate; weapon2 = WEAPON_NONE; } } } else if (g_Vars.currentplayer->weapons != NULL) { struct invitem *item = g_Vars.currentplayer->weapons->prev; while (true) { if (item->type == INVITEMTYPE_WEAP) { if (item->type_weap.weapon1 < NUM_CYCLEABLE_WEAPONS && (item->type_weap.weapon1 < weapon1 || (weapon1 == item->type_weap.weapon1 && weapon2 > 0))) { if (!arg2 || bgun0f0a1a10(item->type_weap.weapon1)) { weapon1 = item->type_weap.weapon1; weapon2 = WEAPON_NONE; break; } } } else if (item->type == INVITEMTYPE_DUAL) { if (item->type_dual.weapon1 < weapon1 || (weapon1 == item->type_dual.weapon1 && item->type_dual.weapon2 < weapon2)) { if (!arg2 || bgun0f0a1a10(item->type_dual.weapon1) || bgun0f0a1a10(item->type_dual.weapon2)) { weapon1 = item->type_dual.weapon1; weapon2 = item->type_dual.weapon2; break; } } } if (item == g_Vars.currentplayer->weapons) { if (arg2) { break; } weapon1 = 1000; weapon2 = 1000; } item = item->prev; } } *ptr1 = weapon1; *ptr2 = weapon2; } bool invHasKeyFlags(u32 wantkeyflags) { u32 heldkeyflags = 0; struct invitem *item = g_Vars.currentplayer->weapons; while (item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; if (prop && prop->type == PROPTYPE_OBJ) { struct defaultobj *obj = prop->obj; if (obj && obj->type == OBJTYPE_KEY) { struct keyobj *key = (struct keyobj *)prop->obj; heldkeyflags |= key->keyflags; if ((wantkeyflags & heldkeyflags) == wantkeyflags) { return true; } } } } item = item->next; if (item == g_Vars.currentplayer->weapons) { break; } } return false; } bool func0f11283c(void) { return false; } bool invHasBriefcase(void) { if (g_Vars.currentplayer->isdead == false) { return invHasSingleWeaponExcAllGuns(WEAPON_BRIEFCASE2); } return false; } bool invHasDataUplink(void) { if (g_Vars.currentplayer->isdead == false) { return invHasSingleWeaponExcAllGuns(WEAPON_DATAUPLINK); } return false; } bool func0f1128c4(void) { return false; } bool invHasProp(struct prop *prop) { struct invitem *item = g_Vars.currentplayer->weapons; struct prop *child; while (item) { if (item->type == INVITEMTYPE_PROP && item->type_prop.prop == prop) { return true; } item = item->next; if (item == g_Vars.currentplayer->weapons) { break; } } child = g_Vars.currentplayer->prop->child; while (child) { if (child == prop) { return true; } child = child->next; } return false; } s32 invGetCount(void) { s32 numitems = 0; struct invitem *item; if (g_Vars.currentplayer->equipallguns) { numitems = WEAPON_PSYCHOSISGUN - currentStageForbidsSlayer(); } item = g_Vars.currentplayer->weapons; while (item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; if (prop) { struct defaultobj *obj = prop->obj; if (obj) { if (prop->type == PROPTYPE_WEAPON) { if (obj->hidden & OBJHFLAG_HASTEXTOVERRIDE) { numitems++; } } else if (prop->type == PROPTYPE_OBJ) { if ((obj->flags2 & OBJFLAG2_00040000) == 0) { numitems++; } } } } } else if (item->type == INVITEMTYPE_WEAP) { if (g_Vars.currentplayer->equipallguns == false || item->type_weap.weapon1 > WEAPON_PSYCHOSISGUN) { numitems++; } } item = item->next; if (item == g_Vars.currentplayer->weapons) { break; } } return numitems; } struct invitem *invGetItemByIndex(s32 index) { struct invitem *item; if (g_Vars.currentplayer->equipallguns) { if (index < WEAPON_PSYCHOSISGUN - currentStageForbidsSlayer()) { return NULL; } index += currentStageForbidsSlayer() - WEAPON_PSYCHOSISGUN; } item = g_Vars.currentplayer->weapons; while (item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; if (prop) { struct defaultobj *obj = prop->obj; if (obj) { if (prop->type == PROPTYPE_WEAPON) { if (obj->hidden & OBJHFLAG_HASTEXTOVERRIDE) { if (index == 0) { return item; } index--; } } else if (prop->type == PROPTYPE_OBJ) { if ((obj->flags2 & OBJFLAG2_00040000) == 0) { if (index == 0) { return item; } index--; } } } } } else if (item->type == INVITEMTYPE_WEAP) { if (g_Vars.currentplayer->equipallguns == false || item->type_weap.weapon1 > WEAPON_PSYCHOSISGUN) { if (index == 0) { return item; } index--; } } item = item->next; if (item == g_Vars.currentplayer->weapons) { break; } } return NULL; } struct textoverride *invGetTextOverrideForObj(struct defaultobj *obj) { struct textoverride *override = g_Vars.textoverrides; while (override) { if (override->obj == obj) { return override; } override = override->next; } return NULL; } struct textoverride *invGetTextOverrideForWeapon(s32 weaponnum) { struct textoverride *override = g_Vars.textoverrides; while (override) { if (override->objoffset == 0 && override->weapon == weaponnum) { return override; } override = override->next; } return NULL; } s32 invGetWeaponNumByIndex(s32 index) { struct invitem *item = invGetItemByIndex(index); if (item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; struct textoverride *override = invGetTextOverrideForObj(prop->obj); if (override) { return override->weapon; } } else if (item->type == INVITEMTYPE_WEAP) { return item->type_weap.weapon1; } } else if (g_Vars.currentplayer->equipallguns) { if (index < WEAPON_PSYCHOSISGUN - currentStageForbidsSlayer()) { index++; return invAddOneIfCantHaveSlayer(index); } } return 0; } u16 invGetNameIdByIndex(s32 index) { struct invitem *item = invGetItemByIndex(index); s32 weaponnum = 0; struct textoverride *override; if (item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; override = invGetTextOverrideForObj(prop->obj); if (override) { if (override->inventorytext) { return override->inventorytext; } weaponnum = override->weapon; } } else if (item->type == INVITEMTYPE_WEAP) { weaponnum = item->type_weap.weapon1; override = invGetTextOverrideForWeapon(weaponnum); if (override && override->inventorytext) { return override->inventorytext; } } } else { if (g_Vars.currentplayer->equipallguns) { if (index < WEAPON_PSYCHOSISGUN - currentStageForbidsSlayer()) { index++; return bgunGetNameId(invAddOneIfCantHaveSlayer(index)); } } } return bgunGetNameId(weaponnum); } char *invGetNameByIndex(s32 index) { return langGet(invGetNameIdByIndex(index)); } char *invGetShortNameByIndex(s32 index) { struct invitem *item = invGetItemByIndex(index); s32 weaponnum = 0; struct textoverride *override; if (item) { if (item->type == INVITEMTYPE_PROP) { struct prop *prop = item->type_prop.prop; override = invGetTextOverrideForObj(prop->obj); if (override) { #if VERSION < VERSION_JPN_FINAL if (override->inventorytext) { return langGet(override->inventorytext); } #endif weaponnum = override->weapon; } } else if (item->type == INVITEMTYPE_WEAP) { weaponnum = item->type_weap.weapon1; #if VERSION < VERSION_JPN_FINAL override = invGetTextOverrideForWeapon(weaponnum); if (override && override->inventorytext) { return langGet(override->inventorytext); } #endif } } else if (g_Vars.currentplayer->equipallguns) { if (index < WEAPON_PSYCHOSISGUN - currentStageForbidsSlayer()) { index++; return bgunGetShortName(invAddOneIfCantHaveSlayer(index)); } } return bgunGetShortName(weaponnum); } void invInsertTextOverride(struct textoverride *override) { override->next = g_Vars.textoverrides; g_Vars.textoverrides = override; } u32 invGetCurrentIndex(void) { return g_Vars.currentplayer->equipcuritem; } void invSetCurrentIndex(u32 item) { g_Vars.currentplayer->equipcuritem = item; } void invCalculateCurrentIndex(void) { s32 curweaponnum = bgunGetWeaponNum(HAND_RIGHT); s32 i; g_Vars.currentplayer->equipcuritem = 0; for (i = 0; i < invGetCount(); i++) { if (invGetWeaponNumByIndex(i) == curweaponnum) { g_Vars.currentplayer->equipcuritem = i; break; } } } char *invGetPickupTextByObj(struct defaultobj *obj) { struct textoverride *override = invGetTextOverrideForObj(obj); if (override && override->pickuptext) { return langGet(override->pickuptext); } return NULL; } char *invGetPickupTextByWeaponNum(s32 weaponnum) { struct textoverride *override = invGetTextOverrideForWeapon(weaponnum); if (override && override->pickuptext) { return langGet(override->pickuptext); } return NULL; } void invIncrementHeldTime(s32 weapon1, s32 weapon2) { s32 leastusedtime; s32 leastusedindex; s32 i; if (!weaponHasFlag(weapon1, WEAPONFLAG_TRACKTIMEUSED)) { return; } leastusedtime = 0x7fffffff; leastusedindex = 0; if (!weaponHasFlag(weapon2, WEAPONFLAG_TRACKTIMEUSED)) { weapon2 = 0; } for (i = 0; i < ARRAYCOUNT(g_Vars.currentplayer->gunheldarr); i++) { s32 time = g_Vars.currentplayer->gunheldarr[i].totaltime240_60; if (time >= 0) { if (weapon1 == g_Vars.currentplayer->gunheldarr[i].weapon1 && weapon2 == g_Vars.currentplayer->gunheldarr[i].weapon2) { g_Vars.currentplayer->gunheldarr[i].totaltime240_60 = time + g_Vars.lvupdate60; break; } if (time < leastusedtime) { leastusedtime = time; leastusedindex = i; } } else { leastusedindex = i; i = ARRAYCOUNT(g_Vars.currentplayer->gunheldarr); break; } } if (i == ARRAYCOUNT(g_Vars.currentplayer->gunheldarr)) { g_Vars.currentplayer->gunheldarr[leastusedindex].totaltime240_60 = g_Vars.lvupdate60; g_Vars.currentplayer->gunheldarr[leastusedindex].weapon1 = weapon1; g_Vars.currentplayer->gunheldarr[leastusedindex].weapon2 = weapon2; } } void invGetWeaponOfChoice(s32 *weapon1, s32 *weapon2) { s32 mosttime = -1; s32 i; *weapon1 = 0; *weapon2 = 0; for (i = 0; i < ARRAYCOUNT(g_Vars.currentplayer->gunheldarr); i++) { if (g_Vars.currentplayer->gunheldarr[i].totaltime240_60 >= 0 && g_Vars.currentplayer->gunheldarr[i].totaltime240_60 > mosttime) { mosttime = g_Vars.currentplayer->gunheldarr[i].totaltime240_60; *weapon1 = g_Vars.currentplayer->gunheldarr[i].weapon1; *weapon2 = g_Vars.currentplayer->gunheldarr[i].weapon2; } } }