mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-23 05:12:28 +00:00
feat(playlist): add the Doomsday Clock to the public modifier rotation (#4589)
## Description: Adds the anti-stall **Doomsday Clock** to the public "special" modifier rotation, so it rolls into public games like the other spice modifiers, with a lobby badge. - `MapPlaylist`: new `isDoomsdayClock` ticket in `SPECIAL_MODIFIER_POOL` (weight 4, ~20% of special games). When rolled, enables `doomsdayClock` at a speed picked per game (slow/normal/fast/veryfast). - `PublicGameModifiers` (type + schema): `isDoomsdayClock` flag drives the badge. - `getActiveModifiers` + `en.json`: a "Doomsday Clock" badge/label. - Test covering the badge wiring. ## 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
This commit is contained in:
@@ -220,6 +220,12 @@ export function getActiveModifiers(
|
||||
badgeKey: "public_game_modifier.water_nukes",
|
||||
});
|
||||
}
|
||||
if (modifiers.isDoomsdayClock) {
|
||||
result.push({
|
||||
labelKey: "public_game_modifier.doomsday_clock_label",
|
||||
badgeKey: "public_game_modifier.doomsday_clock",
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,6 +328,7 @@ export const GameConfigSchema = z.object({
|
||||
isSAMsDisabled: z.boolean().optional(),
|
||||
isPeaceTime: z.boolean().optional(),
|
||||
isWaterNukes: z.boolean().optional(),
|
||||
isDoomsdayClock: z.boolean().optional(),
|
||||
})
|
||||
.optional(),
|
||||
nations: z
|
||||
|
||||
@@ -148,6 +148,7 @@ export interface PublicGameModifiers {
|
||||
isSAMsDisabled?: boolean;
|
||||
isPeaceTime?: boolean;
|
||||
isWaterNukes?: boolean;
|
||||
isDoomsdayClock?: boolean;
|
||||
}
|
||||
|
||||
export interface UnitInfo {
|
||||
|
||||
@@ -78,7 +78,8 @@ type ModifierKey =
|
||||
| "isNukesDisabled"
|
||||
| "isSAMsDisabled"
|
||||
| "isPeaceTime"
|
||||
| "isWaterNukes";
|
||||
| "isWaterNukes"
|
||||
| "isDoomsdayClock";
|
||||
|
||||
// Each entry represents one "ticket" in the pool. More tickets = higher chance of selection.
|
||||
// Weights are roughly informed by the community "favorite modifier" poll.
|
||||
@@ -96,8 +97,19 @@ const SPECIAL_MODIFIER_POOL: ModifierKey[] = [
|
||||
...Array<ModifierKey>(1).fill("isSAMsDisabled"),
|
||||
...Array<ModifierKey>(1).fill("isPeaceTime"),
|
||||
...Array<ModifierKey>(4).fill("isWaterNukes"),
|
||||
...Array<ModifierKey>(4).fill("isDoomsdayClock"),
|
||||
];
|
||||
|
||||
// Speeds the Doomsday Clock can roll at when it lands in the rotation. Picked
|
||||
// per game (see getSpecialConfig) so the pacing varies instead of always being
|
||||
// the same preset.
|
||||
const DOOMSDAY_ROTATION_SPEEDS = [
|
||||
"slow",
|
||||
"normal",
|
||||
"fast",
|
||||
"veryfast",
|
||||
] as const;
|
||||
|
||||
// Maps where water nukes have a higher chance on top of the normal pool
|
||||
// Water nukes are especially fun here
|
||||
const WATER_NUKES_BOOSTED_MAPS: ReadonlySet<GameMapType> = new Set([
|
||||
@@ -258,6 +270,7 @@ export class MapPlaylist {
|
||||
isSAMsDisabled,
|
||||
isPeaceTime,
|
||||
isWaterNukes,
|
||||
isDoomsdayClock,
|
||||
} = poolResult;
|
||||
if (boostWaterNukes) {
|
||||
isWaterNukes = true;
|
||||
@@ -284,7 +297,8 @@ export class MapPlaylist {
|
||||
!isNukesDisabled &&
|
||||
!isSAMsDisabled &&
|
||||
!isPeaceTime &&
|
||||
!isWaterNukes
|
||||
!isWaterNukes &&
|
||||
!isDoomsdayClock
|
||||
) {
|
||||
excludedModifiers.push("isCrowded");
|
||||
const fallback = this.getRandomSpecialGameModifiers(
|
||||
@@ -301,6 +315,7 @@ export class MapPlaylist {
|
||||
isSAMsDisabled,
|
||||
isPeaceTime,
|
||||
isWaterNukes,
|
||||
isDoomsdayClock,
|
||||
} = fallback);
|
||||
({ isHardNations } = fallback);
|
||||
}
|
||||
@@ -357,7 +372,19 @@ export class MapPlaylist {
|
||||
isSAMsDisabled,
|
||||
isPeaceTime,
|
||||
isWaterNukes,
|
||||
isDoomsdayClock,
|
||||
},
|
||||
// Rolled into the rotation: enable the anti-stall clock at a speed picked
|
||||
// per game so the pacing varies across the presets.
|
||||
doomsdayClock: isDoomsdayClock
|
||||
? {
|
||||
enabled: true,
|
||||
speed:
|
||||
DOOMSDAY_ROTATION_SPEEDS[
|
||||
Math.floor(Math.random() * DOOMSDAY_ROTATION_SPEEDS.length)
|
||||
],
|
||||
}
|
||||
: undefined,
|
||||
startingGold,
|
||||
goldMultiplier,
|
||||
disableAlliances: isAlliancesDisabled ? true : undefined,
|
||||
@@ -561,6 +588,7 @@ export class MapPlaylist {
|
||||
isSAMsDisabled: selected.has("isSAMsDisabled") || undefined,
|
||||
isPeaceTime: selected.has("isPeaceTime") || undefined,
|
||||
isWaterNukes: selected.has("isWaterNukes") || undefined,
|
||||
isDoomsdayClock: selected.has("isDoomsdayClock") || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user