-
+
+
@@ -4218,6 +4227,7 @@
+
diff --git a/modules/ui/general.js b/modules/ui/general.js
index 5da081b5..b99ae898 100644
--- a/modules/ui/general.js
+++ b/modules/ui/general.js
@@ -96,10 +96,7 @@ function showMapTooltip(point, e, i, g) {
const land = pack.cells.h[i] >= 20;
// specific elements
- if (group === "armies") {
- tip(e.target.parentNode.dataset.name + ". Click to edit");
- return;
- }
+ if (group === "armies") return tip(e.target.parentNode.dataset.name + ". Click to edit");
if (group === "emblems" && e.target.tagName === "use") {
const parent = e.target.parentNode;
@@ -123,14 +120,11 @@ function showMapTooltip(point, e, i, g) {
if (riversOverview.offsetParent) highlightEditorLine(riversOverview, river, 5000);
return;
}
- if (group === "routes") {
- tip("Click to edit the Route");
- return;
- }
- if (group === "terrain") {
- tip("Click to edit the Relief Icon");
- return;
- }
+
+ if (group === "routes") return tip("Click to edit the Route");
+
+ if (group === "terrain") return tip("Click to edit the Relief Icon");
+
if (subgroup === "burgLabels" || subgroup === "burgIcons") {
const burg = +path[path.length - 10].dataset.id;
const b = pack.burgs[burg];
@@ -139,50 +133,25 @@ function showMapTooltip(point, e, i, g) {
if (burgsOverview.offsetParent) highlightEditorLine(burgsOverview, burg, 5000);
return;
}
- if (group === "labels") {
- tip("Click to edit the Label");
- return;
- }
- if (group === "markers") {
- tip("Click to edit the Marker");
- return;
- }
+ if (group === "labels") return tip("Click to edit the Label");
+
+ if (group === "markers") return tip("Click to edit the Marker");
+
if (group === "ruler") {
const tag = e.target.tagName;
const className = e.target.getAttribute("class");
- if (tag === "circle" && className === "edge") {
- tip("Drag to adjust. Hold Ctrl and drag to add a point. Click to remove the point");
- return;
- }
- if (tag === "circle" && className === "control") {
- tip("Drag to adjust. Hold Shifta and drag to keep axial direction. Click to remove the point");
- return;
- }
- if (tag === "circle") {
- tip("Drag to adjust the measurer");
- return;
- }
- if (tag === "polyline") {
- tip("Click on drag to add a control point");
- return;
- }
- if (tag === "path") {
- tip("Drag to move the measurer");
- return;
- }
- if (tag === "text") {
- tip("Drag to move, click to remove the measurer");
- return;
- }
- }
- if (subgroup === "burgIcons") {
- tip("Click to edit the Burg");
- return;
- }
- if (subgroup === "burgLabels") {
- tip("Click to edit the Burg");
- return;
+ if (tag === "circle" && className === "edge") return tip("Drag to adjust. Hold Ctrl and drag to add a point. Click to remove the point");
+ if (tag === "circle" && className === "control") return tip("Drag to adjust. Hold Shift and drag to keep axial direction. Click to remove the point");
+ if (tag === "circle") return tip("Drag to adjust the measurer");
+ if (tag === "polyline") return tip("Click on drag to add a control point");
+ if (tag === "path") return tip("Drag to move the measurer");
+ if (tag === "text") return tip("Drag to move, click to remove the measurer");
}
+
+ if (subgroup === "burgIcons") return tip("Click to edit the Burg");
+
+ if (subgroup === "burgLabels") return tip("Click to edit the Burg");
+
if (group === "lakes" && !land) {
const lakeId = +e.target.dataset.f;
const name = pack.features[lakeId]?.name;
@@ -190,20 +159,16 @@ function showMapTooltip(point, e, i, g) {
tip(`${fullName} lake. Click to edit`);
return;
}
- if (group === "coastline") {
- tip("Click to edit the coastline");
- return;
- }
+ if (group === "coastline") return tip("Click to edit the coastline");
+
if (group === "zones") {
const zone = path[path.length - 8];
tip(zone.dataset.description);
if (zonesEditor.offsetParent) highlightEditorLine(zonesEditor, zone.id, 5000);
return;
}
- if (group === "ice") {
- tip("Click to edit the Ice");
- return;
- }
+
+ if (group === "ice") return tip("Click to edit the Ice");
// covering elements
if (layerIsOn("togglePrec") && land) tip("Annual Precipitation: " + getFriendlyPrecipitation(i));
diff --git a/modules/ui/rivers-creator.js b/modules/ui/rivers-creator.js
new file mode 100644
index 00000000..6e1b94e8
--- /dev/null
+++ b/modules/ui/rivers-creator.js
@@ -0,0 +1,120 @@
+"use strict";
+function createRiver() {
+ if (customization) return;
+ closeDialogs();
+ if (!layerIsOn("toggleRivers")) toggleRivers();
+
+ document.getElementById("toggleCells").dataset.forced = +!layerIsOn("toggleCells");
+ if (!layerIsOn("toggleCells")) toggleCells();
+
+ tip("Click to add river point, click again to remove", true);
+ debug.append("g").attr("id", "controlCells");
+ viewbox.style("cursor", "crosshair").on("click", onCellClick);
+
+ createRiver.cells = [];
+ const body = document.getElementById("riverCreatorBody");
+
+ $("#riverCreator").dialog({
+ title: "Create River",
+ resizable: false,
+ position: {my: "left top", at: "left+10 top+10", of: "#map"},
+ close: closeRiverCreator
+ });
+
+ if (modules.createRiver) return;
+ modules.createRiver = true;
+
+ // add listeners
+ document.getElementById("riverCreatorComplete").addEventListener("click", addRiver);
+ document.getElementById("riverCreatorCancel").addEventListener("click", () => $("#riverCreator").dialog("close"));
+ body.addEventListener("click", function (ev) {
+ const el = ev.target;
+ const cl = el.classList;
+ const cell = +el.parentNode.dataset.cell;
+ if (cl.contains("editFlux")) pack.cells.fl[cell] = +el.value;
+ else if (cl.contains("icon-trash-empty")) removeCell(cell);
+ });
+
+ function onCellClick() {
+ const cell = findCell(...d3.mouse(this));
+
+ if (createRiver.cells.includes(cell)) removeCell(cell);
+ else addCell(cell);
+ }
+
+ function addCell(cell) {
+ createRiver.cells.push(cell);
+ drawCells(createRiver.cells);
+
+ const flux = pack.cells.fl[cell];
+ const line = `
+ Cell ${cell}
+ Flux
+
+
+
`;
+ body.innerHTML += line;
+ }
+
+ function removeCell(cell) {
+ createRiver.cells = createRiver.cells.filter(c => c !== cell);
+ drawCells(createRiver.cells);
+ body.querySelector(`div[data-cell='${cell}']`)?.remove();
+ }
+
+ function drawCells(cells) {
+ debug
+ .select("#controlCells")
+ .selectAll(`polygon`)
+ .data(cells)
+ .join("polygon")
+ .attr("points", d => getPackPolygon(d))
+ .attr("class", "current");
+ }
+
+ function addRiver() {
+ const {rivers, cells} = pack;
+ const {addMeandering, getApproximateLength, getWidth, getOffset, getName, getRiverPath} = Rivers;
+
+ const riverId = last(rivers).i + 1;
+ const riverCells = createRiver.cells;
+
+ riverCells.forEach(cell => {
+ if (!cells.r[cell]) cells.r[cell] = riverId;
+ });
+
+ const source = riverCells[0];
+ const mouth = riverCells[riverCells.length - 1];
+ const sourceWidth = 0.05;
+ const widthFactor = 1;
+
+ const meanderedPoints = addMeandering(riverCells);
+
+ const discharge = cells.fl[mouth]; // m3 in second
+ const length = getApproximateLength(meanderedPoints);
+ const width = getWidth(getOffset(discharge, meanderedPoints.length, widthFactor, sourceWidth));
+ const name = getName(mouth);
+
+ rivers.push({i: riverId, source, mouth, discharge, length, width, widthFactor, sourceWidth, parent: riverId, cells: riverCells, basin: riverId, name, type: "River"});
+
+ // render river
+ lineGen.curve(d3.curveCatmullRom.alpha(0.1));
+ viewbox
+ .select("#rivers")
+ .append("path")
+ .attr("id", "river" + riverId)
+ .attr("d", getRiverPath(meanderedPoints, widthFactor, sourceWidth));
+
+ editRiver(riverId);
+ }
+
+ function closeRiverCreator() {
+ debug.select("#controlCells").remove();
+ restoreDefaultEvents();
+ clearMainTip();
+
+ const forced = +document.getElementById("toggleCells").dataset.forced;
+ document.getElementById("toggleCells").dataset.forced = 0;
+ if (forced && layerIsOn("toggleCells")) toggleCells();
+ }
+}
diff --git a/modules/ui/rivers-editor.js b/modules/ui/rivers-editor.js
index 4d73e79c..e17df410 100644
--- a/modules/ui/rivers-editor.js
+++ b/modules/ui/rivers-editor.js
@@ -25,7 +25,7 @@ function editRiver(id) {
$("#riverEditor").dialog({
title: "Edit River",
resizable: false,
- position: {my: "left+40 center", at: "center", of: "svg", collision: "fit"},
+ position: {my: "left top", at: "left+10 top+10", of: "#map"},
close: closeRiverEditor
});
diff --git a/modules/ui/rivers-overview.js b/modules/ui/rivers-overview.js
index 2d8c6ef4..fcde2ae5 100644
--- a/modules/ui/rivers-overview.js
+++ b/modules/ui/rivers-overview.js
@@ -21,6 +21,7 @@ function overviewRivers() {
// add listeners
document.getElementById("riversOverviewRefresh").addEventListener("click", riversOverviewAddLines);
document.getElementById("addNewRiver").addEventListener("click", toggleAddRiver);
+ document.getElementById("riverCreateNew").addEventListener("click", createRiver);
document.getElementById("riversBasinHighlight").addEventListener("click", toggleBasinsHightlight);
document.getElementById("riversExport").addEventListener("click", downloadRiversData);
document.getElementById("riversRemoveAll").addEventListener("click", triggerAllRiversRemove);
diff --git a/modules/ui/tools.js b/modules/ui/tools.js
index 4c7cc4a7..5243cd95 100644
--- a/modules/ui/tools.js
+++ b/modules/ui/tools.js
@@ -531,8 +531,7 @@ function toggleAddRiver() {
function addRiverOnClick() {
const {cells, rivers} = pack;
- const point = d3.mouse(this);
- let i = findCell(point[0], point[1]);
+ let i = findCell(...d3.mouse(this));
if (cells.r[i]) return tip("There is already a river here", false, "error");
if (cells.h[i] < 20) return tip("Cannot create river in water cell", false, "error");