mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-30 12:02:12 +00:00
NukeWars: only block MIRV; prevent ships crossing midpoint; bias spawn selection toward midpoint for balance
This commit is contained in:
@@ -319,20 +319,12 @@ export class DefaultConfig implements Config {
|
||||
}
|
||||
|
||||
isUnitDisabled(unitType: UnitType): boolean {
|
||||
// First check game mode specific restrictions
|
||||
// Nuke Wars: only MIRV is blocked explicitly. Keep any server-configured
|
||||
// disabledUnits in the check as well.
|
||||
if (this._gameConfig.gameMode === GameMode.NukeWars) {
|
||||
const allowedUnits = [
|
||||
UnitType.MissileSilo,
|
||||
UnitType.SAMLauncher,
|
||||
UnitType.AtomBomb,
|
||||
UnitType.HydrogenBomb,
|
||||
];
|
||||
if (!allowedUnits.includes(unitType)) {
|
||||
return true;
|
||||
}
|
||||
if (unitType === UnitType.MIRV) return true;
|
||||
}
|
||||
|
||||
// Then check manually disabled units
|
||||
return this._gameConfig.disabledUnits?.includes(unitType) ?? false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { Execution, Game, Player, UnitType } from "../game/Game";
|
||||
import {
|
||||
Execution,
|
||||
Game,
|
||||
GameMapType,
|
||||
GameMode,
|
||||
Player,
|
||||
UnitType,
|
||||
} from "../game/Game";
|
||||
import { TileRef } from "../game/GameMap";
|
||||
|
||||
export class MoveWarshipExecution implements Execution {
|
||||
@@ -24,6 +31,24 @@ export class MoveWarshipExecution implements Execution {
|
||||
console.warn("MoveWarshipExecution: warship is not active");
|
||||
return;
|
||||
}
|
||||
// In Nuke Wars on Baikal, prevent assigning patrols that cross the midpoint.
|
||||
const gc = mg.config().gameConfig();
|
||||
if (
|
||||
gc.gameMode === GameMode.NukeWars &&
|
||||
gc.gameMap === GameMapType.Baikal
|
||||
) {
|
||||
const mapWidth = mg.width();
|
||||
const wantLeft = this.owner.smallID() % 2 === 1;
|
||||
const posLeft = mg.x(this.position) < Math.floor(mapWidth / 2);
|
||||
if (wantLeft !== posLeft) {
|
||||
// reject the move
|
||||
console.warn(
|
||||
"MoveWarshipExecution: cannot assign warship patrol across midpoint in Nuke Wars",
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
warship.setPatrolTile(this.position);
|
||||
warship.setTargetTile(undefined);
|
||||
}
|
||||
|
||||
@@ -59,18 +59,24 @@ export class SpawnExecution implements Execution {
|
||||
const wantLeft = player.smallID() % 2 === 1;
|
||||
const isLeft = tx < Math.floor(mapWidth / 2);
|
||||
if (wantLeft !== isLeft) {
|
||||
// Find nearest valid tile on the correct half
|
||||
// Find nearest valid tile on the correct half. Bias selection toward
|
||||
// tiles closer to the midpoint so both sides get spawn tiles that
|
||||
// produce more balanced territory when map land distribution is uneven.
|
||||
let best: TileRef | null = null;
|
||||
let bestDist = Infinity;
|
||||
let bestScore = Infinity;
|
||||
const midpoint = Math.floor(mapWidth / 2);
|
||||
this.mg.forEachTile((t) => {
|
||||
const xt = this.mg.x(t);
|
||||
const onCorrectHalf = wantLeft
|
||||
? xt < Math.floor(mapWidth / 2)
|
||||
: xt >= Math.floor(mapWidth / 2);
|
||||
const onCorrectHalf = wantLeft ? xt < midpoint : xt >= midpoint;
|
||||
if (onCorrectHalf && !this.mg.hasOwner(t) && this.mg.isLand(t)) {
|
||||
const d = this.mg.manhattanDist(this.tile, t);
|
||||
if (d < bestDist) {
|
||||
bestDist = d;
|
||||
// score combines distance from original tile and distance from midpoint
|
||||
// biasFactor controls how strongly we prefer midline tiles (0.0-1.0)
|
||||
const biasFactor = 0.5;
|
||||
const centerDistance = Math.abs(xt - midpoint);
|
||||
const score = d + centerDistance * biasFactor;
|
||||
if (score < bestScore) {
|
||||
bestScore = score;
|
||||
best = t;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-11
@@ -930,19 +930,23 @@ export class PlayerImpl implements Player {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check spawn zone restrictions in Nuke Wars mode
|
||||
if (this.mg.config().gameConfig().gameMode === GameMode.NukeWars) {
|
||||
// During spawn phase, enforce strict spawn zones
|
||||
if (this.mg.inSpawnPhase() && !this.isInTeamSpawnZone(targetTile)) {
|
||||
return false;
|
||||
// Prevent crossing midpoint with ships/boats at any time in Nuke Wars.
|
||||
const gc = this.mg.config().gameConfig();
|
||||
if (
|
||||
gc.gameMode === GameMode.NukeWars &&
|
||||
gc.gameMap === GameMapType.Baikal
|
||||
) {
|
||||
if (
|
||||
unitType === UnitType.TransportShip ||
|
||||
unitType === UnitType.Warship ||
|
||||
unitType === UnitType.TradeShip
|
||||
) {
|
||||
if (!this.isInTeamSpawnZone(targetTile)) return false;
|
||||
}
|
||||
|
||||
// After spawn phase, only allow missiles to cross the midpoint
|
||||
if (!this.mg.inSpawnPhase() && !this.isInTeamSpawnZone(targetTile)) {
|
||||
const allowedTypes = [UnitType.AtomBomb, UnitType.HydrogenBomb];
|
||||
if (!allowedTypes.includes(unitType)) {
|
||||
return false;
|
||||
}
|
||||
// During spawn phase we enforce that regular land spawns happen on-team.
|
||||
if (this.mg.inSpawnPhase() && !this.isInTeamSpawnZone(targetTile)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PathFindResultType } from "../pathfinding/AStar";
|
||||
import { MiniAStar } from "../pathfinding/MiniAStar";
|
||||
import { Game, Player, UnitType } from "./Game";
|
||||
import { Game, GameMapType, GameMode, Player, UnitType } from "./Game";
|
||||
import { andFN, GameMap, manhattanDistFN, TileRef } from "./GameMap";
|
||||
|
||||
export function canBuildTransportShip(
|
||||
@@ -49,6 +49,18 @@ export function canBuildTransportShip(
|
||||
}
|
||||
|
||||
if (myPlayerBordersOcean && otherPlayerBordersOcean) {
|
||||
// In Nuke Wars on Baikal, ensure transport source/destination are on same half.
|
||||
const gc = game.config().gameConfig();
|
||||
if (
|
||||
gc.gameMode === GameMode.NukeWars &&
|
||||
gc.gameMap === GameMapType.Baikal
|
||||
) {
|
||||
const mapWidth = game.width();
|
||||
const wantLeft = player.smallID() % 2 === 1;
|
||||
const dstX = game.x(dst);
|
||||
const dstLeft = dstX < Math.floor(mapWidth / 2);
|
||||
if (wantLeft !== dstLeft) return false;
|
||||
}
|
||||
return transportShipSpawn(game, player, dst);
|
||||
} else {
|
||||
return false;
|
||||
@@ -72,6 +84,18 @@ export function canBuildTransportShip(
|
||||
|
||||
for (const t of sorted) {
|
||||
if (game.owner(t) === player) {
|
||||
// Block cross-midpoint lake deployments in Nuke Wars on Baikal
|
||||
const gc = game.config().gameConfig();
|
||||
if (
|
||||
gc.gameMode === GameMode.NukeWars &&
|
||||
gc.gameMap === GameMapType.Baikal
|
||||
) {
|
||||
const mapWidth = game.width();
|
||||
const wantLeft = player.smallID() % 2 === 1;
|
||||
const tX = game.x(t);
|
||||
const tLeft = tX < Math.floor(mapWidth / 2);
|
||||
if (wantLeft !== tLeft) return false;
|
||||
}
|
||||
return transportShipSpawn(game, player, t);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user