This commit is contained in:
Azgaar 2019-10-24 22:27:41 +03:00
parent 2ba1332eec
commit a3fa5443d6
16 changed files with 137 additions and 113 deletions

View file

@ -70,10 +70,12 @@ button, select, a {
#biomes { #biomes {
stroke-width: .7; stroke-width: .7;
fill-rule: evenodd;
} }
#landmass { #landmass {
mask: url(#land); mask: url(#land);
fill-rule: evenodd;
} }
#lakes, #coastline { #lakes, #coastline {
@ -86,6 +88,11 @@ button, select, a {
text-anchor: middle; text-anchor: middle;
dominant-baseline: central; dominant-baseline: central;
text-shadow: 0px 0px 10px white; text-shadow: 0px 0px 10px white;
fill-rule: evenodd;
}
#oceanLayers {
fill-rule: evenodd;
} }
#coastline { #coastline {
@ -99,7 +106,7 @@ button, select, a {
#statesBody, #provincesBody { #statesBody, #provincesBody {
stroke-width: 2; stroke-width: 2;
fill-rule: evenodd;
mask: url(#land); mask: url(#land);
} }
@ -620,14 +627,8 @@ fieldset {
cursor: default; cursor: default;
} }
#cellInfo>div { #cellInfo {
margin: 3px 0px 3px 3px; user-select: text;
display: inline-block;
vertical-align: top;
}
#cellInfo>div:nth-child(2) {
width: 50%;
} }
#tooltip { #tooltip {
@ -1582,7 +1583,7 @@ div.states > div.biomeArea {
#ruler .planimeter { #ruler .planimeter {
fill: lightblue; fill: lightblue;
fill-rule: evenodd;
fill-opacity: 0.5; fill-opacity: 0.5;
stroke: #737373; stroke: #737373;
} }
@ -1831,8 +1832,9 @@ svg.button {
#alertMessage { #alertMessage {
-moz-user-select: text; -moz-user-select: text;
user-select: text; user-select: text;
max-height: 75vh; max-height: 70vh;
max-width: 75vw; max-width: 75vw;
overflow: auto;
} }
#alertMessage ul { #alertMessage ul {

View file

