mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:30:45 +00:00
fix
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -170,6 +170,7 @@ export interface Config {
|
||||
structureMinDist(): number;
|
||||
isReplay(): boolean;
|
||||
allianceExtensionPromptOffset(): number;
|
||||
setMap(map: GameMap): void;
|
||||
}
|
||||
|
||||
export interface Theme {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user