From 266d29a923ea83a2c58971c417eb4aadf1b1ca2e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Fri, 17 Jan 2020 17:10:31 +1000 Subject: [PATCH] Decompile chrGetDistanceLostToTargetInLastSecond and discover commands if_target_moving_slowly, if_target_moving_away and if_target_moving_closer --- src/files/setup/setuplee.c | 2 +- src/files/setup/setuppete.c | 4 +- src/files/setup/setupsho.c | 2 +- src/game/chr/chr.c | 120 ++++++--------------------- src/game/chr/chrai.c | 2 +- src/game/chr/chraicommands.c | 26 +++--- src/include/commands.h | 33 +++++--- src/include/game/chr/chr.h | 4 +- src/include/game/chr/chraicommands.h | 6 +- src/setup/ailists.c | 5 +- src/setup/setup_000000.c | 6 +- 11 files changed, 78 insertions(+), 132 deletions(-) diff --git a/src/files/setup/setuplee.c b/src/files/setup/setuplee.c index 8c094032a..f1427cb8d 100644 --- a/src/files/setup/setuplee.c +++ b/src/files/setup/setuplee.c @@ -2313,7 +2313,7 @@ u8 func041a_bridgeclone[] = { if_chr_death_animation_finished(CHR_TARGET, /*goto*/ 0x10) if_chr_dying(CHR_TARGET, /*goto*/ 0x10) if_chr_unloaded(CHR_TARGET, /*goto*/ 0x10) - if_distance_to_home_gt_50_maybe(/*goto*/ 0x2c) + if_target_moving_away(/*goto*/ 0x2c) if_chr_distance_lt(150, /*goto*/ 0x2e) label(0x2c) if_chr_distance_lt(50, /*goto*/ 0x2e) diff --git a/src/files/setup/setuppete.c b/src/files/setup/setuppete.c index 5e578620d..ab5ea6b53 100644 --- a/src/files/setup/setuppete.c +++ b/src/files/setup/setuppete.c @@ -1966,7 +1966,7 @@ u8 func041a_robot[] = { beginloop(0x02) set_target_chr(CHR_HIDDENGUY) - if_something_chicago_robot(/*goto*/ 0x03) + if_target_moving_closer(/*goto*/ 0x03) unset_stage_flag(STAGEFLAG_ROBOT_NEAR_HOME) goto_next(0x04) @@ -2023,7 +2023,7 @@ u8 func041a_robot[] = { beginloop(0x05) set_target_chr(CHR_HIDDENGUY) - if_something_chicago_robot(/*goto*/ 0x03) + if_target_moving_closer(/*goto*/ 0x03) unset_stage_flag(STAGEFLAG_ROBOT_NEAR_HOME) goto_next(0x04) label(0x03) diff --git a/src/files/setup/setupsho.c b/src/files/setup/setupsho.c index d268bd0a5..362cd5765 100644 --- a/src/files/setup/setupsho.c +++ b/src/files/setup/setupsho.c @@ -597,7 +597,7 @@ u8 func0402_unarmed_skedar[] = { if_chr_death_animation_finished(CHR_TARGET, /*goto*/ 0x10) if_chr_dying(CHR_TARGET, /*goto*/ 0x10) if_chr_unloaded(CHR_TARGET, /*goto*/ 0x10) - if_distance_to_home_gt_50_maybe(/*goto*/ 0x2d) + if_target_moving_away(/*goto*/ 0x2d) if_chr_distance_lt(150, /*goto*/ 0x2f) label(0x2d) if_chr_distance_lt(50, /*goto*/ 0x2f) diff --git a/src/game/chr/chr.c b/src/game/chr/chr.c index dc0a1c6d4..319bdf31e 100644 --- a/src/game/chr/chr.c +++ b/src/game/chr/chr.c @@ -51750,111 +51750,41 @@ glabel func0f04c2e8 /* f04c440: 00000000 */ sll $zero,$zero,0x0 ); -GLOBAL_ASM( -glabel func0f04c444 -/* f04c444: 27bdffe8 */ addiu $sp,$sp,-24 -/* f04c448: afbf0014 */ sw $ra,0x14($sp) -/* f04c44c: 8c8e001c */ lw $t6,0x1c($a0) -/* f04c450: 51c00048 */ beqzl $t6,.L0f04c574 -/* f04c454: 8fbf0014 */ lw $ra,0x14($sp) -/* f04c458: 0fc0a221 */ jal chrGetTargetProp -/* f04c45c: afa40018 */ sw $a0,0x18($sp) -/* f04c460: 10400043 */ beqz $v0,.L0f04c570 -/* f04c464: 8fa40018 */ lw $a0,0x18($sp) -/* f04c468: 3c06800a */ lui $a2,%hi(g_Vars) -/* f04c46c: 24c69fc0 */ addiu $a2,$a2,%lo(g_Vars) -/* f04c470: 8ccf0038 */ lw $t7,0x38($a2) -/* f04c474: 00002825 */ or $a1,$zero,$zero -/* f04c478: 2403003c */ addiu $v1,$zero,0x3c -/* f04c47c: 59e0003d */ blezl $t7,.L0f04c574 -/* f04c480: 8fbf0014 */ lw $ra,0x14($sp) -/* f04c484: 8c98001c */ lw $t8,0x1c($a0) -.L0f04c488: -/* f04c488: c4440008 */ lwc1 $f4,0x8($v0) -/* f04c48c: 90890290 */ lbu $t1,0x290($a0) -/* f04c490: c7060008 */ lwc1 $f6,0x8($t8) -/* f04c494: 24a50001 */ addiu $a1,$a1,0x1 -/* f04c498: 00095080 */ sll $t2,$t1,0x2 -/* f04c49c: 46062201 */ sub.s $f8,$f4,$f6 -/* f04c4a0: 008a5821 */ addu $t3,$a0,$t2 -/* f04c4a4: 4600428d */ trunc.w.s $f10,$f8 -/* f04c4a8: 44085000 */ mfc1 $t0,$f10 -/* f04c4ac: 00000000 */ sll $zero,$zero,0x0 -/* f04c4b0: ad6801a0 */ sw $t0,0x1a0($t3) -/* f04c4b4: 908c0290 */ lbu $t4,0x290($a0) -/* f04c4b8: 8c98001c */ lw $t8,0x1c($a0) -/* f04c4bc: 258d0001 */ addiu $t5,$t4,0x1 -/* f04c4c0: 31ae00ff */ andi $t6,$t5,0xff -/* f04c4c4: 01c3001a */ div $zero,$t6,$v1 -/* f04c4c8: 00007810 */ mfhi $t7 -/* f04c4cc: a08d0290 */ sb $t5,0x290($a0) -/* f04c4d0: a08f0290 */ sb $t7,0x290($a0) -/* f04c4d4: c4500010 */ lwc1 $f16,0x10($v0) -/* f04c4d8: c7120010 */ lwc1 $f18,0x10($t8) -/* f04c4dc: 31ea00ff */ andi $t2,$t7,0xff -/* f04c4e0: 000a4080 */ sll $t0,$t2,0x2 -/* f04c4e4: 46128101 */ sub.s $f4,$f16,$f18 -/* f04c4e8: 00885821 */ addu $t3,$a0,$t0 -/* f04c4ec: 14600002 */ bnez $v1,.L0f04c4f8 -/* f04c4f0: 00000000 */ sll $zero,$zero,0x0 -/* f04c4f4: 0007000d */ break 0x7 -.L0f04c4f8: -/* f04c4f8: 2401ffff */ addiu $at,$zero,-1 -/* f04c4fc: 14610004 */ bne $v1,$at,.L0f04c510 -/* f04c500: 3c018000 */ lui $at,0x8000 -/* f04c504: 15c10002 */ bne $t6,$at,.L0f04c510 -/* f04c508: 00000000 */ sll $zero,$zero,0x0 -/* f04c50c: 0006000d */ break 0x6 -.L0f04c510: -/* f04c510: 4600218d */ trunc.w.s $f6,$f4 -/* f04c514: 44093000 */ mfc1 $t1,$f6 -/* f04c518: 00000000 */ sll $zero,$zero,0x0 -/* f04c51c: ad6901a0 */ sw $t1,0x1a0($t3) -/* f04c520: 908c0290 */ lbu $t4,0x290($a0) -/* f04c524: 258d0001 */ addiu $t5,$t4,0x1 -/* f04c528: 31ae00ff */ andi $t6,$t5,0xff -/* f04c52c: 01c3001a */ div $zero,$t6,$v1 -/* f04c530: a08d0290 */ sb $t5,0x290($a0) -/* f04c534: 00007810 */ mfhi $t7 -/* f04c538: a08f0290 */ sb $t7,0x290($a0) -/* f04c53c: 14600002 */ bnez $v1,.L0f04c548 -/* f04c540: 00000000 */ sll $zero,$zero,0x0 -/* f04c544: 0007000d */ break 0x7 -.L0f04c548: -/* f04c548: 2401ffff */ addiu $at,$zero,-1 -/* f04c54c: 14610004 */ bne $v1,$at,.L0f04c560 -/* f04c550: 3c018000 */ lui $at,0x8000 -/* f04c554: 15c10002 */ bne $t6,$at,.L0f04c560 -/* f04c558: 00000000 */ sll $zero,$zero,0x0 -/* f04c55c: 0006000d */ break 0x6 -.L0f04c560: -/* f04c560: 8cd80038 */ lw $t8,0x38($a2) -/* f04c564: 00b8082a */ slt $at,$a1,$t8 -/* f04c568: 5420ffc7 */ bnezl $at,.L0f04c488 -/* f04c56c: 8c98001c */ lw $t8,0x1c($a0) -.L0f04c570: -/* f04c570: 8fbf0014 */ lw $ra,0x14($sp) -.L0f04c574: -/* f04c574: 27bd0018 */ addiu $sp,$sp,0x18 -/* f04c578: 03e00008 */ jr $ra -/* f04c57c: 00000000 */ sll $zero,$zero,0x0 -); +void chrAddTargetToBdlist(struct chrdata *chr) +{ + if (chr->prop) { + struct prop *target = chrGetTargetProp(chr); + s32 i; -s32 func0f04c580(struct chrdata *chr) + if (target) { + for (i = 0; i < g_Vars.lvupdate240_60; i++) { + chr->bdlist[chr->bdstart] = target->pos.x - chr->prop->pos.x; + chr->bdstart++; + chr->bdstart %= 60; + + chr->bdlist[chr->bdstart] = target->pos.z - chr->prop->pos.z; + chr->bdstart++; + chr->bdstart %= 60; + } + } + } +} + +s32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr) { s32 *bdlist = &chr->bdlist[0]; s32 index = chr->bdstart; u32 stack[2]; s32 x1 = bdlist[(index + 1) % 60]; - s32 y1 = bdlist[index]; - s32 a = sqrtf(x1 * x1 + y1 * y1); + s32 z1 = bdlist[index]; + s32 olddist = sqrtf(x1 * x1 + z1 * z1); s32 x2 = bdlist[(index + 59) % 60]; - s32 y2 = bdlist[(index + 58) % 60]; - s32 b = sqrtf(x2 * x2 + y2 * y2); + s32 z2 = bdlist[(index + 58) % 60]; + s32 curdist = sqrtf(x2 * x2 + z2 * z2); - return b - a; + return curdist - olddist; } bool func0f04c6b4(struct chrdata *chr, u32 distance) diff --git a/src/game/chr/chrai.c b/src/game/chr/chrai.c index 6897d97b2..d5ad7287c 100644 --- a/src/game/chr/chrai.c +++ b/src/game/chr/chrai.c @@ -90,7 +90,7 @@ void chraiExecute(void *entity, s32 proptype) if (g_Vars.ailist) { if (g_Vars.chrdata) { - func0f04c444(g_Vars.chrdata); + chrAddTargetToBdlist(g_Vars.chrdata); } // Check if the ailist should be switched to a different one diff --git a/src/game/chr/chraicommands.c b/src/game/chr/chraicommands.c index 36eb1799d..97c4964cd 100644 --- a/src/game/chr/chraicommands.c +++ b/src/game/chr/chraicommands.c @@ -9325,22 +9325,22 @@ glabel ai0129 /** * @cmd 012a */ -bool ai012a(void) +bool aiIfTargetMovingSlowly(void) { - s32 value; - s32 absvalue; + s32 delta; + s32 absdelta; u8 *cmd = g_Vars.ailist + g_Vars.aioffset; if (cmd[2] == 0) { - value = func0f04c580(g_Vars.chrdata); + delta = chrGetDistanceLostToTargetInLastSecond(g_Vars.chrdata); } else { struct chrdata *chr = chrFindById(g_Vars.chrdata, cmd[2]); - value = func0f04c580(chr); + delta = chrGetDistanceLostToTargetInLastSecond(chr); } - absvalue = value > 0 ? value : -value; + absdelta = delta > 0 ? delta : -delta; - if (absvalue < 50) { + if (absdelta < 50) { g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[3]); } else { g_Vars.aioffset += 4; @@ -9352,11 +9352,11 @@ bool ai012a(void) /** * @cmd 012b */ -bool ai012b(void) +bool aiIfTargetMovingCloser(void) { u8 *cmd = g_Vars.ailist + g_Vars.aioffset; - if (func0f04c580(g_Vars.chrdata) < -50) { + if (chrGetDistanceLostToTargetInLastSecond(g_Vars.chrdata) < -50) { g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[2]); } else { g_Vars.aioffset += 3; @@ -9368,11 +9368,11 @@ bool ai012b(void) /** * @cmd 012c */ -bool ai012c(void) +bool aiIfTargetMovingAway(void) { u8 *cmd = g_Vars.ailist + g_Vars.aioffset; - if (func0f04c580(g_Vars.chrdata) > 50) { + if (chrGetDistanceLostToTargetInLastSecond(g_Vars.chrdata) > 50) { g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[2]); } else { g_Vars.aioffset += 3; @@ -9769,7 +9769,7 @@ glabel ai0130 /* f05a7b0: 10000026 */ beqz $zero,.L0f05a84c /* f05a7b4: 8faa009c */ lw $t2,0x9c($sp) .L0f05a7b8: -/* f05a7b8: 0fc13160 */ jal func0f04c580 +/* f05a7b8: 0fc13160 */ jal chrGetDistanceLostToTargetInLastSecond /* f05a7bc: 8e040424 */ lw $a0,0x424($s0) /* f05a7c0: 18400003 */ blez $v0,.L0f05a7d0 /* f05a7c4: 00021823 */ negu $v1,$v0 @@ -9964,7 +9964,7 @@ glabel ai0130 .L0f05aa90: /* f05aa90: 8e040424 */ lw $a0,0x424($s0) .L0f05aa94: -/* f05aa94: 0fc13160 */ jal func0f04c580 +/* f05aa94: 0fc13160 */ jal chrGetDistanceLostToTargetInLastSecond /* f05aa98: a3a800a3 */ sb $t0,0xa3($sp) /* f05aa9c: 18400003 */ blez $v0,.L0f05aaac /* f05aaa0: 93a800a3 */ lbu $t0,0xa3($sp) diff --git a/src/include/commands.h b/src/include/commands.h index c3e93d6f6..ea6d6fcda 100644 --- a/src/include/commands.h +++ b/src/include/commands.h @@ -2503,22 +2503,35 @@ score, \ label, -// If value is nonzero then it's an chr ID. If zero then use current chr. -// This means chr ID 0 cannot be used. In practice, this command is only -// called once and it has value 0. -#define if_something_hypotenuse(value, label) \ +/** + * Checks if the distance change from the current chr to the chr's target has + * not changed by more than 50 units since 1 second ago. In other words, if the + * distance between the two is somewhat constant (eg. they are both not moving + * much). + * + * It's used to decide whether to throw grenades or not. + * + * If chr is zero, compare the current chr and their target. + * If chr is non-zero, compare the given chr and their target. + */ +#define if_target_moving_slowly(chr, label) \ mkshort(0x012a), \ - value, \ + chr, \ label, -// Checks if the chr is within 50 units of something -#define if_something_chicago_robot(label) \ +/** + * Checks if the distance between the chr and their target has decreased by at + * least 50 units in the last second. + */ +#define if_target_moving_closer(label) \ mkshort(0x012b), \ label, -// Does some math on chr's bdlist, possibly involving square roots. -// If result is > 50, goto label -#define if_distance_to_home_gt_50_maybe(label) \ +/** + * Checks if the distance between the chr and their target has increased by at + * least 50 units in the last second. + */ +#define if_target_moving_away(label) \ mkshort(0x012c), \ label, diff --git a/src/include/game/chr/chr.h b/src/include/game/chr/chr.h index ff6ce2040..81374670b 100644 --- a/src/include/game/chr/chr.h +++ b/src/include/game/chr/chr.h @@ -395,8 +395,8 @@ u32 func0f04ba34(struct chrdata *chr, u16 arg1, u32 arg2); u32 func0f04bffc(struct chrdata *chr, u32 arg1, u32 arg2); s16 func0f04c268(struct chrdata *chr, u8 speed); u32 func0f04c2e8(void); -u32 func0f04c444(void); -s32 func0f04c580(struct chrdata *chr); +void chrAddTargetToBdlist(struct chrdata *chr); +s32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr); bool func0f04c6b4(struct chrdata *chr, u32 distance); bool func0f04c71c(struct chrdata *chr, u32 distance); u32 func0f04c784(void); diff --git a/src/include/game/chr/chraicommands.h b/src/include/game/chr/chraicommands.h index e3d83e1f6..6939a7efe 100644 --- a/src/include/game/chr/chraicommands.h +++ b/src/include/game/chr/chraicommands.h @@ -298,9 +298,9 @@ /*0x0127*/ bool ai0127(void); /*0x0128*/ bool ai0128(void); /*0x0129*/ bool ai0129(void); -/*0x012a*/ bool ai012a(void); -/*0x012b*/ bool ai012b(void); -/*0x012c*/ bool ai012c(void); +/*0x012a*/ bool aiIfTargetMovingSlowly(void); +/*0x012b*/ bool aiIfTargetMovingCloser(void); +/*0x012c*/ bool aiIfTargetMovingAway(void); /*0x012f*/ bool ai012f(void); /*0x0130*/ bool ai0130(void); /*0x0131*/ bool ai0131(void); diff --git a/src/setup/ailists.c b/src/setup/ailists.c index 92c4c7027..cdac5e129 100644 --- a/src/setup/ailists.c +++ b/src/setup/ailists.c @@ -3134,7 +3134,10 @@ u8 func000c_combat_with_target_chr[] = { label(0x16) if_chr_distance_lt(800, /*goto*/ 0xc2) - if_something_hypotenuse(0, /*goto*/ 0xc2) + + // @bug: Guards will consider throwing grenades if you're moving quickly + // rather than slowly. The below statement skips the grenade logic if slow. + if_target_moving_slowly(0, /*goto*/ 0xc2) dprint 'G','R','E','N','A','D','E','\n',0, restart_timer if_chr_in_squadron_doing_action(MA_GRENADE, /*goto*/ 0xc2) diff --git a/src/setup/setup_000000.c b/src/setup/setup_000000.c index 064cc3bc5..10d1e1d92 100644 --- a/src/setup/setup_000000.c +++ b/src/setup/setup_000000.c @@ -14432,9 +14432,9 @@ bool (*g_CommandPointers[])(void) = { /*0x0127*/ ai0127, /*0x0128*/ ai0128, /*0x0129*/ ai0129, - /*0x012a*/ ai012a, - /*0x012b*/ ai012b, - /*0x012c*/ ai012c, + /*0x012a*/ aiIfTargetMovingSlowly, + /*0x012b*/ aiIfTargetMovingCloser, + /*0x012c*/ aiIfTargetMovingAway, /*0x012d*/ NULL, /*0x012e*/ NULL, /*0x012f*/ ai012f,