Skip to content

Commit 5a17de4

Browse files
committed
map-specific statistics
1 parent ab5cc83 commit 5a17de4

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

build/scripts/maps.js

Lines changed: 26 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/maps.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import { FFunction } from './commands';
77
import { computeStatistics } from './funcs';
88
import { FishEvents } from './globals';
99
import { dataClass, serialize } from './io';
10-
import { formatTime } from './utils';
10+
import { formatTime, match } from './utils';
11+
import { Gamemode } from './config';
1112

1213
type FinishedMapRunData = {
1314
winTeam:Team;
@@ -79,7 +80,7 @@ export class PartialMapRun {
7980
}):FinishedMapRun {
8081
return new FinishedMapRun({
8182
winTeam,
82-
success: winTeam == Vars.state.rules.defaultTeam,
83+
success: Gamemode.pvp() ? true : winTeam == Vars.state.rules.defaultTeam,
8384
startTime: this.startTime,
8485
endTime: Date.now(),
8586
maxPlayerCount: this.maxPlayerCount
@@ -161,8 +162,13 @@ export class FMap extends dataClass<FMapData>() {
161162
const lateRTVs = this.runs.filter(r => r.outcome()[1] === "late rtv").length;
162163
const significantRunCount = allRunCount - earlyRTVs;
163164
const totalLosses = losses + lateRTVs;
164-
const durations = this.runs.map(r => r.duration() / 1000); //convert to seconds
165+
const durations = this.runs.filter(r => r.outcome()[0] !== "rtv").map(r => r.duration() / 1000); //convert to seconds
165166
const durationStats = computeStatistics(durations);
167+
const teamWins = this.runs.filter(r => r.success).reduce((acc, item) => {
168+
acc[item.winTeam.name] = (acc[item.winTeam.name] ?? 0) + 1;
169+
return acc;
170+
}, {} as Record<string, number>);
171+
const teamWinRate = Object.fromEntries(Object.entries(teamWins).map(([team, wins]) => [team, wins / victories]));
166172
return {
167173
allRunCount,
168174
significantRunCount,
@@ -177,14 +183,44 @@ export class FMap extends dataClass<FMapData>() {
177183
averagePlaytime: durationStats.average,
178184
shortestWinTime: Math.min(...this.runs.filter(r => r.outcome()[0] === "win").map(r => r.duration())),
179185
longestTime: durationStats.highest,
186+
shortestTime: durationStats.lowest,
180187
averageHighestPlayerCount: computeStatistics(this.runs.map(r => r.maxPlayerCount)).average,
188+
teamWins,
189+
teamWinRate,
181190
};
182191
}
183192
displayStats(f:FFunction):string | null {
184193
const map = this.map; if(!map) return null;
185194
const stats = this.stats();
186195
const rules = this.rules()!;
187196

197+
const modeSpecificStats = match(Gamemode.name(), {
198+
attack: `\
199+
[accent]Total runs: ${stats.allRunCount} (${stats.victories} wins, ${stats.totalLosses} losses, ${stats.earlyRTVs} RTVs)
200+
[accent]Outcomes: ${f.percent(stats.winRate, 1)} wins, ${f.percent(stats.lossRate, 1)} losses, ${f.percent(stats.earlyRTVRate, 1)} RTVs
201+
[accent]Average playtime: ${formatTime(stats.averagePlaytime)}
202+
[accent]Shortest win time: ${formatTime(stats.shortestWinTime)}`,
203+
survival: `\
204+
[accent]Total runs: ${stats.allRunCount} (${stats.earlyRTVs} RTVs)
205+
[accent]RTV rate: ${f.percent(stats.earlyRTVRate, 1)}
206+
[accent]Average duration: ${formatTime(stats.averagePlaytime)}
207+
[accent]Longest duration: ${formatTime(stats.longestTime)}`,
208+
pvp: `\
209+
[accent]Total runs: ${stats.allRunCount} (${stats.earlyRTVs} RTVs)
210+
[accent]Team win rates: ${Object.entries(stats.teamWinRate).map(([team, rate]) => `${team} ${f.percent(rate, 1)}`).join(", ")}
211+
[accent]RTV rate: ${f.percent(stats.earlyRTVRate, 1)}
212+
[accent]Average match duration: ${formatTime(stats.averagePlaytime)}
213+
[accent]Shortest match duration: ${formatTime(stats.shortestWinTime)}`,
214+
hexed: `\
215+
[accent]Total runs: ${stats.allRunCount} (${stats.earlyRTVs} RTVs)
216+
[accent]RTV rate: ${f.percent(stats.earlyRTVRate, 1)}
217+
[accent]Average match duration: ${formatTime(stats.averagePlaytime)}
218+
[accent]Shortest match duration: ${formatTime(stats.shortestWinTime)}`,
219+
sandbox: `\
220+
[accent]Total plays: ${stats.allRunCount}
221+
[accent]Average play time: ${formatTime(stats.averagePlaytime)}
222+
[accent]Shortest play time: ${formatTime(stats.shortestTime)}`,
223+
}, "");
188224
return (`\
189225
[coral]Information for map ${map.name()} [gray](${map.file.name()})[coral]:
190226
[accent]Map by: ${map.author()}
@@ -193,11 +229,8 @@ export class FMap extends dataClass<FMapData>() {
193229
[accent]Last updated: ${new Date(map.file.lastModified()).toLocaleDateString()}
194230
[accent]BvB allowed: ${f.boolGood(rules.placeRangeCheck)}, unit item transfer allowed: ${f.boolGood(rules.onlyDepositCore)}
195231
196-
[accent]Total runs: ${stats.allRunCount} (${stats.victories} wins, ${stats.totalLosses} losses, ${stats.earlyRTVs} RTVs)
197-
[accent]Outcomes: ${f.percent(stats.winRate, 1)} wins, ${f.percent(stats.lossRate, 1)} losses, ${f.percent(stats.earlyRTVRate, 1)} RTVs
198-
[accent]Average playtime: ${formatTime(stats.averagePlaytime)}
199-
[accent]Shortest win time: ${formatTime(stats.shortestWinTime)}
200-
[accent]Longest run: ${formatTime(stats.longestTime)}
232+
${modeSpecificStats}
233+
[accent]Longest play time: ${formatTime(stats.longestTime)}
201234
[accent]Average player count: ${stats.averageHighestPlayerCount}`
202235
);
203236
}

0 commit comments

Comments
 (0)