mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 09:21:24 +01:00
refactor: drawReliefIcons, v1.108.4
This commit is contained in:
parent
791347b1ee
commit
4dd34e13d1
8 changed files with 149 additions and 145 deletions
10
index.html
10
index.html
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
})();
|
||||
124
modules/renderers/draw-relief-icons.js
Normal file
124
modules/renderers/draw-relief-icons.js
Normal 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
|
||||
}
|
||||
}
|
||||
|
|
@ -317,7 +317,7 @@ function editBiomes() {
|
|||
}
|
||||
|
||||
function regenerateIcons() {
|
||||
ReliefIcons.draw();
|
||||
drawReliefIcons();
|
||||
if (!layerIsOn("toggleRelief")) toggleRelief();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue