riddhiman commited on
Commit
a40bc12
·
verified ·
1 Parent(s): 727114f

Create src/multiplayer/raceStandings.js

Browse files
Files changed (1) hide show
  1. src/multiplayer/raceStandings.js +70 -0
src/multiplayer/raceStandings.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export function isRaceParticipant(player) {
2
+ return Boolean(player) && !player.disconnected && player.raceStatus !== 'lobby';
3
+ }
4
+
5
+ function getExplicitRacePosition(player) {
6
+ return Number.isFinite(player?.racePosition) ? player.racePosition : null;
7
+ }
8
+
9
+ function getComparableFinishTime(player) {
10
+ const value = player?.authoritativeFinishTime ?? player?.finishTime;
11
+ return Number.isFinite(value) ? value : Number.POSITIVE_INFINITY;
12
+ }
13
+
14
+ export function comparePlayersByRaceStandings(a, b) {
15
+ const explicitPositionA = getExplicitRacePosition(a);
16
+ const explicitPositionB = getExplicitRacePosition(b);
17
+ if (explicitPositionA != null && explicitPositionB != null && explicitPositionA !== explicitPositionB) {
18
+ return explicitPositionA - explicitPositionB;
19
+ }
20
+
21
+ const finishedA = Boolean(a?.finished);
22
+ const finishedB = Boolean(b?.finished);
23
+ const finishTimeA = getComparableFinishTime(a);
24
+ const finishTimeB = getComparableFinishTime(b);
25
+
26
+ if (finishedA && finishedB && finishTimeA !== finishTimeB) return finishTimeA - finishTimeB;
27
+ if (finishedA !== finishedB) return finishedA ? -1 : 1;
28
+
29
+ const progressDelta = (b?.progressDistance ?? 0) - (a?.progressDistance ?? 0);
30
+ if (progressDelta !== 0) return progressDelta;
31
+
32
+ const lapDelta = (b?.currentLap ?? 1) - (a?.currentLap ?? 1);
33
+ if (lapDelta !== 0) return lapDelta;
34
+
35
+ const checkpointDelta = (b?.highestCheckpointReached ?? 0) - (a?.highestCheckpointReached ?? 0);
36
+ if (checkpointDelta !== 0) return checkpointDelta;
37
+
38
+ const currentCheckpointDelta = (b?.currentCheckpoint ?? 0) - (a?.currentCheckpoint ?? 0);
39
+ if (currentCheckpointDelta !== 0) return currentCheckpointDelta;
40
+
41
+ const joinedAtDelta = (a?.joinedAt ?? 0) - (b?.joinedAt ?? 0);
42
+ if (joinedAtDelta !== 0) return joinedAtDelta;
43
+
44
+ return String(a?.username ?? a?.name ?? a?.id ?? '')
45
+ .localeCompare(String(b?.username ?? b?.name ?? b?.id ?? ''));
46
+ }
47
+
48
+ export function getRaceStandings(players = []) {
49
+ return [...players]
50
+ .filter(isRaceParticipant)
51
+ .sort(comparePlayersByRaceStandings)
52
+ .map((player, index) => ({
53
+ ...player,
54
+ racePosition: getExplicitRacePosition(player) ?? index + 1,
55
+ }));
56
+ }
57
+
58
+ export function getRaceStandingsMap(players = []) {
59
+ const standings = new Map();
60
+ getRaceStandings(players).forEach((player) => {
61
+ if (player?.id) standings.set(player.id, player.racePosition);
62
+ });
63
+ return standings;
64
+ }
65
+
66
+ export function getRacePositionForPlayer(players = [], playerId) {
67
+ if (!playerId) return null;
68
+ const player = getRaceStandings(players).find((entry) => entry.id === playerId);
69
+ return Number.isFinite(player?.racePosition) ? player.racePosition : null;
70
+ }