@ -1249,7 +1249,7 @@
<td>Style</td> <td>Style</td>
<td> <td>
<select id="styleReliefSet"> <select id="styleReliefSet">
<option value="simple" selected>Old</option> <option value="simple" selected>Simple</option>
<option value="gray">Gray</option> <option value="gray">Gray</option>
<option value="colored">Colored</option> <option value="colored">Colored</option>
</select> </select>
@ -1520,9 +1520,9 @@
<p data-tip="Map generation settings. Generate a new map to apply the settings">Map settings (new map to apply):</p> <p data-tip="Map generation settings. Generate a new map to apply the settings">Map settings (new map to apply):</p>
<table> <table>
<tr data-tip="Map height and width in pixels. Please consider reducing map size in case of performance issues"> <tr data-tip="Canvas height and width in pixels, please keep at your screen size or less to improve performance">
<td></td> <td></td>
<td>Map size</td> <td>Canvas size</td>
<td> <td>
<span data-tip="Map width in pixels">width</span> <span data-tip="Map width in pixels">width</span>
<input data-tip="Map width in pixels" id="mapWidthInput" class="paired" type="number" min=240 value=960> <input data-tip="Map width in pixels" id="mapWidthInput" class="paired" type="number" min=240 value=960>
@ -1530,11 +1530,11 @@
<input data-tip="Map height in pixels" id="mapHeightInput" class="paired" type="number" min=135 value=540> <input data-tip="Map height in pixels" id="mapHeightInput" class="paired" type="number" min=135 value=540>
</td> </td>
<td> <td>
<i data-tip="Toggle between screen size and initial map size" id="toggleFullscreen" class="icon-resize-full-alt"></i> <i data-tip="Toggle between screen size and initial canvas size" id="toggleFullscreen" class="icon-resize-full-alt"></i>
</td> </td>
</tr> </tr>
<tr data-tip="Map seed number. Seed produces the same map only if map size and options are the same"> <tr data-tip="Map seed number. Seed produces the same map only if canvas size and options are the same">
<td> <td>
<i data-tip="Click to generate a map for this seed" id="optionsSeedGenerate"></i> <i data-tip="Click to generate a map for this seed" id="optionsSeedGenerate"></i>
</td> </td>
@ -1581,7 +1581,7 @@
<option value="Volcano">Volcano</option> <option value="Volcano">Volcano</option>
<option value="High Island">High Island</option> <option value="High Island">High Island</option>
<option value="Low Island">Low Island</option> <option value="Low Island">Low Island</option>
<option value="Continents">Continents</option> <option value="Continents">Two Continents</option>
<option value="Archipelago">Archipelago</option> <option value="Archipelago">Archipelago</option>
<option value="Atoll">Atoll</option> <option value="Atoll">Atoll</option>
<option value="Mediterranean">Mediterranean</option> <option value="Mediterranean">Mediterranean</option>
@ -1692,7 +1692,7 @@
</td> </td>
</tr> </tr>
<tr data-tip="Define how many organized (!) religions and cults should be generated"> <tr data-tip="Define how many organized religions and cults should be generated. Cultures will have their own folk religions in any case">
<td> <td>
<i data-locked=0 id="lock_religions" class="icon-lock-open"></i> <i data-locked=0 id="lock_religions" class="icon-lock-open"></i>
</td> </td>
@ -1805,6 +1805,7 @@
<div> <div>
<p>Click to overview:</p> <p>Click to overview:</p>
<button id="overviewBurgsButton" data-tip="Click to open Burgs Overview. Shortcut: Shift + T">Burgs</button> <button id="overviewBurgsButton" data-tip="Click to open Burgs Overview. Shortcut: Shift + T">Burgs</button>
<button id="overviewCellsButton" data-tip="Click to open Cell details view. Shortcut: Shift + E">Cells</button>
<!-- <button id="overviewLandmassedButton" data-tip="Click to open Landmasses Overview. Shortcut: Shift + L">Landmasses</button> --> <!-- <button id="overviewLandmassedButton" data-tip="Click to open Landmasses Overview. Shortcut: Shift + L">Landmasses</button> -->
<!-- <button id="overviewWaterbodiesButton" data-tip="Click to open Waterbodies Overview. Shortcut: Shift + W">Waterbodies</button> --> <!-- <button id="overviewWaterbodiesButton" data-tip="Click to open Waterbodies Overview. Shortcut: Shift + W">Waterbodies</button> -->
<!-- <button id="overviewRiversButton" data-tip="Click to open Rivers Overview. Shortcut: Shift + V">Rivers</button> --> <!-- <button id="overviewRiversButton" data-tip="Click to open Rivers Overview. Shortcut: Shift + V">Rivers</button> -->
@ -1834,30 +1835,6 @@
<button id="addRoute" data-tip="Click on map to place a route. Shortcut: Shift + E">Route</button> <button id="addRoute" data-tip="Click on map to place a route. Shortcut: Shift + E">Route</button>
<button id="addMarker" data-tip="Click on map to place a marker. Hold Shift to add multiple. Shortcut: Shift + K">Marker</button> <button id="addMarker" data-tip="Click on map to place a marker. Hold Shift to add multiple. Shortcut: Shift + K">Marker</button>
</div> </div>
<p>Cell info: <i data-tip="Click to toggle the section" class="collapsible icon-down-open pointer"></i></p>
<div id="cellInfo" style="display: none">
<div>
Coord: <span id="infoX">0</span>/<span id="infoY">0</span><br>
Cell: <span id="infoCell">0</span><br>
Area: <span id="infoArea">0</span><br>
</div>
<div>
Type: <span id="infoFeature">n/a</span><br>
Precip: <span id="infoPrec">0</span><br>
Population: <span id="infoPopulation">0</span>
</div>
<div>
Height: <span id="infoHeight">0</span><br>
Temperature: <span id="infoTemp">0</span><br>
Biome: <span id="infoBiome">n/a</span><br>
State: <span id="infoState">n/a</span><br>
Province: <span id="infoProvince">n/a</span><br>
Culture: <span id="infoCulture">n/a</span><br>
Religion: <span id="infoReligion">n/a</span><br>
Burg: <span id="infoBurg">n/a</span>
</div>
</div>
</div> </div>
<div id="customizationMenu" class="tabcontent"> <div id="customizationMenu" class="tabcontent">
@ -1995,8 +1972,8 @@
<input id="precOutput" data-stored="prec" type="range" min="0" max="500" value="50"> <input id="precOutput" data-stored="prec" type="range" min="0" max="500" value="50">
</label> </label>
</div> </div>
<div data-tip="Map size. Can be changed in general options"> <div data-tip="Canvas size. Can be changed in general options on new map generation">
<i>Map size:</i><br> <i>Canvas size:</i><br>
<span id="mapSize"></span> px = <span id="mapSizeFriendly"></span> <span id="mapSize"></span> px = <span id="mapSizeFriendly"></span>
</div> </div>
<div> <div>
@ -2503,7 +2480,7 @@
<option value="templateVolcano">Volcano</option> <option value="templateVolcano">Volcano</option>
<option value="templateHighIsland">High Island</option> <option value="templateHighIsland">High Island</option>
<option value="templateLowIsland">Low Island</option> <option value="templateLowIsland">Low Island</option>
<option value="templateContinents">Continents</option> <option value="templateContinents">Two Continents</option>
<option value="templateArchipelago">Archipelago</option> <option value="templateArchipelago">Archipelago</option>
<option value="templateAtoll">Atoll</option> <option value="templateAtoll">Atoll</option>
<option value="templateMediterranean">Mediterranean</option> <option value="templateMediterranean">Mediterranean</option>
@ -3238,6 +3215,23 @@
</div> </div>
</div> </div>
<div id="cellInfo" style="display: none" class="dialog stable">
<p><b>Cell:</b> <span id="infoCell">0</span></p>
<p><b>Coord:</b> <span id="infoX">0</span>/<span id="infoY">0</span></p>
<p><b>Area:</b> <span id="infoArea">0</span></p>
<p><b>Type:</b> <span id="infoFeature">n/a</span></p>
<p><b>Precipitation:</b> <span id="infoPrec">0</span></p>
<p><b>Population:</b> <span id="infoPopulation">0</span></p>
<p><b>Height:</b> <span id="infoHeight">0</span></p>
<p><b>Temperature:</b> <span id="infoTemp">0</span></p>
<p><b>Biome:</b> <span id="infoBiome">n/a</span></p>
<p><b>State:</b> <span id="infoState">n/a</span></p>
<p><b>Province:</b> <span id="infoProvince">n/a</span></p>
<p><b>Culture:</b> <span id="infoCulture">n/a</span></p>
<p><b>Religion:</b> <span id="infoReligion">n/a</span></p>
<p><b>Burg:</b> <span id="infoBurg">n/a</span></p>
</div>
<div id="preview3d" class="dialog stable" style="display: none; padding: 0px"></div> <div id="preview3d" class="dialog stable" style="display: none; padding: 0px"></div>
<div id="alert" style="display: none" class="dialog"> <div id="alert" style="display: none" class="dialog">

