mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-17 06:50:43 +00:00
Back to current hardcoded StructureTypes and isStructureType in Game.ts, add PlayerBuildableTypes in the same fasion. Same maintainability (not perfect compared to doing it in unitinfo from DefaultConfig) but better for performance.
This commit is contained in:
@@ -348,7 +348,6 @@ export class DefaultConfig implements Config {
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: false,
|
||||
};
|
||||
case UnitType.Warship:
|
||||
return {
|
||||
@@ -357,21 +356,18 @@ 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 {
|
||||
@@ -382,7 +378,6 @@ export class DefaultConfig implements Config {
|
||||
UnitType.Factory,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
@@ -390,13 +385,11 @@ export class DefaultConfig implements Config {
|
||||
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 {
|
||||
@@ -407,25 +400,21 @@ 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,
|
||||
};
|
||||
@@ -436,7 +425,6 @@ export class DefaultConfig implements Config {
|
||||
UnitType.DefensePost,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 5 * 10,
|
||||
};
|
||||
case UnitType.SAMLauncher:
|
||||
@@ -447,7 +435,6 @@ export class DefaultConfig implements Config {
|
||||
UnitType.SAMLauncher,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 30 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
@@ -459,7 +446,6 @@ export class DefaultConfig implements Config {
|
||||
UnitType.City,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
@@ -472,7 +458,6 @@ export class DefaultConfig implements Config {
|
||||
UnitType.Port,
|
||||
),
|
||||
territoryBound: true,
|
||||
playerBuildable: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
@@ -480,7 +465,6 @@ export class DefaultConfig implements Config {
|
||||
return {
|
||||
cost: () => 0n,
|
||||
territoryBound: false,
|
||||
playerBuildable: false,
|
||||
};
|
||||
default:
|
||||
assertNever(type);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Execution, Game, Player } from "../game/Game";
|
||||
import { Execution, Game, isStructureType, Player } from "../game/Game";
|
||||
import { PseudoRandom } from "../PseudoRandom";
|
||||
import { simpleHash } from "../Util";
|
||||
import { AllianceExtensionExecution } from "./alliance/AllianceExtensionExecution";
|
||||
@@ -85,7 +85,7 @@ export class BotExecution implements Execution {
|
||||
|
||||
private deleteAllStructures() {
|
||||
for (const unit of this.bot.units()) {
|
||||
if (this.mg.isStructureType(unit.type()) && this.bot.canDeleteUnit()) {
|
||||
if (isStructureType(unit.type()) && this.bot.canDeleteUnit()) {
|
||||
this.mg.addExecution(new DeleteUnitExecution(this.bot, unit.id()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
Execution,
|
||||
Game,
|
||||
isStructureType,
|
||||
MessageType,
|
||||
Player,
|
||||
TerraNullius,
|
||||
@@ -332,7 +333,7 @@ export class NukeExecution implements Execution {
|
||||
private redrawBuildings(range: number) {
|
||||
const rangeSquared = range * range;
|
||||
for (const unit of this.mg.units()) {
|
||||
if (this.mg.isStructureType(unit.type())) {
|
||||
if (isStructureType(unit.type())) {
|
||||
if (
|
||||
this.mg.euclideanDistSquared(this.dst, unit.tile()) < rangeSquared
|
||||
) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NukeMagnitude } from "../configuration/Config";
|
||||
import { Game, Player } from "../game/Game";
|
||||
import { Game, Player, StructureTypes } from "../game/Game";
|
||||
import { euclDistFN, GameMap, TileRef } from "../game/GameMap";
|
||||
import { GameView } from "../game/GameView";
|
||||
|
||||
@@ -60,7 +60,7 @@ export function wouldNukeBreakAlliance(
|
||||
const wouldDestroyAlliedStructure = game.anyUnitNearby(
|
||||
targetTile,
|
||||
magnitude.outer,
|
||||
game.getStructureTypes(),
|
||||
StructureTypes,
|
||||
(unit) =>
|
||||
unit.owner().isPlayer() && allySmallIds.has(unit.owner().smallID()),
|
||||
);
|
||||
@@ -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, StructureTypes)
|
||||
.forEach(({ unit }) =>
|
||||
playersToBreakAllianceWith.add(unit.owner().smallID()),
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
Player,
|
||||
PlayerType,
|
||||
Relation,
|
||||
StructureTypes,
|
||||
Unit,
|
||||
UnitType,
|
||||
} from "../../game/Game";
|
||||
@@ -344,7 +345,7 @@ export class NationStructureBehavior {
|
||||
private getTotalStructureDensity(): number {
|
||||
const tilesOwned = this.player.numTilesOwned();
|
||||
return tilesOwned > 0
|
||||
? this.player.units(...this.game.getStructureTypes()).length / tilesOwned
|
||||
? this.player.units(...StructureTypes).length / tilesOwned
|
||||
: 0; //ignoring levels for structures
|
||||
}
|
||||
|
||||
|
||||
+34
-5
@@ -225,7 +225,6 @@ 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;
|
||||
@@ -257,6 +256,39 @@ export enum TrainType {
|
||||
Carriage = "Carriage",
|
||||
}
|
||||
|
||||
const _structureTypes: ReadonlySet<UnitType> = new Set([
|
||||
UnitType.City,
|
||||
UnitType.DefensePost,
|
||||
UnitType.SAMLauncher,
|
||||
UnitType.MissileSilo,
|
||||
UnitType.Port,
|
||||
UnitType.Factory,
|
||||
]);
|
||||
|
||||
export const StructureTypes: readonly UnitType[] = [..._structureTypes];
|
||||
|
||||
export function isStructureType(type: UnitType): boolean {
|
||||
return _structureTypes.has(type);
|
||||
}
|
||||
|
||||
const _playerBuildableTypes: ReadonlySet<UnitType> = new Set([
|
||||
UnitType.City,
|
||||
UnitType.DefensePost,
|
||||
UnitType.SAMLauncher,
|
||||
UnitType.MissileSilo,
|
||||
UnitType.Port,
|
||||
UnitType.Factory,
|
||||
UnitType.TransportShip,
|
||||
UnitType.Warship,
|
||||
UnitType.AtomBomb,
|
||||
UnitType.HydrogenBomb,
|
||||
UnitType.MIRV,
|
||||
]);
|
||||
|
||||
export const PlayerBuildableTypes: readonly UnitType[] = [
|
||||
..._playerBuildableTypes,
|
||||
];
|
||||
|
||||
export interface OwnerComp {
|
||||
owner: Player;
|
||||
}
|
||||
@@ -774,13 +806,10 @@ export interface Game extends GameMap {
|
||||
nearbyUnits(
|
||||
tile: TileRef,
|
||||
searchRange: number,
|
||||
types: UnitType | UnitType[],
|
||||
types: UnitType | readonly UnitType[],
|
||||
predicate?: UnitPredicate,
|
||||
includeUnderConstruction?: boolean,
|
||||
): Array<{ unit: Unit; distSquared: number }>;
|
||||
getStructureTypes(): readonly UnitType[];
|
||||
isStructureType(type: UnitType): boolean;
|
||||
getPlayerBuildableUnitTypes(): readonly UnitType[];
|
||||
|
||||
addExecution(...exec: Execution[]): void;
|
||||
displayMessage(
|
||||
|
||||
@@ -97,10 +97,6 @@ export class GameImpl implements Game {
|
||||
private _miniWaterGraph: AbstractGraph | null = null;
|
||||
private _miniWaterHPA: AStarWaterHierarchical | null = null;
|
||||
|
||||
private _structureTypes: UnitType[] = [];
|
||||
private _structureTypesSet: Set<UnitType>;
|
||||
private _buildableUnitTypes: UnitType[] = [];
|
||||
|
||||
constructor(
|
||||
private _humans: PlayerInfo[],
|
||||
private _nations: Nation[],
|
||||
@@ -132,17 +128,6 @@ export class GameImpl implements Game {
|
||||
);
|
||||
}
|
||||
|
||||
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`,
|
||||
);
|
||||
@@ -908,7 +893,7 @@ export class GameImpl implements Game {
|
||||
nearbyUnits(
|
||||
tile: TileRef,
|
||||
searchRange: number,
|
||||
types: UnitType | UnitType[],
|
||||
types: UnitType | readonly UnitType[],
|
||||
predicate?: UnitPredicate,
|
||||
includeUnderConstruction?: boolean,
|
||||
): Array<{ unit: Unit; distSquared: number }> {
|
||||
@@ -924,18 +909,6 @@ export class GameImpl implements Game {
|
||||
}>;
|
||||
}
|
||||
|
||||
getStructureTypes(): UnitType[] {
|
||||
return this._structureTypes;
|
||||
}
|
||||
|
||||
isStructureType(type: UnitType): boolean {
|
||||
return this._structureTypesSet.has(type);
|
||||
}
|
||||
|
||||
getPlayerBuildableUnitTypes(): UnitType[] {
|
||||
return this._buildableUnitTypes;
|
||||
}
|
||||
|
||||
ref(x: number, y: number): TileRef {
|
||||
return this._map.ref(x, y);
|
||||
}
|
||||
|
||||
@@ -598,9 +598,6 @@ export class GameView implements GameMap {
|
||||
|
||||
private _map: GameMap;
|
||||
|
||||
private _structureTypes: UnitType[];
|
||||
private _structureTypesSet: Set<UnitType>;
|
||||
|
||||
constructor(
|
||||
public worker: WorkerClient,
|
||||
private _config: Config,
|
||||
@@ -629,12 +626,6 @@ export class GameView implements GameMap {
|
||||
flag: nation.flag,
|
||||
} satisfies PlayerCosmetics);
|
||||
}
|
||||
|
||||
this._structureTypes =
|
||||
Object.values(UnitType).filter(
|
||||
(t) => this._config.unitInfo(t).territoryBound,
|
||||
) ?? [];
|
||||
this._structureTypesSet = new Set(this._structureTypes);
|
||||
}
|
||||
|
||||
isOnEdgeOfMap(ref: TileRef): boolean {
|
||||
@@ -715,7 +706,7 @@ export class GameView implements GameMap {
|
||||
nearbyUnits(
|
||||
tile: TileRef,
|
||||
searchRange: number,
|
||||
types: UnitType | UnitType[],
|
||||
types: UnitType | readonly UnitType[],
|
||||
predicate?: UnitPredicate,
|
||||
): Array<{ unit: UnitView; distSquared: number }> {
|
||||
return this.unitGrid.nearbyUnits(
|
||||
@@ -763,14 +754,6 @@ export class GameView implements GameMap {
|
||||
);
|
||||
}
|
||||
|
||||
getStructureTypes(): UnitType[] {
|
||||
return this._structureTypes;
|
||||
}
|
||||
|
||||
isStructureType(type: UnitType): boolean {
|
||||
return this._structureTypesSet.has(type);
|
||||
}
|
||||
|
||||
myClientID(): ClientID {
|
||||
return this._myClientID;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,13 @@ import {
|
||||
MessageType,
|
||||
MutableAlliance,
|
||||
Player,
|
||||
PlayerBuildableTypes,
|
||||
PlayerID,
|
||||
PlayerInfo,
|
||||
PlayerProfile,
|
||||
PlayerType,
|
||||
Relation,
|
||||
StructureTypes,
|
||||
Team,
|
||||
TerraNullius,
|
||||
Tick,
|
||||
@@ -966,7 +968,7 @@ export class PlayerImpl implements Player {
|
||||
public buildableUnits(tile: TileRef | null): BuildableUnit[] {
|
||||
const validTiles = tile !== null ? this.validStructureSpawnTiles(tile) : [];
|
||||
|
||||
return this.mg.getPlayerBuildableUnitTypes().map((u) => {
|
||||
return PlayerBuildableTypes.map((u) => {
|
||||
const cost = this.mg.config().unitInfo(u).cost(this.mg, this);
|
||||
let canUpgrade: number | false = false;
|
||||
let canBuild: TileRef | false = false;
|
||||
@@ -1062,7 +1064,7 @@ export class PlayerImpl implements Player {
|
||||
const wouldHitTeammate = this.mg.anyUnitNearby(
|
||||
tile,
|
||||
magnitude.outer,
|
||||
this.mg.getStructureTypes(),
|
||||
StructureTypes,
|
||||
(unit) => unit.owner().isPlayer() && this.isOnSameTeam(unit.owner()),
|
||||
);
|
||||
if (wouldHitTeammate) {
|
||||
@@ -1145,7 +1147,7 @@ export class PlayerImpl implements Player {
|
||||
const nearbyUnits = this.mg.nearbyUnits(
|
||||
tile,
|
||||
searchRadius * 2,
|
||||
this.mg.getStructureTypes(),
|
||||
StructureTypes,
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user