From 24971ff6ff10f9f6e4cecf97f63cc3c1aacaf264 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 2 Jan 2022 10:44:57 +1000 Subject: [PATCH] Attempt to decompile botFindPickup --- src/game/bondgun.c | 2 +- src/game/bot.c | 516 +++++++++++++++++++++++++++++++++++-- src/game/botact.c | 4 +- src/game/botinv.c | 213 +++++++-------- src/include/game/bondgun.h | 2 +- src/include/game/bot.h | 8 +- src/include/game/botact.h | 4 +- src/include/game/botinv.h | 2 +- src/include/types.h | 21 +- 9 files changed, 619 insertions(+), 153 deletions(-) diff --git a/src/game/bondgun.c b/src/game/bondgun.c index 273e8175f..4e57eef96 100644 --- a/src/game/bondgun.c +++ b/src/game/bondgun.c @@ -28979,7 +28979,7 @@ s32 bgunGetAmmoCount(s32 ammotype) return total; } -s32 bgunGetCapacityByAmmotype(u32 ammotype) +s32 bgunGetCapacityByAmmotype(s32 ammotype) { return g_AmmoTypes[ammotype].capacity; } diff --git a/src/game/bot.c b/src/game/bot.c index 84dd0128e..14047546b 100644 --- a/src/game/bot.c +++ b/src/game/bot.c @@ -33,6 +33,10 @@ #include "data.h" #include "types.h" +#define PICKUPCRITERIA_DEFAULT 0 +#define PICKUPCRITERIA_CRITICAL 1 +#define PICKUPCRITERIA_ANY 2 + struct chrdata *g_MpBotChrPtrs[MAX_SIMULANTS]; u8 g_BotCount = 0; @@ -6756,22 +6760,486 @@ glabel var7f1b8f50 ); #endif -bool bot0f194670(struct chrdata *chr) +#define HASENOUGHPRI(aibot, weaponnum, goal) (g_AibotWeaponPreferences[weaponnum].haspriammogoal && botactGetAmmoQuantityByWeapon(aibot, weaponnum, FUNC_PRIMARY, true) >= (goal)) +#define HASENOUGHSEC(aibot, weaponnum, goal) (g_AibotWeaponPreferences[weaponnum].hassecammogoal && botactGetAmmoQuantityByWeapon(aibot, weaponnum, FUNC_SECONDARY, true) >= (goal)) + +/** + * Find a prop for the bot to pick up. + * + * Criteria can be: + * + * PICKUPCRITERIA_DEFAULT: + * This is the most common criteria. It is used when the bot has spawned and + * is gathering weapons, as well as when they return to their main loop. + * + * PICKUPCRITERIA_CRITICAL: + * Find props only if the bot needs them critically, eg if they are low on + * shield or ammo. This is used when the bot has other things it can be + * doing such as scenario objectives and has to decide between the two. + * + * PICKUPCRITERIA_ANY: + * Find pretty much any prop. This is used when the bot has nothing else to + * do (eg. if all opponents are cloaked) and may as well stock up on ammo. + */ +// Mismatch: The below uses a1/a2/a3 for aibot/criteria/1 near ce8 +// while goal loads them from the stack when used +//struct prop *botFindPickup(struct chrdata *chr, s32 criteria) +//{ +// struct aibot *aibot = chr->aibot; // 274 +// s32 weaponnums[6]; // 25c +// s32 scores1[6]; // 244 +// s32 scores2[6]; // 22c +// struct prop *weapproplist[6]; // 214 +// f32 weapdistlist[6]; // 1fc +// struct prop *ammoproplist[33]; // 178 +// f32 ammodistlist[33]; // f4 +// struct invitem *invitems[6]; // dc +// s32 i; // d8 +// s32 j; +// u32 stack[2]; +// struct prop *chosenprop = NULL; // c8 +// bool barelydominatinghill = false; // c4 +// s32 numteam; +// s32 numopponents; +// f32 healthlimit; +// f32 shieldlimit; +// s32 priammogoal; +// s32 secammogoal; +// bool include_equipped; +// s32 ammotype; +// s32 bestscore1; // a0 +// bool done; // 9c +// struct prop *prop; +// +// // 7f0 +// // If the hill has one or two bots from the same team in it, the bots will +// // be less likely to leave the hill for pickups (barelydominatinghill = true). +// // If there are three or more then this limitation is removed. +// // The amount increases if there are opponents in the hill too. +// if (aibot->teamisonlyai +// && g_MpSetup.scenario == MPSCENARIO_KINGOFTHEHILL +// && chr->prop->rooms[0] == g_ScenarioData.koh.hillrooms[0]) { +// numteam = botGetNumTeammatesDefendingHill(chr); +// numopponents = botGetNumOpponentsInHill(chr); +// +// if (numteam >= numopponents && numteam <= numopponents + 2) { +// barelydominatinghill = true; +// } +// } +// +// // 850 +// botinvScoreAllWeapons(chr, weaponnums, scores1, scores2); +// +// for (i = 0; i < 6; i++) { +// weapproplist[i] = NULL; +// } +// +// for (i = 0; i < 33; i++) { +// ammoproplist[i] = NULL; +// } +// +// for (i = 0; i < 6; i++) { +// invitems[i] = botinvGetItem(chr, weaponnums[i]); +// } +// +// // Iterate all active props and populate the proplist and distlist arrays. +// // Generally these arrays are populated with the closest prop of each weapon +// // and ammotype, however there's a 1/16 chance that any prop will be skipped +// // and a 1/16 chance that a further prop will overwrite the current closest. +// prop = g_Vars.activeprops; +// +// // 8e0 +// while (prop) { +// if (prop->parent == NULL && prop->timetoregen == 0) { +// if (prop->type == PROPTYPE_WEAPON) { +// struct weaponobj *weapon = prop->weapon; +// +// if ((weapon->base.flags3 & OBJFLAG3_ISFETCHTARGET) == 0) { +// f32 sqdist = chrGetSquaredDistanceToCoord(chr, &prop->pos); +// s32 ammotype; +// +// for (i = 0; i < 6; i++) { +// if (weaponnums[i] > WEAPON_UNARMED && weaponnums[i] == weapon->weaponnum) { +// if (random() % 16) { +// if (weapproplist[i] == NULL || sqdist < weapdistlist[i] || random() % 16 == 0) { +// weapproplist[i] = prop; +// weapdistlist[i] = sqdist; +// } +// } +// break; +// } +// } +// +// ammotype = botactGetAmmoTypeByFunction(weapon->weaponnum, FUNC_PRIMARY); +// +// if (ammotype > 0 && random() % 16) { +// if (ammoproplist[ammotype] == NULL || sqdist < ammodistlist[ammotype] || random() % 16 == 0) { +// ammoproplist[ammotype] = prop; +// ammodistlist[ammotype] = sqdist; +// } +// } +// } +// } else if (prop->type == PROPTYPE_OBJ) { +// struct defaultobj *obj = prop->obj; +// f32 sqdist; +// +// if ((obj->flags3 & OBJFLAG3_ISFETCHTARGET) == 0) { +// if (obj->type == OBJTYPE_MULTIAMMOCRATE) { +// struct multiammocrateobj *crate = (struct multiammocrateobj *)prop->obj; +// sqdist = chrGetSquaredDistanceToCoord(chr, &prop->pos); +// +// for (i = 0; i < 19; i++) { +// s32 ammotype = i + 1; +// +// if (crate->slots[i].quantity > 0) { +// s32 weaponnum = botactGetWeaponByAmmoType(ammotype); +// +// if (weaponnum > 0) { +// for (j = 0; j < 6; j++) { +// if (weaponnums[j] > WEAPON_UNARMED && weaponnum == weaponnums[j]) { +// if (random() % 16) { +// if (weapproplist[j] == NULL || sqdist < weapdistlist[j] || random() % 16 == 0) { +// weapproplist[j] = prop; +// weapdistlist[j] = sqdist; +// } +// } +// break; +// } +// } +// } +// +// if (random() % 16) { +// if (ammoproplist[ammotype] == NULL || sqdist < ammodistlist[ammotype] || random() % 16 == 0) { +// ammoproplist[ammotype] = prop; +// ammodistlist[ammotype] = sqdist; +// } +// } +// } +// } +// } else if (obj->type == OBJTYPE_SHIELD) { +// for (i = 0; i < 6; i++) { +// if (weaponnums[i] == WEAPON_MPSHIELD) { +// sqdist = chrGetSquaredDistanceToCoord(chr, &prop->pos); +// +// if (random() % 16 == 0) { +// break; +// } +// +// if (weapproplist[i] == NULL || sqdist < weapdistlist[i] || random() % 16 == 0) { +// weapproplist[i] = prop; +// weapdistlist[i] = sqdist; +// } +// +// break; +// } +// } +// } +// } +// } +// } +// +// prop = prop->next; +// } +// +// // c50 +// // Find the best score out of the 6 weapons +// bestscore1 = 0; +// done = false; +// +// for (i = 0; i < 6; i++) { +// if ((botinvAllowsWeapon(chr, weaponnums[i], FUNC_PRIMARY) || botinvAllowsWeapon(chr, weaponnums[i], FUNC_SECONDARY)) +// && (g_AibotWeaponPreferences[weaponnums[i]].haspriammogoal || g_AibotWeaponPreferences[weaponnums[i]].hassecammogoal) +// && scores1[i] > bestscore1) { +// bestscore1 = scores1[i]; +// } +// } +// +// // ce8 +// // Decide if the bot wants to find a shield, based on the amount of health +// // and shield the bot currently has. This shield logic is done prior to +// // weapons and ammo, so a shield takes precedence. +// // Note that max health and shield is 8 each, and that the bot must be under +// // BOTH the limits for a shield to be fetched. +// for (i = 0; i < 6 && !done; i++) { +// if (weaponnums[i] == WEAPON_MPSHIELD +// && (g_MpSetup.scenario != MPSCENARIO_HOLDTHEBRIEFCASE || !chr->aibot->hasbriefcase)) { +// healthlimit = 8.1f; +// shieldlimit = 0; +// +// // d64 +// if (aibot->config->type == BOTTYPE_SHIELD) { +// // Setting higher shield limits makes ShieldSims more likely to +// // fetch shields +// if (criteria == PICKUPCRITERIA_ANY) { +// shieldlimit = 7.9f; +// } else if (criteria == PICKUPCRITERIA_DEFAULT) { +// shieldlimit = 6 - (aibot->randomfrac + aibot->randomfrac); +// } else if (criteria == PICKUPCRITERIA_CRITICAL) { +// shieldlimit = 4 - (aibot->randomfrac + aibot->randomfrac); +// } +// } else if (barelydominatinghill) { +// // Bots will be less likely to fetch shields while defending the hill +// healthlimit = 4 - (aibot->randomfrac + aibot->randomfrac); +// shieldlimit = 1 - aibot->randomfrac; +// } else if (g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE && botShouldReturnCtcToken(chr)) { +// // Bots will be less likely to fetch shields while returning a CTC case +// healthlimit = 3 - (aibot->randomfrac + aibot->randomfrac); +// } else if (chr->myaction == MA_AIBOTDOWNLOAD) { +// // Bots will be less likely to fetch shields while uplinking +// healthlimit = 4 - (aibot->randomfrac + aibot->randomfrac); +// shieldlimit = 1; +// } else { +// // Default behaviour +// if (criteria == PICKUPCRITERIA_ANY) { +// shieldlimit = 7.9f; +// } else if (criteria == PICKUPCRITERIA_DEFAULT) { +// shieldlimit = 4 - (aibot->randomfrac + aibot->randomfrac); +// } else if (criteria == PICKUPCRITERIA_CRITICAL) { +// shieldlimit = 2 - aibot->randomfrac; +// } +// } +// +// // Meat, easy and normal sims reduce the limits further, +// // making them less likely to fetch shields. +// if (aibot->config->difficulty == BOTDIFF_MEAT) { +// s32 rand = aibot->random2 % 8; +// +// if (rand < 2) { +// healthlimit = 0; +// shieldlimit = 0; +// } else if (rand < 4) { +// healthlimit = 2 - aibot->randomfrac; +// shieldlimit = 0; +// } else { +// shieldlimit -= aibot->randomfrac * 16; +// +// if (shieldlimit <= 0) { +// healthlimit += shieldlimit; +// shieldlimit = 0; +// } +// } +// } else if (aibot->config->difficulty == BOTDIFF_EASY) { +// s32 rand = aibot->random2 % 8; +// +// if (rand <= 0) { +// healthlimit = 0; +// shieldlimit = 0; +// } else { +// shieldlimit -= aibot->randomfrac * 11; +// +// if (shieldlimit <= 0) { +// healthlimit += shieldlimit; +// shieldlimit = 0; +// } +// } +// } else if (aibot->config->difficulty == BOTDIFF_NORMAL) { +// shieldlimit -= aibot->randomfrac * 4; +// +// if (shieldlimit <= 0) { +// healthlimit += shieldlimit; +// shieldlimit = 0; +// } +// } +// +// // Actually check the limits and decide if the shield is desired +// if (chr->maxdamage - chr->damage < healthlimit +// && chr->cshield <= shieldlimit +// && weapproplist[i] != NULL +// && scores2[i] >= bestscore1) { +// chosenprop = weapproplist[i]; +// done = true; +// break; +// } +// } +// } +// +// // 078 +// // Consider ammo for weapons that the bot already has. +// // This loop is iterated in order of highest scoring weapons first. If the +// // first iterated weapon which the bot holds has enough ammo then the lower +// // scoring weapons will not be considered, nor will any new weapons be +// // picked up. +// for (i = 0; i < 6 && !done; i++) { +// if (weaponnums[i] != WEAPON_MPSHIELD +// && invitems[i] != NULL +// && (g_AibotWeaponPreferences[weaponnums[i]].haspriammogoal +// || g_AibotWeaponPreferences[weaponnums[i]].hassecammogoal) +// && scores2[i] >= bestscore1) { +// // 0fc +// include_equipped = true; +// +// // Don't go after ammo when returning a CTC token +// if (g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE && botShouldReturnCtcToken(chr)) { +// done = true; +// break; +// } +// +// // Don't go after ammo when downloading in Hacker Central +// if (chr->myaction == MA_AIBOTDOWNLOAD) { +// done = true; +// break; +// } +// +// if (barelydominatinghill) { +// // If the bot's team is only barely controlling the hill, +// // don't leave it unless the bot is out of ammo +// priammogoal = g_AibotWeaponPreferences[weaponnums[i]].criticalammopri; +// +// if (priammogoal > 1) { +// priammogoal = 1; +// } +// +// secammogoal = g_AibotWeaponPreferences[weaponnums[i]].criticalammosec; +// +// if (secammogoal > 1) { +// secammogoal = 1; +// } +// +// if (HASENOUGHPRI(aibot, weaponnums[i], priammogoal) +// || HASENOUGHSEC(aibot, weaponnums[i], secammogoal)) { +// done = true; +// break; +// } +// } else if (criteria == PICKUPCRITERIA_ANY) { +// // If looking for any pickups at all, use the weapon's ammo +// // capacities as the goal ammo +// priammogoal = bgunGetCapacityByAmmotype(botactGetAmmoTypeByFunction(weaponnums[i], FUNC_PRIMARY)); +// secammogoal = bgunGetCapacityByAmmotype(botactGetAmmoTypeByFunction(weaponnums[i], FUNC_SECONDARY)); +// +// // If bot has max ammo for both weapon's functions +// if ((g_AibotWeaponPreferences[weaponnums[i]].haspriammogoal == false +// || botactGetAmmoQuantityByWeapon(aibot, weaponnums[i], FUNC_PRIMARY, false) >= priammogoal) +// && (g_AibotWeaponPreferences[weaponnums[i]].hassecammogoal == false +// || botactGetAmmoQuantityByWeapon(aibot, weaponnums[i], FUNC_SECONDARY, false) >= secammogoal)) { +// // Consider next weapon +// continue; +// } +// +// include_equipped = false; +// } else if (criteria == PICKUPCRITERIA_DEFAULT) { +// // Default - use the target ammo amount +// priammogoal = g_AibotWeaponPreferences[weaponnums[i]].targetammopri; +// secammogoal = g_AibotWeaponPreferences[weaponnums[i]].targetammosec; +// +// if (HASENOUGHPRI(aibot, weaponnums[i], priammogoal) +// || HASENOUGHSEC(aibot, weaponnums[i], secammogoal)) { +// done = true; +// break; +// } +// } else if (criteria == PICKUPCRITERIA_CRITICAL) { +// // Critical - use the critical ammo amount +// priammogoal = g_AibotWeaponPreferences[weaponnums[i]].criticalammopri; +// secammogoal = g_AibotWeaponPreferences[weaponnums[i]].criticalammosec; +// +// if (HASENOUGHPRI(aibot, weaponnums[i], priammogoal) +// || HASENOUGHSEC(aibot, weaponnums[i], secammogoal)) { +// done = true; +// break; +// } +// } +// +// // Iterate both weapon functions and check +// // if the bot has enough ammo for that function +// for (j = 0; j < 2; j++) { +// if (botinvAllowsWeapon(chr, weaponnums[i], j)) { +// s32 ammotype = botactGetAmmoTypeByFunction(weaponnums[i], j); +// +// if (ammotype > 0) { +// s32 goal = j ? secammogoal : priammogoal; +// s32 qty = botactGetAmmoQuantityByType(aibot, ammotype, include_equipped); +// +// if (qty < goal +// && ammoproplist[ammotype]) { +// chosenprop = ammoproplist[ammotype]; +// done = true; +// break; +// } +// } +// } +// } +// } +// } +// +// // 478 +// // If done is still false, the bot mustn't have any weapons. +// // Consider picking up weapons that the bot doesn't have. +// // Fetch the highest scoring weapon if there are any pickups for it. +// for (i = 0; i < 6 && !done; i++) { +// if (weaponnums[i] != WEAPON_MPSHIELD) { +// if (g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE && botShouldReturnCtcToken(chr)) { +// done = true; +// break; +// } +// +// if (chr->myaction == MA_AIBOTDOWNLOAD) { +// done = true; +// break; +// } +// +// if (!barelydominatinghill +// && (botinvAllowsWeapon(chr, weaponnums[i], FUNC_PRIMARY) +// || botinvAllowsWeapon(chr, weaponnums[i], FUNC_SECONDARY)) +// && invitems[i] == NULL +// && weapproplist[i] != NULL) { +// chosenprop = weapproplist[i]; +// done = true; +// break; +// } +// } +// } +// +// // 568 +// if (criteria == PICKUPCRITERIA_ANY) { +// // Consider ammo even for weapons that the bot doesn't have +// for (i = 0; i < 6 && !done; i++) { +// if (weaponnums[i] != WEAPON_MPSHIELD) { +// for (j = 0; j < 2; j++) { +// if (botinvAllowsWeapon(chr, weaponnums[i], j)) { +// ammotype = botactGetAmmoTypeByFunction(weaponnums[i], j); +// +// if (ammotype > 0 +// && botactGetAmmoQuantityByType(aibot, ammotype, false) < bgunGetCapacityByAmmotype(ammotype) +// && ammoproplist[ammotype] != NULL) { +// chosenprop = ammoproplist[ammotype]; +// done = true; +// break; +// } +// } +// } +// } +// } +// } +// +// return chosenprop; +//} + +/** + * Check if the bot wants to do a critical pickup. + * + * This returns true when the bot is low on health or ammo and there are pickups + * available. + */ +bool botCanDoCriticalPickup(struct chrdata *chr) { - return botFindPickup(chr, 1) != 0; + return botFindPickup(chr, PICKUPCRITERIA_CRITICAL) != NULL; } /** - * Choose a prop to fetch. + * Find a pickup to fetch based on default criteria. Default criteria basically + * means a good amount of ammo - not lacking but not excessive either. */ -struct prop *botFindNecessaryPickup(struct chrdata *chr) +struct prop *botFindDefaultPickup(struct chrdata *chr) { - return botFindPickup(chr, 0); + return botFindPickup(chr, PICKUPCRITERIA_DEFAULT); } -struct prop *botFindUnnecessaryPickup(struct chrdata *chr) +/** + * Find any pickup to fetch. This is used when the bot has nothing else to do + * (eg. if all opponents are cloaked). + */ +struct prop *botFindAnyPickup(struct chrdata *chr) { - return botFindPickup(chr, 2); + return botFindPickup(chr, PICKUPCRITERIA_ANY); } s32 botGetTeamSize(struct chrdata *chr) @@ -6838,7 +7306,7 @@ s32 botGetNumTeammatesDefendingHill(struct chrdata *bot) for (i = 0; i < g_MpNumChrs; i++) { if (bot->team == g_MpAllChrPtrs[i]->team - && g_MpAllChrPtrs[i]->prop->rooms[0] == g_ScenarioData.cbt.unk0e[0]) { + && g_MpAllChrPtrs[i]->prop->rooms[0] == g_ScenarioData.koh.hillrooms[0]) { if (g_MpAllChrPtrs[i]->aibot->command == AIBOTCMD_DEFHILL || g_MpAllChrPtrs[i]->aibot->command == AIBOTCMD_HOLDHILL) { count++; @@ -7699,7 +8167,7 @@ glabel var7f1b8fc8 .PF0f196668: /* f196668: 06a10006 */ bgez $s5,.PF0f196684 /* f19666c: 00000000 */ nop -/* f196670: 0fc655d3 */ jal botFindNecessaryPickup +/* f196670: 0fc655d3 */ jal botFindDefaultPickup /* f196674: 02802025 */ move $a0,$s4 /* f196678: 10400002 */ beqz $v0,.PF0f196684 /* f19667c: ae420010 */ sw $v0,0x10($s2) @@ -8658,7 +9126,7 @@ glabel var7f1b8fc8 .PF0f197460: /* f197460: 06a10006 */ bgez $s5,.PF0f19747c /* f197464: 00000000 */ nop -/* f197468: 0fc655db */ jal botFindUnnecessaryPickup +/* f197468: 0fc655db */ jal botFindAnyPickup /* f19746c: 02802025 */ move $a0,$s4 /* f197470: 10400002 */ beqz $v0,.PF0f19747c /* f197474: ae420010 */ sw $v0,0x10($s2) @@ -8882,7 +9350,7 @@ glabel var7f1b8fc8 .PF0f19778c: /* f19778c: 0fc661c0 */ jal botcmdTickDistMode /* f197790: 02802025 */ move $a0,$s4 -/* f197794: 0fc655ca */ jal bot0f194670 +/* f197794: 0fc655ca */ jal botCanDoCriticalPickup /* f197798: 02802025 */ move $a0,$s4 /* f19779c: 10400003 */ beqz $v0,.PF0f1977ac /* f1977a0: 240d0029 */ li $t5,0x29 @@ -8980,7 +9448,7 @@ glabel var7f1b8fc8 /* f1978f8: ae4f01d8 */ sw $t7,0x1d8($s2) /* f1978fc: a25e0074 */ sb $s8,0x74($s2) .PF0f197900: -/* f197900: 0fc655ca */ jal bot0f194670 +/* f197900: 0fc655ca */ jal botCanDoCriticalPickup /* f197904: 02802025 */ move $a0,$s4 /* f197908: 104000d3 */ beqz $v0,.PF0f197c58 /* f19790c: 24190029 */ li $t9,0x29 @@ -9090,7 +9558,7 @@ glabel var7f1b8fc8 /* f197a88: 00000000 */ nop /* f197a8c: ae4e00dc */ sw $t6,0xdc($s2) .PF0f197a90: -/* f197a90: 0fc655ca */ jal bot0f194670 +/* f197a90: 0fc655ca */ jal botCanDoCriticalPickup /* f197a94: 02802025 */ move $a0,$s4 /* f197a98: 1040006f */ beqz $v0,.PF0f197c58 /* f197a9c: 240b0029 */ li $t3,0x29 @@ -9145,7 +9613,7 @@ glabel var7f1b8fc8 /* f197b4c: 10000042 */ b .PF0f197c58 /* f197b50: a28c02a0 */ sb $t4,0x2a0($s4) .PF0f197b54: -/* f197b54: 0fc655ca */ jal bot0f194670 +/* f197b54: 0fc655ca */ jal botCanDoCriticalPickup /* f197b58: 02802025 */ move $a0,$s4 /* f197b5c: 1040003e */ beqz $v0,.PF0f197c58 /* f197b60: 24180029 */ li $t8,0x29 @@ -9155,7 +9623,7 @@ glabel var7f1b8fc8 /* f197b6c: 2401002c */ li $at,0x2c /* f197b70: 54410029 */ bnel $v0,$at,.PF0f197c18 /* f197b74: 2401002e */ li $at,0x2e -/* f197b78: 0fc655ca */ jal bot0f194670 +/* f197b78: 0fc655ca */ jal botCanDoCriticalPickup /* f197b7c: 02802025 */ move $a0,$s4 /* f197b80: 10400003 */ beqz $v0,.PF0f197b90 /* f197b84: 240f0029 */ li $t7,0x29 @@ -9201,7 +9669,7 @@ glabel var7f1b8fc8 .PF0f197c18: /* f197c18: 1441000f */ bne $v0,$at,.PF0f197c58 /* f197c1c: 00000000 */ nop -/* f197c20: 0fc655ca */ jal bot0f194670 +/* f197c20: 0fc655ca */ jal botCanDoCriticalPickup /* f197c24: 02802025 */ move $a0,$s4 /* f197c28: 10400003 */ beqz $v0,.PF0f197c38 /* f197c2c: 24180029 */ li $t8,0x29 @@ -10162,7 +10630,7 @@ void botTickUnpaused(struct chrdata *chr) // Check if the bot needs to fetch some weapons or ammo if (newaction < 0) { - aibot->gotoprop = botFindNecessaryPickup(chr); + aibot->gotoprop = botFindDefaultPickup(chr); if (aibot->gotoprop) { newaction = MA_AIBOTGETITEM; @@ -10614,7 +11082,7 @@ void botTickUnpaused(struct chrdata *chr) // If there's no teammate to follow, stock up on weapons and ammo if (newaction < 0) { - aibot->gotoprop = botFindUnnecessaryPickup(chr); + aibot->gotoprop = botFindAnyPickup(chr); if (aibot->gotoprop) { newaction = MA_AIBOTGETITEM; @@ -10706,7 +11174,7 @@ void botTickUnpaused(struct chrdata *chr) } else { botcmdTickDistMode(chr); - if (bot0f194670(chr)) { + if (botCanDoCriticalPickup(chr)) { chr->myaction = MA_AIBOTMAINLOOP; } else if (aibot->abortattacktimer60 >= 0 && aibot->targetlastseen60 < g_Vars.lvframe60 - aibot->abortattacktimer60) { chr->myaction = MA_AIBOTMAINLOOP; @@ -10743,7 +11211,7 @@ void botTickUnpaused(struct chrdata *chr) } } - if (bot0f194670(chr)) { + if (botCanDoCriticalPickup(chr)) { chr->myaction = MA_AIBOTMAINLOOP; } } @@ -10788,7 +11256,7 @@ void botTickUnpaused(struct chrdata *chr) } } - if (bot0f194670(chr)) { + if (botCanDoCriticalPickup(chr)) { chr->myaction = MA_AIBOTMAINLOOP; } } else if (chr->myaction == MA_AIBOTGOTOPOS) { @@ -10807,11 +11275,11 @@ void botTickUnpaused(struct chrdata *chr) if (chr->actiontype != ACT_GOPOS) { chr->myaction = MA_AIBOTMAINLOOP; - } else if (bot0f194670(chr)) { + } else if (botCanDoCriticalPickup(chr)) { chr->myaction = MA_AIBOTMAINLOOP; } } else if (chr->myaction == MA_AIBOTGOTOPROP) { - if (bot0f194670(chr)) { + if (botCanDoCriticalPickup(chr)) { chr->myaction = MA_AIBOTMAINLOOP; } else if (chr->actiontype != ACT_GOPOS || aibot->gotoprop == NULL || aibot->gotoprop->parent) { chr->myaction = MA_AIBOTMAINLOOP; @@ -10823,7 +11291,7 @@ void botTickUnpaused(struct chrdata *chr) chr->myaction = MA_AIBOTMAINLOOP; } } else if (chr->myaction == MA_AIBOTDOWNLOAD) { - if (bot0f194670(chr)) { + if (botCanDoCriticalPickup(chr)) { chr->myaction = MA_AIBOTMAINLOOP; } else if (g_ScenarioData.htm.uplinkingplayernum != mpPlayerGetIndex(chr)) { chr->myaction = MA_AIBOTMAINLOOP; diff --git a/src/game/botact.c b/src/game/botact.c index 1f6d1f022..01621866e 100644 --- a/src/game/botact.c +++ b/src/game/botact.c @@ -19,7 +19,7 @@ #include "data.h" #include "types.h" -s32 botactGetAmmoTypeByFunction(s32 weaponnum, u32 funcnum) +s32 botactGetAmmoTypeByFunction(s32 weaponnum, s32 funcnum) { if (weaponnum >= WEAPON_FALCON2 && weaponnum <= WEAPON_SUICIDEPILL) { struct inventory_ammo *ammo = weaponGetAmmoByFunction(weaponnum, funcnum); @@ -322,7 +322,7 @@ u32 botactGetProjectileThrowInterval(u32 weapon) } } -u32 botactGetWeaponByAmmoType(u32 ammotype) +s32 botactGetWeaponByAmmoType(s32 ammotype) { switch (ammotype) { case AMMOTYPE_NBOMB: return WEAPON_NBOMB; diff --git a/src/game/botinv.c b/src/game/botinv.c index 852ad6384..efbc3213b 100644 --- a/src/game/botinv.c +++ b/src/game/botinv.c @@ -19,106 +19,113 @@ #include "types.h" struct aibotweaponpreference g_AibotWeaponPreferences[] = { - /*0x00*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 0, 0 }, // WEAPON_NONE - /*0x01*/ { 13, 13, 13, 13, 1, 1, BOTDISTCFG_CLOSE, BOTDISTCFG_CLOSE, 0, 0, 0, 0, 0, 0 }, // WEAPON_UNARMED - /*0x02*/ { 56, 60, 84, 88, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 10, 0, 1, 0 }, // WEAPON_FALCON2 - /*0x03*/ { 52, 60, 80, 88, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 10, 0, 1, 0 }, // WEAPON_FALCON2_SILENCER - /*0x04*/ { 60, 60, 88, 88, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 10, 0, 1, 0 }, // WEAPON_FALCON2_SCOPE - /*0x05*/ { 76, 88, 104, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 1, 0 }, // WEAPON_MAGSEC4 - /*0x06*/ { 64, 88, 92, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 1, 0 }, // WEAPON_MAULER - /*0x07*/ { 72, 76, 100, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 2, 0 }, // WEAPON_PHOENIX - /*0x08*/ { 68, 76, 96, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 8, 0, 3, 0 }, // WEAPON_DY357MAGNUM - /*0x09*/ { 180, 188, 184, 188, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 20, 0, 6, 0, 3, 0 }, // WEAPON_DY357LX - /*0x0a*/ { 116, 128, 136, 152, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 100, 100, 30, 30, 2, 0 }, // WEAPON_CMP150 - /*0x0b*/ { 120, 128, 132, 140, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 150, 150, 50, 50, 2, 0 }, // WEAPON_CYCLONE - /*0x0c*/ { 152, 176, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 100, 70, 25, 15, 2, 0 }, // WEAPON_CALLISTO - /*0x0d*/ { 172, 188, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 300, 0, 40, 0, 2, 0 }, // WEAPON_RCP120 - /*0x0e*/ { 128, 140, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 100, 0, 30, 0, 3, 0 }, // WEAPON_LAPTOPGUN - /*0x0f*/ { 124, 148, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 90, 0, 30, 0, 1, 0 }, // WEAPON_DRAGON - /*0x10*/ { 156, 180, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 150, 0, 40, 0, 2, 0 }, // WEAPON_K7AVENGER - /*0x11*/ { 148, 176, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 120, 0, 40, 0, 2, 0 }, // WEAPON_AR34 - /*0x12*/ { 164, 188, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_SHOOTEXPLOSIVE, 120, 20, 30, 6, 1, 0 }, // WEAPON_SUPERDRAGON - /*0x13*/ { 140, 156, 0, 0, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_PISTOL, 18, 18, 8, 8, 6, 1 }, // WEAPON_SHOTGUN - /*0x14*/ { 144, 176, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_CLOSE, 400, 0, 80, 0, 3, 0 }, // WEAPON_REAPER - /*0x15*/ { 28, 40, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 2, 0 }, // WEAPON_SNIPERRIFLE - /*0x16*/ { 188, 188, 0, 0, 1, 0, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_FARSIGHT, 16, 0, 4, 0, 2, 0 }, // WEAPON_FARSIGHT - /*0x17*/ { 176, 188, 0, 0, 1, 1, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_SHOOTEXPLOSIVE, 20, 20, 4, 4, 2, 0 }, // WEAPON_DEVASTATOR - /*0x18*/ { 160, 188, 0, 0, 1, 1, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_SHOOTEXPLOSIVE, 2, 2, 1, 1, 2, 0 }, // WEAPON_ROCKETLAUNCHER - /*0x19*/ { 168, 188, 0, 0, 1, 1, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_SHOOTEXPLOSIVE, 2, 2, 1, 1, 3, 0 }, // WEAPON_SLAYER - /*0x1a*/ { 20, 40, 24, 40, 1, 1, BOTDISTCFG_CLOSE, BOTDISTCFG_DEFAULT, 0, 5, 0, 1, 1, 0 }, // WEAPON_COMBATKNIFE - /*0x1b*/ { 108, 176, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 15, 15, 5, 5, 4, 1 }, // WEAPON_CROSSBOW - /*0x1c*/ { 48, 188, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_CLOSE, 20, 24, 6, 8, 1, 0 }, // WEAPON_TRANQUILIZER - /*0x1d*/ { 112, 112, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_CLOSE, 0, 0, 0, 0, 1, 0 }, // WEAPON_LASER - /*0x1e*/ { 36, 172, 0, 0, 1, 1, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_THROWEXPLOSIVE, 6, 6, 2, 2, 1, 0 }, // WEAPON_GRENADE - /*0x1f*/ { 32, 188, 0, 0, 1, 1, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_THROWEXPLOSIVE, 3, 3, 1, 1, 1, 0 }, // WEAPON_NBOMB - /*0x20*/ { 12, 12, 0, 0, 0, 0, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_DEFAULT, 5, 5, 1, 1, 1, 0 }, // WEAPON_TIMEDMINE - /*0x21*/ { 40, 176, 0, 0, 0, 0, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_DEFAULT, 5, 5, 1, 1, 1, 0 }, // WEAPON_PROXIMITYMINE - /*0x22*/ { 44, 156, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 5, 5, 2, 2, 1, 0 }, // WEAPON_REMOTEMINE - /*0x23*/ { 8, 8, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_COMBATBOOST - /*0x24*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_PP9I - /*0x25*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_CC13 - /*0x26*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KL01313 - /*0x27*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KF7SPECIAL - /*0x28*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ZZT - /*0x29*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DMC - /*0x2a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_AR53 - /*0x2b*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_RCP45 - /*0x2c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_PSYCHOSISGUN - /*0x2d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_NIGHTVISION - /*0x2e*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_EYESPY - /*0x2f*/ { 4, 4, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_XRAYSCANNER - /*0x30*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_IRSCANNER -#if PAL - /*0x31*/ { 218, 218, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 1000, 0, 0, 0, 1, 0 }, // WEAPON_CLOAKINGDEVICE -#else - /*0x31*/ { 218, 218, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 1200, 0, 0, 0, 1, 0 }, // WEAPON_CLOAKINGDEVICE -#endif - /*0x32*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_HORIZONSCANNER - /*0x33*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_TESTER - /*0x34*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ROCKETLAUNCHER_34 - /*0x35*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ECMMINE - /*0x36*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DATAUPLINK - /*0x37*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_RTRACKER - /*0x38*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_PRESIDENTSCANNER - /*0x39*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DOORDECODER - /*0x3a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_AUTOSURGEON - /*0x3b*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_EXPLOSIVES - /*0x3c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SKEDARBOMB - /*0x3d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_COMMSRIDER - /*0x3e*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_TRACERBUG - /*0x3f*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_TARGETAMPLIFIER - /*0x40*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DISGUISE40 - /*0x41*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DISGUISE41 - /*0x42*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_FLIGHTPLANS - /*0x43*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_RESEARCHTAPE - /*0x44*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BACKUPDISK - /*0x45*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD45 - /*0x46*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD46 - /*0x47*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD47 - /*0x48*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD48 - /*0x49*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD49 - /*0x4a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD4A - /*0x4b*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD4B - /*0x4c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD4C - /*0x4d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SUITCASE - /*0x4e*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BRIEFCASE + // haspriammogoal + // | hassecammogoal + // | | pridistconfig + // | | | secdistconfig + // | | | | targetammopri + // | | | | | targetammosec + // | | | | | | criticalammopri + // | | | | | | | criticalammosec + // | | | | | | | | reloaddelay (seconds) + // | | | | | | | | | allowpartialreloaddelay + // | | | | | | | | | | + /*0x00*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 0, 0 }, // WEAPON_NONE + /*0x01*/ { 13, 13, 13, 13, 1, 1, BOTDISTCFG_CLOSE, BOTDISTCFG_CLOSE, 0, 0, 0, 0, 0, 0 }, // WEAPON_UNARMED + /*0x02*/ { 56, 60, 84, 88, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 10, 0, 1, 0 }, // WEAPON_FALCON2 + /*0x03*/ { 52, 60, 80, 88, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 10, 0, 1, 0 }, // WEAPON_FALCON2_SILENCER + /*0x04*/ { 60, 60, 88, 88, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 10, 0, 1, 0 }, // WEAPON_FALCON2_SCOPE + /*0x05*/ { 76, 88, 104, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 1, 0 }, // WEAPON_MAGSEC4 + /*0x06*/ { 64, 88, 92, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 1, 0 }, // WEAPON_MAULER + /*0x07*/ { 72, 76, 100, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 2, 0 }, // WEAPON_PHOENIX + /*0x08*/ { 68, 76, 96, 120, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 30, 0, 8, 0, 3, 0 }, // WEAPON_DY357MAGNUM + /*0x09*/ { 180, 188, 184, 188, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_CLOSE, 20, 0, 6, 0, 3, 0 }, // WEAPON_DY357LX + /*0x0a*/ { 116, 128, 136, 152, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 100, 100, 30, 30, 2, 0 }, // WEAPON_CMP150 + /*0x0b*/ { 120, 128, 132, 140, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 150, 150, 50, 50, 2, 0 }, // WEAPON_CYCLONE + /*0x0c*/ { 152, 176, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 100, 70, 25, 15, 2, 0 }, // WEAPON_CALLISTO + /*0x0d*/ { 172, 188, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 300, 0, 40, 0, 2, 0 }, // WEAPON_RCP120 + /*0x0e*/ { 128, 140, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 100, 0, 30, 0, 3, 0 }, // WEAPON_LAPTOPGUN + /*0x0f*/ { 124, 148, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 90, 0, 30, 0, 1, 0 }, // WEAPON_DRAGON + /*0x10*/ { 156, 180, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 150, 0, 40, 0, 2, 0 }, // WEAPON_K7AVENGER + /*0x11*/ { 148, 176, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 120, 0, 40, 0, 2, 0 }, // WEAPON_AR34 + /*0x12*/ { 164, 188, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_SHOOTEXPLOSIVE, 120, 20, 30, 6, 1, 0 }, // WEAPON_SUPERDRAGON + /*0x13*/ { 140, 156, 0, 0, 1, 1, BOTDISTCFG_PISTOL, BOTDISTCFG_PISTOL, 18, 18, 8, 8, 6, 1 }, // WEAPON_SHOTGUN + /*0x14*/ { 144, 176, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_CLOSE, 400, 0, 80, 0, 3, 0 }, // WEAPON_REAPER + /*0x15*/ { 28, 40, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 30, 30, 10, 10, 2, 0 }, // WEAPON_SNIPERRIFLE + /*0x16*/ { 188, 188, 0, 0, 1, 0, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_FARSIGHT, 16, 0, 4, 0, 2, 0 }, // WEAPON_FARSIGHT + /*0x17*/ { 176, 188, 0, 0, 1, 1, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_SHOOTEXPLOSIVE, 20, 20, 4, 4, 2, 0 }, // WEAPON_DEVASTATOR + /*0x18*/ { 160, 188, 0, 0, 1, 1, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_SHOOTEXPLOSIVE, 2, 2, 1, 1, 2, 0 }, // WEAPON_ROCKETLAUNCHER + /*0x19*/ { 168, 188, 0, 0, 1, 1, BOTDISTCFG_SHOOTEXPLOSIVE, BOTDISTCFG_SHOOTEXPLOSIVE, 2, 2, 1, 1, 3, 0 }, // WEAPON_SLAYER + /*0x1a*/ { 20, 40, 24, 40, 1, 1, BOTDISTCFG_CLOSE, BOTDISTCFG_DEFAULT, 0, 5, 0, 1, 1, 0 }, // WEAPON_COMBATKNIFE + /*0x1b*/ { 108, 176, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 15, 15, 5, 5, 4, 1 }, // WEAPON_CROSSBOW + /*0x1c*/ { 48, 188, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_CLOSE, 20, 24, 6, 8, 1, 0 }, // WEAPON_TRANQUILIZER + /*0x1d*/ { 112, 112, 0, 0, 1, 1, BOTDISTCFG_DEFAULT, BOTDISTCFG_CLOSE, 0, 0, 0, 0, 1, 0 }, // WEAPON_LASER + /*0x1e*/ { 36, 172, 0, 0, 1, 1, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_THROWEXPLOSIVE, 6, 6, 2, 2, 1, 0 }, // WEAPON_GRENADE + /*0x1f*/ { 32, 188, 0, 0, 1, 1, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_THROWEXPLOSIVE, 3, 3, 1, 1, 1, 0 }, // WEAPON_NBOMB + /*0x20*/ { 12, 12, 0, 0, 0, 0, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_DEFAULT, 5, 5, 1, 1, 1, 0 }, // WEAPON_TIMEDMINE + /*0x21*/ { 40, 176, 0, 0, 0, 0, BOTDISTCFG_THROWEXPLOSIVE, BOTDISTCFG_DEFAULT, 5, 5, 1, 1, 1, 0 }, // WEAPON_PROXIMITYMINE + /*0x22*/ { 44, 156, 0, 0, 1, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 5, 5, 2, 2, 1, 0 }, // WEAPON_REMOTEMINE + /*0x23*/ { 8, 8, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_COMBATBOOST + /*0x24*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_PP9I + /*0x25*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_CC13 + /*0x26*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KL01313 + /*0x27*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KF7SPECIAL + /*0x28*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ZZT + /*0x29*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DMC + /*0x2a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_AR53 + /*0x2b*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_RCP45 + /*0x2c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_PSYCHOSISGUN + /*0x2d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_NIGHTVISION + /*0x2e*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_EYESPY + /*0x2f*/ { 4, 4, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_XRAYSCANNER + /*0x30*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_IRSCANNER + /*0x31*/ { 218, 218, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, PALDOWN(1200), 0, 0, 0, 1, 0 }, // WEAPON_CLOAKINGDEVICE + /*0x32*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_HORIZONSCANNER + /*0x33*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_TESTER + /*0x34*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ROCKETLAUNCHER_34 + /*0x35*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ECMMINE + /*0x36*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DATAUPLINK + /*0x37*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_RTRACKER + /*0x38*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_PRESIDENTSCANNER + /*0x39*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DOORDECODER + /*0x3a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_AUTOSURGEON + /*0x3b*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_EXPLOSIVES + /*0x3c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SKEDARBOMB + /*0x3d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_COMMSRIDER + /*0x3e*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_TRACERBUG + /*0x3f*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_TARGETAMPLIFIER + /*0x40*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DISGUISE40 + /*0x41*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DISGUISE41 + /*0x42*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_FLIGHTPLANS + /*0x43*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_RESEARCHTAPE + /*0x44*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BACKUPDISK + /*0x45*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD45 + /*0x46*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD46 + /*0x47*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD47 + /*0x48*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD48 + /*0x49*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD49 + /*0x4a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD4A + /*0x4b*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD4B + /*0x4c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_KEYCARD4C + /*0x4d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SUITCASE + /*0x4e*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BRIEFCASE #if VERSION >= VERSION_NTSC_1_0 - /*0x4f*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SHIELDTECHITEM + /*0x4f*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SHIELDTECHITEM #endif - /*0x50*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_NECKLACE - /*0x51*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_HAMMER - /*0x52*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SCREWDRIVER - /*0x53*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ROCKET - /*0x54*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_HOMINGROCKET - /*0x55*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_GRENADEROUND - /*0x56*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BOLT - /*0x57*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BRIEFCASE2 - /*0x58*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SKROCKET - /*0x59*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_59 - /*0x5a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_WATCHLASER - /*0x5b*/ { 220, 220, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_MPSHIELD - /*0x5c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DISABLED - /*0x5d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SUICIDEPILL + /*0x50*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_NECKLACE + /*0x51*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_HAMMER + /*0x52*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SCREWDRIVER + /*0x53*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_ROCKET + /*0x54*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_HOMINGROCKET + /*0x55*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_GRENADEROUND + /*0x56*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BOLT + /*0x57*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_BRIEFCASE2 + /*0x58*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SKROCKET + /*0x59*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_59 + /*0x5a*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_WATCHLASER + /*0x5b*/ { 220, 220, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_MPSHIELD + /*0x5c*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_DISABLED + /*0x5d*/ { 0, 0, 0, 0, 0, 0, BOTDISTCFG_DEFAULT, BOTDISTCFG_DEFAULT, 0, 0, 0, 0, 1, 0 }, // WEAPON_SUICIDEPILL }; /** @@ -166,7 +173,7 @@ struct invitem *botinvGetFreeSlot(struct chrdata *chr) /** * Retrieve an inventory item from the bot's inventory. */ -struct invitem *botinvGetItem(struct chrdata *chr, u32 weaponnum) +struct invitem *botinvGetItem(struct chrdata *chr, s32 weaponnum) { s32 i; @@ -458,8 +465,8 @@ void botinvScoreWeapon(struct chrdata *chr, s32 weaponnum, s32 funcnum, s32 arg3 // @dangerous: Array overflow can occur if more weapons are added to the // game without extending the preferences table if (arg3 < 0 - || (!funcnum && arg3 == g_AibotWeaponPreferences[weaponnum].unk04_00) - || (funcnum && arg3 == g_AibotWeaponPreferences[weaponnum].unk04_01)) { + || (!funcnum && arg3 == g_AibotWeaponPreferences[weaponnum].haspriammogoal) + || (funcnum && arg3 == g_AibotWeaponPreferences[weaponnum].hassecammogoal)) { if (arg4) { score1 = g_AibotWeaponPreferences[weaponnum].unk02; score2 = g_AibotWeaponPreferences[weaponnum].unk03; @@ -952,9 +959,9 @@ void botinvTick(struct chrdata *chr) if (weaponnum >= 0) { for (j = 1; j >= 0; j--) { if (j != FUNC_PRIMARY) { - canuse = g_AibotWeaponPreferences[weaponnum].unk04_01; + canuse = g_AibotWeaponPreferences[weaponnum].hassecammogoal; } else { - canuse = g_AibotWeaponPreferences[weaponnum].unk04_00; + canuse = g_AibotWeaponPreferences[weaponnum].haspriammogoal; } if (canuse && botinvAllowsWeapon(chr, weaponnum, j)) { diff --git a/src/include/game/bondgun.h b/src/include/game/bondgun.h index fbc8da244..74b17857b 100644 --- a/src/include/game/bondgun.h +++ b/src/include/game/bondgun.h @@ -155,7 +155,7 @@ void bgunSetGunAmmoVisible(u32 reason, bool enable); void bgunSetAmmoQuantity(s32 ammotype, s32 quantity); s32 bgunGetReservedAmmoCount(s32 type); s32 bgunGetAmmoCount(s32 ammotype); -s32 bgunGetCapacityByAmmotype(u32 ammotype); +s32 bgunGetCapacityByAmmotype(s32 ammotype); bool bgunAmmotypeAllowsUnlimitedAmmo(u32 ammotype); void bgunGiveMaxAmmo(bool force); u32 bgunGetAmmoTypeForWeapon(u32 weaponnum, u32 func); diff --git a/src/include/game/bot.h b/src/include/game/bot.h index 23ec44ea4..8ead4347a 100644 --- a/src/include/game/bot.h +++ b/src/include/game/bot.h @@ -33,7 +33,7 @@ bool botPassesPeaceCheck(struct chrdata *botchr, struct chrdata *otherchr); bool botPassesCowardCheck(struct chrdata *botchr, struct chrdata *otherchr); void botChooseGeneralTarget(struct chrdata *chr); void botScheduleReload(struct chrdata *chr, s32 handnum); -struct prop *botFindPickup(struct chrdata *chr, s32 arg1); +struct prop *botFindPickup(struct chrdata *chr, s32 criteria); s32 botGetNumOpponentsInHill(struct chrdata *chr); void botTickUnpaused(struct chrdata *chr); s32 botIsObjCollectable(struct defaultobj *obj); @@ -48,9 +48,9 @@ void botApplyHold(struct chrdata *chr, struct coord *pos, s16 *room, f32 arg3); void botApplyScenarioCommand(struct chrdata *chr, u32 arg1); bool botCanFollow(struct chrdata *leader, struct chrdata *follower); s32 botFindTeammateToFollow(struct chrdata *chr, f32 range); -bool bot0f194670(struct chrdata *chr); -struct prop *botFindNecessaryPickup(struct chrdata *chr); -struct prop *botFindUnnecessaryPickup(struct chrdata *chr); +bool botCanDoCriticalPickup(struct chrdata *chr); +struct prop *botFindDefaultPickup(struct chrdata *chr); +struct prop *botFindAnyPickup(struct chrdata *chr); s32 botGetTeamSize(struct chrdata *chr); s32 botGetCountInTeamDoingCommand(struct chrdata *self, u32 command, bool includeself); s32 botIsChrsCtcTokenHeld(struct chrdata *chr); diff --git a/src/include/game/botact.h b/src/include/game/botact.h index 8f64647cf..dd365944e 100644 --- a/src/include/game/botact.h +++ b/src/include/game/botact.h @@ -4,7 +4,7 @@ #include "data.h" #include "types.h" -s32 botactGetAmmoTypeByFunction(s32 weaponnum, u32 funcnum); +s32 botactGetAmmoTypeByFunction(s32 weaponnum, s32 funcnum); s32 botactGetClipCapacityByFunction(s32 weaponnum, u32 funcnum); void botactReload(struct chrdata *chr, s32 handnum, bool withsound); s32 botactGetAmmoQuantityByWeapon(struct aibot *aibot, s32 weaponnum, s32 funcnum, bool include_equipped); @@ -15,7 +15,7 @@ void botactGiveAmmoByType(struct aibot *aibot, u32 ammotype, s32 quantity); bool botactShootFarsight(struct chrdata *chr, s32 arg1, struct coord *arg2, struct coord *arg3); bool botactIsWeaponThrowable(s32 weaponnum, bool is_secondary); u32 botactGetProjectileThrowInterval(u32 weapon); -u32 botactGetWeaponByAmmoType(u32 ammotype); +s32 botactGetWeaponByAmmoType(s32 ammotype); void botact0f19a37c(struct chrdata *chr); s32 botactGetShootInterval60(s32 weaponnum, s32 funcnum); bool botactFindRocketRoute(struct chrdata *chr, struct coord *frompos, struct coord *topos, s16 *fromrooms, s16 *torooms, struct projectile *projectile); diff --git a/src/include/game/botinv.h b/src/include/game/botinv.h index a302ae860..673b1853b 100644 --- a/src/include/game/botinv.h +++ b/src/include/game/botinv.h @@ -6,7 +6,7 @@ void botinvClear(struct chrdata *chr); struct invitem *botinvGetFreeSlot(struct chrdata *chr); -struct invitem *botinvGetItem(struct chrdata *chr, u32 weaponnum); +struct invitem *botinvGetItem(struct chrdata *chr, s32 weaponnum); void botinvRemoveItem(struct chrdata *chr, s32 weaponnum); u32 botinvGetItemType(struct chrdata *chr, u32 weaponnum); bool botinvGiveSingleWeapon(struct chrdata *chr, u32 weaponnum); diff --git a/src/include/types.h b/src/include/types.h index c0b2189e2..de2d2a184 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -4743,14 +4743,6 @@ struct challenge { /*0x09*/ u8 unlockfeatures[16]; }; -struct scenariodata_cbt { - u32 unk00; - u32 unk04; - u32 unk08; - u16 unk0c; - s16 unk0e[1]; // possibly for a different scenario - see botGetNumTeammatesDefendingHill -}; - struct scenariodata_htb { u32 unk00; struct prop *token; // Briefcase or chr @@ -4823,7 +4815,6 @@ struct scenariodata_ctc { struct scenariodata { union { - struct scenariodata_cbt cbt; struct scenariodata_htb htb; struct scenariodata_htm htm; struct scenariodata_pac pac; @@ -6929,14 +6920,14 @@ struct aibotweaponpreference { u8 unk01; u8 unk02; u8 unk03; - u16 unk04_00 : 1; - u16 unk04_01 : 1; + u16 haspriammogoal : 1; + u16 hassecammogoal : 1; u16 pridistconfig : 4; u16 secdistconfig : 4; - u16 unk06; - u16 unk08; - u16 unk0a; - u16 unk0c; + u16 targetammopri; + u16 targetammosec; + u16 criticalammopri; + u16 criticalammosec; u16 reloaddelay : 3; // in seconds u16 allowpartialreloaddelay : 1; };