mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-30 11:12:18 +00:00
For v30: Add new modifiers (Hard nations and 25M Starting Gold) 🙂 (#3316)
## Description: Adds two new public game modifiers for variety and improves compact map eligibility for team games. ### New Modifiers **Hard Nations (`isHardNations`)** - We need this modifier for HvN, because medium nations are easier now (will result in a much higher human winrate) - In a discord discussion we concluded that HvN should generally be easier (higher winrate than 50%, so players are less frustated) - Thats why only 20% of HvN games have the hard nations modifier (for now) - For PvPvE enjoyers, the modifier is also active in FFA games => (Only 2.5% chance, and 1 ticket in `SPECIAL_MODIFIER_POOL`) **25M Starting Gold (`startingGoldHigh`)** - Some people in the main discord wanted this modifier, and it will result in crazy games - Rare special-only modifier (1 ticket in pool); mutually exclusive with 5M starting gold via `MUTUALLY_EXCLUSIVE_MODIFIERS` - Disables nations (they lack PVP immunity, so 25M gold doesn't work well with them) - Excluded from HumansVsNations games (since it disables nations) - Spawn immunity set to **2 minutes 30 seconds** (vs 30s for 5M gold), so people can spend the gold and prepare ### Other Changes - **Improved `supportsCompactMapForTeams`**: Replaced the hard `smallest >= 50` land-tile cutoff with a per-team-config calculation that simulates worst-case compact player count and checks every team gets at least 2 players. - **HvN spawn immunity**: Always 5 seconds in both regular and special lobbies (to get rid of a confusing PVP immunity HeadsUpMessage in 5M starting gold games) - **Regular public lobby random spawn modifier probabilty**: Reduced from 10% to 5% (Because of the new modifier, so there aren't too many modifiers in non-special-lobbies, should only occur sometimes there) - Rebalanced `SPECIAL_MODIFIER_POOL` a bit ## 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: FloPinguin
This commit is contained in:
@@ -5,7 +5,6 @@ import {
|
||||
GameMapType,
|
||||
GameMode,
|
||||
HumansVsNations,
|
||||
PublicGameModifiers,
|
||||
Quads,
|
||||
Trios,
|
||||
} from "../core/game/Game";
|
||||
@@ -16,7 +15,12 @@ import { PublicLobbySocket } from "./LobbySocket";
|
||||
import { JoinLobbyEvent } from "./Main";
|
||||
import { SinglePlayerModal } from "./SinglePlayerModal";
|
||||
import { terrainMapFileLoader } from "./TerrainMapFileLoader";
|
||||
import { getMapName, renderDuration, translateText } from "./Utils";
|
||||
import {
|
||||
getMapName,
|
||||
getModifierLabels,
|
||||
renderDuration,
|
||||
translateText,
|
||||
} from "./Utils";
|
||||
|
||||
const CARD_BG = "bg-[color-mix(in_oklab,var(--frenchBlue)_70%,black)]";
|
||||
|
||||
@@ -198,7 +202,7 @@ export class GameModeSelector extends LitElement {
|
||||
|
||||
const mapName = getMapName(lobby.gameConfig?.gameMap);
|
||||
|
||||
const modifierLabels = this.getModifierLabels(
|
||||
const modifierLabels = getModifierLabels(
|
||||
lobby.gameConfig?.publicGameModifiers,
|
||||
);
|
||||
// Sort by length for visual consistency (shorter labels first)
|
||||
@@ -283,16 +287,6 @@ export class GameModeSelector extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private getModifierLabels(mods: PublicGameModifiers | undefined): string[] {
|
||||
if (!mods) return [];
|
||||
return [
|
||||
mods.isRandomSpawn && translateText("public_game_modifier.random_spawn"),
|
||||
mods.isCompact && translateText("public_game_modifier.compact_map"),
|
||||
mods.isCrowded && translateText("public_game_modifier.crowded"),
|
||||
mods.startingGold && translateText("public_game_modifier.starting_gold"),
|
||||
].filter((x): x is string => !!x);
|
||||
}
|
||||
|
||||
private getLobbyTitle(lobby: PublicGameInfo): string {
|
||||
const config = lobby.gameConfig!;
|
||||
if (config.gameMode === GameMode.FFA) {
|
||||
|
||||
+14
-1
@@ -109,6 +109,8 @@ export interface ModifierInfo {
|
||||
labelKey: string;
|
||||
/** Translation key for badge/short label (e.g. "public_game_modifier.random_spawn") */
|
||||
badgeKey: string;
|
||||
/** Parameters to pass to translateText for the badge key */
|
||||
badgeParams?: Record<string, string | number>;
|
||||
/** The raw value if applicable (e.g. startingGold amount) */
|
||||
value?: number;
|
||||
}
|
||||
@@ -139,10 +141,19 @@ export function getActiveModifiers(
|
||||
badgeKey: "public_game_modifier.crowded",
|
||||
});
|
||||
}
|
||||
if (modifiers.isHardNations) {
|
||||
result.push({
|
||||
labelKey: "host_modal.hard_nations",
|
||||
badgeKey: "public_game_modifier.hard_nations",
|
||||
});
|
||||
}
|
||||
if (modifiers.startingGold) {
|
||||
result.push({
|
||||
labelKey: "host_modal.starting_gold",
|
||||
badgeKey: "public_game_modifier.starting_gold",
|
||||
badgeParams: {
|
||||
amount: Math.round(modifiers.startingGold / 1_000_000),
|
||||
},
|
||||
value: modifiers.startingGold,
|
||||
});
|
||||
}
|
||||
@@ -155,7 +166,9 @@ export function getActiveModifiers(
|
||||
export function getModifierLabels(
|
||||
modifiers: PublicGameModifiers | undefined,
|
||||
): string[] {
|
||||
return getActiveModifiers(modifiers).map((m) => translateText(m.badgeKey));
|
||||
return getActiveModifiers(modifiers).map((m) =>
|
||||
translateText(m.badgeKey, m.badgeParams),
|
||||
);
|
||||
}
|
||||
|
||||
export function renderDuration(totalSeconds: number): string {
|
||||
|
||||
Reference in New Issue
Block a user