From 4dd34e13d11f9343df2fc0dd66a8ffa686b49732 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 15 Feb 2025 18:03:54 +0100 Subject: [PATCH] refactor: drawReliefIcons, v1.108.4 --- index.html | 10 +- modules/relief-icons.js | 128 ------------------------- modules/renderers/draw-relief-icons.js | 124 ++++++++++++++++++++++++ modules/ui/biomes-editor.js | 2 +- modules/ui/layers.js | 4 +- modules/ui/style.js | 22 +++-- modules/ui/tools.js | 2 +- versioning.js | 2 +- 8 files changed, 149 insertions(+), 145 deletions(-) delete mode 100644 modules/relief-icons.js create mode 100644 modules/renderers/draw-relief-icons.js diff --git a/index.html b/index.html index adbddd4e..c71ed2a3 100644 --- a/index.html +++ b/index.html @@ -8088,7 +8088,7 @@ - + @@ -8115,14 +8115,13 @@ - - + - + - + @@ -8175,5 +8174,6 @@ + diff --git a/modules/relief-icons.js b/modules/relief-icons.js deleted file mode 100644 index 85bf0b76..00000000 --- a/modules/relief-icons.js +++ /dev/null @@ -1,128 +0,0 @@ -"use strict"; - -window.ReliefIcons = (function () { - const draw = function () { - TIME && console.time("drawRelief"); - terrain.selectAll("*").remove(); - - const cells = pack.cells; - const density = terrain.attr("density") || 0.4; - const size = 2 * (terrain.attr("size") || 1); - const mod = 0.2 * size; // size modifier - const relief = []; - - for (const i of cells.i) { - const height = cells.h[i]; - if (height < 20) continue; // no icons on water - if (cells.r[i]) continue; // no icons on rivers - const biome = cells.biome[i]; - if (height < 50 && biomesData.iconsDensity[biome] === 0) continue; // no icons for this biome - - const polygon = getPackPolygon(i); - const [minX, maxX] = d3.extent(polygon, p => p[0]); - const [minY, maxY] = d3.extent(polygon, p => p[1]); - - if (height < 50) placeBiomeIcons(i, biome); - else placeReliefIcons(i); - - function placeBiomeIcons() { - const iconsDensity = biomesData.iconsDensity[biome] / 100; - const radius = 2 / iconsDensity / density; - if (Math.random() > iconsDensity * 10) return; - - for (const [cx, cy] of poissonDiscSampler(minX, minY, maxX, maxY, radius)) { - if (!d3.polygonContains(polygon, [cx, cy])) continue; - let h = (4 + Math.random()) * size; - const icon = getBiomeIcon(i, biomesData.icons[biome]); - if (icon === "#relief-grass-1") h *= 1.2; - relief.push({i: icon, x: rn(cx - h, 2), y: rn(cy - h, 2), s: rn(h * 2, 2)}); - } - } - - function placeReliefIcons(i) { - const radius = 2 / density; - const [icon, h] = getReliefIcon(i, height); - - for (const [cx, cy] of poissonDiscSampler(minX, minY, maxX, maxY, radius)) { - if (!d3.polygonContains(polygon, [cx, cy])) continue; - relief.push({i: icon, x: rn(cx - h, 2), y: rn(cy - h, 2), s: rn(h * 2, 2)}); - } - } - - function getReliefIcon(i, h) { - const temp = grid.cells.temp[pack.cells.g[i]]; - const type = h > 70 && temp < 0 ? "mountSnow" : h > 70 ? "mount" : "hill"; - const size = h > 70 ? (h - 45) * mod : minmax((h - 40) * mod, 3, 6); - return [getIcon(type), size]; - } - } - - // sort relief icons by y+size - relief.sort((a, b) => a.y + a.s - (b.y + b.s)); - - let reliefHTML = ""; - for (const r of relief) { - reliefHTML += ``; - } - terrain.html(reliefHTML); - - TIME && console.timeEnd("drawRelief"); - }; - - function getBiomeIcon(i, b) { - let type = b[Math.floor(Math.random() * b.length)]; - const temp = grid.cells.temp[pack.cells.g[i]]; - if (type === "conifer" && temp < 0) type = "coniferSnow"; - return getIcon(type); - } - - function getVariant(type) { - switch (type) { - case "mount": - return rand(2, 7); - case "mountSnow": - return rand(1, 6); - case "hill": - return rand(2, 5); - case "conifer": - return 2; - case "coniferSnow": - return 1; - case "swamp": - return rand(2, 3); - case "cactus": - return rand(1, 3); - case "deadTree": - return rand(1, 2); - default: - return 2; - } - } - - function getOldIcon(type) { - switch (type) { - case "mountSnow": - return "mount"; - case "vulcan": - return "mount"; - case "coniferSnow": - return "conifer"; - case "cactus": - return "dune"; - case "deadTree": - return "dune"; - default: - return type; - } - } - - function getIcon(type) { - const set = terrain.attr("set") || "simple"; - if (set === "simple") return "#relief-" + getOldIcon(type) + "-1"; - if (set === "colored") return "#relief-" + type + "-" + getVariant(type); - if (set === "gray") return "#relief-" + type + "-" + getVariant(type) + "-bw"; - return "#relief-" + getOldIcon(type) + "-1"; // simple - } - - return {draw}; -})(); diff --git a/modules/renderers/draw-relief-icons.js b/modules/renderers/draw-relief-icons.js new file mode 100644 index 00000000..ffa0b69c --- /dev/null +++ b/modules/renderers/draw-relief-icons.js @@ -0,0 +1,124 @@ +"use strict"; + +function drawReliefIcons() { + TIME && console.time("drawRelief"); + terrain.selectAll("*").remove(); + + const cells = pack.cells; + const density = terrain.attr("density") || 0.4; + const size = 2 * (terrain.attr("size") || 1); + const mod = 0.2 * size; // size modifier + const relief = []; + + for (const i of cells.i) { + const height = cells.h[i]; + if (height < 20) continue; // no icons on water + if (cells.r[i]) continue; // no icons on rivers + const biome = cells.biome[i]; + if (height < 50 && biomesData.iconsDensity[biome] === 0) continue; // no icons for this biome + + const polygon = getPackPolygon(i); + const [minX, maxX] = d3.extent(polygon, p => p[0]); + const [minY, maxY] = d3.extent(polygon, p => p[1]); + + if (height < 50) placeBiomeIcons(i, biome); + else placeReliefIcons(i); + + function placeBiomeIcons() { + const iconsDensity = biomesData.iconsDensity[biome] / 100; + const radius = 2 / iconsDensity / density; + if (Math.random() > iconsDensity * 10) return; + + for (const [cx, cy] of poissonDiscSampler(minX, minY, maxX, maxY, radius)) { + if (!d3.polygonContains(polygon, [cx, cy])) continue; + let h = (4 + Math.random()) * size; + const icon = getBiomeIcon(i, biomesData.icons[biome]); + if (icon === "#relief-grass-1") h *= 1.2; + relief.push({i: icon, x: rn(cx - h, 2), y: rn(cy - h, 2), s: rn(h * 2, 2)}); + } + } + + function placeReliefIcons(i) { + const radius = 2 / density; + const [icon, h] = getReliefIcon(i, height); + + for (const [cx, cy] of poissonDiscSampler(minX, minY, maxX, maxY, radius)) { + if (!d3.polygonContains(polygon, [cx, cy])) continue; + relief.push({i: icon, x: rn(cx - h, 2), y: rn(cy - h, 2), s: rn(h * 2, 2)}); + } + } + + function getReliefIcon(i, h) { + const temp = grid.cells.temp[pack.cells.g[i]]; + const type = h > 70 && temp < 0 ? "mountSnow" : h > 70 ? "mount" : "hill"; + const size = h > 70 ? (h - 45) * mod : minmax((h - 40) * mod, 3, 6); + return [getIcon(type), size]; + } + } + + // sort relief icons by y+size + relief.sort((a, b) => a.y + a.s - (b.y + b.s)); + + const reliefHTML = new Array(relief.length); + for (const r of relief) { + reliefHTML.push(``); + } + terrain.html(reliefHTML.join("")); + + TIME && console.timeEnd("drawRelief"); + + function getBiomeIcon(i, b) { + let type = b[Math.floor(Math.random() * b.length)]; + const temp = grid.cells.temp[pack.cells.g[i]]; + if (type === "conifer" && temp < 0) type = "coniferSnow"; + return getIcon(type); + } + + function getVariant(type) { + switch (type) { + case "mount": + return rand(2, 7); + case "mountSnow": + return rand(1, 6); + case "hill": + return rand(2, 5); + case "conifer": + return 2; + case "coniferSnow": + return 1; + case "swamp": + return rand(2, 3); + case "cactus": + return rand(1, 3); + case "deadTree": + return rand(1, 2); + default: + return 2; + } + } + + function getOldIcon(type) { + switch (type) { + case "mountSnow": + return "mount"; + case "vulcan": + return "mount"; + case "coniferSnow": + return "conifer"; + case "cactus": + return "dune"; + case "deadTree": + return "dune"; + default: + return type; + } + } + + function getIcon(type) { + const set = terrain.attr("set") || "simple"; + if (set === "simple") return "#relief-" + getOldIcon(type) + "-1"; + if (set === "colored") return "#relief-" + type + "-" + getVariant(type); + if (set === "gray") return "#relief-" + type + "-" + getVariant(type) + "-bw"; + return "#relief-" + getOldIcon(type) + "-1"; // simple + } +} diff --git a/modules/ui/biomes-editor.js b/modules/ui/biomes-editor.js index 4a91231b..8c50993d 100644 --- a/modules/ui/biomes-editor.js +++ b/modules/ui/biomes-editor.js @@ -317,7 +317,7 @@ function editBiomes() { } function regenerateIcons() { - ReliefIcons.draw(); + drawReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief(); } diff --git a/modules/ui/layers.js b/modules/ui/layers.js index 0e0e1597..a1e3b503 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -192,7 +192,7 @@ function drawLayers() { if (layerIsOn("toggleCoordinates")) drawCoordinates(); if (layerIsOn("toggleCompass")) compass.style("display", "block"); if (layerIsOn("toggleRivers")) drawRivers(); - if (layerIsOn("toggleRelief")) ReliefIcons.draw(); + if (layerIsOn("toggleRelief")) drawReliefIcons(); if (layerIsOn("toggleReligions")) drawReligions(); if (layerIsOn("toggleCultures")) drawCultures(); if (layerIsOn("toggleStates")) drawStates(); @@ -742,7 +742,7 @@ function toggleCompass(event) { function toggleRelief(event) { if (!layerIsOn("toggleRelief")) { turnButtonOn("toggleRelief"); - if (!terrain.selectAll("*").size()) ReliefIcons.draw(); + if (!terrain.selectAll("*").size()) drawReliefIcons(); $("#terrain").fadeIn(); if (event && isCtrlClick(event)) editStyle("terrain"); } else { diff --git a/modules/ui/style.js b/modules/ui/style.js index 3df79026..d8f16ad7 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -140,9 +140,17 @@ function selectStyleElement() { // stroke dash if ( - ["borders", "cells", "coordinates", "gridOverlay", "legend", "population", "routes", "temperature", "zones"].includes( - styleElement - ) + [ + "borders", + "cells", + "coordinates", + "gridOverlay", + "legend", + "population", + "routes", + "temperature", + "zones" + ].includes(styleElement) ) { styleStrokeDash.style.display = "block"; styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || ""; @@ -711,19 +719,19 @@ styleHeightmapCurve.on("change", e => { styleReliefSet.on("change", e => { terrain.attr("set", e.target.value); - ReliefIcons.draw(); + drawReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief(); }); styleReliefSize.on("change", e => { terrain.attr("size", e.target.value); - ReliefIcons.draw(); + drawReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief(); }); styleReliefDensity.on("change", e => { terrain.attr("density", e.target.value); - ReliefIcons.draw(); + drawReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief(); }); @@ -788,7 +796,7 @@ styleShadowInput.on("input", function () { styleFontAdd.on("click", function () { addFontNameInput.value = ""; addFontURLInput.value = ""; - + $("#addFontDialog").dialog({ title: "Add custom font", width: "26em", diff --git a/modules/ui/tools.js b/modules/ui/tools.js index b2d9681c..5662bf0d 100644 --- a/modules/ui/tools.js +++ b/modules/ui/tools.js @@ -79,7 +79,7 @@ function processFeatureRegeneration(event, button) { $("#labels").fadeIn(); drawStateLabels(); } else if (button === "regenerateReliefIcons") { - ReliefIcons.draw(); + drawReliefIcons(); if (!layerIsOn("toggleRelief")) toggleRelief(); } else if (button === "regenerateRoutes") { regenerateRoutes(); diff --git a/versioning.js b/versioning.js index 57f0d9f5..58559a7f 100644 --- a/versioning.js +++ b/versioning.js @@ -13,7 +13,7 @@ * Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2 */ -const VERSION = "1.108.3"; +const VERSION = "1.108.4"; if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format or parsing function"); {