Create ranked type enum, last person not afk wins in 1v1 (#2892)

## Description:

* Add RankedType enum, for now it's just 1v1
* Add new method to MapPlaylist to create 1v1 game config
* Update WinCheck so the last player is declared a winner on 1v1.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2026-01-13 19:48:14 -08:00
committed by GitHub
parent 247c78151c
commit 42c944c9cc
6 changed files with 275 additions and 6 deletions
+3 -2
View File
@@ -16,6 +16,7 @@ import {
GameType,
HumansVsNations,
Quads,
RankedType,
Trios,
UnitType,
} from "./game/Game";
@@ -183,6 +184,7 @@ export const GameConfigSchema = z.object({
donateTroops: z.boolean(), // Configures donations to humans only
gameType: z.enum(GameType),
gameMode: z.enum(GameMode),
rankedType: z.enum(RankedType).optional(), // Only set for ranked games.
gameMapSize: z.enum(GameMapSize),
publicGameModifiers: z
.object({
@@ -198,11 +200,10 @@ export const GameConfigSchema = z.object({
disableNavMesh: z.boolean().optional(),
randomSpawn: z.boolean(),
maxPlayers: z.number().optional(),
maxTimerValue: z.number().int().min(1).max(120).optional(),
maxTimerValue: z.number().int().min(1).max(120).optional(), // In minutes
spawnImmunityDuration: z.number().int().min(0).optional(), // In ticks
disabledUnits: z.enum(UnitType).array().optional(),
playerTeams: TeamCountConfigSchema.optional(),
isOneVOne: z.boolean().optional(),
});
export const TeamSchema = z.string();
+15
View File
@@ -5,6 +5,8 @@ import {
Game,
GameMode,
Player,
PlayerType,
RankedType,
Team,
} from "../game/Game";
@@ -44,6 +46,19 @@ export class WinCheckExecution implements Execution {
if (sorted.length === 0) {
return;
}
if (this.mg.config().gameConfig().rankedType === RankedType.OneVOne) {
const humans = sorted.filter(
(p) => p.type() === PlayerType.Human && !p.isDisconnected(),
);
if (humans.length === 1) {
this.mg.setWinner(humans[0], this.mg.stats().stats());
console.log(`${humans[0].name()} has won the game`);
this.active = false;
return;
}
}
const max = sorted[0];
const timeElapsed =
(this.mg.ticks() - this.mg.config().numSpawnPhaseTurns()) / 10;
+5
View File
@@ -195,6 +195,11 @@ export enum GameMode {
FFA = "Free For All",
Team = "Team",
}
export enum RankedType {
OneVOne = "1v1",
}
export const isGameMode = (value: unknown): value is GameMode =>
isEnumValue(GameMode, value);