?
This commit is contained in:
parent
3ac2c116bd
commit
da9d8ef904
11 changed files with 612 additions and 344 deletions
|
|
@ -1219,6 +1219,72 @@ export function generateTerrainAndRivers(seed) {
|
|||
}
|
||||
}
|
||||
|
||||
function countWaterComponents(mask, minArea = 1) {
|
||||
const seen = new Uint8Array(SIZE);
|
||||
let count = 0;
|
||||
for (let i = 0; i < SIZE; i++) {
|
||||
if (!mask[i] || seen[i]) continue;
|
||||
const queue = [i];
|
||||
seen[i] = 1;
|
||||
let area = 0;
|
||||
for (let q = 0; q < queue.length; q++) {
|
||||
const cur = queue[q];
|
||||
area++;
|
||||
const x = cur % MAP_W;
|
||||
const y = Math.floor(cur / MAP_W);
|
||||
for (const [nx, ny] of neighbors8(x, y)) {
|
||||
const ni = indexOf(nx, ny);
|
||||
if (!mask[ni] || seen[ni]) continue;
|
||||
seen[ni] = 1;
|
||||
queue.push(ni);
|
||||
}
|
||||
}
|
||||
if (area >= minArea) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function countSmallLandIslands(maxArea = 8) {
|
||||
const seen = new Uint8Array(SIZE);
|
||||
let count = 0;
|
||||
for (let i = 0; i < SIZE; i++) {
|
||||
if (sea[i] || seen[i]) continue;
|
||||
const queue = [i];
|
||||
seen[i] = 1;
|
||||
let area = 0;
|
||||
let touchesEdge = false;
|
||||
for (let q = 0; q < queue.length; q++) {
|
||||
const cur = queue[q];
|
||||
area++;
|
||||
const x = cur % MAP_W;
|
||||
const y = Math.floor(cur / MAP_W);
|
||||
if (x === 0 || y === 0 || x === MAP_W - 1 || y === MAP_H - 1) touchesEdge = true;
|
||||
for (const [nx, ny] of neighbors8(x, y)) {
|
||||
const ni = indexOf(nx, ny);
|
||||
if (sea[ni] || seen[ni]) continue;
|
||||
seen[ni] = 1;
|
||||
queue.push(ni);
|
||||
}
|
||||
}
|
||||
if (!touchesEdge && area <= maxArea) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const spineValues = [...arcSpineField].filter((_, i) => !sea[i]).sort((a, b) => b - a);
|
||||
const strongSpineSample = Math.max(1, Math.floor(spineValues.length * 0.05));
|
||||
const primarySpineStrength = spineValues.slice(0, strongSpineSample).reduce((sum, value) => sum + value, 0) / strongSpineSample;
|
||||
const riverConnectivityRate = mainRivers.length
|
||||
? mainRivers.filter((path) => path.some(([x, y], k) => k > path.length * 0.45 && neighbors8(x, y).some(([nx, ny]) => sea[indexOf(nx, ny)] || lake[indexOf(nx, ny)]))).length / mainRivers.length
|
||||
: 0;
|
||||
const depositionLowlandArea = [...depositionalLowland].filter((value, i) => !sea[i] && value > 0.24).length;
|
||||
const terrainDebug = {
|
||||
primarySpineStrength,
|
||||
riverConnectivityRate,
|
||||
smallIslandCount: countSmallLandIslands(8),
|
||||
largeInlandLakeCount: countWaterComponents(Float32Array.from(lake, (value) => value ? 1 : 0), 120),
|
||||
depositionLowlandArea,
|
||||
};
|
||||
|
||||
return {
|
||||
terrainTemplate,
|
||||
|
|
@ -1252,6 +1318,7 @@ export function generateTerrainAndRivers(seed) {
|
|||
prefectureBorder,
|
||||
prefectureRegionId,
|
||||
regionalDebug,
|
||||
terrainDebug,
|
||||
regionalPrefectureBorders,
|
||||
riverPaths,
|
||||
mainRivers,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue