From 49e7e5c53376546675559abc39a13d12e2cd28c7 Mon Sep 17 00:00:00 2001 From: Marc Emmanuel Date: Wed, 21 Jan 2026 22:34:30 +0100 Subject: [PATCH] refactor: Remove river-generator.js reference and add biomes module --- src/index.html | 1 - .../biomes.js => src/modules/biomes.ts | 84 ++++++++++++------- src/modules/index.ts | 3 +- 3 files changed, 54 insertions(+), 34 deletions(-) rename public/modules/biomes.js => src/modules/biomes.ts (62%) diff --git a/src/index.html b/src/index.html index b6a4a603..5d9cf35a 100644 --- a/src/index.html +++ b/src/index.html @@ -8470,7 +8470,6 @@ - diff --git a/public/modules/biomes.js b/src/modules/biomes.ts similarity index 62% rename from public/modules/biomes.js rename to src/modules/biomes.ts index 06280fad..49bc24b8 100644 --- a/public/modules/biomes.js +++ b/src/modules/biomes.ts @@ -1,10 +1,30 @@ -"use strict"; +import { range, mean } from "d3"; +import { rn } from "../utils"; -window.Biomes = (function () { - const MIN_LAND_HEIGHT = 20; +declare global { + var Biomes: BiomesModule; - const getDefault = () => { - const name = [ + var pack: any; + var grid: any; + var TIME: boolean; + + var biomesData: { + i: number[]; + name: string[]; + color: string[]; + biomesMartix: Uint8Array[]; + habitability: number[]; + iconsDensity: number[]; + icons: string[][]; + cost: number[]; + }; +} + +class BiomesModule { + private MIN_LAND_HEIGHT = 20; + + getDefault() { + const name: string[] = [ "Marine", "Hot desert", "Cold desert", @@ -20,7 +40,7 @@ window.Biomes = (function () { "Wetland" ]; - const color = [ + const color: string[] = [ "#466eab", "#fbe79f", "#b5b887", @@ -35,9 +55,9 @@ window.Biomes = (function () { "#d5e7eb", "#0b9131" ]; - const habitability = [0, 4, 10, 22, 30, 50, 100, 80, 90, 12, 4, 0, 12]; - const iconsDensity = [0, 3, 2, 120, 120, 120, 120, 150, 150, 100, 5, 0, 250]; - const icons = [ + const habitability: number[] = [0, 4, 10, 22, 30, 50, 100, 80, 90, 12, 4, 0, 12]; + const iconsDensity: number[] = [0, 3, 2, 120, 120, 120, 120, 150, 150, 100, 5, 0, 250]; + const icons: Array<{[key: string]: number}> = [ {}, {dune: 3, cactus: 6, deadTree: 1}, {dune: 9, deadTree: 1}, @@ -52,8 +72,8 @@ window.Biomes = (function () { {}, {swamp: 1} ]; - const cost = [10, 200, 150, 60, 50, 70, 70, 80, 90, 200, 1000, 5000, 150]; // biome movement cost - const biomesMartix = [ + const cost: number[] = [10, 200, 150, 60, 50, 70, 70, 80, 90, 200, 1000, 5000, 150]; // biome movement cost + const biomesMartix: Uint8Array[] = [ // hot ↔ cold [>19°C; <-4°C]; dry ↕ wet new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10]), new Uint8Array([3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9, 9, 9, 10, 10, 10]), @@ -63,53 +83,53 @@ window.Biomes = (function () { ]; // parse icons weighted array into a simple array + const parsedIcons: string[][] = []; for (let i = 0; i < icons.length; i++) { - const parsed = []; + const parsed: string[] = []; for (const icon in icons[i]) { for (let j = 0; j < icons[i][icon]; j++) { parsed.push(icon); } } - icons[i] = parsed; + parsedIcons[i] = parsed; } - return {i: d3.range(0, name.length), name, color, biomesMartix, habitability, iconsDensity, icons, cost}; + return {i: range(0, name.length), name, color, biomesMartix, habitability, iconsDensity, icons: parsedIcons, cost}; }; - // assign biome id for each cell - function define() { + define() { TIME && console.time("defineBiomes"); const {fl: flux, r: riverIds, h: heights, c: neighbors, g: gridReference} = pack.cells; const {temp, prec} = grid.cells; pack.cells.biome = new Uint8Array(pack.cells.i.length); // biomes array - for (let cellId = 0; cellId < heights.length; cellId++) { - const height = heights[cellId]; - const moisture = height < MIN_LAND_HEIGHT ? 0 : calculateMoisture(cellId); - const temperature = temp[gridReference[cellId]]; - pack.cells.biome[cellId] = getId(moisture, temperature, height, Boolean(riverIds[cellId])); - } - - function calculateMoisture(cellId) { + const calculateMoisture = (cellId: number) => { let moisture = prec[gridReference[cellId]]; if (riverIds[cellId]) moisture += Math.max(flux[cellId] / 10, 2); const moistAround = neighbors[cellId] - .filter(neibCellId => heights[neibCellId] >= MIN_LAND_HEIGHT) - .map(c => prec[gridReference[c]]) + .filter((neibCellId: number) => heights[neibCellId] >= this.MIN_LAND_HEIGHT) + .map((c: number) => prec[gridReference[c]]) .concat([moisture]); - return rn(4 + d3.mean(moistAround)); + return rn(4 + (mean(moistAround) as number)); + } + + for (let cellId = 0; cellId < heights.length; cellId++) { + const height = heights[cellId]; + const moisture = height < this.MIN_LAND_HEIGHT ? 0 : calculateMoisture(cellId); + const temperature = temp[gridReference[cellId]]; + pack.cells.biome[cellId] = this.getId(moisture, temperature, height, Boolean(riverIds[cellId])); } TIME && console.timeEnd("defineBiomes"); } - function getId(moisture, temperature, height, hasRiver) { + getId(moisture: number, temperature: number, height: number, hasRiver: boolean) { if (height < 20) return 0; // all water cells: marine biome if (temperature < -5) return 11; // too cold: permafrost biome if (temperature >= 25 && !hasRiver && moisture < 8) return 1; // too hot and dry: hot desert biome - if (isWetland(moisture, temperature, height)) return 12; // too wet: wetland biome + if (this.isWetland(moisture, temperature, height)) return 12; // too wet: wetland biome // in other cases use biome matrix const moistureBand = Math.min((moisture / 5) | 0, 4); // [0-4] @@ -117,12 +137,12 @@ window.Biomes = (function () { return biomesData.biomesMartix[moistureBand][temperatureBand]; } - function isWetland(moisture, temperature, height) { + private isWetland(moisture: number, temperature: number, height: number) { if (temperature <= -2) return false; // too cold if (moisture > 40 && height < 25) return true; // near coast if (moisture > 24 && height > 24 && height < 60) return true; // off coast return false; } +} - return {getDefault, define, getId}; -})(); +window.Biomes = new BiomesModule(); diff --git a/src/modules/index.ts b/src/modules/index.ts index 09b6be21..21836080 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -2,4 +2,5 @@ import "./voronoi"; import "./heightmap-generator"; import "./features"; import "./ocean-layers"; -import "./river-generator"; \ No newline at end of file +import "./river-generator"; +import "./biomes" \ No newline at end of file