diff --git a/src/game/chr/chraicommands.c b/src/game/chr/chraicommands.c index e31b2e848..bb4378ac0 100644 --- a/src/game/chr/chraicommands.c +++ b/src/game/chr/chraicommands.c @@ -6823,15 +6823,20 @@ glabel var7f1a9d4c /* f059518: 00001025 */ or $v0,$zero,$zero ); -// Mismatch because score is masked with 0xff near 47c. Seems like it needs to -// use use int promotion but I haven't found a way to trigger it. +// Mismatch: The below has an extra store to score and it's due to the +// `if (score);` trick. But removing it creates vastly different codegen. +// Could be related to the switch statement because cmd 0129 is similar and +// matches but has no switch. //bool ai0120(void) //{ // u8 *cmd = g_Vars.ailist + g_Vars.aioffset; -// u8 score = 6; -// u8 numnearby = 0; +// u8 score; +// u8 numnearby; // s16 *chrnums = teamGetChrIds(g_Vars.chrdata->team); // +// score = 6; +// numnearby = 0; +// // // 350 // if (chrGetNumArghs(g_Vars.chrdata) > 0) { // score -= 2; @@ -6897,10 +6902,13 @@ glabel var7f1a9d4c // score--; // } // +// // 4a8 // if (score < 3 && numnearby != 0) { // score = 3; // } // +// if (score); +// // if (score < cmd[2]) { // g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[3]); // } else { diff --git a/src/game/data/ailists.c b/src/game/data/ailists.c index 19882d6fd..cd2bbdf9a 100644 --- a/src/game/data/ailists.c +++ b/src/game/data/ailists.c @@ -1146,13 +1146,13 @@ u8 func0007_alerted[] = { dprint 'A','M','B','U','S','H',' ','F','A','I','L','E','D','\n',0, if_self_flag_bankx_eq(CHRFLAG0_CAN_RETREAT, FALSE, BANK_0, /*goto*/ 0x16) if_num_times_shot_lt(1, /*goto*/ 0x16) - if_retreat_risk_lt(3, /*goto*/ LABEL_RETREAT) + if_calculated_safety2_lt(3, /*goto*/ LABEL_RETREAT) dprint 'R','I','S','K',' ','F','A','I','L','E','D','\n',0, label(0x16) if_self_flag_bankx_eq(CHRFLAG0_00004000, TRUE, BANK_0, /*goto*/ 0x91) if_self_flag_bankx_eq(CHRFLAG0_00002000, TRUE, BANK_0, /*goto*/ 0x92) label(0x91) - if_retreat_risk_lt(5, /*goto*/ 0x52) + if_calculated_safety2_lt(5, /*goto*/ 0x52) label(0x92) goto_next(0x68) @@ -1750,12 +1750,12 @@ u8 func0007_alerted[] = { if_self_flag_bankx_eq(CHRFLAG0_CAN_RETREAT, FALSE, BANK_0, /*goto*/ 0x16) if_self_flag_bankx_eq(CHRFLAG0_CANT_ALERT_GROUP, TRUE, BANK_0, /*goto*/ LABEL_RETREAT) if_num_times_shot_lt(1, /*goto*/ 0x16) - if_retreat_risk_lt(3, /*goto*/ LABEL_RETREAT) + if_calculated_safety2_lt(3, /*goto*/ LABEL_RETREAT) label(0x16) if_self_flag_bankx_eq(CHRFLAG0_00004000, TRUE, BANK_0, /*goto*/ 0x91) if_self_flag_bankx_eq(CHRFLAG0_00002000, TRUE, BANK_0, /*goto*/ 0x4d) label(0x91) - if_retreat_risk_lt(5, /*goto*/ 0x32) + if_calculated_safety2_lt(5, /*goto*/ 0x32) goto_next(0x4d) label(0x4d) @@ -1841,12 +1841,12 @@ u8 func0007_alerted[] = { if_self_flag_bankx_eq(CHRFLAG0_CAN_RETREAT, FALSE, BANK_0, /*goto*/ 0x16) if_self_flag_bankx_eq(CHRFLAG0_CANT_ALERT_GROUP, TRUE, BANK_0, /*goto*/ LABEL_RETREAT) if_num_times_shot_lt(1, /*goto*/ 0x16) - if_retreat_risk_lt(3, /*goto*/ LABEL_RETREAT) + if_calculated_safety2_lt(3, /*goto*/ LABEL_RETREAT) label(0x16) if_self_flag_bankx_eq(CHRFLAG0_00004000, TRUE, BANK_0, /*goto*/ 0x91) if_self_flag_bankx_eq(CHRFLAG0_00002000, TRUE, BANK_0, /*goto*/ 0x4d) label(0x91) - if_retreat_risk_lt(5, /*goto*/ 0x51) + if_calculated_safety2_lt(5, /*goto*/ 0x51) label(0x4d) dprint 'C',' ','3','\n',0, if_self_flag_bankx_eq(CHRFLAG0_00008000, TRUE, BANK_0, /*goto*/ 0x48) @@ -1941,7 +1941,7 @@ u8 func0007_alerted[] = { if_self_flag_bankx_eq(CHRFLAG0_00004000, TRUE, BANK_0, /*goto*/ 0x91) if_self_flag_bankx_eq(CHRFLAG0_00002000, TRUE, BANK_0, /*goto*/ 0x16) label(0x91) - if_retreat_risk_lt(5, /*goto*/ 0x41) + if_calculated_safety2_lt(5, /*goto*/ 0x41) label(0x16) if_self_flag_bankx_eq(CHRFLAG0_CAN_FLANK, FALSE, BANK_0, /*goto*/ 0x93) if_has_orders(/*goto*/ 0x84) @@ -1986,7 +1986,7 @@ u8 func0007_alerted[] = { if_self_flag_bankx_eq(CHRFLAG0_00004000, TRUE, BANK_0, /*goto*/ 0x91) if_self_flag_bankx_eq(CHRFLAG0_00002000, TRUE, BANK_0, /*goto*/ 0x16) label(0x91) - if_retreat_risk_lt(5, /*goto*/ 0x41) + if_calculated_safety2_lt(5, /*goto*/ 0x41) label(0x16) if_can_see_attack_target(/*goto*/ 0x8a) if_timer_gt(60, /*goto*/ 0x29) @@ -2243,12 +2243,12 @@ u8 func0007_alerted[] = { if_self_flag_bankx_eq(CHRFLAG0_CAN_RETREAT, FALSE, BANK_0, /*goto*/ 0x16) if_self_flag_bankx_eq(CHRFLAG0_CANT_ALERT_GROUP, TRUE, BANK_0, /*goto*/ LABEL_RETREAT) if_num_times_shot_lt(1, /*goto*/ 0x16) - if_retreat_risk_lt(3, /*goto*/ LABEL_RETREAT) + if_calculated_safety2_lt(3, /*goto*/ LABEL_RETREAT) label(0x16) if_self_flag_bankx_eq(CHRFLAG0_00004000, TRUE, BANK_0, /*goto*/ 0x91) if_self_flag_bankx_eq(CHRFLAG0_00002000, TRUE, BANK_0, /*goto*/ 0x4d) label(0x91) - if_retreat_risk_lt(5, /*goto*/ 0x39) + if_calculated_safety2_lt(5, /*goto*/ 0x39) label(0x4d) if_self_flag_bankx_eq(CHRFLAG0_00008000, TRUE, BANK_0, /*goto*/ 0x3a) goto_next(0x3c) diff --git a/src/include/commands.h b/src/include/commands.h index 974e62175..6cd1cd6cc 100644 --- a/src/include/commands.h +++ b/src/include/commands.h @@ -2623,13 +2623,22 @@ label, /** - * Tries to find a chr in the smae team who meets certain criteria. + * Calculates a safety score based on several factors and compares it to the + * given value. * - * For each chr, a risk is calculated based on several factors, such as whether - * they've been shot. If any chr in the team has a risk lower than the given - * value then the condition passes. + * The safety score starts at 6. + * Subtract 2 points if current chr has been shot. + * Subtract 2, 1, or add 1 point depending on player's equipped weapon. + * Subtract 2 points if there are no other chrs nearby. + * Subtract 1 point if there is 1 chr nearby. + * Enforce a minimum of 3 if there are any chrs nearby. + * + * So maximum safety is 7 and minimum safety is 0. + * + * See also if_calculated_safety_lt, which is similar but doesn't have the + * weapon check. */ -#define if_retreat_risk_lt(value, label) \ +#define if_calculated_safety2_lt(value, label) \ mkshort(0x0120), \ value, \ label, @@ -2707,6 +2716,9 @@ * Subtract 1 point if there are 1 or 2 chrs nearby. * * So maximum safety is 6 and minimum safety is 3. + * + * See also if_calculated_safety2_lt, which is similar but includes a player + * weapon check. */ #define if_calculated_safety_lt(score, label) \ mkshort(0x0129), \