From 96a103376f55883009fe1f3d53d5d557225d482a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:05:12 +0000 Subject: [PATCH 1/3] Initial plan From 62da4f8b53579e0f93e4f5aa68a1167fa64c8519 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:17:50 +0000 Subject: [PATCH 2/3] Add 'Change Only Ocean Cells' checkbox to heightmap editor Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/4011258c-2dd9-45c2-bec6-bd390cb8ca73 Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/modules/ui/heightmap-editor.js | 50 ++++++++++++++++++++++----- src/index.html | 8 +++++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/public/modules/ui/heightmap-editor.js b/public/modules/ui/heightmap-editor.js index 69be50591..9d2495212 100644 --- a/public/modules/ui/heightmap-editor.js +++ b/public/modules/ui/heightmap-editor.js @@ -71,14 +71,17 @@ function editHeightmap(options) { if (mode === "erase") { undraw(); changeOnlyLand.checked = false; + changeOnlyOcean.checked = false; } else if (mode === "keep") { viewbox.selectAll("#landmass, #lakes").style("display", "none"); changeOnlyLand.checked = true; + changeOnlyOcean.checked = false; } else if (mode === "risk") { defs.selectAll("#land, #water").selectAll("path").remove(); defs.select("#featurePaths").selectAll("path").remove(); viewbox.selectAll("#coastline use, #lakes path, #oceanLayers path").remove(); changeOnlyLand.checked = false; + changeOnlyOcean.checked = false; } // show convert and template buttons for Erase mode only @@ -488,6 +491,13 @@ function editHeightmap(options) { } } + // check land cells are not changed if only ocean edit is allowed + if (changeOnlyOcean.checked) { + for (const i of grid.cells.i) { + if (prev[i] >= 20 || grid.cells.h[i] >= 20) grid.cells.h[i] = prev[i]; + } + } + mockHeightmap(); updateHistory(); } @@ -588,6 +598,7 @@ function editHeightmap(options) { // add listeners byId("brushesButtons").on("click", e => toggleBrushMode(e)); byId("changeOnlyLand").on("click", e => changeOnlyLandClick(e)); + byId("changeOnlyOcean").on("click", e => changeOnlyOceanClick(e)); byId("undo").on("click", () => restoreHistory(edits.n - 1)); byId("redo").on("click", () => restoreHistory(edits.n + 1)); byId("rescaleShow").on("click", () => { @@ -686,6 +697,7 @@ function editHeightmap(options) { for (let i = 0; i < heights.length; i++) { if (changedHeights[i] === heights[i]) continue; if (changeOnlyLand.checked && heights[i] < 20) continue; + if (changeOnlyOcean.checked && heights[i] >= 20) continue; heights[i] = changedHeights[i]; selection.push(i); } @@ -705,7 +717,9 @@ function editHeightmap(options) { if (~~d3.event.sourceEvent.timeStamp % 5 != 0) return; // slow down the edit const inRadius = findGridAll(p[0], p[1], r); - const selection = changeOnlyLand.checked ? inRadius.filter(i => grid.cells.h[i] >= 20) : inRadius; + let selection = inRadius; + if (changeOnlyLand.checked) selection = inRadius.filter(i => grid.cells.h[i] >= 20); + else if (changeOnlyOcean.checked) selection = inRadius.filter(i => grid.cells.h[i] < 20); if (selection && selection.length) changeHeightForSelection(selection, start); }); @@ -717,11 +731,12 @@ function editHeightmap(options) { const interpolate = d3.interpolateRound(power, 1); const land = changeOnlyLand.checked; - const lim = v => minmax(v, land ? 20 : 0, 100); + const ocean = changeOnlyOcean.checked; + const lim = v => minmax(v, land ? 20 : 0, ocean ? 19 : 100); const heights = grid.cells.h; const brush = document.querySelector("#brushesButtons > button.pressed").id; - if (brush === "brushRaise") selection.forEach(i => (heights[i] = heights[i] < 20 ? 20 : lim(heights[i] + power))); + if (brush === "brushRaise") selection.forEach(i => (heights[i] = !ocean && heights[i] < 20 ? 20 : lim(heights[i] + power))); else if (brush === "brushElevate") selection.forEach( (i, d) => (heights[i] = lim(heights[i] + interpolate(d / Math.max(selection.length - 1, 1)))) @@ -736,7 +751,7 @@ function editHeightmap(options) { selection.forEach( i => (heights[i] = rn( - (d3.mean(grid.cells.c[i].filter(i => (land ? heights[i] >= 20 : 1)).map(c => heights[c])) + + (d3.mean(grid.cells.c[i].filter(c => (land ? heights[c] >= 20 : ocean ? heights[c] < 20 : 1)).map(c => heights[c])) + heights[i] * (10 - power) + 0.6) / (11 - power), @@ -753,14 +768,32 @@ function editHeightmap(options) { } function changeOnlyLandClick(e) { - if (heightmapEditMode.innerHTML !== "keep") return; - e.preventDefault(); - tip("You cannot change the coastline in 'Keep' edit mode", false, "error"); + if (heightmapEditMode.innerHTML === "keep") { + e.preventDefault(); + tip("You cannot change the coastline in 'Keep' edit mode", false, "error"); + return; + } + if (changeOnlyLand.checked) changeOnlyOcean.checked = false; + } + + function changeOnlyOceanClick(e) { + if (heightmapEditMode.innerHTML === "keep") { + e.preventDefault(); + tip("You cannot change the coastline in 'Keep' edit mode", false, "error"); + return; + } + if (changeOnlyOcean.checked) changeOnlyLand.checked = false; } function rescale(v) { const land = changeOnlyLand.checked; - grid.cells.h = grid.cells.h.map(h => (land && (h < 20 || h + v < 20) ? h : lim(h + v))); + const ocean = changeOnlyOcean.checked; + grid.cells.h = grid.cells.h.map(h => { + if (land && (h < 20 || h + v < 20)) return h; + if (ocean && h >= 20) return h; + const newH = lim(h + v); + return ocean ? Math.min(newH, 19) : newH; + }); updateHeightmap(); byId("rescaler").value = 0; } @@ -799,6 +832,7 @@ function editHeightmap(options) { function startFromScratch() { if (changeOnlyLand.checked) return tip("Not allowed when 'Change only land cells' mode is set", false, "error"); + if (changeOnlyOcean.checked) return tip("Not allowed when 'Change only ocean cells' mode is set", false, "error"); const someHeights = grid.cells.h.some(h => h); if (!someHeights) return tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); diff --git a/src/index.html b/src/index.html index f721353b5..ac7d5ffc5 100644 --- a/src/index.html +++ b/src/index.html @@ -4199,6 +4199,14 @@ +
+ + +
+
From 1edb1e241580fca8850962802675380c7119cb53 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:04:18 +0000 Subject: [PATCH 3/3] Replace land/ocean checkboxes with cellTypeFilter select dropdown Agent-Logs-Url: https://github.com/Azgaar/Fantasy-Map-Generator/sessions/e456d324-554b-4ee5-98ae-3c28da95ecca Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com> --- public/modules/ui/heightmap-editor.js | 57 ++++++++++----------------- src/index.html | 21 ++++------ 2 files changed, 28 insertions(+), 50 deletions(-) diff --git a/public/modules/ui/heightmap-editor.js b/public/modules/ui/heightmap-editor.js index 9d2495212..227c07920 100644 --- a/public/modules/ui/heightmap-editor.js +++ b/public/modules/ui/heightmap-editor.js @@ -70,18 +70,15 @@ function editHeightmap(options) { if (mode === "erase") { undraw(); - changeOnlyLand.checked = false; - changeOnlyOcean.checked = false; + cellTypeFilter.value = "all"; } else if (mode === "keep") { viewbox.selectAll("#landmass, #lakes").style("display", "none"); - changeOnlyLand.checked = true; - changeOnlyOcean.checked = false; + cellTypeFilter.value = "land"; } else if (mode === "risk") { defs.selectAll("#land, #water").selectAll("path").remove(); defs.select("#featurePaths").selectAll("path").remove(); viewbox.selectAll("#coastline use, #lakes path, #oceanLayers path").remove(); - changeOnlyLand.checked = false; - changeOnlyOcean.checked = false; + cellTypeFilter.value = "all"; } // show convert and template buttons for Erase mode only @@ -484,15 +481,15 @@ function editHeightmap(options) { tip("Cells changed: " + changed); if (!changed) return; - // check ocean cells are not checged if olny land edit is allowed - if (changeOnlyLand.checked) { + // check ocean cells are not changed if only land edit is allowed + if (cellTypeFilter.value === "land") { for (const i of grid.cells.i) { if (prev[i] < 20 || grid.cells.h[i] < 20) grid.cells.h[i] = prev[i]; } } - // check land cells are not changed if only ocean edit is allowed - if (changeOnlyOcean.checked) { + // check land cells are not changed if only water edit is allowed + if (cellTypeFilter.value === "water") { for (const i of grid.cells.i) { if (prev[i] >= 20 || grid.cells.h[i] >= 20) grid.cells.h[i] = prev[i]; } @@ -597,8 +594,7 @@ function editHeightmap(options) { // add listeners byId("brushesButtons").on("click", e => toggleBrushMode(e)); - byId("changeOnlyLand").on("click", e => changeOnlyLandClick(e)); - byId("changeOnlyOcean").on("click", e => changeOnlyOceanClick(e)); + byId("cellTypeFilter").on("change", cellTypeFilterChange); byId("undo").on("click", () => restoreHistory(edits.n - 1)); byId("redo").on("click", () => restoreHistory(edits.n + 1)); byId("rescaleShow").on("click", () => { @@ -696,8 +692,8 @@ function editHeightmap(options) { let selection = []; for (let i = 0; i < heights.length; i++) { if (changedHeights[i] === heights[i]) continue; - if (changeOnlyLand.checked && heights[i] < 20) continue; - if (changeOnlyOcean.checked && heights[i] >= 20) continue; + if (cellTypeFilter.value === "land" && heights[i] < 20) continue; + if (cellTypeFilter.value === "water" && heights[i] >= 20) continue; heights[i] = changedHeights[i]; selection.push(i); } @@ -718,8 +714,8 @@ function editHeightmap(options) { const inRadius = findGridAll(p[0], p[1], r); let selection = inRadius; - if (changeOnlyLand.checked) selection = inRadius.filter(i => grid.cells.h[i] >= 20); - else if (changeOnlyOcean.checked) selection = inRadius.filter(i => grid.cells.h[i] < 20); + if (cellTypeFilter.value === "land") selection = inRadius.filter(i => grid.cells.h[i] >= 20); + else if (cellTypeFilter.value === "water") selection = inRadius.filter(i => grid.cells.h[i] < 20); if (selection && selection.length) changeHeightForSelection(selection, start); }); @@ -730,8 +726,8 @@ function editHeightmap(options) { const power = heightmapBrushPower.valueAsNumber; const interpolate = d3.interpolateRound(power, 1); - const land = changeOnlyLand.checked; - const ocean = changeOnlyOcean.checked; + const land = cellTypeFilter.value === "land"; + const ocean = cellTypeFilter.value === "water"; const lim = v => minmax(v, land ? 20 : 0, ocean ? 19 : 100); const heights = grid.cells.h; @@ -767,27 +763,16 @@ function editHeightmap(options) { // updateHistory(); uncomment to update history on every step } - function changeOnlyLandClick(e) { - if (heightmapEditMode.innerHTML === "keep") { - e.preventDefault(); + function cellTypeFilterChange() { + if (cellTypeFilter.value === "land" && heightmapEditMode.innerHTML === "keep") { tip("You cannot change the coastline in 'Keep' edit mode", false, "error"); - return; - } - if (changeOnlyLand.checked) changeOnlyOcean.checked = false; - } - - function changeOnlyOceanClick(e) { - if (heightmapEditMode.innerHTML === "keep") { - e.preventDefault(); - tip("You cannot change the coastline in 'Keep' edit mode", false, "error"); - return; + cellTypeFilter.value = "all"; } - if (changeOnlyOcean.checked) changeOnlyLand.checked = false; } function rescale(v) { - const land = changeOnlyLand.checked; - const ocean = changeOnlyOcean.checked; + const land = cellTypeFilter.value === "land"; + const ocean = cellTypeFilter.value === "water"; grid.cells.h = grid.cells.h.map(h => { if (land && (h < 20 || h + v < 20)) return h; if (ocean && h >= 20) return h; @@ -831,8 +816,8 @@ function editHeightmap(options) { } function startFromScratch() { - if (changeOnlyLand.checked) return tip("Not allowed when 'Change only land cells' mode is set", false, "error"); - if (changeOnlyOcean.checked) return tip("Not allowed when 'Change only ocean cells' mode is set", false, "error"); + if (cellTypeFilter.value === "land") return tip("Not allowed when 'only land cells' filter is set", false, "error"); + if (cellTypeFilter.value === "water") return tip("Not allowed when 'only water cells' filter is set", false, "error"); const someHeights = grid.cells.h.some(h => h); if (!someHeights) return tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); diff --git a/src/index.html b/src/index.html index ac7d5ffc5..2ef9d95a5 100644 --- a/src/index.html +++ b/src/index.html @@ -4191,20 +4191,13 @@
-
- - -
- -
- - +
+ +