tweak
This commit is contained in:
parent
d762a88b22
commit
5c82bfcab7
13 changed files with 1028 additions and 8801 deletions
63
mapOutput.js
63
mapOutput.js
|
|
@ -1,7 +1,6 @@
|
|||
import { createNameDebug } from "./names.js";
|
||||
import { CELL_SIZE, INF, MAP_H, MAP_W, clamp, hash2, indexOf, inside, rand } from "./mapUtils.js";
|
||||
import { applyOutputOptions, attachIdsAndNames, recalculatePopulationAfterLanduse, tagInsidePrefecture } from "./mapGeneratorHelpers.js";
|
||||
import { LANDUSE } from "./landuseCodes.js";
|
||||
import { CELL_SIZE, INF, MAP_H, MAP_W, clamp, indexOf, inside, rand } from "./mapUtils.js";
|
||||
import { applyOutputOptions, attachIdsAndNames, tagInsidePrefecture } from "./mapGeneratorHelpers.js";
|
||||
|
||||
const MUNICIPAL_SUFFIX_RE = /[市町村区]$/u;
|
||||
|
||||
|
|
@ -25,48 +24,6 @@ function municipalityNameFromRoot(root, center, fields, seed, ordinal = 0) {
|
|||
return `${value}${municipalitySuffixForCenter(center, fields, seed, ordinal)}`;
|
||||
}
|
||||
|
||||
function ensureMunicipalOfficeSettlementFootprints(adminCentersRaw, { sea, elevation, slope, ridgeField, plain, basinField, coastalLowland, populationDensity, landuse, humanRegionMask, roadInfluence, stationInfluence }, seed) {
|
||||
let changedCells = 0;
|
||||
const isBuildable = (i) => !sea[i] && (!humanRegionMask || humanRegionMask[i]) && elevation[i] < 0.78 && slope[i] < 0.62 && ridgeField[i] < 0.76;
|
||||
for (const [n, center] of (adminCentersRaw || []).entries()) {
|
||||
if (!center || !inside(center.x, center.y)) continue;
|
||||
const ci = indexOf(center.x, center.y);
|
||||
if (!isBuildable(ci)) continue;
|
||||
const existingUrban = landuse[ci] >= LANDUSE.OLD_URBAN && landuse[ci] <= LANDUSE.NEW_TOWN;
|
||||
const baseRadius = existingUrban ? 1.2 : (center.population || 0) >= 60000 ? 2.6 : 2.0;
|
||||
const scoreBoost = clamp((populationDensity[ci] || 0) * 0.45 + (roadInfluence?.[ci] || 0) * 0.22 + (stationInfluence?.[ci] || 0) * 0.26 + 0.24);
|
||||
const r = Math.ceil(baseRadius);
|
||||
for (let dy = -r; dy <= r; dy++) {
|
||||
for (let dx = -r; dx <= r; dx++) {
|
||||
const x = center.x + dx;
|
||||
const y = center.y + dy;
|
||||
if (!inside(x, y)) continue;
|
||||
const i = indexOf(x, y);
|
||||
if (!isBuildable(i)) continue;
|
||||
const d = Math.hypot(dx, dy);
|
||||
if (d > baseRadius) continue;
|
||||
const lowland = clamp(plain[i] * 0.28 + basinField[i] * 0.24 + coastalLowland[i] * 0.20 + (roadInfluence?.[i] || 0) * 0.14 - slope[i] * 0.28 - ridgeField[i] * 0.16 + 0.30);
|
||||
if (lowland <= 0.12) continue;
|
||||
if (d <= 0.85) {
|
||||
if (landuse[i] < LANDUSE.OLD_URBAN || landuse[i] === LANDUSE.FARMLAND || landuse[i] === LANDUSE.RURAL) {
|
||||
landuse[i] = LANDUSE.OLD_URBAN;
|
||||
changedCells++;
|
||||
}
|
||||
populationDensity[i] = Math.max(populationDensity[i] || 0, 0.34 + scoreBoost * 0.35);
|
||||
} else if (d <= baseRadius && landuse[i] <= LANDUSE.FARMLAND) {
|
||||
const keep = lowland * (1 - d / (baseRadius + 0.1)) + hash2(x, y, seed + 18800 + n) * 0.08;
|
||||
if (keep > 0.16) {
|
||||
landuse[i] = LANDUSE.SUBURB;
|
||||
changedCells++;
|
||||
populationDensity[i] = Math.max(populationDensity[i] || 0, 0.20 + scoreBoost * 0.20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return changedCells;
|
||||
}
|
||||
|
||||
export function finishMapOutput({
|
||||
seed,
|
||||
options,
|
||||
|
|
@ -177,17 +134,17 @@ export function finishMapOutput({
|
|||
let externalGateways = inputExternalGateways;
|
||||
|
||||
const outputProgress = (step) => options?.onProgress?.({ status: "output-step", key: "output", label: `Output: ${step}`, step });
|
||||
outputProgress("population recalculation");
|
||||
// Final population pass after land-use cleanup, satellite municipality locking, and isolated urban deletion.
|
||||
// Use all generated prefecture regions for human-geography density, not only the focused prefecture.
|
||||
outputProgress("final packaging");
|
||||
// Use all generated prefecture regions for human-geography masks, not only
|
||||
// the focused prefecture. Population density itself is already generated in
|
||||
// the human stage and is not rebuilt here.
|
||||
const humanRegionMask = new Uint8Array(MAP_W * MAP_H);
|
||||
for (let i = 0; i < humanRegionMask.length; i++) {
|
||||
humanRegionMask[i] = !sea[i] && ((prefectureRegionId?.[i] ?? -1) >= 0 || prefectureMask[i]) ? 1 : 0;
|
||||
}
|
||||
const municipalOfficeUrbanizedCells = ensureMunicipalOfficeSettlementFootprints(adminCentersRaw, {
|
||||
sea, elevation, slope, ridgeField, plain, basinField, coastalLowland, populationDensity, landuse, humanRegionMask, roadInfluence, stationInfluence,
|
||||
}, seed);
|
||||
recalculatePopulationAfterLanduse(modernCities, satelliteCities, populationDensity, landuse, humanRegionMask, sea, stationInfluence, roadInfluence, railInfluence2);
|
||||
// Population density is generated directly in the human stage. Do not rebuild
|
||||
// it here from land-use or municipal offices; output should only package and
|
||||
// name features.
|
||||
for (const city of modernCities) {
|
||||
const cap = cityPopulationCap(city);
|
||||
if (cap < INF && (city.population || 0) > cap) {
|
||||
|
|
@ -366,7 +323,7 @@ export function finishMapOutput({
|
|||
adminCenters,
|
||||
adminId,
|
||||
adminBorders,
|
||||
adminDebug: adminDebug ? { ...adminDebug, municipalOfficeUrbanizedCells } : { municipalOfficeUrbanizedCells },
|
||||
adminDebug,
|
||||
castleRuins,
|
||||
riverPaths,
|
||||
mainRivers,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue