From 7fcbaa85840d0c9c3f64aab213c4439ada37858a Mon Sep 17 00:00:00 2001
From: NewHappyRabbit <31893343+NewHappyRabbit@users.noreply.github.com>
Date: Wed, 12 Feb 2025 00:15:30 +0200
Subject: [PATCH] Added creative mode. Everything costs 0 gold, builds
instantly and you start with 100k population
---
src/client/ClientGameRunner.ts | 2 ++
src/client/HostLobbyModal.ts | 17 +++++++++++++++
src/client/Main.ts | 1 +
src/client/SinglePlayerModal.ts | 14 +++++++++++++
src/core/Schemas.ts | 1 +
src/core/configuration/DefaultConfig.ts | 28 +++++++++++++++----------
src/core/configuration/DevConfig.ts | 6 +++---
src/server/GameManager.ts | 2 ++
src/server/Server.ts | 1 +
9 files changed, 58 insertions(+), 14 deletions(-)
diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts
index 2587af3de..26de903ae 100644
--- a/src/client/ClientGameRunner.ts
+++ b/src/client/ClientGameRunner.ts
@@ -59,6 +59,7 @@ export interface LobbyConfig {
difficulty: Difficulty | null;
disableBots: boolean | null;
disableNPCs: boolean | null;
+ creativeMode: boolean | null;
}
export function joinLobby(
@@ -82,6 +83,7 @@ export function joinLobby(
difficulty: lobbyConfig.difficulty,
disableBots: lobbyConfig.disableBots,
disableNPCs: lobbyConfig.disableNPCs,
+ creativeMode: lobbyConfig.creativeMode,
};
}
diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts
index 28dc377d7..0a37a2410 100644
--- a/src/client/HostLobbyModal.ts
+++ b/src/client/HostLobbyModal.ts
@@ -11,6 +11,7 @@ export class HostLobbyModal extends LitElement {
@state() private selectedDiffculty: Difficulty = Difficulty.Medium;
@state() private disableNPCs = false;
@state() private disableBots = false;
+ @state() private creativeMode = false;
@state() private lobbyId = "";
@state() private copySuccess = false;
@state() private players: string[] = [];
@@ -183,6 +184,14 @@ export class HostLobbyModal extends LitElement {
/>
+
+
+
+
Players: ${this.players.join(", ")}
@@ -211,6 +220,7 @@ export class HostLobbyModal extends LitElement {
difficulty: this.selectedDiffculty,
disableBots: this.disableBots,
disableNPCs: this.disableNPCs,
+ creativeMode: this.creativeMode,
},
bubbles: true,
composed: true,
@@ -258,6 +268,12 @@ export class HostLobbyModal extends LitElement {
this.putGameConfig();
}
+ private async handleCreativeModeChange(e: Event) {
+ this.creativeMode = Boolean((e.target as HTMLInputElement).checked);
+ consolex.log(`updating creative mode to ${this.creativeMode}`);
+ this.putGameConfig();
+ }
+
private async putGameConfig() {
const response = await fetch(`/private_lobby/${this.lobbyId}`, {
method: "PUT",
@@ -269,6 +285,7 @@ export class HostLobbyModal extends LitElement {
difficulty: this.selectedDiffculty,
disableBots: this.disableBots,
disableNPCs: this.disableNPCs,
+ creativeMode: this.creativeMode,
}),
});
}
diff --git a/src/client/Main.ts b/src/client/Main.ts
index 542588b68..3b36a7fe4 100644
--- a/src/client/Main.ts
+++ b/src/client/Main.ts
@@ -115,6 +115,7 @@ class Client {
difficulty: event.detail.difficulty,
disableBots: event.detail.disableBots,
disableNPCs: event.detail.disableNPCs,
+ creativeMode: event.detail.creativeMode,
},
() => this.joinModal.close()
);
diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts
index 9645b25f3..fdb03c28b 100644
--- a/src/client/SinglePlayerModal.ts
+++ b/src/client/SinglePlayerModal.ts
@@ -11,6 +11,7 @@ export class SinglePlayerModal extends LitElement {
@state() private selectedDifficulty: Difficulty = Difficulty.Medium;
@state() private disableNPCs = false;
@state() private disableBots = false;
+ @state() private creativeMode = false;
static styles = css`
.modal-overlay {
@@ -134,6 +135,15 @@ export class SinglePlayerModal extends LitElement {
+
+
+
+
+
@@ -164,6 +174,9 @@ export class SinglePlayerModal extends LitElement {
private handleDisableNPCsChange(e: Event) {
this.disableNPCs = Boolean((e.target as HTMLInputElement).checked);
}
+ private handleCreativeModeChange(e: Event) {
+ this.creativeMode = Boolean((e.target as HTMLInputElement).checked);
+ }
private startGame() {
consolex.log(
`Starting single player game with map: ${GameMapType[this.selectedMap]}`,
@@ -179,6 +192,7 @@ export class SinglePlayerModal extends LitElement {
difficulty: this.selectedDifficulty,
disableBots: this.disableBots,
disableNPCs: this.disableNPCs,
+ creativeMode: this.creativeMode,
},
bubbles: true,
composed: true,
diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts
index 4ca90568b..a4b31c18f 100644
--- a/src/core/Schemas.ts
+++ b/src/core/Schemas.ts
@@ -94,6 +94,7 @@ const GameConfigSchema = z.object({
gameType: z.nativeEnum(GameType),
disableBots: z.boolean(),
disableNPCs: z.boolean(),
+ creativeMode: z.boolean(),
});
const SafeString = z
diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts
index 521c28b25..c1a81d14b 100644
--- a/src/core/configuration/DefaultConfig.ts
+++ b/src/core/configuration/DefaultConfig.ts
@@ -81,6 +81,9 @@ export class DefaultConfig implements Config {
spawnBots(): boolean {
return !this._gameConfig.disableBots;
}
+ creativeMode(): boolean {
+ return this._gameConfig.creativeMode;
+ }
tradeShipGold(dist: number): Gold {
return 10000 + 100 * Math.pow(dist, 1.1);
}
@@ -97,7 +100,7 @@ export class DefaultConfig implements Config {
};
case UnitType.Warship:
return {
- cost: (p: Player) => (p.units(UnitType.Warship).length + 1) * 250_000,
+ cost: (p: Player) => this.creativeMode() ? 0 : (p.units(UnitType.Warship).length + 1) * 250_000,
territoryBound: false,
maxHealth: 1000,
};
@@ -110,26 +113,27 @@ export class DefaultConfig implements Config {
case UnitType.Port:
return {
cost: (p: Player) =>
+ this.creativeMode() ? 0 :
Math.min(
1_000_000,
Math.pow(2, p.units(UnitType.Port).length) * 250_000
),
territoryBound: true,
- constructionDuration: 2 * 10,
+ constructionDuration: this.creativeMode() ? 0 : 2 * 10,
};
case UnitType.AtomBomb:
return {
- cost: () => 750_000,
+ cost: () => this.creativeMode() ? 0 : 750_000,
territoryBound: false,
};
case UnitType.HydrogenBomb:
return {
- cost: () => 5_000_000,
+ cost: () => this.creativeMode() ? 0 : 5_000_000,
territoryBound: false,
};
case UnitType.MIRV:
return {
- cost: () => 10_000_000,
+ cost: () => this.creativeMode() ? 0 : 10_000_000,
territoryBound: false,
};
case UnitType.MIRVWarhead:
@@ -144,29 +148,31 @@ export class DefaultConfig implements Config {
};
case UnitType.MissileSilo:
return {
- cost: () => 1_000_000,
+ cost: () => this.creativeMode() ? 0 : 1_000_000,
territoryBound: true,
- constructionDuration: 10 * 10,
+ constructionDuration: this.creativeMode() ? 0 : 10 * 10,
};
case UnitType.DefensePost:
return {
cost: (p: Player) =>
+ this.creativeMode() ? 0 :
Math.min(
250_000,
(p.units(UnitType.DefensePost).length + 1) * 50_000
),
territoryBound: true,
- constructionDuration: 5 * 10,
+ constructionDuration: this.creativeMode() ? 0 : 5 * 10,
};
case UnitType.City:
return {
cost: (p: Player) =>
+ this.creativeMode() ? 0 :
Math.min(
1_000_000,
Math.pow(2, p.units(UnitType.City).length) * 125_000
),
territoryBound: true,
- constructionDuration: 2 * 10,
+ constructionDuration: this.creativeMode() ? 0 : 2 * 10,
};
case UnitType.Construction:
return {
@@ -347,11 +353,11 @@ export class DefaultConfig implements Config {
return 20_000 * (playerInfo?.nation?.strength ?? 1);
}
}
- return 25_000;
+ return this.creativeMode() ? 1_000_000 : 25_000;
}
maxPopulation(player: Player | PlayerView): number {
- let maxPop =
+ let maxPop = this.creativeMode() ? 999_999_999_999 :
2 * (Math.pow(player.numTilesOwned(), 0.6) * 1000 + 50000) +
player.units(UnitType.City).length * this.cityPopulationIncrease();
diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts
index bc447870f..56d2bf27c 100644
--- a/src/core/configuration/DevConfig.ts
+++ b/src/core/configuration/DevConfig.ts
@@ -37,9 +37,9 @@ export class DevConfig extends DefaultConfig {
// return 1
// }
- populationIncreaseRate(player: Player): number {
- return this.maxPopulation(player)
- }
+ // populationIncreaseRate(player: Player): number {
+ // return this.maxPopulation(player)
+ // }
// boatMaxDistance(): number {
// return 5000
diff --git a/src/server/GameManager.ts b/src/server/GameManager.ts
index 6a98b6f41..0e0c6d80e 100644
--- a/src/server/GameManager.ts
+++ b/src/server/GameManager.ts
@@ -51,6 +51,7 @@ export class GameManager {
difficulty: Difficulty.Medium,
disableBots: false,
disableNPCs: false,
+ creativeMode: false,
})
);
return id;
@@ -91,6 +92,7 @@ export class GameManager {
difficulty: Difficulty.Medium,
disableBots: false,
disableNPCs: false,
+ creativeMode: false,
})
);
}
diff --git a/src/server/Server.ts b/src/server/Server.ts
index 90d847ef9..1931b2d31 100644
--- a/src/server/Server.ts
+++ b/src/server/Server.ts
@@ -96,6 +96,7 @@ app.put("/private_lobby/:id", (req, res) => {
difficulty: req.body.difficulty,
disableBots: req.body.disableBots,
disableNPCs: req.body.disableNPCs,
+ creativeMode: req.body.creativeMode,
});
});