View file

@ -4,13 +4,12 @@
(global.ReliefIcons = factory()); (global.ReliefIcons = factory());
}(this, (function () {'use strict'; }(this, (function () {'use strict';
var ReliefIcons = function ReliefIcons() { const ReliefIcons = function() {
console.time('drawRelief'); console.time('drawRelief');
terrain.selectAll("*").remove(); terrain.selectAll("*").remove();
const density = +styleReliefDensityInput.value; const density = terrain.attr("density") || .4;
if (!density) return; const size = 1.6 * (terrain.attr("size") || 1);
const mod = .2 * size; // size modifier;s
const size = 1.6, mod = .2 * size; // size modifier;s
const relief = []; // t: type, c: cell, x: centerX, y: centerY, s: size; const relief = []; // t: type, c: cell, x: centerX, y: centerY, s: size;
const cells = pack.cells; const cells = pack.cells;
@ -106,9 +105,10 @@
} }
function getIcon(type) { function getIcon(type) {
if (styleReliefSet.value === "simple") return "#relief-" + getOldIcon(type) + "-1"; const set = terrain.attr("set") || "simple";
if (styleReliefSet.value === "colored") return "#relief-" + type + "-" + getVariant(type); if (set === "simple") return "#relief-" + getOldIcon(type) + "-1";
if (styleReliefSet.value === "gray") return "#relief-" + type + "-" + getVariant(type) + "-bw"; if (set === "colored") return "#relief-" + type + "-" + getVariant(type);
if (set === "gray") return "#relief-" + type + "-" + getVariant(type) + "-bw";
return "#relief-" + getOldIcon(type) + "-1"; // simple return "#relief-" + getOldIcon(type) + "-1"; // simple
} }

View file

@ -74,7 +74,7 @@ async function saveJPEG() {
} }
// parse map svg to object url // parse map svg to object url
async function getMapURL(type) { async function getMapURL(type, subtype) {
const cloneEl = document.getElementById("map").cloneNode(true); // clone svg const cloneEl = document.getElementById("map").cloneNode(true); // clone svg
cloneEl.id = "fantasyMap"; cloneEl.id = "fantasyMap";
document.body.appendChild(cloneEl); document.body.appendChild(cloneEl);
@ -83,6 +83,7 @@ async function getMapURL(type) {
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if (isFirefox && type === "mesh") clone.select("#oceanPattern").remove(); if (isFirefox && type === "mesh") clone.select("#oceanPattern").remove();
if (subtype === "globe") clone.select("#scaleBar").remove();
if (type === "mesh") clone.attr("width", graphWidth).attr("height", graphHeight); if (type === "mesh") clone.attr("width", graphWidth).attr("height", graphHeight);
if (type !== "png") clone.select("#viewbox").attr("transform", null); // reset transform to show whole map if (type !== "png") clone.select("#viewbox").attr("transform", null); // reset transform to show whole map
if (type === "svg") removeUnusedElements(clone); if (type === "svg") removeUnusedElements(clone);
@ -551,7 +552,7 @@ function uploadMap(file, callback) {
function parseLoadedData(data) { function parseLoadedData(data) {
try { try {
// exit customization // exit customization
closeDialogs(); if (window.closeDialogs) closeDialogs();
customization = 0; customization = 0;
if (customizationMenu.offsetParent) styleTab.click(); if (customizationMenu.offsetParent) styleTab.click();
@ -908,12 +909,18 @@ function parseLoadedData(data) {
// v 1.11 had an issue with fogging being displayed on load // v 1.11 had an issue with fogging being displayed on load
unfog(); unfog();
// v 1.2 added new terrain attributes
if (!terrain.attr("set")) terrain.attr("set", "simple");
if (!terrain.attr("size")) terrain.attr("size", 1);
if (!terrain.attr("density")) terrain.attr("density", .4);
} }
}() }()
changeMapSize(); changeMapSize();
if (window.restoreDefaultEvents) restoreDefaultEvents(); if (window.restoreDefaultEvents) restoreDefaultEvents();
focusOn(); // based on searchParams focus on point, cell or burg
invokeActiveZooming(); invokeActiveZooming();
console.warn(`TOTAL: ${rn((performance.now()-uploadMap.timeStart)/1000,2)}s`); console.warn(`TOTAL: ${rn((performance.now()-uploadMap.timeStart)/1000,2)}s`);

View file

@ -190,7 +190,7 @@ async function startGlobe(canvas) {
// create globe mesh just from svg // create globe mesh just from svg
async function addGlobe3dMesh() { async function addGlobe3dMesh() {
threeD.material = new THREE.MeshLambertMaterial(); threeD.material = new THREE.MeshLambertMaterial();
const url = await getMapURL("mesh"); const url = await getMapURL("mesh", "globe");
threeD.material.map = new THREE.TextureLoader().load(url, render); threeD.material.map = new THREE.TextureLoader().load(url, render);
threeD.mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(1, 64, 64), threeD.material); threeD.mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(1, 64, 64), threeD.material);
threeD.scene.add(threeD.mesh); threeD.scene.add(threeD.mesh);

View file

@ -304,6 +304,9 @@ function editCultures() {
pack.cells.culture.forEach((c, i) => {if(c === culture) pack.cells.culture[i] = 0;}); pack.cells.culture.forEach((c, i) => {if(c === culture) pack.cells.culture[i] = 0;});
pack.cultures[culture].removed = true; pack.cultures[culture].removed = true;
const origin = pack.cultures[culture].origin;
pack.cultures.forEach(c => {if(c.origin === culture) c.origin = origin;});
refreshCulturesEditor(); refreshCulturesEditor();
} }
@ -363,6 +366,7 @@ function editCultures() {
// build hierarchy tree // build hierarchy tree
pack.cultures[0].origin = null; pack.cultures[0].origin = null;
const cultures = pack.cultures.filter(c => !c.removed); const cultures = pack.cultures.filter(c => !c.removed);
if (cultures.length < 3) {tip("Not enough cultures to show hierarchy", false, "error"); return;}
const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(cultures); const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(cultures);
const treeWidth = root.leaves().length; const treeWidth = root.leaves().length;
const treeHeight = root.height; const treeHeight = root.height;
@ -452,7 +456,6 @@ function editCultures() {
} }
} }
// re-calculate cultures
function recalculateCultures(must) { function recalculateCultures(must) {
if (!must && !culturesAutoChange.checked) return; if (!must && !culturesAutoChange.checked) return;
@ -508,7 +511,7 @@ function editCultures() {
body.querySelector("div.selected").classList.remove("selected"); body.querySelector("div.selected").classList.remove("selected");
body.querySelector("div[data-id='"+culture+"']").classList.add("selected"); body.querySelector("div[data-id='"+culture+"']").classList.add("selected");
} }
function dragCultureBrush() { function dragCultureBrush() {
const r = +culturesManuallyBrush.value; const r = +culturesManuallyBrush.value;
@ -523,7 +526,6 @@ function editCultures() {
}); });
} }
// change culture within selection
function changeCultureForSelection(selection) { function changeCultureForSelection(selection) {
const temp = cults.select("#temp"); const temp = cults.select("#temp");
const selected = body.querySelector("div.selected"); const selected = body.querySelector("div.selected");
@ -564,7 +566,7 @@ function editCultures() {
} }
exitCulturesManualAssignment(); exitCulturesManualAssignment();
} }
function exitCulturesManualAssignment(close) { function exitCulturesManualAssignment(close) {
customization = 0; customization = 0;
cults.select("#temp").remove(); cults.select("#temp").remove();
@ -637,7 +639,7 @@ function editCultures() {
const name = getFileName("Cultures") + ".csv"; const name = getFileName("Cultures") + ".csv";
downloadFile(data, name); downloadFile(data, name);
} }
function closeCulturesEditor() { function closeCulturesEditor() {
debug.select("#cultureCenters").remove(); debug.select("#cultureCenters").remove();
exitCulturesManualAssignment("close"); exitCulturesManualAssignment("close");

View file

@ -262,7 +262,7 @@ function drawLegend(name, data) {
fitLegendBox(); fitLegendBox();
} }
// fit Legend box to map size // fit Legend box to canvas size
function fitLegendBox() { function fitLegendBox() {
if (!legend.selectAll("*").size()) return; if (!legend.selectAll("*").size()) return;
const px = isNaN(+legend.attr("data-x")) ? 99 : legend.attr("data-x") / 100; const px = isNaN(+legend.attr("data-x")) ? 99 : legend.attr("data-x") / 100;

View file

@ -50,7 +50,7 @@ function moved() {
showNotes(d3.event, i); showNotes(d3.event, i);
const g = findGridCell(point[0], point[1]); // grid cell id const g = findGridCell(point[0], point[1]); // grid cell id
if (tooltip.dataset.main) showMainTip(); else showMapTooltip(point, d3.event, i, g); if (tooltip.dataset.main) showMainTip(); else showMapTooltip(point, d3.event, i, g);
if (toolsContent.style.display === "block" && cellInfo.style.display === "block") updateCellInfo(point, i, g); if (cellInfo.offsetParent) updateCellInfo(point, i, g);
} }
// show note box on hover (if any) // show note box on hover (if any)

View file

@ -2,10 +2,6 @@
"use strict"; "use strict";
function editHeightmap() { function editHeightmap() {
const heights = viewbox.select("#heights").size()
? viewbox.select("#heights")
: viewbox.insert("g", "#terrs").attr("id", "heights");
void function selectEditMode() { void function selectEditMode() {
alertMessage.innerHTML = `<p>Heightmap is a core element on which all other data (rivers, burgs, states etc) is based. alertMessage.innerHTML = `<p>Heightmap is a core element on which all other data (rivers, burgs, states etc) is based.
So the best edit approach is to <i>erase</i> the secondary data and let the system automatically regenerate it on edit completion.</p> So the best edit approach is to <i>erase</i> the secondary data and let the system automatically regenerate it on edit completion.</p>
@ -31,6 +27,7 @@ function editHeightmap() {
let edits = []; let edits = [];
restartHistory(); restartHistory();
viewbox.insert("g", "#terrs").attr("id", "heights");
if (modules.editHeightmap) return; if (modules.editHeightmap) return;
modules.editHeightmap = true; modules.editHeightmap = true;
@ -111,7 +108,7 @@ function editHeightmap() {
// Exit customization mode // Exit customization mode
function finalizeHeightmap() { function finalizeHeightmap() {
if (heights.selectAll("*").size() < 200) { if (viewbox.select("#heights").selectAll("*").size() < 200) {
tip("Insufficient land area! There should be at least 200 land cells to finalize the heightmap", null, "error"); tip("Insufficient land area! There should be at least 200 land cells to finalize the heightmap", null, "error");
return; return;
} }
@ -136,7 +133,7 @@ function editHeightmap() {
else if (mode === "risk") restoreRiskedData(); else if (mode === "risk") restoreRiskedData();
// restore initial layers // restore initial layers
heights.selectAll("*").remove(); viewbox.select("#heights").remove();
turnButtonOff("toggleHeight"); turnButtonOff("toggleHeight");
document.getElementById("mapLayers").querySelectorAll("li").forEach(function(e) { document.getElementById("mapLayers").querySelectorAll("li").forEach(function(e) {
if (editHeightmap.layers.includes(e.id) && !layerIsOn(e.id)) e.click(); // turn on if (editHeightmap.layers.includes(e.id) && !layerIsOn(e.id)) e.click(); // turn on
@ -381,7 +378,7 @@ function editHeightmap() {
function mockHeightmap() { function mockHeightmap() {
const data = renderOcean.checked ? grid.cells.i : grid.cells.i.filter(i => grid.cells.h[i] >= 20); const data = renderOcean.checked ? grid.cells.i : grid.cells.i.filter(i => grid.cells.h[i] >= 20);
const scheme = getColorScheme(); const scheme = getColorScheme();
heights.selectAll("polygon").data(data).join("polygon").attr("points", d => getGridPolygon(d)) viewbox.select("#heights").selectAll("polygon").data(data).join("polygon").attr("points", d => getGridPolygon(d))
.attr("id", d => "cell"+d).attr("fill", d => getColor(grid.cells.h[d], scheme)); .attr("id", d => "cell"+d).attr("fill", d => getColor(grid.cells.h[d], scheme));
} }
@ -391,9 +388,9 @@ function editHeightmap() {
const scheme = getColorScheme(); const scheme = getColorScheme();
selection.forEach(function(i) { selection.forEach(function(i) {
let cell = heights.select("#cell"+i); let cell = viewbox.select("#heights").select("#cell"+i);
if (!ocean && grid.cells.h[i] < 20) {cell.remove(); return;} if (!ocean && grid.cells.h[i] < 20) {cell.remove(); return;}
if (!cell.size()) cell = heights.append("polygon").attr("points", getGridPolygon(i)).attr("id", "cell"+i); if (!cell.size()) cell = viewbox.select("#heights").append("polygon").attr("points", getGridPolygon(i)).attr("id", "cell"+i);
cell.attr("fill", getColor(grid.cells.h[i], scheme)); cell.attr("fill", getColor(grid.cells.h[i], scheme));
}); });
} }
@ -579,7 +576,7 @@ function editHeightmap() {
const someHeights = grid.cells.h.some(h => h); const someHeights = grid.cells.h.some(h => h);
if (!someHeights) {tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); return;} if (!someHeights) {tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); return;}
grid.cells.h = new Uint8Array(grid.cells.i.length); grid.cells.h = new Uint8Array(grid.cells.i.length);
heights.selectAll("*").remove(); viewbox.select("#heights").selectAll("*").remove();
updateHistory(); updateHistory();
} }
@ -941,7 +938,7 @@ function editHeightmap() {
// remove all heights // remove all heights
grid.cells.h = new Uint8Array(grid.cells.i.length); grid.cells.h = new Uint8Array(grid.cells.i.length);
heights.selectAll("*").remove(); viewbox.select("#heights").selectAll("*").remove();
updateHistory(); updateHistory();
if (modules.openImageConverter) return; if (modules.openImageConverter) return;
@ -995,7 +992,7 @@ function editHeightmap() {
const imageData = ctx.getImageData(0, 0, graphWidth, graphHeight); const imageData = ctx.getImageData(0, 0, graphWidth, graphHeight);
const data = imageData.data; const data = imageData.data;
heights.selectAll("*").remove(); viewbox.select("#heights").selectAll("*").remove();
d3.select("#imageConverter").selectAll("div.color-div").remove(); d3.select("#imageConverter").selectAll("div.color-div").remove();
colorsSelect.style.display = "block"; colorsSelect.style.display = "block";
colorsUnassigned.style.display = "block"; colorsUnassigned.style.display = "block";
@ -1011,7 +1008,7 @@ function editHeightmap() {
const cmap = MMCQ.quantize(gridColors, count); const cmap = MMCQ.quantize(gridColors, count);
const usedColors = new Set(); const usedColors = new Set();
heights.selectAll("polygon").data(grid.cells.i).join("polygon") viewbox.select("#heights").selectAll("polygon").data(grid.cells.i).join("polygon")
.attr("points", d => getGridPolygon(d)) .attr("points", d => getGridPolygon(d))
.attr("id", d => "cell"+d).attr("fill", d => { .attr("id", d => "cell"+d).attr("fill", d => {
const clr = `rgb(${cmap.nearest(gridColors[d])})`; const clr = `rgb(${cmap.nearest(gridColors[d])})`;
@ -1035,7 +1032,7 @@ function editHeightmap() {
} }
function colorClicked() { function colorClicked() {
heights.selectAll(".selectedCell").attr("class", null); viewbox.select("#heights").selectAll(".selectedCell").attr("class", null);
const unselect = this.classList.contains("selectedColor"); const unselect = this.classList.contains("selectedColor");
const selectedColor = imageConverter.querySelector("div.selectedColor"); const selectedColor = imageConverter.querySelector("div.selectedColor");
@ -1054,8 +1051,8 @@ function editHeightmap() {
} }
const color = this.getAttribute("data-color"); const color = this.getAttribute("data-color");
heights.selectAll("polygon.selectedCell").classed("selectedCell", 0); viewbox.select("#heights").selectAll("polygon.selectedCell").classed("selectedCell", 0);
heights.selectAll("polygon[fill='" + color + "']").classed("selectedCell", 1); viewbox.select("#heights").selectAll("polygon[fill='" + color + "']").classed("selectedCell", 1);
} }
function assignHeight() { function assignHeight() {
@ -1066,7 +1063,7 @@ function editHeightmap() {
selectedColor.setAttribute("data-color", rgb); selectedColor.setAttribute("data-color", rgb);
selectedColor.setAttribute("data-height", height); selectedColor.setAttribute("data-height", height);
heights.selectAll(".selectedCell").each(function() { viewbox.select("#heights").selectAll(".selectedCell").each(function() {
this.setAttribute("fill", rgb); this.setAttribute("fill", rgb);
this.setAttribute("data-height", height); this.setAttribute("data-height", height);
}); });
@ -1090,7 +1087,7 @@ function editHeightmap() {
const colorTo = color(1 - (normalized < .2 ? normalized-.05 : normalized)); const colorTo = color(1 - (normalized < .2 ? normalized-.05 : normalized));
const heightTo = normalized * 100; const heightTo = normalized * 100;
heights.selectAll("polygon[fill='" + colorFrom + "']").attr("fill", colorTo).attr("data-height", heightTo); viewbox.select("#heights").selectAll("polygon[fill='" + colorFrom + "']").attr("fill", colorTo).attr("data-height", heightTo);
el.style.backgroundColor = colorTo; el.style.backgroundColor = colorTo;
el.setAttribute("data-color", colorTo); el.setAttribute("data-color", colorTo);
el.setAttribute("data-height", heightTo); el.setAttribute("data-height", heightTo);
@ -1127,13 +1124,13 @@ function editHeightmap() {
viewbox.style("cursor", "default").on(".drag", null); viewbox.style("cursor", "default").on(".drag", null);
tip('Heightmap edit mode is active. Click on "Exit Customization" to finalize the heightmap', true); tip('Heightmap edit mode is active. Click on "Exit Customization" to finalize the heightmap', true);
heights.selectAll("polygon").each(function() { viewbox.select("#heights").selectAll("polygon").each(function() {
const height = +this.getAttribute("data-height") || 0; const height = +this.getAttribute("data-height") || 0;
const i = +this.id.slice(4); const i = +this.id.slice(4);
grid.cells.h[i] = height; grid.cells.h[i] = height;
}); });
heights.selectAll("polygon").remove(); viewbox.select("#heights").selectAll("polygon").remove();
updateHeightmap(); updateHeightmap();
} }
} }

View file

@ -461,7 +461,9 @@ function drawCells() {
} }
function toggleCultures(event) { function toggleCultures(event) {
if (!cults.selectAll("path").size()) { const cultures = pack.cultures.filter(c => c.i && !c.removed);
const empty = !cults.selectAll("path").size();
if (empty && cultures.length) {
turnButtonOn("toggleCultures"); turnButtonOn("toggleCultures");
drawCultures(); drawCultures();
if (event && event.ctrlKey) editStyle("cults"); if (event && event.ctrlKey) editStyle("cults");
@ -472,7 +474,7 @@ function toggleCultures(event) {
} }
} }
function drawCultures(event) { function drawCultures() {
console.time("drawCultures"); console.time("drawCultures");
cults.selectAll("path").remove(); cults.selectAll("path").remove();
@ -520,7 +522,8 @@ function drawCultures(event) {
} }
function toggleReligions(event) { function toggleReligions(event) {
if (!relig.selectAll("path").size()) { const religions = pack.religions.filter(r => r.i && !r.removed);
if (!relig.selectAll("path").size() && religions.length) {
turnButtonOn("toggleReligions"); turnButtonOn("toggleReligions");
drawReligions(); drawReligions();
if (event && event.ctrlKey) editStyle("relig"); if (event && event.ctrlKey) editStyle("relig");

View file

@ -266,7 +266,7 @@ function drawScaleBar() {
fitScaleBar(); fitScaleBar();
} }
// fit ScaleBar to map size // fit ScaleBar to canvas size
function fitScaleBar() { function fitScaleBar() {
if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return; if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return;
const px = isNaN(+barPosX.value) ? .99 : barPosX.value / 100; const px = isNaN(+barPosX.value) ? .99 : barPosX.value / 100;

View file

@ -133,26 +133,33 @@ function mapSizeInputChange() {
// change svg size on manual size change or window resize, do not change graph size // change svg size on manual size change or window resize, do not change graph size
function changeMapSize() { function changeMapSize() {
svgWidth = +mapWidthInput.value; const svgWidth = Math.min(+mapWidthInput.value, window.innerWidth);
svgHeight = +mapHeightInput.value; const svgHeight = Math.min(+mapHeightInput.value, window.innerHeight);
svg.attr("width", svgWidth).attr("height", svgHeight); svg.attr("width", svgWidth).attr("height", svgHeight);
const width = Math.max(svgWidth, graphWidth);
const height = Math.max(svgHeight, graphHeight); const maxWidth = Math.max(+mapWidthInput.value, graphWidth);
zoom.translateExtent([[0, 0], [width, height]]); const maxHeight = Math.max(+mapHeightInput.value, graphHeight);
landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height); zoom.translateExtent([[0, 0], [maxWidth, maxHeight]]);
oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height); landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
oceanLayers.select("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height); oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
oceanLayers.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
defs.select("#mapClip > rect").attr("width", maxWidth).attr("height", maxHeight);
fitScaleBar(); fitScaleBar();
if (window.fitLegendBox) fitLegendBox(); if (window.fitLegendBox) fitLegendBox();
} }
// just apply map size that was already set, apply graph size! // just apply canvas size that was already set
function applyMapSize() { function applyMapSize() {
svgWidth = graphWidth = +mapWidthInput.value; graphWidth = +mapWidthInput.value;
svgHeight = graphHeight = +mapHeightInput.value; graphHeight = +mapHeightInput.value;
svgWidth = Math.min(graphWidth, window.innerWidth)
svgHeight = Math.min(graphHeight, window.innerHeight)
svg.attr("width", svgWidth).attr("height", svgHeight); svg.attr("width", svgWidth).attr("height", svgHeight);
zoom.translateExtent([[0, 0],[graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1); zoom.translateExtent([[0, 0],[graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1);
viewbox.attr("transform", null); viewbox.attr("transform", null).attr("clip-path", "url(#mapClip)");
defs.append("clipPath").attr("id", "mapClip").append("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
//zoom.translateExtent([[-svgWidth*.2, -graphHeight*.2], [svgWidth*1.2, graphHeight*1.2]]);
} }
function toggleFullscreen() { function toggleFullscreen() {

View file

@ -57,11 +57,12 @@ function editProvinces() {
} }
function collectStatistics() { function collectStatistics() {
const cells = pack.cells, provinces = pack.provinces; const cells = pack.cells, provinces = pack.provinces, burgs = pack.burgs;
provinces.forEach(p => { provinces.forEach(p => {
if (!p.i || p.removed) return; if (!p.i || p.removed) return;
p.area = p.rural = p.urban = 0; p.area = p.rural = p.urban = 0;
p.burgs = []; p.burgs = [];
if (p.burg && !burgs[p.burg] || burgs[p.burg].removed) p.burg = 0;
}); });
for (const i of cells.i) { for (const i of cells.i) {
@ -71,7 +72,7 @@ function editProvinces() {
provinces[p].area += cells.area[i]; provinces[p].area += cells.area[i];
provinces[p].rural += cells.pop[i]; provinces[p].rural += cells.pop[i];
if (!cells.burg[i]) continue; if (!cells.burg[i]) continue;
provinces[p].urban += pack.burgs[cells.burg[i]].population; provinces[p].urban += burgs[cells.burg[i]].population;
provinces[p].burgs.push(cells.burg[i]); provinces[p].burgs.push(cells.burg[i]);
} }

View file

@ -360,6 +360,7 @@ function editReligions() {
// build hierarchy tree // build hierarchy tree
pack.religions[0].origin = null; pack.religions[0].origin = null;
const religions = pack.religions.filter(r => !r.removed); const religions = pack.religions.filter(r => !r.removed);
if (religions.length < 3) {tip("Not enough religions to show hierarchy", false, "error"); return;}
const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(religions); const root = d3.stratify().id(d => d.i).parentId(d => d.origin)(religions);
const treeWidth = root.leaves().length; const treeWidth = root.leaves().length;
const treeHeight = root.height; const treeHeight = root.height;

File diff suppressed because one or more lines are too long

View file

@ -15,10 +15,11 @@ toolsContent.addEventListener("click", function(event) {
if (button === "editCulturesButton") editCultures(); else if (button === "editCulturesButton") editCultures(); else
if (button === "editReligions") editReligions(); else if (button === "editReligions") editReligions(); else
if (button === "editNamesBaseButton") editNamesbase(); else if (button === "editNamesBaseButton") editNamesbase(); else
if (button === "overviewBurgsButton") editBurgs(); else
if (button === "editUnitsButton") editUnits(); else if (button === "editUnitsButton") editUnits(); else
if (button === "editNotesButton") editNotes(); else if (button === "editNotesButton") editNotes(); else
if (button === "editZonesButton") editZones(); if (button === "editZonesButton") editZones(); else
if (button === "overviewBurgsButton") editBurgs(); else
if (button === "overviewCellsButton") viewCellDetails();
// Click to Regenerate buttons // Click to Regenerate buttons
if (event.target.parentNode.id === "regenerateFeature") { if (event.target.parentNode.id === "regenerateFeature") {
@ -90,7 +91,8 @@ function regenerateBurgs() {
rankCells(); rankCells();
cells.burg = new Uint16Array(cells.i.length); cells.burg = new Uint16Array(cells.i.length);
const burgs = pack.burgs = [0]; // clear burgs array const burgs = pack.burgs = [0]; // clear burgs array
states.filter(s => s.i).forEach(s => s.capital = 0); // clear capitals states.filter(s => s.i).forEach(s => s.capital = 0); // clear state capitals
pack.provinces.filter(p => p.i).forEach(p => p.burg = 0); // clear province capitals
const burgsTree = d3.quadtree(); const burgsTree = d3.quadtree();
const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for capitals placement const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for capitals placement
@ -477,4 +479,8 @@ function addMarkerOnClick() {
.attr("data-size", desired).attr("width", size).attr("height", size); .attr("data-size", desired).attr("width", size).attr("height", size);
if (d3.event.shiftKey === false) unpressClickToAddButton(); if (d3.event.shiftKey === false) unpressClickToAddButton();
}
function viewCellDetails() {
$("#cellInfo").dialog({resizable: false, width: "22em", title: "Cell Details"});
} }