Merge main into nations-nuke

This commit is contained in:
Scott Anderson
2025-04-02 21:40:19 -04:00
63 changed files with 3153 additions and 1581 deletions
+49 -6
View File
@@ -2,6 +2,7 @@ import {
Difficulty,
Game,
GameMapType,
GameMode,
GameType,
Gold,
Player,
@@ -58,15 +59,54 @@ export abstract class DefaultServerConfig implements ServerConfig {
return 60 * 1000;
}
lobbyMaxPlayers(map: GameMapType): number {
if (map == GameMapType.World) {
return Math.random() < 0.3 ? 150 : 60;
}
// Maps with ~4 mil pixels
if (
[GameMapType.Mars, GameMapType.Africa, GameMapType.BlackSea].includes(map)
[
GameMapType.GatewayToTheAtlantic,
GameMapType.SouthAmerica,
GameMapType.NorthAmerica,
GameMapType.Africa,
GameMapType.Europe,
].includes(map)
) {
return Math.random() < 0.3 ? 70 : 50;
return Math.random() < 0.2 ? 150 : 70;
}
return Math.random() < 0.3 ? 60 : 40;
// Maps with ~2.5 - ~3.5 mil pixels
if (
[
GameMapType.Australia,
GameMapType.Iceland,
GameMapType.Britannia,
GameMapType.Asia,
].includes(map)
) {
return Math.random() < 0.2 ? 100 : 50;
}
// Maps with ~2 mil pixels
if (
[
GameMapType.Mena,
GameMapType.Mars,
GameMapType.Oceania,
GameMapType.Japan, // Japan at this level because its 2/3 water
].includes(map)
) {
return Math.random() < 0.2 ? 70 : 40;
}
// Maps smaller than ~2 mil pixels
if (
[GameMapType.TwoSeas, GameMapType.BlackSea, GameMapType.Pangaea].includes(
map,
)
) {
return Math.random() < 0.2 ? 60 : 35;
}
// world belongs with the ~2 mils, but these amounts never made sense so I assume the insanity is intended.
if (map == GameMapType.World) {
return Math.random() < 0.2 ? 150 : 60;
}
// default return for non specified map
return Math.random() < 0.2 ? 85 : 45;
}
workerIndex(gameID: GameID): number {
return simpleHash(gameID) % this.numWorkers();
@@ -337,6 +377,9 @@ export class DefaultConfig implements Config {
return 600 * 10; // 10 minutes.
}
percentageTilesOwnedToWin(): number {
if (this._gameConfig.gameMode == GameMode.Team) {
return 95;
}
return 80;
}
boatMaxNumber(): number {
+5 -1
View File
@@ -190,7 +190,11 @@ export class AttackExecution implements Execution {
tick(ticks: number) {
if (this.attack.retreated()) {
this.retreat(malusForRetreat);
if (this.attack.target().isPlayer()) {
this.retreat(malusForRetreat);
} else {
this.retreat();
}
this.active = false;
return;
}
+4 -2
View File
@@ -60,6 +60,8 @@ export enum GameMapType {
Australia = "Australia",
Iceland = "Iceland",
Japan = "Japan",
TwoSeas = "Between Two Seas",
KnownWorld = "Known World",
}
export enum GameType {
@@ -135,8 +137,8 @@ export class Cell {
private strRepr: string;
constructor(
public readonly x,
public readonly y,
public readonly x: number,
public readonly y: number,
) {
this.strRepr = `Cell[${this.x},${this.y}]`;
}
+2 -2
View File
@@ -141,7 +141,7 @@ export class GameImpl implements Game {
}
addUpdate(update: GameUpdate) {
(this.updates[update.type] as any[]).push(update);
(this.updates[update.type] as GameUpdate[]).push(update);
}
nextUnitID(): number {
@@ -383,7 +383,7 @@ export class GameImpl implements Game {
}
playerByClientID(id: ClientID): Player | null {
for (const [pID, player] of this._players) {
for (const [, player] of this._players) {
if (player.clientID() == id) {
return player;
}
+8
View File
@@ -32,6 +32,9 @@ import {
} from "./GameUpdates";
import { TerraNulliusImpl } from "./TerraNulliusImpl";
import { UnitGrid } from "./UnitGrid";
import { UserSettings } from "./UserSettings";
const userSettings: UserSettings = new UserSettings();
export class UnitView {
public _wasUpdated = true;
@@ -384,6 +387,10 @@ export class GameView implements GameMap {
throw Error(`player id ${id} not found`);
}
players(): PlayerView[] {
return Array.from(this._players.values());
}
playerBySmallID(id: number): PlayerView | TerraNullius {
if (id == 0) {
return new TerraNulliusImpl();
@@ -542,6 +549,7 @@ export class GameView implements GameMap {
}
focusedPlayer(): PlayerView | null {
if (userSettings.focusLocked()) return this.myPlayer();
return this._focusedPlayer;
}
setFocusedPlayer(player: PlayerView | null): void {
+2 -1
View File
@@ -92,6 +92,7 @@ export class PlayerImpl implements Player {
public _incomingAttacks: Attack[] = [];
public _outgoingAttacks: Attack[] = [];
public _outgoingLandAttacks: Attack[] = [];
constructor(
private mg: GameImpl,
@@ -1003,7 +1004,7 @@ export class PlayerImpl implements Player {
// It's a probability list, so if an element appears twice it's because it's
// twice more likely to be picked later.
tradingPorts(port: Unit): Unit[] {
let ports = this.mg
const ports = this.mg
.players()
.filter((p) => p != port.owner() && p.canTrade(port.owner()))
.flatMap((p) => p.units(UnitType.Port))
+2
View File
@@ -39,6 +39,8 @@ const MAP_FILE_NAMES: Record<GameMapType, string> = {
[GameMapType.Australia]: "Australia",
[GameMapType.Iceland]: "Iceland",
[GameMapType.Japan]: "Japan",
[GameMapType.TwoSeas]: "TwoSeas",
[GameMapType.KnownWorld]: "KnownWorld",
};
class GameMapLoader {
+8
View File
@@ -24,10 +24,18 @@ export class UserSettings {
return this.get("settings.leftClickOpensMenu", false);
}
focusLocked() {
return this.get("settings.focusLocked", false);
}
toggleLeftClickOpenMenu() {
this.set("settings.leftClickOpensMenu", !this.leftClickOpensMenu());
}
toggleFocusLocked() {
this.set("settings.focusLocked", !this.focusLocked());
}
toggleEmojis() {
this.set("settings.emojis", !this.emojis());
}