mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 12:00:44 +00:00
Mark train stations and factories as experimental (#1309)
## Description: Train stations and factories won't be ready for v24. Disable them by default. They can be reactivated on private lobies and solo games, allowing us to gather feedbacks. Changes: - added an "experimental" attribute for units. When set, they are hidden entirely when disabled, rather than appearing grayed out. - disabled train stations and factories by default. Default values:  No factories:  ## 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 - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: IngloriousTom
This commit is contained in:
@@ -241,7 +241,9 @@
|
||||
"sam_launcher": "SAM Launcher",
|
||||
"atom_bomb": "Atom Bomb",
|
||||
"hydrogen_bomb": "Hydrogen Bomb",
|
||||
"mirv": "MIRV"
|
||||
"mirv": "MIRV",
|
||||
"train": "Train",
|
||||
"factory": "Factory"
|
||||
},
|
||||
"user_setting": {
|
||||
"title": "User Settings",
|
||||
|
||||
@@ -39,7 +39,10 @@ export class HostLobbyModal extends LitElement {
|
||||
@state() private copySuccess = false;
|
||||
@state() private players: string[] = [];
|
||||
@state() private useRandomMap: boolean = false;
|
||||
@state() private disabledUnits: UnitType[] = [];
|
||||
@state() private disabledUnits: UnitType[] = [
|
||||
UnitType.Factory,
|
||||
UnitType.Train,
|
||||
];
|
||||
|
||||
private playersInterval: NodeJS.Timeout | null = null;
|
||||
// Add a new timer for debouncing bot changes
|
||||
|
||||
@@ -40,7 +40,10 @@ export class SinglePlayerModal extends LitElement {
|
||||
@state() private gameMode: GameMode = GameMode.FFA;
|
||||
@state() private teamCount: number | typeof Duos = 2;
|
||||
|
||||
@state() private disabledUnits: UnitType[] = [];
|
||||
@state() private disabledUnits: UnitType[] = [
|
||||
UnitType.Factory,
|
||||
UnitType.Train,
|
||||
];
|
||||
|
||||
private userSettings: UserSettings = new UserSettings();
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Config } from "../../../core/configuration/Config";
|
||||
import {
|
||||
AllPlayers,
|
||||
Cell,
|
||||
@@ -322,6 +323,32 @@ export const infoMenuElement: MenuElement = {
|
||||
},
|
||||
};
|
||||
|
||||
function getAllEnabledUnits(myPlayer: boolean, config: Config): Set<UnitType> {
|
||||
const Units: Set<UnitType> = new Set<UnitType>();
|
||||
|
||||
const addStructureIfEnabled = (unitType: UnitType) => {
|
||||
if (!config.isUnitDisabled(unitType)) {
|
||||
Units.add(unitType);
|
||||
}
|
||||
};
|
||||
|
||||
if (myPlayer) {
|
||||
addStructureIfEnabled(UnitType.City);
|
||||
addStructureIfEnabled(UnitType.DefensePost);
|
||||
addStructureIfEnabled(UnitType.Port);
|
||||
addStructureIfEnabled(UnitType.MissileSilo);
|
||||
addStructureIfEnabled(UnitType.SAMLauncher);
|
||||
addStructureIfEnabled(UnitType.Factory);
|
||||
} else {
|
||||
addStructureIfEnabled(UnitType.Warship);
|
||||
addStructureIfEnabled(UnitType.HydrogenBomb);
|
||||
addStructureIfEnabled(UnitType.MIRV);
|
||||
addStructureIfEnabled(UnitType.AtomBomb);
|
||||
}
|
||||
|
||||
return Units;
|
||||
}
|
||||
|
||||
export const buildMenuElement: MenuElement = {
|
||||
id: Slot.Build,
|
||||
name: "build",
|
||||
@@ -332,21 +359,10 @@ export const buildMenuElement: MenuElement = {
|
||||
subMenu: (params: MenuElementParams) => {
|
||||
if (params === undefined) return [];
|
||||
|
||||
const unitTypes: Set<UnitType> = new Set<UnitType>();
|
||||
if (params.selected === params.myPlayer) {
|
||||
unitTypes.add(UnitType.City);
|
||||
unitTypes.add(UnitType.DefensePost);
|
||||
unitTypes.add(UnitType.Port);
|
||||
unitTypes.add(UnitType.MissileSilo);
|
||||
unitTypes.add(UnitType.SAMLauncher);
|
||||
unitTypes.add(UnitType.Factory);
|
||||
} else {
|
||||
unitTypes.add(UnitType.Warship);
|
||||
unitTypes.add(UnitType.HydrogenBomb);
|
||||
unitTypes.add(UnitType.MIRV);
|
||||
unitTypes.add(UnitType.AtomBomb);
|
||||
}
|
||||
|
||||
const unitTypes: Set<UnitType> = getAllEnabledUnits(
|
||||
params.selected === params.myPlayer,
|
||||
params.game.config(),
|
||||
);
|
||||
const buildElements: MenuElement[] = flattenedBuildTable
|
||||
.filter((item) => unitTypes.has(item.unitType))
|
||||
.map((item: BuildItemDisplay) => ({
|
||||
|
||||
@@ -246,7 +246,8 @@ export class UnitInfoModal extends LitElement implements Layer {
|
||||
class="upgrade-button"
|
||||
title="${translateText("unit_info_modal.create_station")}"
|
||||
style="width: 100px; height: 32px;
|
||||
display: ${this.unit.hasTrainStation() ||
|
||||
display: ${this.game.config().isUnitDisabled(UnitType.Train) ||
|
||||
this.unit.hasTrainStation() ||
|
||||
!this.game.unitInfo(this.unit.type()).canBuildTrainStation
|
||||
? "none"
|
||||
: "block"};"
|
||||
|
||||
@@ -18,6 +18,8 @@ const unitOptions: { type: UnitType; translationKey: string }[] = [
|
||||
{ type: UnitType.AtomBomb, translationKey: "unit_type.atom_bomb" },
|
||||
{ type: UnitType.HydrogenBomb, translationKey: "unit_type.hydrogen_bomb" },
|
||||
{ type: UnitType.MIRV, translationKey: "unit_type.mirv" },
|
||||
{ type: UnitType.Train, translationKey: "unit_type.train" },
|
||||
{ type: UnitType.Factory, translationKey: "unit_type.factory" },
|
||||
];
|
||||
|
||||
export function renderUnitTypeOptions({
|
||||
|
||||
@@ -469,6 +469,7 @@ export class DefaultConfig implements Config {
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
canBuildTrainStation: true,
|
||||
experimental: true,
|
||||
};
|
||||
case UnitType.Construction:
|
||||
return {
|
||||
@@ -479,6 +480,7 @@ export class DefaultConfig implements Config {
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
experimental: true,
|
||||
};
|
||||
default:
|
||||
assertNever(type);
|
||||
|
||||
@@ -444,6 +444,9 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
private maybeSpawnTrainStation(): boolean {
|
||||
if (this.mg.config().isUnitDisabled(UnitType.Train)) {
|
||||
return false;
|
||||
}
|
||||
if (this.player === null) throw new Error("not initialized");
|
||||
const citiesWithoutStations = this.player.units().filter((unit) => {
|
||||
switch (unit.type()) {
|
||||
|
||||
@@ -133,6 +133,7 @@ export interface UnitInfo {
|
||||
constructionDuration?: number;
|
||||
upgradable?: boolean;
|
||||
canBuildTrainStation?: boolean;
|
||||
experimental?: boolean;
|
||||
}
|
||||
|
||||
export enum UnitType {
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from "../core/Schemas";
|
||||
import { createGameRecord } from "../core/Util";
|
||||
import { GameEnv, ServerConfig } from "../core/configuration/Config";
|
||||
import { GameType } from "../core/game/Game";
|
||||
import { GameType, UnitType } from "../core/game/Game";
|
||||
import { archive } from "./Archive";
|
||||
import { Client } from "./Client";
|
||||
import { gatekeeper } from "./Gatekeeper";
|
||||
@@ -222,6 +222,15 @@ export class GameServer {
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
clientMsg.intent.type === "create_station" &&
|
||||
this.gameConfig.disabledUnits?.includes(UnitType.Train)
|
||||
) {
|
||||
this.log.warn(
|
||||
`create_station is disabled, client: ${client.clientID}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.addIntent(clientMsg.intent);
|
||||
}
|
||||
if (clientMsg.type === "ping") {
|
||||
|
||||
Reference in New Issue
Block a user