tweak
This commit is contained in:
parent
6c10d5d70e
commit
3fe9c31453
12 changed files with 963 additions and 127 deletions
71
mapOutput.js
71
mapOutput.js
|
|
@ -5,6 +5,7 @@ import { applyOutputOptions, attachIdsAndNames, recalculatePopulationAfterLandus
|
|||
export function finishMapOutput({
|
||||
seed,
|
||||
options,
|
||||
terrainTemplate,
|
||||
cityPopulationCap,
|
||||
stationInfluence,
|
||||
roadInfluence,
|
||||
|
|
@ -13,6 +14,8 @@ export function finishMapOutput({
|
|||
moisture,
|
||||
slope,
|
||||
sea,
|
||||
ocean,
|
||||
lake,
|
||||
river,
|
||||
floodplain,
|
||||
plain,
|
||||
|
|
@ -25,6 +28,12 @@ export function finishMapOutput({
|
|||
flowAccum,
|
||||
erosionField,
|
||||
depositionField,
|
||||
arcSpineField,
|
||||
branchRidgeField,
|
||||
depositionalLowland,
|
||||
alluvialFanField,
|
||||
deltaField,
|
||||
naturalBarrierScore,
|
||||
villages,
|
||||
ports,
|
||||
crossings,
|
||||
|
|
@ -132,6 +141,58 @@ export function finishMapOutput({
|
|||
castleRuins = attachIdsAndNames(tagInsidePrefecture(castleRuins, prefectureMask), "castleRuin", seed, null, nameFields, usedNames, nameDebug);
|
||||
externalGateways = attachIdsAndNames(tagInsidePrefecture(externalGateways, prefectureMask), "gateway", seed, "External Gateway", nameFields, usedNames, nameDebug);
|
||||
const adminCenters = attachIdsAndNames(tagInsidePrefecture(adminCentersRaw, prefectureMask), "admin", seed, "Municipal Center", nameFields, usedNames, nameDebug);
|
||||
const representativeFeatures = [
|
||||
...modernCities.map((p) => ({ ...p, representativeWeight: 5.0 + (p.population || 0) / 180000 })),
|
||||
...markets.map((p) => ({ ...p, representativeWeight: 3.2 })),
|
||||
...ports.map((p) => ({ ...p, representativeWeight: p.portClass === "major" ? 3.8 : 2.4 })),
|
||||
...villages.map((p) => ({ ...p, representativeWeight: 1.6 })),
|
||||
].filter((p) => p.insidePrefecture && p.name);
|
||||
for (const center of adminCenters) {
|
||||
const centerAdmin = adminId?.[indexOf(center.x, center.y)];
|
||||
let best = null;
|
||||
let bestScore = -INF;
|
||||
for (const sameAdminOnly of [true, false]) {
|
||||
for (const feature of representativeFeatures) {
|
||||
const featureAdmin = adminId?.[indexOf(feature.x, feature.y)];
|
||||
if (sameAdminOnly && centerAdmin >= 0 && featureAdmin >= 0 && featureAdmin !== centerAdmin) continue;
|
||||
const d = Math.hypot(center.x - feature.x, center.y - feature.y);
|
||||
const score = feature.representativeWeight - d * 0.11 - (sameAdminOnly ? 0 : 1.2);
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
best = feature;
|
||||
}
|
||||
}
|
||||
if (best) break;
|
||||
}
|
||||
if (best) {
|
||||
center.representativeFeatureId = best.id;
|
||||
center.representativeFeatureName = best.name;
|
||||
center.generatedMunicipalityName = center.name;
|
||||
center.name = best.name;
|
||||
}
|
||||
}
|
||||
const adminNamePrefixes = ["\u6771", "\u897F", "\u5357", "\u5317", "\u4E0A", "\u4E0B", "\u65B0", "\u65E7", "\u4E2D", "\u5916"];
|
||||
const adminNameCounts = new Map();
|
||||
for (const center of adminCenters) adminNameCounts.set(center.name, (adminNameCounts.get(center.name) || 0) + 1);
|
||||
const duplicateOrdinal = new Map();
|
||||
for (const center of adminCenters) {
|
||||
if ((adminNameCounts.get(center.name) || 0) <= 1) continue;
|
||||
const n = duplicateOrdinal.get(center.name) || 0;
|
||||
duplicateOrdinal.set(center.name, n + 1);
|
||||
const prefix = adminNamePrefixes[(Math.floor(center.x / Math.max(1, MAP_W / 3)) + Math.floor(center.y / Math.max(1, MAP_H / 3)) * 3 + n) % adminNamePrefixes.length];
|
||||
if (!String(center.name).startsWith(prefix)) center.name = `${prefix}${center.name}`;
|
||||
}
|
||||
const usedAdminNames = new Set();
|
||||
for (const center of adminCenters) {
|
||||
let candidate = center.name;
|
||||
let guard = 0;
|
||||
while (usedAdminNames.has(candidate) && guard < adminNamePrefixes.length) {
|
||||
candidate = `${adminNamePrefixes[(guard + Math.floor(center.x / 12) + Math.floor(center.y / 12)) % adminNamePrefixes.length]}${center.name}`;
|
||||
guard++;
|
||||
}
|
||||
center.name = candidate;
|
||||
usedAdminNames.add(center.name);
|
||||
}
|
||||
|
||||
const entitiesForNames = [
|
||||
...modernCities,
|
||||
|
|
@ -146,6 +207,7 @@ export function finishMapOutput({
|
|||
...newTowns,
|
||||
...passes,
|
||||
...crossings,
|
||||
...adminCenters,
|
||||
...externalGateways,
|
||||
].filter((p) => p.insidePrefecture || p.kind === "External Gateway");
|
||||
|
||||
|
|
@ -153,6 +215,7 @@ export function finishMapOutput({
|
|||
width: MAP_W,
|
||||
height: MAP_H,
|
||||
cellSize: CELL_SIZE,
|
||||
terrainTemplate,
|
||||
prefectureMask,
|
||||
prefectureBorder,
|
||||
prefectureRegionId,
|
||||
|
|
@ -162,6 +225,8 @@ export function finishMapOutput({
|
|||
moisture,
|
||||
slope,
|
||||
sea,
|
||||
ocean,
|
||||
lake,
|
||||
river,
|
||||
floodplain,
|
||||
plain,
|
||||
|
|
@ -174,6 +239,12 @@ export function finishMapOutput({
|
|||
flowAccum,
|
||||
erosionField,
|
||||
depositionField,
|
||||
arcSpineField,
|
||||
branchRidgeField,
|
||||
depositionalLowland,
|
||||
alluvialFanField,
|
||||
deltaField,
|
||||
naturalBarrierScore,
|
||||
villages,
|
||||
ports,
|
||||
crossings,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue