mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 09:08:11 +00:00
fix: Implement NukeWars gamemode fixes
- Fix NukeWars not being treated as a teams game (always 2 teams) - Fix building restrictions during/after preparation phase * Block only MIRVs completely * Block nuclear weapons during preparation phase only * Allow all other structures - Fix transport boat movement rules * Allow movement within team territory * Block movement into enemy territory - Add proper preparation phase (180 seconds) - Ensure combat is primarily through nuclear weapons Technical changes: - Add NukeWars to GameMode enum - Implement preparation phase configuration and timing - Add team territory checks for transport boats - Fix building restriction logic for NukeWars mode
This commit is contained in:
@@ -89,6 +89,7 @@ export interface Config {
|
||||
donateTroops(): boolean;
|
||||
instantBuild(): boolean;
|
||||
numSpawnPhaseTurns(): number;
|
||||
numPreparationPhaseTurns(): number;
|
||||
userSettings(): UserSettings;
|
||||
playerTeams(): TeamCountConfig;
|
||||
|
||||
|
||||
@@ -622,8 +622,6 @@ export class DefaultConfig implements Config {
|
||||
numSpawnPhaseTurns(): number {
|
||||
return this._gameConfig.gameType === GameType.Singleplayer ? 100 : 300;
|
||||
}
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
|
||||
numPreparationPhaseTurns(): number {
|
||||
if (this._gameConfig.gameMode === GameMode.NukeWars) {
|
||||
@@ -631,7 +629,7 @@ export class DefaultConfig implements Config {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
numBots(): number {
|
||||
return this.bots();
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ export const isGameType = (value: unknown): value is GameType =>
|
||||
export enum GameMode {
|
||||
FFA = "Free For All",
|
||||
Team = "Team",
|
||||
NukeWars = "Nuke Wars"
|
||||
}
|
||||
export const isGameMode = (value: unknown): value is GameMode =>
|
||||
isEnumValue(GameMode, value);
|
||||
|
||||
@@ -96,12 +96,7 @@ export class GameImpl implements Game {
|
||||
this._width = _map.width();
|
||||
this._height = _map.height();
|
||||
this.unitGrid = new UnitGrid(this._map);
|
||||
<<<<<<< Updated upstream
|
||||
|
||||
if (_config.gameConfig().gameMode === GameMode.Team) {
|
||||
=======
|
||||
if (this.isTeamBasedGame()) {
|
||||
>>>>>>> Stashed changes
|
||||
this.populateTeams();
|
||||
}
|
||||
this.addPlayers();
|
||||
@@ -114,12 +109,9 @@ export class GameImpl implements Game {
|
||||
|
||||
private populateTeams() {
|
||||
let numPlayerTeams = this._config.playerTeams();
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
if (this._config.gameConfig().gameMode === GameMode.NukeWars) {
|
||||
numPlayerTeams = 2;
|
||||
}
|
||||
>>>>>>> Stashed changes
|
||||
if (typeof numPlayerTeams !== "number") {
|
||||
const players = this._humans.length + this._nations.length;
|
||||
switch (numPlayerTeams) {
|
||||
@@ -338,15 +330,11 @@ export class GameImpl implements Game {
|
||||
return this._ticks <= this.config().numSpawnPhaseTurns();
|
||||
}
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
inPreparationPhase(): boolean {
|
||||
const spawn = this.config().numSpawnPhaseTurns();
|
||||
const prep = this.config().numPreparationPhaseTurns();
|
||||
return this._ticks > spawn && this._ticks <= spawn + prep;
|
||||
}
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
ticks(): number {
|
||||
return this._ticks;
|
||||
}
|
||||
|
||||
@@ -950,6 +950,22 @@ export class PlayerImpl implements Player {
|
||||
);
|
||||
}
|
||||
|
||||
private isInTeamSpawnZone(tile: TileRef): boolean {
|
||||
const team = this.team();
|
||||
if (!team) return false;
|
||||
|
||||
// Simple geometric split:
|
||||
// Team 1 gets left half (x < width/2)
|
||||
// Team 2 gets right half (x >= width/2)
|
||||
const x = this.mg.x(tile);
|
||||
const mapWidth = this.mg.width();
|
||||
const midpoint = Math.floor(mapWidth / 2);
|
||||
|
||||
// Team 1 gets left half, Team 2 gets right half
|
||||
const isTeam1 = team === this.mg.teams()[0];
|
||||
return isTeam1 ? x < midpoint : x >= midpoint;
|
||||
}
|
||||
|
||||
private canBuildShipNukeWars(
|
||||
unitType: UnitType,
|
||||
targetTile: TileRef,
|
||||
@@ -974,6 +990,17 @@ export class PlayerImpl implements Player {
|
||||
}
|
||||
|
||||
private canBuildNukeNukeWars(unitType: UnitType): boolean {
|
||||
// Always block MIRVs in NukeWars
|
||||
if (unitType === UnitType.MIRV) {
|
||||
this.mg.displayMessage(
|
||||
"MIRVs are not allowed in Nuke Wars mode",
|
||||
MessageType.ATTACK_FAILED,
|
||||
this.id(),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Block nuclear weapons during preparation phase
|
||||
if (
|
||||
(unitType === UnitType.AtomBomb || unitType === UnitType.HydrogenBomb) &&
|
||||
this.mg.inPreparationPhase()
|
||||
@@ -998,8 +1025,6 @@ export class PlayerImpl implements Player {
|
||||
return false;
|
||||
}
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
if (this.isNukeWarsAndBaikal()) {
|
||||
if (!this.canBuildShipNukeWars(unitType, targetTile)) {
|
||||
return false;
|
||||
@@ -1017,7 +1042,6 @@ export class PlayerImpl implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
const cost = this.mg.unitInfo(unitType).cost(this);
|
||||
if (!this.isAlive() || this.gold() < cost) {
|
||||
return false;
|
||||
@@ -1031,12 +1055,9 @@ export class PlayerImpl implements Player {
|
||||
return this.nukeSpawn(targetTile);
|
||||
case UnitType.AtomBomb:
|
||||
case UnitType.HydrogenBomb:
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
if (this.isNukeWars() && !this.canBuildNukeNukeWars(unitType)) {
|
||||
return false;
|
||||
}
|
||||
>>>>>>> Stashed changes
|
||||
return this.nukeSpawn(targetTile);
|
||||
case UnitType.MIRVWarhead:
|
||||
return targetTile;
|
||||
|
||||
Reference in New Issue
Block a user