From 46d30ff2ecd5ed30df6c68ab241f3533bd92e922 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 23 Feb 2021 17:09:23 +1000 Subject: [PATCH] Decompile aibotSwitchToWeapon --- src/game/chr/chr.c | 8 +- src/game/core.c | 2 +- src/game/game_0147d0.c | 18 +- src/game/game_190260.c | 30 ++-- src/game/game_197600.c | 308 +++++++++++---------------------- src/game/game_1999b0.c | 47 ++--- src/game/propobj.c | 2 +- src/game/sight.c | 6 +- src/game/training/training.c | 4 +- src/include/game/game_197600.h | 2 +- src/include/game/game_1999b0.h | 6 +- src/include/types.h | 17 +- 12 files changed, 171 insertions(+), 279 deletions(-) diff --git a/src/game/chr/chr.c b/src/game/chr/chr.c index 54cf50670..8da0bb502 100644 --- a/src/game/chr/chr.c +++ b/src/game/chr/chr.c @@ -4023,11 +4023,11 @@ void chrUpdateCloak(struct chrdata *chr) qty = chr->aibot->unk2c4; chr->aibot->unk2c4 -= qty; - if (chr->aibot->unk024[0] > 0) { - chr->aibot->unk024[0] -= qty; + if (chr->aibot->loadedammo[0] > 0) { + chr->aibot->loadedammo[0] -= qty; - if (chr->aibot->unk024[0] <= 0) { - chr->aibot->unk024[0] = 0; + if (chr->aibot->loadedammo[0] <= 0) { + chr->aibot->loadedammo[0] = 0; } } else { ammotype = weaponGetAmmoTypeByFunction(WEAPON_RCP120, 0); diff --git a/src/game/core.c b/src/game/core.c index b73afbcf1..021060026 100644 --- a/src/game/core.c +++ b/src/game/core.c @@ -689,7 +689,7 @@ void coreFindThreatsForProp(struct prop *prop, bool inchild, struct coord *playe pass = true; break; case WEAPON_DRAGON: - if (weapon->thrown == 1U) { + if (weapon->gunfunc == (u32)FUNC_SECONDARY) { pass = true; } break; diff --git a/src/game/game_0147d0.c b/src/game/game_0147d0.c index d45b27387..196ddd3dc 100644 --- a/src/game/game_0147d0.c +++ b/src/game/game_0147d0.c @@ -157,8 +157,8 @@ void aibotAllocate(s32 chrnum, s32 aibotnum) aibot->unk02c[1] = 0; aibot->unk034 = 0; aibot->unk040 = 0.0f; - aibot->unk024[0] = 0; - aibot->unk024[1] = 0; + aibot->loadedammo[0] = 0; + aibot->loadedammo[1] = 0; aibot->unk058 = 0; aibot->unk059 = 0; aibot->unk05c = 0; @@ -185,13 +185,13 @@ void aibotAllocate(s32 chrnum, s32 aibotnum) aibot->weaponnum = WEAPON_UNARMED; - aibot->unk04d = 0; - aibot->unk04e = 0; + aibot->unk04d[0] = 0; + aibot->unk04d[1] = 0; aibot->unk044 = NULL; aibot->unk0a0 = 0; aibot->gunfunc = 0; - aibot->unk04c_01 = 1; + aibot->iscloserangeweapon = true; aibot->teamisonlyai = 0; aibot->unk09c_00 = 0; aibot->unk09c_01 = 0; @@ -206,14 +206,14 @@ void aibotAllocate(s32 chrnum, s32 aibotnum) aibot->unk04a = -1; aibot->unk0bc = -1; - aibot->unk0c8 = 0; - aibot->unk0c4 = 0; + aibot->unk0c4[HAND_LEFT] = 0; + aibot->unk0c4[HAND_RIGHT] = 0; aibot->unk0cc = 0; aibot->unk0d0 = 0; aibot->unk0d8 = 0; aibot->unk0dc = 0; - aibot->unk0e2 = 0; - aibot->unk0e0 = 0; + aibot->unk0e0[HAND_LEFT] = 0; + aibot->unk0e0[HAND_RIGHT] = 0; aibot->unk0e4[1] = 0.0f; aibot->unk0e4[0] = 0.0f; diff --git a/src/game/game_190260.c b/src/game/game_190260.c index 282b30adb..b77bfe877 100644 --- a/src/game/game_190260.c +++ b/src/game/game_190260.c @@ -353,7 +353,7 @@ glabel mpChrReset // aibotClearInventory(chr); // // aibot->gunfunc = 0; -// aibot->unk04c_01 = 1; +// aibot->iscloserangeweapon = true; // aibot->unk09c_00 = 0; // aibot->cloakdeviceenabled = false; // aibot->unk04c_04 = 0; @@ -361,8 +361,8 @@ glabel mpChrReset // aibot->unk09c_01 = 0; // aibot->unk04c_05 = 0; // aibot->weaponnum = WEAPON_UNARMED; -// aibot->unk024 = 0; -// aibot->unk028 = 0; +// aibot->loadedammo[0] = 0; +// aibot->loadedammo[1] = 0; // aibot->prop = NULL; // aibot->unk02c = 0; // aibot->unk02e = 0; @@ -600,7 +600,7 @@ u32 propobjHandlePickupByAibot(struct prop *prop, struct chrdata *chr) qty = weaponGetPickupAmmoQty(weapon); if (qty) { - aibotGiveAmmoByWeapon(chr->aibot, weapon->weaponnum, weapon->thrown, qty); + aibotGiveAmmoByWeapon(chr->aibot, weapon->weaponnum, weapon->gunfunc, qty); } if (itemtype) { @@ -1101,7 +1101,7 @@ s32 mpObjIsSafe(struct defaultobj *obj) weapon->weaponnum == WEAPON_REMOTEMINE || weapon->weaponnum == WEAPON_TIMEDMINE || weapon->weaponnum == WEAPON_ROCKET2 || - (weapon->weaponnum == WEAPON_DRAGON && weapon->thrown == 1)) { + (weapon->weaponnum == WEAPON_DRAGON && weapon->gunfunc == FUNC_SECONDARY)) { return false; } @@ -2527,10 +2527,10 @@ void func0f192628(struct chrdata *chr, struct prop *arg1) aibotRemoveInvItem(chr, chr->aibot->weaponnum); - chr->aibot->unk024[0] = 0; - chr->aibot->unk024[1] = 0; + chr->aibot->loadedammo[0] = 0; + chr->aibot->loadedammo[1] = 0; - func0f1994b0(chr, true, false); + aibotSwitchToWeapon(chr, WEAPON_UNARMED, FUNC_PRIMARY); } } @@ -3596,7 +3596,7 @@ glabel func0f19369c /* f193710: afa8001c */ sw $t0,0x1c($sp) /* f193714: afa70028 */ sw $a3,0x28($sp) /* f193718: 00055880 */ sll $t3,$a1,0x2 -/* f19371c: 0fc6667e */ jal weaponGetClipSizeByFunction +/* f19371c: 0fc6667e */ jal weaponGetClipCapacityByFunction /* f193720: 000b2fc2 */ srl $a1,$t3,0x1f /* f193724: 8fa70028 */ lw $a3,0x28($sp) /* f193728: 8faf002c */ lw $t7,0x2c($sp) @@ -5022,7 +5022,7 @@ glabel var7f1b8fc8 /* f194c20: 26100001 */ addiu $s0,$s0,0x1 /* f194c24: 02002825 */ or $a1,$s0,$zero /* f194c28: 24060001 */ addiu $a2,$zero,0x1 -/* f194c2c: 0fc66690 */ jal func0f199a40 +/* f194c2c: 0fc66690 */ jal aibotReloadWeapon /* f194c30: afa70054 */ sw $a3,0x54($sp) /* f194c34: 10000030 */ b .L0f194cf8 /* f194c38: 8fa70054 */ lw $a3,0x54($sp) @@ -5043,7 +5043,7 @@ glabel var7f1b8fc8 /* f194c70: 00054880 */ sll $t1,$a1,0x2 /* f194c74: 00092fc2 */ srl $a1,$t1,0x1f /* f194c78: afa70054 */ sw $a3,0x54($sp) -/* f194c7c: 0fc6667e */ jal weaponGetClipSizeByFunction +/* f194c7c: 0fc6667e */ jal weaponGetClipCapacityByFunction /* f194c80: afa302e8 */ sw $v1,0x2e8($sp) /* f194c84: 8fa302e8 */ lw $v1,0x2e8($sp) /* f194c88: 8fa70054 */ lw $a3,0x54($sp) @@ -5105,7 +5105,7 @@ glabel var7f1b8fc8 /* f194d58: 00003825 */ or $a3,$zero,$zero /* f194d5c: 02802025 */ or $a0,$s4,$zero /* f194d60: 00002825 */ or $a1,$zero,$zero -/* f194d64: 0fc66690 */ jal func0f199a40 +/* f194d64: 0fc66690 */ jal aibotReloadWeapon /* f194d68: 00003025 */ or $a2,$zero,$zero /* f194d6c: 8e090000 */ lw $t1,0x0($s0) /* f194d70: 24010003 */ addiu $at,$zero,0x3 @@ -5117,7 +5117,7 @@ glabel var7f1b8fc8 /* f194d88: 3c071000 */ lui $a3,0x1000 /* f194d8c: 02802025 */ or $a0,$s4,$zero /* f194d90: 24050001 */ addiu $a1,$zero,0x1 -/* f194d94: 0fc66690 */ jal func0f199a40 +/* f194d94: 0fc66690 */ jal aibotReloadWeapon /* f194d98: 00003025 */ or $a2,$zero,$zero .L0f194d9c: /* f194d9c: 1000000e */ b .L0f194dd8 @@ -7598,7 +7598,7 @@ glabel var7f1b8fc8 /* f1970fc: 8e450020 */ lw $a1,0x20($s2) /* f197100: 00066880 */ sll $t5,$a2,0x2 /* f197104: 000d37c2 */ srl $a2,$t5,0x1f -/* f197108: 0fc6675c */ jal func0f199d70 +/* f197108: 0fc6675c */ jal aibotTryRemoveAmmoFromReserve /* f19710c: 02e03825 */ or $a3,$s7,$zero /* f197110: 0fc668df */ jal func0f19a37c /* f197114: 02802025 */ or $a0,$s4,$zero @@ -7618,7 +7618,7 @@ glabel var7f1b8fc8 /* f19714c: 8e450020 */ lw $a1,0x20($s2) /* f197150: 02802025 */ or $a0,$s4,$zero /* f197154: 02e02825 */ or $a1,$s7,$zero -/* f197158: 0fc6652c */ jal func0f1994b0 +/* f197158: 0fc6652c */ jal aibotSwitchToWeapon /* f19715c: 00003025 */ or $a2,$zero,$zero /* f197160: 8e8902d4 */ lw $t1,0x2d4($s4) .L0f197164: diff --git a/src/game/game_197600.c b/src/game/game_197600.c index bf2da548c..fba913871 100644 --- a/src/game/game_197600.c +++ b/src/game/game_197600.c @@ -2446,7 +2446,7 @@ glabel var7f1b9094 /* f199470: 8fa400a0 */ lw $a0,0xa0($sp) .L0f199474: /* f199474: 8fa5009c */ lw $a1,0x9c($sp) -/* f199478: 0fc6652c */ jal func0f1994b0 +/* f199478: 0fc6652c */ jal aibotSwitchToWeapon /* f19947c: 8fa60098 */ lw $a2,0x98($sp) .L0f199480: /* f199480: 8fbf004c */ lw $ra,0x4c($sp) @@ -2464,214 +2464,102 @@ glabel var7f1b9094 /* f1994ac: 27bd00a0 */ addiu $sp,$sp,0xa0 ); -GLOBAL_ASM( -glabel func0f1994b0 -/* f1994b0: 27bdffa0 */ addiu $sp,$sp,-96 -/* f1994b4: afb20020 */ sw $s2,0x20($sp) -/* f1994b8: 00809025 */ or $s2,$a0,$zero -/* f1994bc: afbf0024 */ sw $ra,0x24($sp) -/* f1994c0: afb1001c */ sw $s1,0x1c($sp) -/* f1994c4: afb00018 */ sw $s0,0x18($sp) -/* f1994c8: afa50064 */ sw $a1,0x64($sp) -/* f1994cc: 10800006 */ beqz $a0,.L0f1994e8 -/* f1994d0: afa60068 */ sw $a2,0x68($sp) -/* f1994d4: 8c8202d4 */ lw $v0,0x2d4($a0) -/* f1994d8: 8fae0064 */ lw $t6,0x64($sp) -/* f1994dc: 24010057 */ addiu $at,$zero,0x57 -/* f1994e0: 14400003 */ bnez $v0,.L0f1994f0 -/* f1994e4: 00000000 */ nop -.L0f1994e8: -/* f1994e8: 100000a2 */ b .L0f199774 -/* f1994ec: 00001025 */ or $v0,$zero,$zero -.L0f1994f0: -/* f1994f0: 15c10003 */ bne $t6,$at,.L0f199500 -/* f1994f4: 00408825 */ or $s1,$v0,$zero -/* f1994f8: 1000009e */ b .L0f199774 -/* f1994fc: 24020001 */ addiu $v0,$zero,0x1 -.L0f199500: -/* f199500: 8faf0064 */ lw $t7,0x64($sp) -/* f199504: 24010001 */ addiu $at,$zero,0x1 -/* f199508: 02402025 */ or $a0,$s2,$zero -/* f19950c: 51e10009 */ beql $t7,$at,.L0f199534 -/* f199510: 8fb90064 */ lw $t9,0x64($sp) -/* f199514: 0fc65f3c */ jal aibotGetInvItem -/* f199518: 01e02825 */ or $a1,$t7,$zero -/* f19951c: 14400004 */ bnez $v0,.L0f199530 -/* f199520: afa2005c */ sw $v0,0x5c($sp) -/* f199524: 24180001 */ addiu $t8,$zero,0x1 -/* f199528: afb80064 */ sw $t8,0x64($sp) -/* f19952c: afa00068 */ sw $zero,0x68($sp) -.L0f199530: -/* f199530: 8fb90064 */ lw $t9,0x64($sp) -.L0f199534: -/* f199534: 8e2a0020 */ lw $t2,0x20($s1) -/* f199538: 8fac0068 */ lw $t4,0x68($sp) -/* f19953c: 02204025 */ or $t0,$s1,$zero -/* f199540: 032a5826 */ xor $t3,$t9,$t2 -/* f199544: 000b582b */ sltu $t3,$zero,$t3 -/* f199548: afab0048 */ sw $t3,0x48($sp) -/* f19954c: 8e2d004c */ lw $t5,0x4c($s1) -/* f199550: 2419003c */ addiu $t9,$zero,0x3c -/* f199554: 02202025 */ or $a0,$s1,$zero -/* f199558: 000d7080 */ sll $t6,$t5,0x2 -/* f19955c: 000e7fc2 */ srl $t7,$t6,0x1f -/* f199560: 018fc026 */ xor $t8,$t4,$t7 -/* f199564: 0018c02b */ sltu $t8,$zero,$t8 -/* f199568: 11600016 */ beqz $t3,.L0f1995c4 -/* f19956c: afb80044 */ sw $t8,0x44($sp) -/* f199570: ae3900cc */ sw $t9,0xcc($s1) -/* f199574: 00002825 */ or $a1,$zero,$zero -/* f199578: 02203025 */ or $a2,$s1,$zero -/* f19957c: 02403825 */ or $a3,$s2,$zero -/* f199580: 24090004 */ addiu $t1,$zero,0x4 -.L0f199584: -/* f199584: ad0000c4 */ sw $zero,0xc4($t0) -/* f199588: a080004d */ sb $zero,0x4d($a0) -/* f19958c: a4c000e0 */ sh $zero,0xe0($a2) -/* f199590: 8ce20170 */ lw $v0,0x170($a3) -/* f199594: 25080004 */ addiu $t0,$t0,0x4 -/* f199598: 24840001 */ addiu $a0,$a0,0x1 -/* f19959c: 10400006 */ beqz $v0,.L0f1995b8 -/* f1995a0: 24a50002 */ addiu $a1,$a1,0x2 -/* f1995a4: 8c430004 */ lw $v1,0x4($v0) -/* f1995a8: 8c6a0040 */ lw $t2,0x40($v1) -/* f1995ac: 354d0004 */ ori $t5,$t2,0x4 -/* f1995b0: ac6d0040 */ sw $t5,0x40($v1) -/* f1995b4: ace00170 */ sw $zero,0x170($a3) -.L0f1995b8: -/* f1995b8: 24c60002 */ addiu $a2,$a2,0x2 -/* f1995bc: 14a9fff1 */ bne $a1,$t1,.L0f199584 -/* f1995c0: 24e70004 */ addiu $a3,$a3,0x4 -.L0f1995c4: -/* f1995c4: 8fae0044 */ lw $t6,0x44($sp) -/* f1995c8: 8fac0048 */ lw $t4,0x48($sp) -/* f1995cc: 00001825 */ or $v1,$zero,$zero -/* f1995d0: 15c00002 */ bnez $t6,.L0f1995dc -/* f1995d4: 02204025 */ or $t0,$s1,$zero -/* f1995d8: 11800012 */ beqz $t4,.L0f199624 -.L0f1995dc: -/* f1995dc: 24100008 */ addiu $s0,$zero,0x8 -.L0f1995e0: -/* f1995e0: 8d070024 */ lw $a3,0x24($t0) -/* f1995e4: 02202025 */ or $a0,$s1,$zero -/* f1995e8: 58e0000c */ blezl $a3,.L0f19961c -/* f1995ec: 24630004 */ addiu $v1,$v1,0x4 -/* f1995f0: 8e26004c */ lw $a2,0x4c($s1) -/* f1995f4: 8e250020 */ lw $a1,0x20($s1) -/* f1995f8: afa80038 */ sw $t0,0x38($sp) -/* f1995fc: 00067880 */ sll $t7,$a2,0x2 -/* f199600: 000f37c2 */ srl $a2,$t7,0x1f -/* f199604: 0fc6678f */ jal aibotGiveAmmoByWeapon -/* f199608: afa3003c */ sw $v1,0x3c($sp) -/* f19960c: 8fa80038 */ lw $t0,0x38($sp) -/* f199610: 8fa3003c */ lw $v1,0x3c($sp) -/* f199614: ad000024 */ sw $zero,0x24($t0) -/* f199618: 24630004 */ addiu $v1,$v1,0x4 -.L0f19961c: -/* f19961c: 1470fff0 */ bne $v1,$s0,.L0f1995e0 -/* f199620: 25080004 */ addiu $t0,$t0,0x4 -.L0f199624: -/* f199624: 8fb90068 */ lw $t9,0x68($sp) -/* f199628: 922e004c */ lbu $t6,0x4c($s1) -/* f19962c: 00195140 */ sll $t2,$t9,0x5 -/* f199630: 314d0020 */ andi $t5,$t2,0x20 -/* f199634: 31ccffdf */ andi $t4,$t6,0xffdf -/* f199638: 01ac7825 */ or $t7,$t5,$t4 -/* f19963c: a22f004c */ sb $t7,0x4c($s1) -/* f199640: 8fb80064 */ lw $t8,0x64($sp) -/* f199644: ae380020 */ sw $t8,0x20($s1) -/* f199648: 8fab0044 */ lw $t3,0x44($sp) -/* f19964c: 8fb90048 */ lw $t9,0x48($sp) -/* f199650: 51600011 */ beqzl $t3,.L0f199698 -/* f199654: 8fae0048 */ lw $t6,0x48($sp) -/* f199658: 1720000e */ bnez $t9,.L0f199694 -/* f19965c: 00008025 */ or $s0,$zero,$zero -/* f199660: 02403825 */ or $a3,$s2,$zero -.L0f199664: -/* f199664: 8cea0170 */ lw $t2,0x170($a3) -/* f199668: 02402025 */ or $a0,$s2,$zero -/* f19966c: 02002825 */ or $a1,$s0,$zero -/* f199670: 11400004 */ beqz $t2,.L0f199684 -/* f199674: 00003025 */ or $a2,$zero,$zero -/* f199678: 0fc66690 */ jal func0f199a40 -/* f19967c: afa7002c */ sw $a3,0x2c($sp) -/* f199680: 8fa7002c */ lw $a3,0x2c($sp) -.L0f199684: -/* f199684: 26100001 */ addiu $s0,$s0,0x1 -/* f199688: 24010002 */ addiu $at,$zero,0x2 -/* f19968c: 1601fff5 */ bne $s0,$at,.L0f199664 -/* f199690: 24e70004 */ addiu $a3,$a3,0x4 -.L0f199694: -/* f199694: 8fae0048 */ lw $t6,0x48($sp) -.L0f199698: -/* f199698: 55c00018 */ bnezl $t6,.L0f1996fc -/* f19969c: 8fa40064 */ lw $a0,0x64($sp) -/* f1996a0: 0fc4a2bd */ jal weaponGetModel -/* f1996a4: 8fa40064 */ lw $a0,0x64($sp) -/* f1996a8: 04400013 */ bltz $v0,.L0f1996f8 -/* f1996ac: 00402825 */ or $a1,$v0,$zero -/* f1996b0: 8fad005c */ lw $t5,0x5c($sp) -/* f1996b4: 51a00011 */ beqzl $t5,.L0f1996fc -/* f1996b8: 8fa40064 */ lw $a0,0x64($sp) -/* f1996bc: 8dac0000 */ lw $t4,0x0($t5) -/* f1996c0: 24010003 */ addiu $at,$zero,0x3 -/* f1996c4: 5581000d */ bnel $t4,$at,.L0f1996fc -/* f1996c8: 8fa40064 */ lw $a0,0x64($sp) -/* f1996cc: 8e4f0174 */ lw $t7,0x174($s2) -/* f1996d0: 02402025 */ or $a0,$s2,$zero -/* f1996d4: 8fa60064 */ lw $a2,0x64($sp) -/* f1996d8: 55e00008 */ bnezl $t7,.L0f1996fc -/* f1996dc: 8fa40064 */ lw $a0,0x64($sp) -/* f1996e0: 0fc22eb4 */ jal chrGiveWeapon -/* f1996e4: 3c071000 */ lui $a3,0x1000 -/* f1996e8: 02402025 */ or $a0,$s2,$zero -/* f1996ec: 24050001 */ addiu $a1,$zero,0x1 -/* f1996f0: 0fc66690 */ jal func0f199a40 -/* f1996f4: 00003025 */ or $a2,$zero,$zero -.L0f1996f8: -/* f1996f8: 8fa40064 */ lw $a0,0x64($sp) -.L0f1996fc: -/* f1996fc: 0fc2c401 */ jal weaponGetFunctionById -/* f199700: 8fa50068 */ lw $a1,0x68($sp) -/* f199704: 0002202b */ sltu $a0,$zero,$v0 -/* f199708: 10800004 */ beqz $a0,.L0f19971c -/* f19970c: 00001825 */ or $v1,$zero,$zero -/* f199710: 8c440000 */ lw $a0,0x0($v0) -/* f199714: 38980003 */ xori $t8,$a0,0x3 -/* f199718: 2f040001 */ sltiu $a0,$t8,0x1 -.L0f19971c: -/* f19971c: 922e004c */ lbu $t6,0x4c($s1) -/* f199720: 00805825 */ or $t3,$a0,$zero -/* f199724: 000bc980 */ sll $t9,$t3,0x6 -/* f199728: 332a0040 */ andi $t2,$t9,0x40 -/* f19972c: 31cdffbf */ andi $t5,$t6,0xffbf -/* f199730: 014d6025 */ or $t4,$t2,$t5 -/* f199734: a22c004c */ sb $t4,0x4c($s1) -/* f199738: 24040008 */ addiu $a0,$zero,0x8 -/* f19973c: 02403825 */ or $a3,$s2,$zero -.L0f199740: -/* f199740: 8ce20170 */ lw $v0,0x170($a3) -/* f199744: 24630004 */ addiu $v1,$v1,0x4 -/* f199748: 10400007 */ beqz $v0,.L0f199768 -/* f19974c: 00000000 */ nop -/* f199750: 8e4f02d4 */ lw $t7,0x2d4($s2) -/* f199754: 8c4e0004 */ lw $t6,0x4($v0) -/* f199758: 8df8004c */ lw $t8,0x4c($t7) -/* f19975c: 00185880 */ sll $t3,$t8,0x2 -/* f199760: 000bcfc2 */ srl $t9,$t3,0x1f -/* f199764: a1d9005f */ sb $t9,0x5f($t6) -.L0f199768: -/* f199768: 1464fff5 */ bne $v1,$a0,.L0f199740 -/* f19976c: 24e70004 */ addiu $a3,$a3,0x4 -/* f199770: 24020001 */ addiu $v0,$zero,0x1 -.L0f199774: -/* f199774: 8fbf0024 */ lw $ra,0x24($sp) -/* f199778: 8fb00018 */ lw $s0,0x18($sp) -/* f19977c: 8fb1001c */ lw $s1,0x1c($sp) -/* f199780: 8fb20020 */ lw $s2,0x20($sp) -/* f199784: 03e00008 */ jr $ra -/* f199788: 27bd0060 */ addiu $sp,$sp,0x60 -); +bool aibotSwitchToWeapon(struct chrdata *chr, s32 weaponnum, s32 funcnum) +{ + struct invitem *item; + struct weaponfunc *func; + struct aibot *aibot; + s32 i; + s32 modelnum; + bool changinggun; + bool changingfunc; + + if (!chr || !chr->aibot) { + return false; + } + + aibot = chr->aibot; + + if (weaponnum == WEAPON_BRIEFCASE2) { + return true; + } + + // If changing to anything other than unarmed, make sure the aibot has the + // weapon in their inventory. Otherwise make them switch to unarmed. + if (weaponnum != WEAPON_UNARMED) { + item = aibotGetInvItem(chr, weaponnum); + + if (!item) { + weaponnum = WEAPON_UNARMED; + funcnum = FUNC_PRIMARY; + } + } + + changinggun = weaponnum != aibot->weaponnum; + changingfunc = funcnum != aibot->gunfunc; + + if (changinggun) { + aibot->unk0cc = 60; + + for (i = 0; i < 2; i++) { + aibot->unk0c4[i] = 0; + aibot->unk04d[i] = 0; + aibot->unk0e0[i] = 0; + + if (chr->weapons_held[i]) { + chr->weapons_held[i]->obj->hidden |= OBJHFLAG_00000004; + chr->weapons_held[i] = NULL; + } + } + } + + // Return any loaded ammo to reserve + if (changingfunc || changinggun) { + for (i = 0; i < 2; i++) { + if (aibot->loadedammo[i] > 0) { + aibotGiveAmmoByWeapon(aibot, aibot->weaponnum, aibot->gunfunc, aibot->loadedammo[i]); + aibot->loadedammo[i] = 0; + } + } + } + + // Assign new weapon and function + aibot->gunfunc = funcnum; + aibot->weaponnum = weaponnum; + + // Load ammo from reserve into new weapon + if (changingfunc && !changinggun) { + for (i = 0; i < 2; i++) { + if (chr->weapons_held[i]) { + aibotReloadWeapon(chr, i, false); + } + } + } + + if (!changinggun) { + modelnum = weaponGetModel(weaponnum); + + // @dangerous: item is uninitialised if weaponnum is WEAPON_UNARMED. + // This function assumes weaponGetModel returns a negative value for + // WEAPON_UNARMED which is a dangerous assumption to make, but correct. + if (modelnum >= 0 && item && item->type == INVITEMTYPE_DUAL && chr->weapons_held[1] == NULL) { + chrGiveWeapon(chr, modelnum, weaponnum, 0x10000000); + aibotReloadWeapon(chr, HAND_LEFT, false); + } + } + + func = weaponGetFunctionById(weaponnum, funcnum); + + aibot->iscloserangeweapon = func && func->type == INVENTORYFUNCTYPE_CLOSE; + + for (i = 0; i < 2; i++) { + if (chr->weapons_held[i]) { + chr->weapons_held[i]->weapon->gunfunc = chr->aibot->gunfunc; + } + } + + return true; +} void func0f19978c(struct chrdata *chr, s32 weaponnum, u8 arg2) { @@ -2714,7 +2602,7 @@ void func0f19978c(struct chrdata *chr, s32 weaponnum, u8 arg2) if ((arg2 && weaponnum >= WEAPON_FALCON2) || (!arg2 && weaponnum == chr->aibot->weaponnum)) { - func0f1994b0(chr, true, false); + aibotSwitchToWeapon(chr, WEAPON_UNARMED, FUNC_PRIMARY); } chr->hidden |= CHRHFLAG_00000001; diff --git a/src/game/game_1999b0.c b/src/game/game_1999b0.c index 145b56f14..46b64d8ca 100644 --- a/src/game/game_1999b0.c +++ b/src/game/game_1999b0.c @@ -32,7 +32,7 @@ s32 weaponGetAmmoTypeByFunction(s32 weaponnum, u32 funcnum) return 0; } -s32 weaponGetClipSizeByFunction(s32 weaponnum, u32 funcnum) +s32 weaponGetClipCapacityByFunction(s32 weaponnum, u32 funcnum) { if (weaponnum >= WEAPON_FALCON2 && weaponnum <= WEAPON_SUICIDEPILL) { struct inventory_ammo *ammo = weaponGetAmmoByFunction(weaponnum, funcnum); @@ -45,24 +45,24 @@ s32 weaponGetClipSizeByFunction(s32 weaponnum, u32 funcnum) return 0; } -void func0f199a40(struct chrdata *chr, u32 index, bool arg2) +void aibotReloadWeapon(struct chrdata *chr, s32 handnum, bool withsound) { struct aibot *aibot = chr->aibot; - aibot->unk02c[index] = 0; - aibot->unk0e4[index] = 0; + aibot->unk02c[handnum] = 0; + aibot->unk0e4[handnum] = 0; - if (chr->weapons_held[index] + if (chr->weapons_held[handnum] && func0f19a29c(aibot->weaponnum, aibot->gunfunc) == 0) { - s32 clipsize = weaponGetClipSizeByFunction(aibot->weaponnum, aibot->gunfunc); + s32 capacity = weaponGetClipCapacityByFunction(aibot->weaponnum, aibot->gunfunc); - if (clipsize > 0) { - s32 a = clipsize - aibot->unk024[index]; - s32 b = func0f199d70(aibot, aibot->weaponnum, aibot->gunfunc, a); + if (capacity > 0) { + s32 tryamount = capacity - aibot->loadedammo[handnum]; + s32 actualamount = aibotTryRemoveAmmoFromReserve(aibot, aibot->weaponnum, aibot->gunfunc, tryamount); - if (b > 0) { - aibot->unk024[index] += b; + if (actualamount > 0) { + aibot->loadedammo[handnum] += actualamount; - if (arg2) { + if (withsound) { if (aibot->weaponnum == WEAPON_FARSIGHTXR20) { // FarSight reload sound func0f0939f8(NULL, chr->prop, SFX_RELOAD_FARSIGHT, -1, @@ -98,7 +98,7 @@ s32 func0f199be4(struct aibot *aibot, s32 weaponnum, s32 funcnum, bool include_e equippedammotype = weaponGetAmmoTypeByFunction(aibot->weaponnum, aibot->gunfunc); if (equippedammotype == ammotype) { - qty += aibot->unk024[1] + aibot->unk024[0]; + qty += aibot->loadedammo[HAND_LEFT] + aibot->loadedammo[HAND_RIGHT]; } } } @@ -119,38 +119,45 @@ s32 aibotGetAmmoQty(struct aibot *aibot, s32 ammotype, bool include_equipped) if (include_equipped && weaponGetAmmoTypeByFunction(aibot->weaponnum, aibot->gunfunc) == ammotype) { - qty += aibot->unk024[1] + aibot->unk024[0]; + qty += aibot->loadedammo[HAND_LEFT] + aibot->loadedammo[HAND_RIGHT]; } } return qty; } -s32 func0f199d70(struct aibot *aibot, s32 weaponnum, s32 funcnum, s32 qty) +/** + * Attempt to remove the given quantity of ammo from the aibot's reserve and + * return the amount actually removed. + * + * The amount removed will be less than the attempted amount if the aibot + * doesn't have enough ammo in reserve. + */ +s32 aibotTryRemoveAmmoFromReserve(struct aibot *aibot, s32 weaponnum, s32 funcnum, s32 tryqty) { s32 result; s32 *ammoheld = &aibot->ammoheld[weaponGetAmmoTypeByFunction(weaponnum, funcnum)]; - if (!aibot || *ammoheld <= 0 || qty <= 0) { + if (!aibot || *ammoheld <= 0 || tryqty <= 0) { return 0; } if (aibot->unk064 & 1) { - return qty; + return tryqty; } dprint(); - *ammoheld -= qty; + *ammoheld -= tryqty; if (*ammoheld < 0) { - result = qty + *ammoheld; + result = tryqty + *ammoheld; *ammoheld = 0; if (dprint()) { return result; } } else { - result = qty; + result = tryqty; dprint(); } diff --git a/src/game/propobj.c b/src/game/propobj.c index 62f1e2d96..f042a5442 100644 --- a/src/game/propobj.c +++ b/src/game/propobj.c @@ -41849,7 +41849,7 @@ glabel var7f1aae98 /* f08b4b4: 240700c8 */ addiu $a3,$zero,0xc8 /* f08b4b8: 50800008 */ beqzl $a0,.L0f08b4dc /* f08b4bc: 8ca4001c */ lw $a0,0x1c($a1) -/* f08b4c0: 0fc6675c */ jal func0f199d70 +/* f08b4c0: 0fc6675c */ jal aibotTryRemoveAmmoFromReserve /* f08b4c4: 2405000e */ addiu $a1,$zero,0xe /* f08b4c8: 44800000 */ mtc1 $zero,$f0 /* f08b4cc: a20200a9 */ sb $v0,0xa9($s0) diff --git a/src/game/sight.c b/src/game/sight.c index fcfc2613b..d79854c76 100644 --- a/src/game/sight.c +++ b/src/game/sight.c @@ -2448,14 +2448,14 @@ glabel var7f1ade50 // if (weapon && weapon->base.type == OBJTYPE_WEAPON) { // switch (weapon->weaponnum) { // case WEAPON_GRENADE: -// if (weapon->thrown == true) { +// if (weapon->gunfunc == FUNC_SECONDARY) { // textid = L_GUN(212); // "PROXY" // } else { // textid = L_GUN(213); // "TIMED" // } // break; // case WEAPON_NBOMB: -// if (weapon->thrown == true) { +// if (weapon->gunfunc == FUNC_SECONDARY) { // textid = L_GUN(212); // "PROXY" // } else { // textid = L_GUN(216); // "IMPACT" @@ -2471,7 +2471,7 @@ glabel var7f1ade50 // textid = L_GUN(214); // "REMOTE" // break; // case WEAPON_DRAGON: -// if (weapon->thrown == true) { +// if (weapon->gunfunc == FUNC_SECONDARY) { // textid = L_GUN(212); // "PROXY" // } // break; diff --git a/src/game/training/training.c b/src/game/training/training.c index 557811698..295cd7079 100644 --- a/src/game/training/training.c +++ b/src/game/training/training.c @@ -1947,8 +1947,8 @@ void frEndSession(bool hidetargets) || weapon->weaponnum == WEAPON_ROCKET || weapon->weaponnum == WEAPON_TIMEDMINE || weapon->weaponnum == WEAPON_ROCKET2 - || (weapon->weaponnum == WEAPON_DRAGON && weapon->thrown == true) - || (weapon->weaponnum == WEAPON_LAPTOPGUN && weapon->thrown == true)) { + || (weapon->weaponnum == WEAPON_DRAGON && weapon->gunfunc == FUNC_SECONDARY) + || (weapon->weaponnum == WEAPON_LAPTOPGUN && weapon->gunfunc == FUNC_SECONDARY)) { func0f06b34c(obj, true); } } diff --git a/src/include/game/game_197600.h b/src/include/game/game_197600.h index a4563cd99..da1bdd830 100644 --- a/src/include/game/game_197600.h +++ b/src/include/game/game_197600.h @@ -24,7 +24,7 @@ u32 func0f198df8(void); u32 func0f198e38(void); u32 func0f198e78(void); u32 func0f198eec(void); -void func0f1994b0(struct chrdata *chr, bool arg1, bool arg2); +bool aibotSwitchToWeapon(struct chrdata *chr, s32 weaponnum, s32 funcnum); void func0f19978c(struct chrdata *chr, s32 weaponnum, u8 arg2); void func0f199964(struct chrdata *chr, u32 weaponnum); void func0f199984(struct chrdata *chr, u32 weaponnum); diff --git a/src/include/game/game_1999b0.h b/src/include/game/game_1999b0.h index 5e1ff64d7..7773f8419 100644 --- a/src/include/game/game_1999b0.h +++ b/src/include/game/game_1999b0.h @@ -5,11 +5,11 @@ #include "types.h" s32 weaponGetAmmoTypeByFunction(s32 weaponnum, u32 funcnum); -s32 weaponGetClipSizeByFunction(s32 weaponnum, u32 funcnum); -void func0f199a40(struct chrdata *chr, u32 index, bool arg2); +s32 weaponGetClipCapacityByFunction(s32 weaponnum, u32 funcnum); +void aibotReloadWeapon(struct chrdata *chr, s32 handnum, bool withsound); s32 func0f199be4(struct aibot *aibot, s32 weaponnum, s32 funcnum, bool include_equipped); s32 aibotGetAmmoQty(struct aibot *aibot, s32 ammotype, bool include_equipped); -s32 func0f199d70(struct aibot *aibot, s32 weaponnum, s32 funcnum, s32 qty); +s32 aibotTryRemoveAmmoFromReserve(struct aibot *aibot, s32 weaponnum, s32 funcnum, s32 qty); void aibotGiveAmmoByWeapon(struct aibot *aibot, s32 weaponnum, s32 funcnum, s32 qty); void aibotGiveAmmoByType(struct aibot *aibot, u32 ammotype, s32 quantity); bool aibotDoFarsightThing(struct chrdata *chr, u32 arg1, struct coord *arg2, struct coord *arg3); diff --git a/src/include/types.h b/src/include/types.h index 61fae7e8f..cfdd2580d 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -375,7 +375,7 @@ struct aibot { /*0x018*/ s8 maxitems; /*0x01c*/ s32 *ammoheld; /*0x020*/ s32 weaponnum; - /*0x024*/ s32 unk024[2]; // probably current clip count or reserve count + /*0x024*/ s32 loadedammo[2]; // amount of ammo in current clip /*0x02c*/ u16 unk02c[2]; /*0x030*/ u32 unk030; // timer of some sort /*0x034*/ u32 unk034; @@ -387,15 +387,14 @@ struct aibot { /*0x048*/ s16 unk048; /*0x04a*/ s16 unk04a; /*0x04c*/ u8 unk04c_00 : 1; - /*0x04c*/ u8 unk04c_01 : 1; + /*0x04c*/ u8 iscloserangeweapon : 1; /*0x04c*/ u8 gunfunc : 1; /*0x04c*/ u8 unk04c_03 : 1; /*0x04c*/ u8 unk04c_04 : 1; /*0x04c*/ u8 unk04c_05 : 1; /*0x04c*/ u8 cloakdeviceenabled : 1; /*0x04c*/ u8 unk04c_07 : 1; - /*0x04d*/ u8 unk04d; - /*0x04e*/ u8 unk04e; + /*0x04d*/ u8 unk04d[2]; /*0x04f*/ u8 teamisonlyai : 1; /*0x04f*/ u8 unk04f_01 : 1; /*0x04f*/ u8 unk04f_02 : 1; @@ -451,15 +450,13 @@ struct aibot { /*0x0b8*/ f32 unk0b8; /*0x0bc*/ s32 unk0bc; /*0x0c0*/ s32 attackpropnum; - /*0x0c4*/ u32 unk0c4; - /*0x0c8*/ u32 unk0c8; - /*0x0cc*/ u32 unk0cc; + /*0x0c4*/ u32 unk0c4[2]; + /*0x0cc*/ u32 unk0cc; // Timer? Related to weapon switching /*0x0d0*/ u32 unk0d0; /*0x0d4*/ s32 followprotectpropnum; /*0x0d8*/ s32 unk0d8; /*0x0dc*/ u32 unk0dc; - /*0x0e0*/ u16 unk0e0; - /*0x0e2*/ u16 unk0e2; + /*0x0e0*/ u16 unk0e0[2]; /*0x0e4*/ f32 unk0e4[2]; /*0x0ec*/ u32 unk0ec; /*0x0f0*/ u32 unk0f0; @@ -1300,7 +1297,7 @@ struct weaponobj { // objtype 0x08 /*0x5c*/ u8 weaponnum; /*0x5d*/ s8 unk5d; /*0x5e*/ s8 unk5e; - /*0x5f*/ u8 thrown; // Dragon and Laptop Gun + /*0x5f*/ u8 gunfunc; /*0x60*/ s8 unk60; /*0x61*/ s8 dualweaponnum;