mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 02:25:40 +00:00
Only unit types buildable by player and some related changes
This commit is contained in:
@@ -348,6 +348,7 @@ export class DefaultConfig implements Config {
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: false,
|
||||
};
|
||||
case UnitType.Warship:
|
||||
return {
|
||||
@@ -356,18 +357,21 @@ export class DefaultConfig implements Config {
|
||||
UnitType.Warship,
|
||||
),
|
||||
territoryBound: false,
|
||||
playerBuildable: true,
|
||||
maxHealth: 1000,
|
||||
};
|
||||
case UnitType.Shell:
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: false,
|
||||
damage: 250,
|
||||
};
|
||||
case UnitType.SAMMissile:
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: false,
|
||||
};
|
||||
case UnitType.Port:
|
||||
return {
|
||||
@@ -378,19 +382,21 @@ export class DefaultConfig implements Config {
|
||||
UnitType.Factory,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
canBuildTrainStation: true,
|
||||
};
|
||||
case UnitType.AtomBomb:
|
||||
return {
|
||||
cost: this.costWrapper(() => 750_000, UnitType.AtomBomb),
|
||||
territoryBound: false,
|
||||
playerBuildable: true,
|
||||
};
|
||||
case UnitType.HydrogenBomb:
|
||||
return {
|
||||
cost: this.costWrapper(() => 5_000_000, UnitType.HydrogenBomb),
|
||||
territoryBound: false,
|
||||
playerBuildable: true,
|
||||
};
|
||||
case UnitType.MIRV:
|
||||
return {
|
||||
@@ -401,21 +407,25 @@ export class DefaultConfig implements Config {
|
||||
return 25_000_000n + game.stats().numMirvsLaunched() * 15_000_000n;
|
||||
},
|
||||
territoryBound: false,
|
||||
playerBuildable: true,
|
||||
};
|
||||
case UnitType.MIRVWarhead:
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: false,
|
||||
};
|
||||
case UnitType.TradeShip:
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: true,
|
||||
};
|
||||
case UnitType.MissileSilo:
|
||||
return {
|
||||
cost: this.costWrapper(() => 1_000_000, UnitType.MissileSilo),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 10 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
@@ -426,6 +436,7 @@ export class DefaultConfig implements Config {
|
||||
UnitType.DefensePost,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 5 * 10,
|
||||
};
|
||||
case UnitType.SAMLauncher:
|
||||
@@ -436,6 +447,7 @@ export class DefaultConfig implements Config {
|
||||
UnitType.SAMLauncher,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 30 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
@@ -447,9 +459,9 @@ export class DefaultConfig implements Config {
|
||||
UnitType.City,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
canBuildTrainStation: true,
|
||||
};
|
||||
case UnitType.Factory:
|
||||
return {
|
||||
@@ -460,16 +472,15 @@ export class DefaultConfig implements Config {
|
||||
UnitType.Port,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
canBuildTrainStation: true,
|
||||
experimental: true,
|
||||
upgradable: true,
|
||||
};
|
||||
case UnitType.Train:
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
experimental: true,
|
||||
playerBuildable: false,
|
||||
};
|
||||
default:
|
||||
assertNever(type);
|
||||
|
||||
@@ -119,7 +119,7 @@ export function listNukeBreakAlliance(
|
||||
|
||||
// Also check if any allied structures would be destroyed
|
||||
game
|
||||
.nearbyUnits(targetTile, magnitude.outer, game.getStructureTypes())
|
||||
.nearbyUnits(targetTile, magnitude.outer, this.game.getStructureTypes())
|
||||
.forEach(({ unit }) =>
|
||||
playersToBreakAllianceWith.add(unit.owner().smallID()),
|
||||
);
|
||||
|
||||
@@ -227,7 +227,7 @@ export class NationStructureBehavior {
|
||||
const structures = this.player.units(type);
|
||||
if (
|
||||
this.getTotalStructureDensity() > UPGRADE_DENSITY_THRESHOLD &&
|
||||
type !== UnitType.DefensePost
|
||||
this.game.config().unitInfo(type).upgradable
|
||||
) {
|
||||
if (this.maybeUpgradeStructure(structures)) {
|
||||
return true;
|
||||
@@ -329,10 +329,7 @@ export class NationStructureBehavior {
|
||||
return false;
|
||||
}
|
||||
const structureToUpgrade = this.findBestStructureToUpgrade(structures);
|
||||
if (
|
||||
structureToUpgrade !== null &&
|
||||
this.player.canUpgradeUnit(structureToUpgrade)
|
||||
) {
|
||||
if (structureToUpgrade !== null) {
|
||||
this.game.addExecution(
|
||||
new UpgradeStructureExecution(this.player, structureToUpgrade.id()),
|
||||
);
|
||||
@@ -345,12 +342,10 @@ export class NationStructureBehavior {
|
||||
* Calculates total structure density across player's territory.
|
||||
*/
|
||||
private getTotalStructureDensity(): number {
|
||||
let totalStructures = 0;
|
||||
for (const type of this.game.getStructureTypes()) {
|
||||
totalStructures += this.player.units(type).length; // ignoring levels
|
||||
}
|
||||
const tilesOwned = this.player.numTilesOwned();
|
||||
return tilesOwned > 0 ? totalStructures / tilesOwned : 0;
|
||||
return tilesOwned > 0
|
||||
? this.player.units(...this.game.getStructureTypes()).length / tilesOwned
|
||||
: 0; //ignoring levels for structures
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -225,12 +225,11 @@ export interface UnitInfo {
|
||||
cost: (game: Game, player: Player) => Gold;
|
||||
// Determines if its owner changes when its tile is conquered.
|
||||
territoryBound: boolean;
|
||||
playerBuildable: boolean;
|
||||
maxHealth?: number;
|
||||
damage?: number;
|
||||
constructionDuration?: number;
|
||||
upgradable?: boolean;
|
||||
canBuildTrainStation?: boolean;
|
||||
experimental?: boolean;
|
||||
}
|
||||
|
||||
export enum UnitType {
|
||||
@@ -779,7 +778,7 @@ export interface Game extends GameMap {
|
||||
predicate?: UnitPredicate,
|
||||
includeUnderConstruction?: boolean,
|
||||
): Array<{ unit: Unit; distSquared: number }>;
|
||||
getStructureTypes(): UnitType[];
|
||||
getStructureTypes(): readonly UnitType[];
|
||||
isStructureType(type: UnitType): boolean;
|
||||
|
||||
addExecution(...exec: Execution[]): void;
|
||||
|
||||
@@ -97,8 +97,9 @@ export class GameImpl implements Game {
|
||||
private _miniWaterGraph: AbstractGraph | null = null;
|
||||
private _miniWaterHPA: AStarWaterHierarchical | null = null;
|
||||
|
||||
private _structureTypes: UnitType[];
|
||||
private _structureTypes: UnitType[] = [];
|
||||
private _structureTypesSet: Set<UnitType>;
|
||||
private _buildableUnitTypes: UnitType[] = [];
|
||||
|
||||
constructor(
|
||||
private _humans: PlayerInfo[],
|
||||
@@ -131,11 +132,17 @@ export class GameImpl implements Game {
|
||||
);
|
||||
}
|
||||
|
||||
this._structureTypes = Object.values(UnitType).filter(
|
||||
(t) => this._config.unitInfo(t).territoryBound,
|
||||
);
|
||||
this._structureTypes =
|
||||
Object.values(UnitType).filter(
|
||||
(t) => this._config.unitInfo(t).territoryBound,
|
||||
) ?? [];
|
||||
this._structureTypesSet = new Set(this._structureTypes);
|
||||
|
||||
this._buildableUnitTypes =
|
||||
Object.values(UnitType).filter(
|
||||
(t) => this._config.unitInfo(t).playerBuildable,
|
||||
) ?? [];
|
||||
|
||||
console.log(
|
||||
`[GameImpl] Constructor total: ${(performance.now() - constructorStart).toFixed(0)}ms`,
|
||||
);
|
||||
@@ -925,6 +932,10 @@ export class GameImpl implements Game {
|
||||
return this._structureTypesSet.has(type);
|
||||
}
|
||||
|
||||
getPlayerBuildableUnitTypes(): UnitType[] {
|
||||
return this._buildableUnitTypes;
|
||||
}
|
||||
|
||||
ref(x: number, y: number): TileRef {
|
||||
return this._map.ref(x, y);
|
||||
}
|
||||
|
||||
@@ -630,9 +630,10 @@ export class GameView implements GameMap {
|
||||
} satisfies PlayerCosmetics);
|
||||
}
|
||||
|
||||
this._structureTypes = Object.values(UnitType).filter(
|
||||
(t) => this._config.unitInfo(t).territoryBound,
|
||||
);
|
||||
this._structureTypes =
|
||||
Object.values(UnitType).filter(
|
||||
(t) => this._config.unitInfo(t).territoryBound,
|
||||
) ?? [];
|
||||
this._structureTypesSet = new Set(this._structureTypes);
|
||||
}
|
||||
|
||||
|
||||
@@ -967,7 +967,8 @@ export class PlayerImpl implements Player {
|
||||
|
||||
public buildableUnits(tile: TileRef | null): BuildableUnit[] {
|
||||
const validTiles = tile !== null ? this.validStructureSpawnTiles(tile) : [];
|
||||
return UNIT_TYPES.map((u) => {
|
||||
|
||||
return this.mg.getPlayerBuildableUnitTypes().map((u) => {
|
||||
const cost = this.mg.config().unitInfo(u).cost(this.mg, this);
|
||||
let canUpgrade: number | false = false;
|
||||
let canBuild: TileRef | false = false;
|
||||
|
||||
Reference in New Issue
Block a user