This commit is contained in:
33333-33333 2026-05-29 18:50:54 +09:00
commit 4a8aff90b2
7 changed files with 3806 additions and 83 deletions

View file

@ -209,15 +209,16 @@ const TERRAIN_TYPES = [
},
{
id: "oceanic_archipelago",
label: "海洋型・多島海",
weight: 0.16,
label: "Ocean",
weight: 0.00,
autoSelectable: false,
coastStyle: "oceanic_archipelago",
mountainMode: "mixed",
massifnessRange: [0.04, 0.28],
seaRatioRange: [0.72, 0.90],
seaRatioRange: [0.955, 0.985],
twoSidedChance: 1.0,
mountainOffsetRange: [0.25, 0.55],
baseHeightRange: [0.30, 0.62],
baseHeightRange: [0.20, 0.46],
primaryLengthRange: [0.20, 0.52],
primaryWidthRange: [0.08, 0.24],
systemCountRange: [7, 14],
@ -227,7 +228,7 @@ const TERRAIN_TYPES = [
lengthScale: 0.78,
widthScale: 0.82,
heightScale: 0.58,
coastStrength: 1.55,
coastStrength: 2.10,
plainBiasRange: [0.12, 0.34],
riverRichnessRange: [0.18, 0.52],
bigRiverChanceRange: [0.02, 0.12],
@ -315,11 +316,11 @@ function pickTerrainType(seed, requestedType = "auto") {
const selected = TERRAIN_TYPES.find((type) => type.id === normalizedType);
if (selected) return selected;
}
// Terrain type selection is intentionally uniform. Individual terrain
// templates still contain their own parameter ranges, but there is no
// terrain-type appearance weighting.
const index = Math.floor(rand(seed, 10001) * TERRAIN_TYPES.length) % TERRAIN_TYPES.length;
return TERRAIN_TYPES[index];
// Auto excludes explicitly manual/special-purpose templates such as Ocean.
// The selection remains uniform over ordinary land-bearing templates.
const autoTypes = TERRAIN_TYPES.filter((type) => type.autoSelectable !== false);
const index = Math.floor(rand(seed, 10001) * autoTypes.length) % autoTypes.length;
return autoTypes[index];
}
function rangeValue(seed, salt, [lo, hi]) {
@ -1174,8 +1175,8 @@ function enforceLandGradient(elevation, sea, seaLevel) {
function rectTerrainProfile(template) {
const id = String(template?.terrainType || "auto");
if (id.includes("oceanic")) return {
base: 0.36, relief: 0.19, ridge: 0.30, ridgeWidth: 22, ridgeSpacing: 76, coast: 0.34, archipelago: 0.28,
seaQuantile: Math.max(0.68, template.seaRatio ?? 0.76), plain: 0.20, moisture: 0.60, capStart: 0.64, capMax: 0.86,
base: 0.28, relief: 0.11, ridge: 0.20, ridgeWidth: 18, ridgeSpacing: 70, coast: 0.52, archipelago: 0.18,
seaQuantile: Math.max(0.95, template.seaRatio ?? 0.965), plain: 0.12, moisture: 0.66, capStart: 0.56, capMax: 0.74,
};
if (id.includes("setouchi") || id.includes("archipelago")) return {
base: 0.43, relief: 0.18, ridge: 0.34, ridgeWidth: 30, ridgeSpacing: 94, coast: 0.25, archipelago: 0.20,
@ -1697,7 +1698,11 @@ export function generateTerrainRect(options = {}) {
}
}
const seaLevel = clamp(Number.isFinite(options.seaLevel) ? options.seaLevel : rectQuantile(elevation, profile.seaQuantile), 0.13, 0.50);
const seaLevel = clamp(
Number.isFinite(options.seaLevel) ? options.seaLevel : rectQuantile(elevation, profile.seaQuantile),
0.13,
terrainTemplate.terrainType === "oceanic_archipelago" ? 0.72 : 0.50
);
const oceanCells = classifyRectWater(ctx, fields, seaLevel);
recomputeRectSlope(ctx, fields);
const filled = priorityFloodRect(ctx, fields);
@ -1922,7 +1927,7 @@ export function generateTerrainAndRivers(seed, options = {}) {
}
let seaLevel = quantile(elevation, terrainTemplate.seaRatio);
seaLevel = clamp(seaLevel, 0.14, 0.47);
seaLevel = clamp(seaLevel, 0.14, terrainTemplate.terrainType === "oceanic_archipelago" ? 0.72 : 0.47);
classifyWater(elevation, seaLevel, sea, ocean, lake);
recomputeSlope(elevation, sea, slope);