mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 10:01:23 +01:00
v. 0.55993b
This commit is contained in:
parent
da110421bc
commit
05db880f20
3 changed files with 526 additions and 418 deletions
28
index.css
28
index.css
|
|
@ -320,10 +320,11 @@ button.options {
|
|||
top: -2px;
|
||||
position: relative;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
#options input[type="range"]::slider-thumb {
|
||||
appearance: none;
|
||||
#options input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
border-radius: 15%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
|
|
@ -487,12 +488,16 @@ p {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#sizeOutput {
|
||||
color: green;
|
||||
}
|
||||
|
||||
#icons {
|
||||
stroke: #0d0d0d;
|
||||
fill: grey;
|
||||
}
|
||||
|
||||
#fileToLoad {
|
||||
#fileInputs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
@ -704,11 +709,11 @@ body .ui-dialog-titlebar {
|
|||
top: -4px;
|
||||
position: relative;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.ui-dialog input[type="range"]::slider-thumb {
|
||||
appearance: none;
|
||||
.ui-dialog input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
border-radius: 15%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
|
|
@ -776,11 +781,6 @@ div.slider .ui-slider-handle {
|
|||
color: white;
|
||||
}
|
||||
|
||||
#layoutCheckboxes {
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#brushPower, #brushRadius {
|
||||
width: 88px;
|
||||
}
|
||||
|
|
@ -1120,7 +1120,7 @@ input[type="checkbox"] {
|
|||
.checkbox + .checkbox-label:before {
|
||||
content: '';
|
||||
background: #ece6eb;
|
||||
border-radius: 50%;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
width: 8px;
|
||||
|
|
@ -1130,7 +1130,7 @@ input[type="checkbox"] {
|
|||
}
|
||||
|
||||
.checkbox:checked + .checkbox-label:before {
|
||||
background: #826473;
|
||||
border-radius: 50%;
|
||||
background: #8e6d7e;
|
||||
transition: .1s;
|
||||
box-shadow: inset 0px 0px 0px 2px #ece6ea;
|
||||
}
|
||||
25
index.html
25
index.html
|
|
@ -31,8 +31,8 @@
|
|||
<script src="libs/polylabel.min.js"></script>
|
||||
<script src="libs/quantize.min.js" defer></script>
|
||||
<script src="libs/d3-hexbin.v0.2.min.js" defer></script>
|
||||
<link rel="stylesheet" type="text/css" href="index.css?version=0.55992b"/>
|
||||
<link rel="stylesheet" type="text/css" href="icons.css?version=0.55992b"/>
|
||||
<link rel="stylesheet" type="text/css" href="index.css?version=0.55993b"/>
|
||||
<link rel="stylesheet" type="text/css" href="icons.css?version=0.55993b"/>
|
||||
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"/>
|
||||
</head>
|
||||
<body class="fullscreen">
|
||||
|
|
@ -273,7 +273,7 @@
|
|||
<p>Generate new map to apply the options!</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td title="Map size. Will be remembered on change">Map size</td>
|
||||
<td title="Map size. Will be remembered on change. Highly affects performance!">Map size</td>
|
||||
<td style="width: 130px;">
|
||||
<span title="width">w:</span>
|
||||
<input class="pairedNumber" id="mapWidthInput" type="number" min="240" value="960">
|
||||
|
|
@ -300,9 +300,9 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td title="Set the graph size. Map on size 3 and 4 requires up to 1 minute to be generated!">Graph size</td>
|
||||
<td title="Set the graph size. Performance on sizes 2 and 3 can be low!">Graph size</td>
|
||||
<td>
|
||||
<input id="sizeInput" type="range" min="1" max="4" value="1">
|
||||
<input id="sizeInput" type="range" min="1" max="3" value="1">
|
||||
</td>
|
||||
<td>
|
||||
<output id="sizeOutput">1</output>
|
||||
|
|
@ -420,7 +420,7 @@
|
|||
<div id="customizeHeightmap" style="display: none;">
|
||||
<p title="Click 'Start' to initiate customization, 'Complete' to finalize the Heightmap">Heightmap customization:</p>
|
||||
<div>
|
||||
<button title="Roll back to Heightmap customization" id="fromHeightmap">Roll back</button>
|
||||
<button title="Edit Heightmap" id="fromHeightmap">Edit</button>
|
||||
<button title="Start from scratch" id="fromScratch">Clear all</button>
|
||||
<button class="buttonoff" title="Finalize the Heightmap. Not allowed if landmass area is insufficient" id="getMap" disabled="disabled">Complete</button>
|
||||
</div>
|
||||
|
|
@ -463,7 +463,6 @@
|
|||
<div id="savePNG" title="Download the visible part of the map as 4K .png image (may be pretty slow)">.png</div>
|
||||
</div>
|
||||
<button id="loadMap" title="Load fully functional map in a .map format" class="options">Load</button>
|
||||
<input type="file" accept=".map" id="fileToLoad">
|
||||
<button id="zoomReset" title="Reset map zoom to default" class="options">Reset Zoom</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -551,14 +550,12 @@
|
|||
<button id="templateClear" title="Clear the map" class="icon-eraser"></button>
|
||||
<button id="templateComplete" title="Finalize the Heightmap. Not allowed if insufficient land area available" class="icon-check"></button>
|
||||
<button id="templateLoad" title="Open previously saved template" class="icon-upload"></button>
|
||||
<input type="file" accept=".txt" id="templateToLoad" style="display: none;">
|
||||
<button id="templateSave" title="Save template" class="icon-download"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="imageConverter" class="dialog" style="display: none">
|
||||
<div id="convertImageButtons">
|
||||
<input type="file" accept="image/*" id="imageToLoad" style="display: none;">
|
||||
<button id="convertImageLoad" title="Load image to convert" class="icon-upload"></button>
|
||||
<button id="convertAutoLum" title="Auto-assign colors based on liminosity" class="icon-adjust"></button>
|
||||
<button id="convertAutoHue" title="Auto-assign colors based on hue" class="icon-brush"></button>
|
||||
|
|
@ -665,7 +662,6 @@
|
|||
<button id="countriesPercentage" title="Toggle percentage / absolut values views" class="icon-percent"></button>
|
||||
<button id="countriesRegenerate" title='Regenerate countries based on amended "Expansion" values' class="icon-cw"></button>
|
||||
<button id="countriesManually" title="Manually re-assign countries (select a country and drag the map)" class="icon-brush"></button>
|
||||
<input type="file" accept=".txt,.csv" id="burgsListToLoad" style="display: none;">
|
||||
<div id="countriesManuallyButtons" style="display: none">
|
||||
<button id="countriesManuallyComplete" title="Apply assignment" class="icon-check"></button>
|
||||
<button id="countriesAddM" title="Add country" class="icon-plus"></button>
|
||||
|
|
@ -779,5 +775,12 @@
|
|||
Type: <span id="feature">no</span>
|
||||
</div>
|
||||
|
||||
<script src="script.js?version=0.55992b"></script>
|
||||
<div id="fileInputs">
|
||||
<input type="file" accept=".map" id="mapToLoad">
|
||||
<input type="file" accept=".txt,.csv" id="burgsListToLoad">
|
||||
<input type="file" accept="image/*" id="imageToLoad">
|
||||
<input type="file" accept=".txt" id="templateToLoad">
|
||||
</div>
|
||||
|
||||
<script src="script.js?version=0.55993b"></script>
|
||||
</body>
|
||||
297
script.js
297
script.js
|
|
@ -828,6 +828,7 @@ function fantasyMap() {
|
|||
// Mark features (ocean, lakes, islands)
|
||||
function markFeatures() {
|
||||
console.time("markFeatures");
|
||||
island = 0;
|
||||
var queue = [], lake = 0, number = 0, type, greater = 0, less = 0;
|
||||
// ensure all border cells are ocean
|
||||
cells.map(function(l) {
|
||||
|
|
@ -951,10 +952,12 @@ function fantasyMap() {
|
|||
var f = i.f;
|
||||
var fn = i.fn;
|
||||
var harbor = i.harbor;
|
||||
var region = i.region; // handle value for edit hrightmap mode only
|
||||
var culture = i.culture; // handle value for edit hrightmap mode only
|
||||
var copy = $.grep(newPoints, function(e) {return (e[0] == x && e[1] == y);});
|
||||
if (!copy.length) {
|
||||
newPoints.push([x, y]);
|
||||
tempCells.push({index:tempCells.length, data:[x, y], height, ctype, f, fn, harbor});
|
||||
tempCells.push({index:tempCells.length, data:[x, y], height, ctype, f, fn, harbor, region, culture});
|
||||
}
|
||||
// add additional points for cells along coast
|
||||
if (ctype === 2 || ctype === -1) {
|
||||
|
|
@ -966,7 +969,7 @@ function fantasyMap() {
|
|||
copy = $.grep(newPoints, function(e) {return (e[0] === x1 && e[1] === y1);});
|
||||
if (!copy.length) {
|
||||
newPoints.push([x1, y1]);
|
||||
tempCells.push({index:tempCells.length, data:[x1, y1], height, ctype, f, fn, harbor});
|
||||
tempCells.push({index:tempCells.length, data:[x1, y1], height, ctype, f, fn, harbor, region, culture});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
@ -1004,6 +1007,8 @@ function fantasyMap() {
|
|||
})
|
||||
i.neighbors = neighbors;
|
||||
if (i.haven === undefined) {delete i.harbor;}
|
||||
if (i.region === undefined) {delete i.region;}
|
||||
if (i.culture === undefined) {delete i.culture;}
|
||||
i.flux = avPrec;
|
||||
});
|
||||
grid.append("path").attr("d", gridPath);
|
||||
|
|
@ -1641,17 +1646,17 @@ function fantasyMap() {
|
|||
$("#riverEditor .editButton, #riverEditor .editButtonS").click(function() {
|
||||
if (this.id == "riverRemove") {
|
||||
alertMessage.innerHTML = `Are you sure you want to remove the river?`;
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove river",
|
||||
$("#alert").dialog({resizable: false, title: "Remove river",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
elSelected.remove();
|
||||
rivers.select(".riverPoints").remove();
|
||||
$("#riverEditor").dialog("close");
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
});
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (this.id == "riverCopy") {
|
||||
|
|
@ -2438,9 +2443,11 @@ function fantasyMap() {
|
|||
function defineRegions() {
|
||||
console.time('defineRegions');
|
||||
manorTree = d3.quadtree().extent([[0, 0], [mapHeight, mapWidth]]);
|
||||
manors.map(function(m) {manorTree.add([m.x, m.y]);});
|
||||
manors.map(function(m) {
|
||||
if (m.region === "removed") {return;}
|
||||
manorTree.add([m.x, m.y]);
|
||||
});
|
||||
land.map(function(i) {
|
||||
if (i.region !== undefined) {return;}
|
||||
var x = i.data[0], y = i.data[1];
|
||||
var closest = manorTree.find(x, y);
|
||||
var dist = Math.hypot(closest[0] - x, closest[1] - y);
|
||||
|
|
@ -2470,28 +2477,31 @@ function fantasyMap() {
|
|||
// Define areas cells
|
||||
function drawRegions() {
|
||||
console.time('drawRegions');
|
||||
var edges = [], coastalEdges = [], borderEdges = [], neutralEdges = []; // arrays to store edges
|
||||
land.map(function(l) {
|
||||
var s = l.region;
|
||||
if (!edges[s]) {edges[s] = [], coastalEdges[s] = [];}
|
||||
var cell = diagram.cells[l.index];
|
||||
cell.halfedges.forEach(function(e) {
|
||||
var edge = diagram.edges[e];
|
||||
if (edge.left && edge.right) {
|
||||
var ea = edge.left.index;
|
||||
if (ea === l.index) {ea = edge.right.index;}
|
||||
var opp = cells[ea];
|
||||
if (opp.region !== s) {
|
||||
var start = edge[0].join(" ");
|
||||
var end = edge[1].join(" ");
|
||||
edges[s].push({start, end});
|
||||
if (opp.height >= 0.2 && opp.region > s) {borderEdges.push({start, end});}
|
||||
if (opp.height >= 0.2 && opp.region === "neutral") {neutralEdges.push({start, end});}
|
||||
if (opp.height < 0.2) {coastalEdges[s].push({start, end});}
|
||||
// arrays to store edge data
|
||||
var edges = [], coastalEdges = [], borderEdges = [], neutralEdges = [];
|
||||
for (let a=0; a < states.length; a++) {
|
||||
edges[a] = [];
|
||||
coastalEdges[a] = [];
|
||||
}
|
||||
const e = diagram.edges;
|
||||
for (let i=0; i < e.length; i++) {
|
||||
if (e[i] === undefined) {continue;}
|
||||
if (e[i].left === undefined || e[i].right === undefined) {continue;}
|
||||
const l = e[i].left.index;
|
||||
const r = e[i].right.index;
|
||||
const lr = cells[l].region;
|
||||
const rr = cells[r].region;
|
||||
if (lr === rr) {continue;}
|
||||
const start = e[i][0].join(" ");
|
||||
const end = e[i][1].join(" ");
|
||||
const p = {start, end};
|
||||
if (lr !== undefined && lr !== "neutral") {edges[lr].push(p);}
|
||||
if (rr !== undefined && rr !== "neutral") {edges[rr].push(p);}
|
||||
if (lr === undefined && rr !== "neutral") {coastalEdges[rr].push(p); continue;}
|
||||
if (rr === undefined && lr !== "neutral") {coastalEdges[lr].push(p); continue;}
|
||||
if (lr === "neutral" || rr === "neutral") {neutralEdges.push(p);}
|
||||
else {borderEdges.push(p);}
|
||||
}
|
||||
})
|
||||
});
|
||||
edges.map(function(e, i) {
|
||||
if (e.length) {
|
||||
drawRegion(e, i);
|
||||
|
|
@ -2705,6 +2715,9 @@ function fantasyMap() {
|
|||
delete c.used;
|
||||
delete c.coastX;
|
||||
delete c.coastY;
|
||||
if (c.ctype === undefined) {delete c.ctype;}
|
||||
c.height = rn(c.height, 2);
|
||||
c.flux = rn(c.flux, 2);
|
||||
});
|
||||
// restore heightmap layer if it was turned on
|
||||
if (!$("#toggleHeight").hasClass("buttonoff") && !terrs.selectAll("path").size()) {toggleHeight();}
|
||||
|
|
@ -2887,7 +2900,7 @@ function fantasyMap() {
|
|||
}
|
||||
|
||||
// Complete the map for the "customize" mode
|
||||
function getMap() {
|
||||
function getMap(keepData) {
|
||||
exitCustomization();
|
||||
console.time("TOTAL");
|
||||
applyMapSize();
|
||||
|
|
@ -2899,7 +2912,7 @@ function fantasyMap() {
|
|||
flux();
|
||||
drawRelief();
|
||||
drawCoastline();
|
||||
manorsAndRegions();
|
||||
if (!keepData) {manorsAndRegions();} else {restoreRegions();}
|
||||
cleanData();
|
||||
console.timeEnd("TOTAL");
|
||||
}
|
||||
|
|
@ -3221,16 +3234,16 @@ function fantasyMap() {
|
|||
var group = d3.select(elSelected.node().parentNode);
|
||||
if (this.id == "editRemoveSingle") {
|
||||
alertMessage.innerHTML = "Are you sure you want to remove the label?";
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove label",
|
||||
$("#alert").dialog({resizable: false, title: "Remove label",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
elSelected.remove();
|
||||
$("#labelEditor").dialog("close");
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
});
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (this.id == "editGroupRemove") {
|
||||
|
|
@ -3242,16 +3255,16 @@ function fantasyMap() {
|
|||
}
|
||||
var message = "Are you sure you want to remove all labels (" + count + ") of that group?";
|
||||
alertMessage.innerHTML = message;
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove labels",
|
||||
$("#alert").dialog({resizable: false, title: "Remove labels",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
group.remove();
|
||||
$("#labelEditor").dialog("close");
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
});
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (this.id == "editCopy") {
|
||||
|
|
@ -3650,7 +3663,7 @@ function fantasyMap() {
|
|||
}
|
||||
|
||||
// Map Loader based on FileSystem API
|
||||
$("#fileToLoad").change(function() {
|
||||
$("#mapToLoad").change(function() {
|
||||
console.time("loadMap");
|
||||
closeAllDialogs();
|
||||
var fileToLoad = this.files[0];
|
||||
|
|
@ -3708,13 +3721,7 @@ function fantasyMap() {
|
|||
alertMessage.innerHTML = message;
|
||||
$("#alert").dialog({title: "Map size conflict",
|
||||
buttons: {
|
||||
"Keep": function() {
|
||||
voronoi = d3.voronoi().extent([[0, 0], [nWidth, nHeight]]);
|
||||
zoom.translateExtent([[0, 0], [nWidth, nHeight]]);
|
||||
applyLoadedData(data);
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Change": function() {
|
||||
Change: function() {
|
||||
mapWidthInput.value = nWidth;
|
||||
mapHeightInput.value = nHeight;
|
||||
changeMapSize();
|
||||
|
|
@ -3727,6 +3734,12 @@ function fantasyMap() {
|
|||
}
|
||||
applyLoadedData(data);
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Keep: function() {
|
||||
voronoi = d3.voronoi().extent([[0, 0], [nWidth, nHeight]]);
|
||||
zoom.translateExtent([[0, 0], [nWidth, nHeight]]);
|
||||
applyLoadedData(data);
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -3785,7 +3798,7 @@ function fantasyMap() {
|
|||
ruler.selectAll(".linear").selectAll("circle.center").call(d3.drag().on("drag", rulerCenterDrag));
|
||||
|
||||
// update data
|
||||
newPoints = [], riversData = [], island = 0, queue = [], elSelected = "";
|
||||
newPoints = [], riversData = [], queue = [], elSelected = "";
|
||||
points = JSON.parse(data[1]);
|
||||
cells = JSON.parse(data[2]);
|
||||
land = $.grep(cells, function(e) {return (e.height >= 0.2);});
|
||||
|
|
@ -4190,9 +4203,10 @@ function fantasyMap() {
|
|||
if (id === "burgNamesImport") {burgsListToLoad.click();}
|
||||
if (id === "removeCountries") {
|
||||
alertMessage.innerHTML = `Are you sure you want to remove all countries?`;
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove countries",
|
||||
$("#alert").dialog({resizable: false, title: "Remove countries",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Cancel: function() {$(this).dialog("close");},
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
$("#countriesBody").empty();
|
||||
manors.map(function(m) {m.region = "neutral";});
|
||||
|
|
@ -4210,16 +4224,16 @@ function fantasyMap() {
|
|||
recalculateStateData(0);
|
||||
if ($("#burgsEditor").is(":visible")) {$("#burgsEditor").dialog("close");}
|
||||
editCountries();
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (id === "removeBurgs") {
|
||||
alertMessage.innerHTML = `Are you sure you want to remove all burgs associated with the country?`;
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove associated burgs",
|
||||
$("#alert").dialog({resizable: false, title: "Remove associated burgs",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Cancel: function() {$(this).dialog("close");},
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
var state = +$("#burgsEditor").attr("data-state");
|
||||
var region = states[state].capital === "neutral" ? "neutral" : state;
|
||||
|
|
@ -4240,9 +4254,8 @@ function fantasyMap() {
|
|||
}
|
||||
burgsFooterBurgs.innerHTML = 0;
|
||||
burgsFooterPopulation.value = 0;
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (id === "changeCapital") {
|
||||
|
|
@ -4311,42 +4324,55 @@ function fantasyMap() {
|
|||
if (id === "removeAllRulers") {
|
||||
if ($("#ruler > g").length < 1) {return;}
|
||||
alertMessage.innerHTML = `Are you sure you want to remove all placed rulers?`;
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove all rulers",
|
||||
$("#alert").dialog({resizable: false, title: "Remove all rulers",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
$("#ruler > g").remove();
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (id === "editHeightmap") {$("#customizeHeightmap").slideToggle();}
|
||||
if (id === "fromScratch") {
|
||||
alertMessage.innerHTML = "Are you sure you want to clear the map? All progress will be lost";
|
||||
$("#alert").dialog({resizable: false, title: "Clear map",
|
||||
buttons: {
|
||||
Cancel: function() {$(this).dialog("close");},
|
||||
Clear: function() {
|
||||
closeAllDialogs();
|
||||
undraw();
|
||||
placePoints();
|
||||
calculateVoronoi(points);
|
||||
detectNeighbors("grid");
|
||||
drawScaleBar();
|
||||
customizeHeightmap();
|
||||
return;
|
||||
$("#paintBrushes").click();
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (id === "fromHeightmap") {
|
||||
var heights = [];
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var cell = diagram.find(points[i][0], points[i][1]).index;
|
||||
heights.push(cells[cell].height);
|
||||
let message = "It's highly recommended to finalize a heightmap as a first step. ";
|
||||
message += "If you want to edit a map, it's better to clean up all the data except on heights. ";
|
||||
message += "You may also keep the data, but it can cause unexpected errors";
|
||||
alertMessage.innerHTML = message;
|
||||
$("#alert").dialog({resizable: false, title: "Edit Heightmap",
|
||||
buttons: {
|
||||
"Clean up": function() {
|
||||
editHeightmap("clean");
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Keep: function() {
|
||||
editHeightmap("keep");
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}
|
||||
undraw();
|
||||
calculateVoronoi(points);
|
||||
detectNeighbors("grid");
|
||||
drawScaleBar();
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
cells[i].height = heights[i];
|
||||
}
|
||||
mockHeightmap();
|
||||
customizeHeightmap();
|
||||
});
|
||||
return;
|
||||
}
|
||||
// heightmap customization buttons
|
||||
|
|
@ -4377,7 +4403,9 @@ function fantasyMap() {
|
|||
if (id === "redo") {restoreHistory(historyStage + 1);}
|
||||
if (id === "smoothHeights") {smoothHeights(4); mockHeightmap();}
|
||||
if (id === "disruptHeights") {disruptHeights(); mockHeightmap();}
|
||||
if (id === "getMap") {getMap();}
|
||||
if (id === "getMap") {
|
||||
if (states.length && manors.length) {getMap("keep");} else {getMap();}
|
||||
}
|
||||
if (id === "applyTemplate") {
|
||||
if ($("#templateEditor").is(":visible")) {return;}
|
||||
$("#templateEditor").dialog({
|
||||
|
|
@ -4465,14 +4493,15 @@ function fantasyMap() {
|
|||
alertMessage.innerHTML = "Are you sure you want to restore default style?";
|
||||
$("#alert").dialog({resizable: false, title: "Restore style",
|
||||
buttons: {
|
||||
"Restore": function() {
|
||||
Restore: function() {
|
||||
applyDefaultStyle();
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Cancel: function() {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}});
|
||||
}
|
||||
});
|
||||
}
|
||||
if ($(this).hasClass('radio') && parent === "mapFilters") {
|
||||
$("svg").attr("filter", "");
|
||||
|
|
@ -4502,7 +4531,7 @@ function fantasyMap() {
|
|||
changeMapSize();
|
||||
}
|
||||
if (id === "saveButton") {$("#saveDropdown").slideToggle();}
|
||||
if (id === "loadMap") {fileToLoad.click();}
|
||||
if (id === "loadMap") {mapToLoad.click();}
|
||||
if (id === "zoomReset") {resetZoom(1000);}
|
||||
if (id === "zoomPlus") {
|
||||
scale += 1;
|
||||
|
|
@ -4553,9 +4582,9 @@ function fantasyMap() {
|
|||
if (customization === 1) {
|
||||
var message = "Are you sure you want to clear the map?";
|
||||
alertMessage.innerHTML = message;
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Clear map",
|
||||
$("#alert").dialog({resizable: false, title: "Clear map",
|
||||
buttons: {
|
||||
"Clear": function() {
|
||||
Clear: function() {
|
||||
$(this).dialog("close");
|
||||
viewbox.style("cursor", "crosshair").call(drag);
|
||||
landmassCounter.innerHTML = "0";
|
||||
|
|
@ -4568,7 +4597,7 @@ function fantasyMap() {
|
|||
undo.disabled = true;
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
}
|
||||
});
|
||||
} else {
|
||||
start.click();
|
||||
|
|
@ -4590,7 +4619,7 @@ function fantasyMap() {
|
|||
heightsFromImage(current);
|
||||
}
|
||||
if (id === "convertOverlayButton") {
|
||||
$("#convertImageButtons").children().not(this).not("#imageToLoad, #convertColors").toggle();
|
||||
$("#convertImageButtons").children().not(this).not("#convertColors").toggle();
|
||||
}
|
||||
if (id === "convertAutoLum") {autoAssing("lum");}
|
||||
if (id === "convertAutoHue") {autoAssing("hue");}
|
||||
|
|
@ -4623,6 +4652,39 @@ function fantasyMap() {
|
|||
$("#saveDropdown").slideUp("fast");
|
||||
});
|
||||
|
||||
function editHeightmap(type) {
|
||||
closeAllDialogs();
|
||||
var heights = [], regionData = [], cultureData = [];
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var cell = diagram.find(points[i][0], points[i][1]).index;
|
||||
heights.push(cells[cell].height);
|
||||
var region = cells[cell].region;
|
||||
if (region === undefined) {region = -1;}
|
||||
regionData.push(region);
|
||||
var culture = cells[cell].culture;
|
||||
if (culture === undefined) {culture = -1;}
|
||||
cultureData.push(culture);
|
||||
}
|
||||
if (type === "clean") {undraw();}
|
||||
calculateVoronoi(points);
|
||||
detectNeighbors("grid");
|
||||
drawScaleBar();
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
cells[i].height = heights[i];
|
||||
}
|
||||
if (type === "keep") {
|
||||
svg.selectAll("#shape, #lakes, #coastline, #terrain, #rivers, #grid, #terrs, #landmass, #ocean, #regions")
|
||||
.selectAll("path, circle, line").remove();
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
if (regionData[i] !== -1) {cells[i].region = regionData[i];}
|
||||
if (cultureData[i] !== -1) {cells[i].culture = cultureData[i];}
|
||||
}
|
||||
}
|
||||
mockHeightmap();
|
||||
customizeHeightmap();
|
||||
$("#paintBrushes").click();
|
||||
}
|
||||
|
||||
function drawPerspective() {
|
||||
console.time("drawPerspective");
|
||||
const width = 320, height = 180;
|
||||
|
|
@ -4740,9 +4802,9 @@ function fantasyMap() {
|
|||
var template = this.value;
|
||||
if (steps && changed === 1) {
|
||||
alertMessage.innerHTML = "Are you sure you want to change the base template? All the changes will be lost.";
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Change Template",
|
||||
$("#alert").dialog({resizable: false, title: "Change Template",
|
||||
buttons: {
|
||||
"Change": function() {
|
||||
Change: function() {
|
||||
changeTemplate(template);
|
||||
$(this).dialog("close");
|
||||
},
|
||||
|
|
@ -4751,7 +4813,7 @@ function fantasyMap() {
|
|||
$("#templateSelect").val(prev);
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}})
|
||||
}
|
||||
});
|
||||
}
|
||||
if (steps === 0 || changed === 0) {changeTemplate(template);}
|
||||
|
|
@ -5115,7 +5177,7 @@ function fantasyMap() {
|
|||
// Clear the map
|
||||
function undraw() {
|
||||
svg.selectAll("path, circle, line, text, #ruler > g").remove();
|
||||
cells = [], land = [], riversData = [], island = 0, manors = [], states = [], queue = [];
|
||||
cells = [], land = [], riversData = [], manors = [], states = [], queue = [];
|
||||
history = [], historyStage = -1; redo.disabled = true; undo.disabled = true; // clear history
|
||||
}
|
||||
|
||||
|
|
@ -5326,7 +5388,7 @@ function fantasyMap() {
|
|||
return;
|
||||
}
|
||||
$("#alert").dialog({resizable: false, title: "Remove country", buttons: {
|
||||
"Remove": function() {
|
||||
Remove: function() {
|
||||
states.splice(s, 1);
|
||||
states.map(function(s, i) {s.i = i;});
|
||||
$("#manorLabel"+capital).detach().appendTo($("#towns")).attr("dy", -0.7); // change capital label to burg
|
||||
|
|
@ -5486,9 +5548,9 @@ function fantasyMap() {
|
|||
$("#burgsBody .icon-trash-empty").on("click", function() {
|
||||
alertMessage.innerHTML = `Are you sure you want to remove the burg?`;
|
||||
var b = +(this.parentNode.id).slice(5);
|
||||
$(function() {$("#alert").dialog({resizable: false, title: "Remove burg",
|
||||
$("#alert").dialog({resizable: false, title: "Remove burg",
|
||||
buttons: {
|
||||
"Remove": function() {
|
||||
Remove: function() {
|
||||
$(this).dialog("close");
|
||||
var state = +$("#burgsEditor").attr("data-state");
|
||||
$("#burgs"+b).remove();
|
||||
|
|
@ -5508,7 +5570,7 @@ function fantasyMap() {
|
|||
icons.select("#manorIcon"+b).remove();
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}})
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -5592,17 +5654,55 @@ function fantasyMap() {
|
|||
// remove drawn regions and draw all regions again
|
||||
function redrawRegions() {
|
||||
regions.selectAll("*").remove();
|
||||
stateBorders.selectAll("*").remove();
|
||||
neutralBorders.selectAll("*").remove();
|
||||
borders.selectAll("path").remove();
|
||||
countries.selectAll("text").remove();
|
||||
drawRegions();
|
||||
}
|
||||
|
||||
// restore keeped region data on edit heightmap completion
|
||||
function restoreRegions() {
|
||||
borders.selectAll("path").remove();
|
||||
countries.selectAll("text").remove();
|
||||
manors.map(function(m) {
|
||||
const cell = diagram.find(m.x, m.y).index;
|
||||
if (cells[cell].height < 0.2) {
|
||||
// remove manor if it ocean
|
||||
m.region = "removed";
|
||||
m.cell = cell;
|
||||
labels.select("#manorLabel"+m.i).remove();
|
||||
icons.select("#manorIcon"+m.i).remove();
|
||||
} else {
|
||||
m.cell = cell;
|
||||
cells[cell].manor = m.i;
|
||||
}
|
||||
});
|
||||
cells.map(function(c) {
|
||||
if (c.height < 0.2) {
|
||||
// no longer a land cell
|
||||
delete c.region;
|
||||
delete c.culture;
|
||||
return;
|
||||
}
|
||||
if (c.region === undefined) {
|
||||
c.region = "neutral";
|
||||
if (states[states.length - 1].capital !== "neutral") {
|
||||
states.push({i: states.length, color: "neutral", capital: "neutral", name: "Neutrals"});
|
||||
}
|
||||
}
|
||||
if (c.culture === undefined) {
|
||||
const closest = cultureTree.find(c.data[0], c.data[1]);
|
||||
c.culture = cultureTree.data().indexOf(closest);
|
||||
}
|
||||
});
|
||||
states.map(function(s) {recalculateStateData(s.i);})
|
||||
drawRegions();
|
||||
}
|
||||
|
||||
function regenerateCountries() {
|
||||
regions.selectAll("*").remove();
|
||||
land.map(function(l) {l.region = undefined;});
|
||||
neutral = +countriesNeutral.value;
|
||||
manors.map(function(m) {
|
||||
if (m.region === "removed") {return;}
|
||||
var state = "neutral", closest = neutral;
|
||||
var x = m.x, y = m.y;
|
||||
states.map(function(s) {
|
||||
|
|
@ -5732,7 +5832,7 @@ function fantasyMap() {
|
|||
$("#alert").dialog({title: "Burgs bulk renaming", position: {my: "center", at: "center", of: "svg"},
|
||||
buttons: {
|
||||
Cancel: function() {$(this).dialog("close");},
|
||||
"Confirm": function() {
|
||||
Confirm: function() {
|
||||
for (var i=0; i < change.length; i++) {
|
||||
const id = change[i].i;
|
||||
manors[id].name = change[i].name;
|
||||
|
|
@ -5989,7 +6089,12 @@ function fantasyMap() {
|
|||
changeMapSize();
|
||||
localStorage.setItem("screenSize", [+mapWidthInput.value, +mapHeightInput.value]);
|
||||
}
|
||||
if (id === "sizeInput") {graphSize = sizeOutput.value = this.value;}
|
||||
if (id === "sizeInput") {
|
||||
graphSize = sizeOutput.value = +this.value;
|
||||
if (graphSize === 3) {sizeOutput.style.color = "red";}
|
||||
if (graphSize === 2) {sizeOutput.style.color = "yellow";}
|
||||
if (graphSize === 1) {sizeOutput.style.color = "green";}
|
||||
}
|
||||
if (id === "randomizeInput") {randomizeOutput.innerHTML = +this.value ? "✓" : "✕";}
|
||||
if (id === "manorsInput") {
|
||||
if (randomizeInput.value === "1") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue