@@ -88,7 +88,7 @@ u16 D_801631F8[10];
8888f32 gCurrentCpuTargetSpeed ;
8989f32 gPreviousCpuTargetSpeed [10 ];
9090s32 D_80163238 ;
91- u16 D_80163240 [12 ];
91+ u16 gCrossedFinishLine [12 ];
9292u16 gWrongDirectionCounter [12 ];
9393u16 gIsPlayerWrongDirection [12 ];
9494s32 gPreviousLapProgressScore [10 ];
@@ -154,7 +154,7 @@ s16 D_80164358;
154154s16 D_8016435A ;
155155s16 D_8016435C ;
156156s16 gGPCurrentRacePlayerIdByRank [12 ]; // D_80164360
157- s16 D_80164378 [12 ];
157+ s16 gPrevPlayerIdByRank [12 ];
158158s32 gLapCountByPlayerId [10 ]; // D_80164390
159159s32 gGPCurrentRaceRankByPlayerId [10 ]; // D_801643B8
160160s32 gPreviousGPCurrentRaceRankByPlayerId [10 ];
@@ -707,15 +707,15 @@ void detect_wrong_player_direction(s32 playerId, Player* player) {
707707}
708708
709709void set_places (void ) {
710- s32 temp_s2 ;
711- f32 temp_f0 ;
712- s32 rankPlayer [8 ];
713- s32 a_really_cool_variable_name ;
710+ s32 playerIdToSwap ;
711+ f32 courseCompletionToSwap ;
712+ s32 playerIdByRank [8 ];
713+ s32 prevPlayerId ;
714714 UNUSED s32 pad ;
715715 s32 numPlayer ;
716+ s32 rank ;
716717 s32 playerId ;
717- s32 temp_a0 ;
718- s32 var_t1_3 ;
718+ s32 rankHigh ;
719719
720720 switch (gModeSelection ) {
721721 case BATTLE :
@@ -731,69 +731,70 @@ void set_places(void) {
731731 }
732732
733733 if (D_8016348C == 0 ) {
734- for (playerId = 0 ; playerId < numPlayer ; playerId ++ ) {
735- temp_a0 = gGPCurrentRacePlayerIdByRank [playerId ];
736- rankPlayer [ playerId ] = temp_a0 ;
737- gCourseCompletionPercentByRank [playerId ] = gCourseCompletionPercentByPlayerId [temp_a0 ];
734+ for (rank = 0 ; rank < numPlayer ; rank ++ ) {
735+ playerId = gGPCurrentRacePlayerIdByRank [rank ];
736+ playerIdByRank [ rank ] = playerId ;
737+ gCourseCompletionPercentByRank [rank ] = gCourseCompletionPercentByPlayerId [playerId ];
738738 }
739739 } else {
740- for (playerId = 0 ; playerId < numPlayer ; playerId ++ ) {
741- temp_a0 = gGPCurrentRacePlayerIdByRank [playerId ];
742- rankPlayer [playerId ] = temp_a0 ;
743- gCourseCompletionPercentByRank [playerId ] = - gTimePlayerLastTouchedFinishLine [temp_a0 ];
740+ // used in grand Prix mode once all players cross finish line to determine finish order
741+ for (rank = 0 ; rank < numPlayer ; rank ++ ) {
742+ playerId = gGPCurrentRacePlayerIdByRank [rank ];
743+ playerIdByRank [rank ] = playerId ;
744+ gCourseCompletionPercentByRank [rank ] = - gTimePlayerLastTouchedFinishLine [playerId ];
744745 }
745746 }
746747
747- for (playerId = 0 ; playerId < numPlayer - 1 ; playerId ++ ) {
748- if ((gPlayers [gGPCurrentRacePlayerIdByRank [playerId ]].type & PLAYER_CINEMATIC_MODE )) {
748+ for (rank = 0 ; rank < numPlayer - 1 ; rank ++ ) {
749+ if ((gPlayers [gGPCurrentRacePlayerIdByRank [rank ]].type & PLAYER_CINEMATIC_MODE )) {
749750 continue ;
750751 }
751752
752- for (var_t1_3 = playerId + 1 ; var_t1_3 < numPlayer ; var_t1_3 ++ ) {
753- if (gCourseCompletionPercentByRank [playerId ] < gCourseCompletionPercentByRank [var_t1_3 ]) {
754- if (!(gPlayers [gGPCurrentRacePlayerIdByRank [var_t1_3 ]].type & 0x800 )) {
755- temp_s2 = rankPlayer [ playerId ];
756- rankPlayer [ playerId ] = rankPlayer [ var_t1_3 ];
757- rankPlayer [ var_t1_3 ] = temp_s2 ;
758- temp_f0 = gCourseCompletionPercentByRank [playerId ];
759- gCourseCompletionPercentByRank [playerId ] = gCourseCompletionPercentByRank [var_t1_3 ];
760- gCourseCompletionPercentByRank [var_t1_3 ] = temp_f0 ;
753+ for (rankHigh = rank + 1 ; rankHigh < numPlayer ; rankHigh ++ ) {
754+ if (gCourseCompletionPercentByRank [rank ] < gCourseCompletionPercentByRank [rankHigh ]) {
755+ if (!(gPlayers [gGPCurrentRacePlayerIdByRank [rankHigh ]].type & PLAYER_CINEMATIC_MODE )) {
756+ playerIdToSwap = playerIdByRank [ rank ];
757+ playerIdByRank [ rank ] = playerIdByRank [ rankHigh ];
758+ playerIdByRank [ rankHigh ] = playerIdToSwap ;
759+ courseCompletionToSwap = gCourseCompletionPercentByRank [rank ];
760+ gCourseCompletionPercentByRank [rank ] = gCourseCompletionPercentByRank [rankHigh ];
761+ gCourseCompletionPercentByRank [rankHigh ] = courseCompletionToSwap ;
761762 }
762763 }
763764 }
764765 }
765766
766- for (playerId = 0 ; playerId < NUM_PLAYERS ; playerId ++ ) {
767- gPreviousGPCurrentRaceRankByPlayerId [playerId ] = gGPCurrentRaceRankByPlayerId [playerId ];
767+ // actually player_id, not rank
768+ for (rank = 0 ; rank < NUM_PLAYERS ; rank ++ ) {
769+ gPreviousGPCurrentRaceRankByPlayerId [rank ] = gGPCurrentRaceRankByPlayerId [rank ];
768770 }
769771
770- for (playerId = 0 ; playerId < numPlayer ; playerId ++ ) {
771- gGPCurrentRacePlayerIdByRank [playerId ] = rankPlayer [ playerId ];
772- gGPCurrentRaceRankByPlayerId [rankPlayer [ playerId ]] = playerId ;
772+ for (rank = 0 ; rank < numPlayer ; rank ++ ) {
773+ gGPCurrentRacePlayerIdByRank [rank ] = playerIdByRank [ rank ];
774+ gGPCurrentRaceRankByPlayerId [playerIdByRank [ rank ]] = rank ;
773775 }
774-
775- for (playerId = 0 ; playerId < numPlayer ; playerId ++ ) {
776- a_really_cool_variable_name = D_80164378 [playerId ];
777- rankPlayer [playerId ] = a_really_cool_variable_name ;
778- gCourseCompletionPercentByRank [playerId ] = gCourseCompletionPercentByPlayerId [a_really_cool_variable_name ];
776+ for (rank = 0 ; rank < numPlayer ; rank ++ ) {
777+ prevPlayerId = gPrevPlayerIdByRank [rank ];
778+ playerIdByRank [rank ] = prevPlayerId ;
779+ gCourseCompletionPercentByRank [rank ] = gCourseCompletionPercentByPlayerId [prevPlayerId ];
779780 }
780781
781- for (playerId = 0 ; playerId < numPlayer - 1 ; playerId ++ ) {
782- for (var_t1_3 = playerId + 1 ; var_t1_3 < numPlayer ; var_t1_3 ++ ) {
783- if (gCourseCompletionPercentByRank [playerId ] < gCourseCompletionPercentByRank [var_t1_3 ]) {
784- temp_s2 = rankPlayer [ playerId ];
785- rankPlayer [ playerId ] = rankPlayer [ var_t1_3 ];
786- rankPlayer [ var_t1_3 ] = temp_s2 ;
787- temp_f0 = gCourseCompletionPercentByRank [playerId ];
788- gCourseCompletionPercentByRank [playerId ] = gCourseCompletionPercentByRank [var_t1_3 ];
789- gCourseCompletionPercentByRank [var_t1_3 ] = temp_f0 ;
782+ for (rank = 0 ; rank < numPlayer - 1 ; rank ++ ) {
783+ for (rankHigh = rank + 1 ; rankHigh < numPlayer ; rankHigh ++ ) {
784+ if (gCourseCompletionPercentByRank [rank ] < gCourseCompletionPercentByRank [rankHigh ]) {
785+ playerIdToSwap = playerIdByRank [ rank ];
786+ playerIdByRank [ rank ] = playerIdByRank [ rankHigh ];
787+ playerIdByRank [ rankHigh ] = playerIdToSwap ;
788+ courseCompletionToSwap = gCourseCompletionPercentByRank [rank ];
789+ gCourseCompletionPercentByRank [rank ] = gCourseCompletionPercentByRank [rankHigh ];
790+ gCourseCompletionPercentByRank [rankHigh ] = courseCompletionToSwap ;
790791 }
791792 }
792793 }
793794
794- for (playerId = 0 ; playerId < numPlayer ; playerId ++ ) {
795- gGPCurrentRaceRankByPlayerIdDup [rankPlayer [ playerId ]] = playerId ;
796- D_80164378 [ playerId ] = rankPlayer [ playerId ];
795+ for (rank = 0 ; rank < numPlayer ; rank ++ ) {
796+ gGPCurrentRaceRankByPlayerIdDup [playerIdByRank [ rank ]] = rank ;
797+ gPrevPlayerIdByRank [ rank ] = playerIdByRank [ rank ];
797798 }
798799}
799800
@@ -992,7 +993,7 @@ bool func_800088D8(s32 playerId, s16 arg1, s16 arg2) {
992993 if (arg2 == 0 ) {
993994 if (gDemoMode == 1 ) {
994995 STEMP_V0 = gNumPathPointsTraversed [playerId ];
995- STEMP_V1 = gNumPathPointsTraversed [D_80164378 [7 ]];
996+ STEMP_V1 = gNumPathPointsTraversed [gPrevPlayerIdByRank [7 ]];
996997 progress = STEMP_V0 - STEMP_V1 ;
997998 if (progress < 0 ) {
998999 progress = - progress ;
@@ -1018,7 +1019,7 @@ bool func_800088D8(s32 playerId, s16 arg1, s16 arg2) {
10181019 rank = gGPCurrentRaceRankByPlayerId [gBestRankedHumanPlayer ];
10191020 if (((((gPathCountByPathIndex [0 ] * 2 ) / 3 )) < progress ) && ((rank ) >= 6 )) {
10201021 STEMP_V0 = gNumPathPointsTraversed [playerId ];
1021- STEMP_V1 = temp = gNumPathPointsTraversed [D_80164378 [rank - 1 ]];
1022+ STEMP_V1 = temp = gNumPathPointsTraversed [gPrevPlayerIdByRank [rank - 1 ]];
10221023 progress = STEMP_V0 - STEMP_V1 ;
10231024 }
10241025 if (progress < 0 ) {
@@ -1200,11 +1201,12 @@ void update_cpu_path_completion(s32 playerId, Player* player) {
12001201
12011202/**
12021203 * Helps calculate time since player last touched finishline.
1204+ * Assumes constant z-speed and subtracts portion of frame where the finish line was already crossed
12031205 **/
1204- f32 func_80009258 (UNUSED s32 playerId , f32 arg1 , f32 arg2 ) {
1205- f32 temp_f2 = gPathStartZ - arg2 ;
1206- f32 temp_f12 = arg1 - gPathStartZ ;
1207- return gCourseTimer - ((COURSE_TIMER_ITER_f * temp_f2 ) / (temp_f2 + temp_f12 ));
1206+ f32 time_crossed_finish_line (UNUSED s32 playerId , f32 previousPlayerZ , f32 playerZ ) {
1207+ f32 z_change_after_cross = gPathStartZ - playerZ ;
1208+ f32 z_change_before_cross = previousPlayerZ - gPathStartZ ;
1209+ return gCourseTimer - ((COURSE_TIMER_ITER_f * z_change_after_cross ) / (z_change_after_cross + z_change_before_cross ));
12081210}
12091211
12101212void update_player_path_completion (s32 playerId , Player * player ) {
@@ -1220,7 +1222,7 @@ void update_player_path_completion(s32 playerId, Player* player) {
12201222 playerZ = player -> pos [2 ];
12211223 previousPlayerZ = gPreviousPlayerZ [playerId ];
12221224 gIsPlayerNewPathPoint = false;
1223- D_80163240 [playerId ] = 0 ;
1225+ gCrossedFinishLine [playerId ] = 0 ;
12241226 sSomeNearestPathPoint = update_player_path (playerX , playerY , playerZ , gNearestPathPointByPlayerId [playerId ], player ,
12251227 playerId , gPlayerPathIndex );
12261228 gCurrentNearestPathPoint = sSomeNearestPathPoint ;
@@ -1276,12 +1278,12 @@ void update_player_path_completion(s32 playerId, Player* player) {
12761278 // clang-format on
12771279 }
12781280 }
1279- D_80163240 [playerId ] = 1 ;
1281+ gCrossedFinishLine [playerId ] = 1 ;
12801282 update_player_completion (playerId );
12811283 reset_cpu_behaviour (playerId );
12821284 cpu_ItemStrategy [playerId ].numItemUse = 0 ;
12831285 if ((D_8016348C == 0 ) && !(player -> type & PLAYER_CINEMATIC_MODE )) {
1284- gTimePlayerLastTouchedFinishLine [playerId ] = func_80009258 (playerId , previousPlayerZ , playerZ );
1286+ gTimePlayerLastTouchedFinishLine [playerId ] = time_crossed_finish_line (playerId , previousPlayerZ , playerZ );
12851287 }
12861288 }
12871289 }
@@ -1461,7 +1463,11 @@ void update_player(s32 playerId) {
14611463 player -> kartProps &= ~BACK_UP ;
14621464 }
14631465 update_player_path_completion (playerId , player );
1464- if ((gCurrentCourseId != COURSE_AWARD_CEREMONY ) && ((D_80163240 [playerId ] == 1 ) || (playerId == 0 ))) {
1466+
1467+ // Because this takes place in a per-player loop and runs primarily when player 1 crosses the finish line,
1468+ // player 1 effectively has a 1 frame advantage when determining places. However, it runs for everyone when
1469+ // they cross the finish line, resulting in lower port numbers always winning ties in versus mode.
1470+ if ((gCurrentCourseId != COURSE_AWARD_CEREMONY ) && ((gCrossedFinishLine [playerId ] == 1 ) || (playerId == 0 ))) {
14651471 set_places ();
14661472 }
14671473 if (player -> type & PLAYER_CPU ) {
@@ -2100,7 +2106,7 @@ void init_players(void) {
21002106 }
21012107 temp_v0_3 = gGPCurrentRaceRankByPlayerId [i ];
21022108 gGPCurrentRacePlayerIdByRank [temp_v0_3 ] = (s16 ) i ;
2103- D_80164378 [temp_v0_3 ] = (s16 ) i ;
2109+ gPrevPlayerIdByRank [temp_v0_3 ] = (s16 ) i ;
21042110 gGPCurrentRaceRankByPlayerIdDup [i ] = temp_v0_3 ;
21052111 gWrongDirectionCounter [i ] = 0 ;
21062112 gIsPlayerWrongDirection [i ] = 0 ;
0 commit comments