refactor: drawReliefIcons, v1.108.4

This commit is contained in:
Azgaar 2025-02-15 18:03:54 +01:00
parent 791347b1ee
commit 4dd34e13d1
8 changed files with 149 additions and 145 deletions

View file

@ -8088,7 +8088,7 @@
<script src="config/precreated-heightmaps.js"></script>
<script src="modules/heightmap-generator.js?v=1.99.00"></script>
<script src="modules/features.js?v=1.104.0"></script>
<script src="modules/ocean-layers.js?v=1.108.3"></script>
<script src="modules/ocean-layers.js?v=1.108.4"></script>
<script src="modules/river-generator.js?v=1.106.7"></script>
<script src="modules/lakes.js?v=1.99.00"></script>
<script src="modules/biomes.js?v=1.99.00"></script>
@ -8115,14 +8115,13 @@
<script src="modules/ui/options.js?v=1.106.2"></script>
<script src="main.js?v=1.108.1"></script>
<script defer src="modules/relief-icons.js?v=1.99.05"></script>
<script defer src="modules/ui/style.js?v=1.104.0"></script>
<script defer src="modules/ui/style.js?v=1.108.4"></script>
<script defer src="modules/ui/editors.js?v=1.108.1"></script>
<script defer src="modules/ui/tools.js?v=1.108.1"></script>
<script defer src="modules/ui/tools.js?v=1.108.4"></script>
<script defer src="modules/ui/world-configurator.js?v=1.105.4"></script>
<script defer src="modules/ui/heightmap-editor.js?v=1.105.2"></script>
<script defer src="modules/ui/provinces-editor.js?v=1.108.1"></script>
<script defer src="modules/ui/biomes-editor.js?v=1.99.05"></script>
<script defer src="modules/ui/biomes-editor.js?v=1.108.4"></script>
<script defer src="modules/ui/namesbase-editor.js?v=1.105.11"></script>
<script defer src="modules/ui/elevation-profile.js?v=1.99.00"></script>
<script defer src="modules/ui/temperature-graph.js?v=1.106.6"></script>
@ -8175,5 +8174,6 @@
<script defer src="modules/renderers/draw-state-labels.js?v=1.108.1"></script>
<script defer src="modules/renderers/draw-burg-labels.js?v=1.108.1"></script>
<script defer src="modules/renderers/draw-burg-icons.js?v=1.104.0"></script>
<script defer src="modules/renderers/draw-relief-icons.js?v=1.108.4"></script>
</body>
</html>

View file

@ -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 += `<use href="${r.i}" x="${r.x}" y="${r.y}" width="${r.s}" height="${r.s}"/>`;
}
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};
})();

View file

@ -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(`<use href="${r.i}" x="${r.x}" y="${r.y}" width="${r.s}" height="${r.s}"/>`);
}
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
}
}

View file

@ -317,7 +317,7 @@ function editBiomes() {
}
function regenerateIcons() {
ReliefIcons.draw();
drawReliefIcons();
if (!layerIsOn("toggleRelief")) toggleRelief();
}

View file

@ -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 {

View file

@ -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();
});

View file

@ -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();

View file

@ -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");
{