diff --git a/src/game/chr/chraicommands.c b/src/game/chr/chraicommands.c index 3d62059da..cdc22031e 100644 --- a/src/game/chr/chraicommands.c +++ b/src/game/chr/chraicommands.c @@ -127,9 +127,6 @@ const u32 var7f1a9d40[] = {0x7f0593a0}; const u32 var7f1a9d44[] = {0x7f0593b0}; const u32 var7f1a9d48[] = {0x7f0593bc}; const u32 var7f1a9d4c[] = {0x455ac000}; -const u32 var7f1a9d50[] = {0x461c3f9a}; -const u32 var7f1a9d54[] = {0x44bb8000}; -const u32 var7f1a9d58[] = {0x461c3c00}; /** * @cmd 0000 @@ -8066,7 +8063,15 @@ bool aiIfPlayerUsingCmpOrAr34(void) * @cmd 0127 */ GLOBAL_ASM( -glabel ai0127 +.late_rodata +glabel var7f1a9d50 +.word 0x461c3f9a +glabel var7f1a9d54 +.word 0x44bb8000 +glabel var7f1a9d58 +.word 0x461c3c00 +.text +glabel aiDetectEnemyOnSameFloor /* f0598b4: 27bdffa0 */ addiu $sp,$sp,-96 /* f0598b8: afb20030 */ sw $s2,0x30($sp) /* f0598bc: 3c12800a */ lui $s2,%hi(g_Vars) @@ -8264,6 +8269,84 @@ glabel ai0127 /* f059b88: 00001025 */ or $v0,$zero,$zero ); +// Mismatch due to the order of variable initialisation. +// The game initialises team = 0 first then saves the callee-save registers, +// while the code below causes it to save the callee-registers first. +//bool aiDetectEnemyOnSameFloor(void) +//{ +// // Note: Must be distance, then any two words, then y then cmd. +// // Everything else is flexible. +// s32 team = 0; +// f32 closestdist = 10000; +// f32 distance; +// u32 stack[2]; +// f32 y; +// u8 *cmd = g_Vars.ailist + g_Vars.aioffset; +// f32 scandist; +// s16 *chrnums = teamGetChrIds(1); +// struct chrdata *chr; +// s16 newtarget = -1; +// +// if (g_Vars.chrdata->teamscandist == 0) { +// scandist = 1500; +// } else if (g_Vars.chrdata->teamscandist == 255) { +// scandist = 9999; +// } else { +// scandist = g_Vars.chrdata->teamscandist * 40.0f; +// } +// +// y = g_Vars.chrdata->prop->pos.y; +// +// while (team < 8) { +// chr = chrFindByLiteralId(*chrnums); +// +// if (*chrnums != -2) { +// if (chr && chr->prop +// && chr->team != TEAM_NONCOMBAT +// && !chrIsDead(chr) +// && chr->actiontype != ACT_DEAD +// && chr->actiontype != ACT_DRUGGEDKO +// && chr->actiontype != ACT_DRUGGEDDROP +// && chr->actiontype != ACT_DRUGGEDCOMINGUP +// && chrCompareTeams(g_Vars.chrdata, chr, 2) +// && (chr->hidden & CHRHFLAG_CLOAKED) == 0 +// && (chr->chrflags & CHRCFLAG_HIDDEN) == 0 +// && (chr->hidden & CHRHFLAG_40000000) == 0 +// && y - chr->prop->pos.y > -200 +// && y - chr->prop->pos.y < 200 +// && ((g_Vars.chrdata->hidden & CHRHFLAG_PSYCHOSISED) == 0 +// || (chr->hidden & CHRHFLAG_40000000) == 0 +// || chr->hidden & CHRHFLAG_08000000) +// && g_Vars.chrdata->chrnum != chr->chrnum) { +// distance = chrGetDistanceToChr(g_Vars.chrdata, chr->chrnum); +// +// if (distance < closestdist) { +// if (distance < scandist || stageGetIndex(g_Vars.stagenum) == STAGEINDEX_MAIANSOS) { +// if (distance < closestdist) { +// closestdist = distance; +// newtarget = chr->chrnum; +// } +// } +// } +// } +// +// chrnums++; +// } else { +// chrnums++; +// team++; +// } +// } +// +// if (newtarget != -1) { +// g_Vars.chrdata->target = propGetIndexByChrId(g_Vars.chrdata, newtarget); +// g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[2]); +// } else { +// g_Vars.aioffset = g_Vars.aioffset + 3; +// } +// +// return false; +//} + /** * @cmd 0128 */ @@ -8309,14 +8392,14 @@ bool aiDetectEnemy(void) && chr->actiontype != ACT_DRUGGEDCOMINGUP && chrCompareTeams(g_Vars.chrdata, chr, 2) && chr != g_Vars.chrdata - && (chr->hidden & 0x20000000) == 0 + && (chr->hidden & CHRHFLAG_CLOAKED) == 0 && (chr->chrflags & CHRCFLAG_HIDDEN) == 0 - && (chr->hidden & 0x00080000) == 0 - && chr->team != 0x80 + && (chr->hidden & CHRHFLAG_DISGUISED) == 0 + && chr->team != TEAM_NONCOMBAT && ( - (g_Vars.chrdata->hidden & 0x80000000) == 0 - || (chr->hidden & 0x40000000) == 0 - || chr->hidden & 0x08000000)) { + (g_Vars.chrdata->hidden & CHRHFLAG_PSYCHOSISED) == 0 + || (chr->hidden & CHRHFLAG_40000000) == 0 + || chr->hidden & CHRHFLAG_08000000)) { f32 distance = chrGetDistanceToChr(g_Vars.chrdata, chr->chrnum); if (distance < maxdist && distance != 0 && distance < closestdist diff --git a/src/game/data/ailists.c b/src/game/data/ailists.c index db35d6e34..146a7b83a 100644 --- a/src/game/data/ailists.c +++ b/src/game/data/ailists.c @@ -2771,7 +2771,7 @@ u8 func000b_choose_target_chr[] = { dprint 'S','C','A','N','\n',0, if_self_flag_bankx_eq(CHRFLAG0_NOHEAR, TRUE, BANK_0, /*goto*/ 0x13) - try_find_chr_in_team(/*goto*/ 0x16) + set_target_to_enemy_on_same_floor(/*goto*/ 0x16) goto_next(0x04) // No hear - only see @@ -2795,7 +2795,7 @@ u8 func000b_choose_target_chr[] = { dprint 'F','O','U','N','D','A','L','E','R','T','\n',0, if_enemy_distance_lt_and_los(2540, /*goto*/ 0x13) if_self_flag_bankx_eq(CHRFLAG0_NOHEAR, TRUE, BANK_0, /*goto*/ 0x16) - try_find_chr_in_team(/*goto*/ 0x13) + set_target_to_enemy_on_same_floor(/*goto*/ 0x13) label(0x16) goto_first(0xd3) @@ -4824,7 +4824,7 @@ u8 func0014_coop_buddy[] = { // Not G5 Building or Deep Sea label(0x15) - try_find_chr_in_team(/*goto*/ 0x0b) + set_target_to_enemy_on_same_floor(/*goto*/ 0x0b) // All stages label(0x13) @@ -5200,7 +5200,7 @@ u8 func0027_psychosised[] = { // Healthy label(0x16) - try_find_chr_in_team(/*goto*/ 0x03) + set_target_to_enemy_on_same_floor(/*goto*/ 0x03) if_enemy_distance_lt_and_los(2540, /*goto*/ 0x03) set_target_chr(CHR_PRESET) if_distance_to_target_lt(200, /*goto*/ 0x16) @@ -5242,7 +5242,7 @@ u8 func0027_psychosised[] = { label(0x06) set_chr_hiddenflag(CHR_SELF, CHRHFLAG_DISGUISED) label(0x07) - try_find_chr_in_team(/*goto*/ 0x03) + set_target_to_enemy_on_same_floor(/*goto*/ 0x03) if_enemy_distance_lt_and_los(2540, /*goto*/ 0x03) set_target_chr(CHR_PRESET) if_distance_to_target_gt(300, /*goto*/ 0x16) diff --git a/src/game/data/data_0083d0.c b/src/game/data/data_0083d0.c index efe404382..df9d9a4d4 100644 --- a/src/game/data/data_0083d0.c +++ b/src/game/data/data_0083d0.c @@ -6514,7 +6514,7 @@ bool (*g_CommandPointers[])(void) = { /*0x0124*/ aiGoToCover, /*0x0125*/ ai0125, /*0x0126*/ aiIfPlayerUsingCmpOrAr34, - /*0x0127*/ ai0127, + /*0x0127*/ aiDetectEnemyOnSameFloor, /*0x0128*/ aiDetectEnemy, /*0x0129*/ aiIfSafetyLessThan, /*0x012a*/ aiIfTargetMovingSlowly, diff --git a/src/include/commands.h b/src/include/commands.h index ccfd25436..bb52cd611 100644 --- a/src/include/commands.h +++ b/src/include/commands.h @@ -2512,12 +2512,11 @@ label, /** - * Tries to find a chr in the team who meets some criteria and sets them as the - * current chr's target. - * - * Probably used to run to them for safety or to alert them. + * Tries to find a chr who meets some criteria and sets them as the current + * chr's target. Only enemeies who are on the same floor will be considered. + * A line of sight check is not used. */ -#define try_find_chr_in_team(label) \ +#define set_target_to_enemy_on_same_floor(label) \ mkshort(0x0127), \ label, diff --git a/src/include/game/chr/chraicommands.h b/src/include/game/chr/chraicommands.h index efbeaa71f..fe1b2c0cf 100644 --- a/src/include/game/chr/chraicommands.h +++ b/src/include/game/chr/chraicommands.h @@ -295,7 +295,7 @@ /*0x0124*/ bool aiGoToCover(void); /*0x0125*/ bool ai0125(void); /*0x0126*/ bool aiIfPlayerUsingCmpOrAr34(void); -/*0x0127*/ bool ai0127(void); +/*0x0127*/ bool aiDetectEnemyOnSameFloor(void); /*0x0128*/ bool aiDetectEnemy(void); /*0x0129*/ bool aiIfSafetyLessThan(void); /*0x012a*/ bool aiIfTargetMovingSlowly(void);