This commit is contained in:
33333-33333 2026-05-20 20:56:27 +09:00
commit e2cb1f55ca
2 changed files with 236 additions and 49 deletions

View file

@ -1,5 +1,4 @@
import { CUSTOM_NAMES, NAME_PARTS } from "./names.js";
import { NAME_PROBABILITIES, contextualDefaultName } from "./placeNameContext.js";
import {
applyLandscapeUnitAdminPartition,
generateAdminRegions,
@ -607,7 +606,6 @@ function applyOutputOptions(map, options = {}) {
delete slim.basinField;
delete slim.coastalLowland;
delete slim.flowAccum;
delete slim.crestCrossingScore;
delete slim.erosionField;
delete slim.depositionField;
return slim;
@ -674,43 +672,6 @@ function recalculatePopulationAfterLanduse(modernCities, satelliteCities, popula
}
}
function computeCrestCrossingScore(elevation, sea, ridgeField, valleyField, coastalLowland, flowAccum, out) {
out.fill(0);
const pairs = [
[[1, 0], [-1, 0]],
[[0, 1], [0, -1]],
[[1, 1], [-1, -1]],
[[1, -1], [-1, 1]],
];
for (let y = 1; y < MAP_H - 1; y++) {
for (let x = 1; x < MAP_W - 1; x++) {
const i = indexOf(x, y);
if (sea[i]) continue;
let bestProminence = 0;
for (const [[ax, ay], [bx, by]] of pairs) {
const ai = indexOf(x + ax, y + ay);
const bi = indexOf(x + bx, y + by);
if (sea[ai] || sea[bi]) continue;
if (elevation[i] <= elevation[ai] || elevation[i] <= elevation[bi]) continue;
bestProminence = Math.max(bestProminence, elevation[i] - Math.max(elevation[ai], elevation[bi]));
}
if (bestProminence < 0.018) continue;
const ridge = ridgeField[i];
if (elevation[i] < 0.38 && ridge < 0.34) continue;
const elevationBoost = Math.exp(Math.max(0, elevation[i] - 0.42) * 3.2);
const ridgeBoost = 0.55 + ridge * 1.9;
const divideSupport = clamp(ridge * 1.25 + Math.max(0, elevation[i] - 0.56) * 0.85);
const valleyPenalty = valleyField[i] * (divideSupport > 0.58 ? 0.22 : 0.72);
const coastPenalty = coastalLowland[i] * (ridge > 0.50 ? 0.20 : 0.82);
const flowPenalty = flowAccum[i] * (ridge > 0.52 ? 0.18 : 0.88);
out[i] = clamp(bestProminence * 18.0 * elevationBoost * ridgeBoost - valleyPenalty - coastPenalty - flowPenalty);
}
}
}
export function generateMap(seedInput = 114514, options = {}) {
const seed = Number(seedInput) >>> 0;
@ -731,7 +692,6 @@ export function generateMap(seedInput = 114514, options = {}) {
basinField,
coastalLowland,
flowAccum,
crestCrossingScore,
erosionField,
depositionField,
flowTo,
@ -1478,8 +1438,6 @@ export function generateMap(seedInput = 114514, options = {}) {
const tributaryRivers = riverPaths.filter((path) => path.some(([x, y]) => !mainRiverCells.has(`${x},${y}`)) && !mainRivers.includes(path));
const smallStreams = streamPaths.filter((path) => path.length >= 5);
computeCrestCrossingScore(elevation, sea, ridgeField, valleyField, coastalLowland, flowAccum, crestCrossingScore);
prefectureMask = makePrefectureMask(seed, sea, elevation, slope, river);
prefectureBorder = extractMaskBorder(prefectureMask, sea);
const regionalPrefectures = generateRegionalPrefectures(seed, sea, elevation, slope, river, ridgeField, flowAccum, prefectureMask);
@ -2857,7 +2815,7 @@ export function generateMap(seedInput = 114514, options = {}) {
const extra = pickEntities(municipalityCandidates, { max: 10 - adminCentersRaw.length, minDistance: 8, threshold: 0.32, seed: seed + 1304 });
adminCentersRaw.push(...extra.filter((p) => adminCentersRaw.every((q) => Math.hypot(p.x - q.x, p.y - q.y) >= 6)));
}
const adminId = generateAdminRegions(adminCentersRaw, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, crestCrossingScore, populationDensity, landuse);
const adminId = generateAdminRegions(adminCentersRaw, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, populationDensity, landuse);
smoothAdminRegionsTerrainAware(adminId, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, populationDensity, landuse, 7);
function lockUrbanClusterToMunicipality(city, radius, allowSuburban = true) {
@ -2917,8 +2875,8 @@ export function generateMap(seedInput = 114514, options = {}) {
lockSmallUrbanComponentsToMunicipality(adminId, prefectureMask, sea, landuse, populationDensity, 620);
mergeTinyMunicipalities(adminId, prefectureMask, sea, populationDensity, [...modernCities, ...satelliteCities], 260);
removeMunicipalExclaves(adminId, prefectureMask, sea, adminCentersRaw, [...modernCities, ...satelliteCities], 180);
applyLandscapeUnitAdminPartition(adminId, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, basinField, coastalLowland, flowAccum, crestCrossingScore, plain, agriculture, populationDensity, landuse, adminCentersRaw);
snapAdminBoundariesToTerrain(adminId, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, flowAccum, crestCrossingScore, populationDensity, landuse, adminCentersRaw, [...modernCities, ...satelliteCities, ...ports, ...industrialZones, ...logisticsParks], 5);
applyLandscapeUnitAdminPartition(adminId, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, basinField, coastalLowland, flowAccum, plain, agriculture, populationDensity, landuse, adminCentersRaw);
snapAdminBoundariesToTerrain(adminId, prefectureMask, sea, elevation, slope, river, ridgeField, valleyField, flowAccum, populationDensity, landuse, adminCentersRaw, [...modernCities, ...satelliteCities, ...ports, ...industrialZones, ...logisticsParks], 5);
removeMunicipalExclaves(adminId, prefectureMask, sea, adminCentersRaw, [...modernCities, ...satelliteCities], 360);
mergeTinyMunicipalities(adminId, prefectureMask, sea, populationDensity, [...modernCities, ...satelliteCities], 220);
const adminBorders = extractAdminBorderSegments(adminId, prefectureMask);
@ -3024,7 +2982,6 @@ export function generateMap(seedInput = 114514, options = {}) {
basinField,
coastalLowland,
flowAccum,
crestCrossingScore,
erosionField,
depositionField,
villages,