This commit is contained in:
Restart2008
2026-02-19 20:49:28 -08:00
parent ca3f577975
commit 0857b4103e
5 changed files with 37 additions and 15 deletions
@@ -492,7 +492,11 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
const isCity = unit.type() === UnitType.City;
const area = Math.PI * Math.pow(unit.areaRadius(), 2);
const population = Math.floor(area * 1500 * (1 + unit.density()));
const terrainMag = this.game.magnitude(unit.tile());
const terrainFactor = Math.max(0.4, 1.0 - terrainMag / 40.0);
const population = Math.floor(
area * 1500 * (1 + unit.density()) * terrainFactor,
);
return html`
<div class="p-2 border-t border-gray-700/50">
+1
View File
@@ -170,6 +170,7 @@ export interface Config {
structureMinDist(): number;
isReplay(): boolean;
allianceExtensionPromptOffset(): number;
setMap(map: GameMap): void;
}
export interface Theme {
+14 -3
View File
@@ -15,7 +15,7 @@ import {
UnitInfo,
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { GameMap, TileRef } from "../game/GameMap";
import { PlayerView } from "../game/GameView";
import { UserSettings } from "../game/UserSettings";
import { GameConfig, GameID, TeamCountConfig } from "../Schemas";
@@ -139,6 +139,8 @@ export abstract class DefaultServerConfig implements ServerConfig {
export class DefaultConfig implements Config {
private pastelTheme: PastelTheme = new PastelTheme();
private pastelThemeDark: PastelThemeDark = new PastelThemeDark();
private _map: GameMap | null = null;
constructor(
private _serverConfig: ServerConfig,
private _gameConfig: GameConfig,
@@ -146,6 +148,10 @@ export class DefaultConfig implements Config {
private _isReplay: boolean,
) {}
setMap(map: GameMap): void {
this._map = map;
}
stripePublishableKey(): string {
return Env.STRIPE_PUBLISHABLE_KEY ?? "";
}
@@ -778,7 +784,10 @@ export class DefaultConfig implements Config {
.reduce((acc, city) => {
const area = Math.PI * Math.pow(city.areaRadius() || 1, 2);
const density = city.density() || 0;
const population = area * 1500 * (1 + density);
// Population/power is based on area, density, and terrain resistance
const terrainMag = this._map?.magnitude(city.tile()) ?? 0;
const terrainFactor = Math.max(0.4, 1.0 - terrainMag / 40.0);
const population = area * 1500 * (1 + density) * terrainFactor;
return acc + (isNaN(population) ? 0 : population);
}, 0);
@@ -853,7 +862,9 @@ export class DefaultConfig implements Config {
if (!city.isUnderConstruction()) {
const area = Math.PI * Math.pow(city.areaRadius() || 1, 2);
const density = city.density() || 0;
cityIncome += area * 0.1 * (1 + density);
const terrainMag = this._map?.magnitude(city.tile()) ?? 0;
const terrainFactor = Math.max(0.4, 1.0 - terrainMag / 40.0);
cityIncome += area * 0.1 * (1 + density) * terrainFactor;
}
}
+1
View File
@@ -107,6 +107,7 @@ export class GameImpl implements Game {
) {
const constructorStart = performance.now();
this._config.setMap(this._map);
this._terraNullius = new TerraNulliusImpl();
this._width = _map.width();
this._height = _map.height();
+16 -11
View File
@@ -674,6 +674,7 @@ export class GameView implements GameMap {
private humans: Player[],
) {
this._map = this._mapData.gameMap;
this._config.setMap(this._map);
this.lastUpdate = null;
this.unitGrid = new UnitGrid(this._map);
// Replace the local player's username with their own stored username.
@@ -1039,7 +1040,7 @@ export class GameView implements GameMap {
const cached = this.urbanizationCache.get(tile);
if (cached) return cached;
const nearby = this.nearbyUnits(tile, 60, UnitType.City);
const nearby = this.nearbyUnits(tile, 120, UnitType.City);
if (nearby.length === 0) {
const result = { density: 0 };
this.urbanizationCache.set(tile, result);
@@ -1071,22 +1072,26 @@ export class GameView implements GameMap {
const angle = Math.atan2(dy, dx);
const uid = unit.id();
const age = unit.age();
// More complex noise to ensure irregular shapes even at high city levels
// Dynamic organic noise: shifts slowly over time (age)
const noise =
1 +
0.22 * Math.sin(angle * 3 + uid) +
0.15 * Math.sin(angle * 7 - uid * 1.3) +
0.25 * Math.sin(angle * 3 + uid + age / 500) +
0.15 * Math.sin(angle * 7 - uid * 1.3 + age / 800) +
0.08 * Math.sin(angle * 13 + uid * 0.7);
// Terrain expansion logic: cities expand easily in plains, poorly in mountains.
// Magnitude 0-30 scale. We penalize distance based on terrain difficulty.
const terrainFactor = Math.max(0.2, 1.0 - Math.min(terrainMag, 25) / 35);
const irregularRadius = radius * noise * terrainFactor;
// "Expand to least resistant (flat) land 1st"
// Mountains (high magnitude) act as resistance, making the "effective distance" greater.
// Magnitude is typically 0-30.
const resistance = 1.0 + terrainMag / 12.0;
const effectiveDist = dist * resistance;
if (dist <= irregularRadius) {
// Linear fade is faster than Math.pow
const fade = 1 - dist / irregularRadius;
const irregularMaxRadius = radius * noise;
if (effectiveDist <= irregularMaxRadius) {
// Density fades out based on effective distance (terrain-aware)
const fade = 1 - effectiveDist / irregularMaxRadius;
const d = unit.density() * fade;
if (d > maxDensity) {