mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 02:01:22 +01:00
Merge branch 'master' of https://github.com/Azgaar/Fantasy-Map-Generator into refactor-path-detection
This commit is contained in:
commit
3f863a5ca3
7 changed files with 169 additions and 89 deletions
47
index.html
47
index.html
|
|
@ -1062,6 +1062,13 @@
|
|||
<option value="pointyHex">Hex grid (pointy)</option>
|
||||
<option value="flatHex">Hex grid (flat)</option>
|
||||
<option value="square">Square grid</option>
|
||||
<option value="square45deg">Square 45 degrees grid</option>
|
||||
<option value="squareTruncated">Truncated square grid</option>
|
||||
<option value="squareTetrakis">Tetrakis square grid</option>
|
||||
<option value="triangleHorizontal">Triangle grid (horizontal)</option>
|
||||
<option value="triangleVertical">Triangle grid (vertical)</option>
|
||||
<option value="trihexagonal">Trihexagonal grid</option>
|
||||
<option value="rhombille">Rhombille grid</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -1074,6 +1081,9 @@
|
|||
id="styleGridSizeFriendly"
|
||||
data-tip="Distance between grid cell centers (in map scale)"
|
||||
></output>
|
||||
<a href="https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Scale-and-distance#grids" target="_blank">
|
||||
<span data-tip="Open wiki article scale and distance to know about grid scale" class="icon-info-circled pointer"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
|
@ -1509,7 +1519,9 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Map seed number. Seed produces the same map only if canvas size and options are the same">
|
||||
<tr
|
||||
data-tip="Map seed number. Press 'Enter' to apply. Seed produces the same map only if canvas size and options are the same"
|
||||
>
|
||||
<td>
|
||||
<i
|
||||
data-tip="Show seed history to apply a previous seed"
|
||||
|
|
@ -1575,7 +1587,7 @@
|
|||
|
||||
<tr data-tip="Define current year and era name">
|
||||
<td>
|
||||
<i data-locked="0" id="lock_era" class="icon-lock-open"></i>
|
||||
<i data-locked="0" id="lock_year" data-ids="year,era" class="icon-lock-open"></i>
|
||||
</td>
|
||||
<td>Year and era</td>
|
||||
<td>
|
||||
|
|
@ -3491,7 +3503,8 @@
|
|||
|
||||
<button id="burgEditEmblem" data-tip="Edit emblem" class="icon-shield-alt"></button>
|
||||
<button id="burgTogglePreview" data-tip="Toggle preview" class="icon-map"></button>
|
||||
<button id="burgRelocate" data-tip="Relocate burg" class="icon-target"></button>
|
||||
<button id="burgLocate" data-tip="Zoom map and center view in the burg" class="icon-target"></button>
|
||||
<button id="burgRelocate" data-tip="Relocate burg. Click on map to move the burg" class="icon-map-pin"></button>
|
||||
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
||||
<button id="burgLock" class="icon-lock-open" onmouseover="showElementLockTip(event)"></button>
|
||||
<button
|
||||
|
|
@ -5703,12 +5716,13 @@
|
|||
</p>
|
||||
<p><b>Latitude:</b> <span id="infoLat"></span></p>
|
||||
<p><b>Longitude:</b> <span id="infoLon"></span></p>
|
||||
<p><b>Geozone:</b> <span id="infoGeozone"></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>River:</b> <span id="infoRiver">no</span></p>
|
||||
<p><b>Population:</b> <span id="infoPopulation">0</span></p>
|
||||
<p><b>Elevation:</b> <span id="infoEvelation">0</span></p>
|
||||
<p><b>Elevation:</b> <span id="infoElevation">0</span></p>
|
||||
<p><b>Depth:</b> <span id="infoDepth">0</span></p>
|
||||
<p><b>Temperature:</b> <span id="infoTemp">0</span></p>
|
||||
<p><b>Biome:</b> <span id="infoBiome">n/a</span></p>
|
||||
|
|
@ -7820,6 +7834,27 @@
|
|||
<pattern id="pattern_flatHex" width="43.4" height="25" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 43.4,0 36.2,12.5 43.4,25 M 21.7,12.5 H 36.2 Z M 0,0 H 14.5 L 21.7,12.5 14.5,25 H 0" />
|
||||
</pattern>
|
||||
<pattern id="pattern_square45deg" width="35.355" height="35.355" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 0 0 L 35.355 35.355 M 0 35.355 L 35.355 0" />
|
||||
</pattern>
|
||||
<pattern id="pattern_squareTruncated" width="25" height="25" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 8.33 25 L 0 16.66 V 8.33 L 8.33 0 16.66 0 25 8.33 M 16.66 25 L 25 16.66 L 25 8.33 M 8.33 25 L 16.66 25" />
|
||||
</pattern>
|
||||
<pattern id="pattern_squareTetrakis" width="25" height="25" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 25 0 L 0 0 0 25 M 0 0 L 25 25 M 0 25 L 25 0 M 12.5 0 L 12.5 25 M 0 12.5 L 25 12.5 M 0 25 L 25 25 L 25 0" />
|
||||
</pattern>
|
||||
<pattern id="pattern_triangleHorizontal" width="41.76" height="72.33" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 41.76 36.165 H 0 L 20.88 0 41.76 36.165 20.88 72.33 0 36.165 M 0 0 H 72.33 M 0 72.33 L 41.76 72.33" />
|
||||
</pattern>
|
||||
<pattern id="pattern_triangleVertical" width="72.33" height="41.76" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 36.165 0 L 0 20.88 36.165 41.76 72.33 20.88 36.165 0 V 41.76 M 0 0 V 72.33 M 72.33 0 L 72.33 41.76">
|
||||
</pattern>
|
||||
<pattern id="pattern_trihexagonal" width="25" height="43.4" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 25 10.85 H 0 L 18.85 43.4 25 32.55 H 0 L 18.85 0 25 10.85" />
|
||||
</pattern>
|
||||
<pattern id="pattern_rhombille" width="82.5" height="50" patternUnits="userSpaceOnUse" fill="none">
|
||||
<path d="M 13.8 50 L 0 25 13.8 0 H 41.2 L 27.5 25 41.2 50 55 25 41.2 0 68.8 0 82.5 25 68.8 50 M 0 25 H 27.5 M 55 25 H 82.5 M 13.8 50 H 41.2 L 68.8 50" />
|
||||
</pattern>
|
||||
</g>
|
||||
|
||||
<g id="defs-hatching">
|
||||
|
|
@ -7984,7 +8019,7 @@
|
|||
<script src="libs/indexedDB.js?v=1.99.00"></script>
|
||||
|
||||
<script src="utils/shorthands.js?v=1.99.00"></script>
|
||||
<script src="utils/commonUtils.js?v=1.99.00"></script>
|
||||
<script src="utils/commonUtils.js?v=1.103.0"></script>
|
||||
<script src="utils/arrayUtils.js?v=1.99.00"></script>
|
||||
<script src="utils/functionUtils.js?v=1.99.00"></script>
|
||||
<script src="utils/colorUtils.js?v=1.99.00"></script>
|
||||
|
|
@ -8053,7 +8088,7 @@
|
|||
<script defer src="modules/ui/rivers-editor.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/rivers-creator.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/relief-editor.js?v=1.99.00"></script>
|
||||
<script defer src="modules/ui/burg-editor.js?v=1.100.00"></script>
|
||||
<script defer src="modules/ui/burg-editor.js?v=1.102.00"></script>
|
||||
<script defer src="modules/ui/units-editor.js?v=1.104.0"></script>
|
||||
<script defer src="modules/ui/notes-editor.js?v=1.99.06"></script>
|
||||
<script defer src="modules/ui/ai-generator.js?v=1.99.09"></script>
|
||||
|
|
|
|||
5
main.js
5
main.js
|
|
@ -1212,7 +1212,8 @@ function showStatistics() {
|
|||
|
||||
const stats = ` Seed: ${seed}
|
||||
Canvas size: ${graphWidth}x${graphHeight} px
|
||||
Heightmap: ${heightmap} (${isRandomTemplate}${heightmapType})
|
||||
Heightmap: ${heightmap}
|
||||
Template: ${isRandomTemplate}${heightmapType}
|
||||
Points: ${grid.points.length}
|
||||
Cells: ${pack.cells.i.length}
|
||||
Map size: ${mapSizeOutput.value}%
|
||||
|
|
@ -1220,7 +1221,7 @@ function showStatistics() {
|
|||
Provinces: ${pack.provinces.length - 1}
|
||||
Burgs: ${pack.burgs.length - 1}
|
||||
Religions: ${pack.religions.length - 1}
|
||||
Culture set: ${culturesSet.selectedOptions[0].innerText}
|
||||
Culture set: ${culturesSet.value}
|
||||
Cultures: ${pack.cultures.length - 1}`;
|
||||
|
||||
mapId = Date.now(); // unique map id is it's creation date number
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
// Functions to load and parse .map/.gz files
|
||||
async function quickLoad() {
|
||||
const blob = await ldb.get("lastMap");
|
||||
|
|
@ -109,19 +110,23 @@ function uploadMap(file, callback) {
|
|||
fileReader.onloadend = async function (fileLoadedEvent) {
|
||||
if (callback) callback();
|
||||
byId("coas").innerHTML = ""; // remove auto-generated emblems
|
||||
|
||||
const result = fileLoadedEvent.target.result;
|
||||
const [mapData, mapVersion] = await parseLoadedResult(result);
|
||||
const {mapData, mapVersion} = await parseLoadedResult(result);
|
||||
|
||||
const isInvalid = !mapData || !isValidVersion(mapVersion) || mapData.length < 26 || !mapData[5];
|
||||
const isUpdated = compareVersions(mapVersion, VERSION).isEqual;
|
||||
const isAncient = compareVersions(mapVersion, "0.7.0").isOlder;
|
||||
const isNewer = compareVersions(mapVersion, VERSION).isNewer;
|
||||
const isOutdated = compareVersions(mapVersion, VERSION).isOlder;
|
||||
|
||||
if (isInvalid) return showUploadMessage("invalid", mapData, mapVersion);
|
||||
|
||||
const isUpdated = compareVersions(mapVersion, VERSION).isEqual;
|
||||
if (isUpdated) return showUploadMessage("updated", mapData, mapVersion);
|
||||
|
||||
const isAncient = compareVersions(mapVersion, "0.70.0").isOlder;
|
||||
if (isAncient) return showUploadMessage("ancient", mapData, mapVersion);
|
||||
|
||||
const isNewer = compareVersions(mapVersion, VERSION).isNewer;
|
||||
if (isNewer) return showUploadMessage("newer", mapData, mapVersion);
|
||||
|
||||
const isOutdated = compareVersions(mapVersion, VERSION).isOlder;
|
||||
if (isOutdated) return showUploadMessage("outdated", mapData, mapVersion);
|
||||
};
|
||||
|
||||
|
|
@ -151,16 +156,16 @@ async function parseLoadedResult(result) {
|
|||
const isDelimited = resultAsString.substring(0, 10).includes("|");
|
||||
const decoded = isDelimited ? resultAsString : decodeURIComponent(atob(resultAsString));
|
||||
|
||||
const mapData = decoded.split("\r\n");
|
||||
const mapVersionString = mapData[0].split("|")[0] || mapData[0] || "";
|
||||
return [mapData, mapVersionString];
|
||||
const mapData = decoded.split("\r\n"); // split by CRLF
|
||||
const mapVersion = parseMapVersion(mapData[0].split("|")[0] || mapData[0] || "");
|
||||
|
||||
return {mapData, mapVersion};
|
||||
} catch (error) {
|
||||
// map file can be compressed with gzip
|
||||
const uncompressedData = await uncompress(result);
|
||||
const uncompressedData = await uncompress(result); // file can be gzip compressed
|
||||
if (uncompressedData) return parseLoadedResult(uncompressedData);
|
||||
|
||||
ERROR && console.error(error);
|
||||
return [null, null];
|
||||
return {mapData: null, mapVersion: null};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,21 +209,19 @@ async function parseLoadedData(data, mapVersion) {
|
|||
customization = 0;
|
||||
if (customizationMenu.offsetParent) styleTab.click();
|
||||
|
||||
const params = data[0].split("|");
|
||||
void (function parseParameters() {
|
||||
{
|
||||
const params = data[0].split("|");
|
||||
if (params[3]) {
|
||||
seed = params[3];
|
||||
optionsSeed.value = seed;
|
||||
}
|
||||
INFO && console.group("Loaded Map " + seed);
|
||||
} else INFO && console.group("Loaded Map");
|
||||
if (params[4]) graphWidth = +params[4];
|
||||
if (params[5]) graphHeight = +params[5];
|
||||
mapId = params[6] ? +params[6] : Date.now();
|
||||
})();
|
||||
}
|
||||
|
||||
INFO && console.group("Loaded Map " + seed);
|
||||
|
||||
// TODO: move all to options object
|
||||
void (function parseSettings() {
|
||||
{
|
||||
const settings = data[1].split("|");
|
||||
if (settings[0]) applyOption(distanceUnitInput, settings[0]);
|
||||
if (settings[1]) distanceScale = distanceScaleInput.value = settings[1];
|
||||
|
|
@ -242,16 +245,16 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (settings[23]) rescaleLabels.checked = +settings[23];
|
||||
if (settings[24]) urbanDensity = urbanDensityInput.value = +settings[24];
|
||||
if (settings[25]) longitudeInput.value = longitudeOutput.value = minmax(settings[25] || 50, 0, 100);
|
||||
})();
|
||||
}
|
||||
|
||||
void (function applyOptionsToUI() {
|
||||
{
|
||||
stateLabelsModeInput.value = options.stateLabelsMode;
|
||||
yearInput.value = options.year;
|
||||
eraInput.value = options.era;
|
||||
shapeRendering.value = viewbox.attr("shape-rendering") || "geometricPrecision";
|
||||
})();
|
||||
}
|
||||
|
||||
void (function parseConfiguration() {
|
||||
{
|
||||
if (data[2]) mapCoordinates = JSON.parse(data[2]);
|
||||
if (data[4]) notes = JSON.parse(data[4]);
|
||||
if (data[33]) rulers.fromString(data[33]);
|
||||
|
|
@ -267,13 +270,14 @@ async function parseLoadedData(data, mapVersion) {
|
|||
declareFont(usedFont);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const biomes = data[3].split("|");
|
||||
biomesData = Biomes.getDefault();
|
||||
biomesData.color = biomes[0].split(",");
|
||||
biomesData.habitability = biomes[1].split(",").map(h => +h);
|
||||
biomesData.name = biomes[2].split(",");
|
||||
|
||||
// push custom biomes if any
|
||||
for (let i = biomesData.i.length; i < biomesData.name.length; i++) {
|
||||
biomesData.i.push(biomesData.i.length);
|
||||
|
|
@ -281,14 +285,14 @@ async function parseLoadedData(data, mapVersion) {
|
|||
biomesData.icons.push([]);
|
||||
biomesData.cost.push(50);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
void (function replaceSVG() {
|
||||
{
|
||||
svg.remove();
|
||||
document.body.insertAdjacentHTML("afterbegin", data[5]);
|
||||
})();
|
||||
}
|
||||
|
||||
void (function redefineElements() {
|
||||
{
|
||||
svg = d3.select("#map");
|
||||
defs = svg.select("#deftemp");
|
||||
viewbox = svg.select("#viewbox");
|
||||
|
|
@ -338,36 +342,31 @@ async function parseLoadedData(data, mapVersion) {
|
|||
fogging = viewbox.select("#fogging");
|
||||
debug = viewbox.select("#debug");
|
||||
burgLabels = labels.select("#burgLabels");
|
||||
})();
|
||||
|
||||
void (function addMissingElements() {
|
||||
if (!texture.size()) {
|
||||
texture = viewbox
|
||||
.insert("g", "#landmass")
|
||||
.attr("id", "texture")
|
||||
.attr("data-href", "./images/textures/plaster.jpg");
|
||||
}
|
||||
|
||||
if (!emblems.size()) {
|
||||
emblems = viewbox.insert("g", "#labels").attr("id", "emblems").style("display", "none");
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
void (function parseGridData() {
|
||||
{
|
||||
grid = JSON.parse(data[6]);
|
||||
|
||||
const {cells, vertices} = calculateVoronoi(grid.points, grid.boundary);
|
||||
grid.cells = cells;
|
||||
grid.vertices = vertices;
|
||||
|
||||
grid.cells.h = Uint8Array.from(data[7].split(","));
|
||||
grid.cells.prec = Uint8Array.from(data[8].split(","));
|
||||
grid.cells.f = Uint16Array.from(data[9].split(","));
|
||||
grid.cells.t = Int8Array.from(data[10].split(","));
|
||||
grid.cells.temp = Int8Array.from(data[11].split(","));
|
||||
})();
|
||||
}
|
||||
|
||||
void (function parsePackData() {
|
||||
{
|
||||
reGraph();
|
||||
Features.markupPack();
|
||||
pack.features = JSON.parse(data[12]);
|
||||
|
|
@ -380,22 +379,20 @@ async function parseLoadedData(data, mapVersion) {
|
|||
pack.markers = data[35] ? JSON.parse(data[35]) : [];
|
||||
pack.routes = data[37] ? JSON.parse(data[37]) : [];
|
||||
pack.zones = data[38] ? JSON.parse(data[38]) : [];
|
||||
|
||||
const cells = pack.cells;
|
||||
cells.biome = Uint8Array.from(data[16].split(","));
|
||||
cells.burg = Uint16Array.from(data[17].split(","));
|
||||
cells.conf = Uint8Array.from(data[18].split(","));
|
||||
cells.culture = Uint16Array.from(data[19].split(","));
|
||||
cells.fl = Uint16Array.from(data[20].split(","));
|
||||
cells.pop = Float32Array.from(data[21].split(","));
|
||||
cells.r = Uint16Array.from(data[22].split(","));
|
||||
// data[23] for deprecated cells.road
|
||||
cells.s = Uint16Array.from(data[24].split(","));
|
||||
cells.state = Uint16Array.from(data[25].split(","));
|
||||
cells.religion = data[26] ? Uint16Array.from(data[26].split(",")) : new Uint16Array(cells.i.length);
|
||||
cells.province = data[27] ? Uint16Array.from(data[27].split(",")) : new Uint16Array(cells.i.length);
|
||||
// data[28] for deprecated cells.crossroad
|
||||
cells.routes = data[36] ? JSON.parse(data[36]) : {};
|
||||
pack.cells.biome = Uint8Array.from(data[16].split(","));
|
||||
pack.cells.burg = Uint16Array.from(data[17].split(","));
|
||||
pack.cells.conf = Uint8Array.from(data[18].split(","));
|
||||
pack.cells.culture = Uint16Array.from(data[19].split(","));
|
||||
pack.cells.fl = Uint16Array.from(data[20].split(","));
|
||||
pack.cells.pop = Float32Array.from(data[21].split(","));
|
||||
pack.cells.r = Uint16Array.from(data[22].split(","));
|
||||
// data[23] had deprecated cells.road
|
||||
pack.cells.s = Uint16Array.from(data[24].split(","));
|
||||
pack.cells.state = Uint16Array.from(data[25].split(","));
|
||||
pack.cells.religion = data[26] ? Uint16Array.from(data[26].split(",")) : new Uint16Array(pack.cells.i.length);
|
||||
pack.cells.province = data[27] ? Uint16Array.from(data[27].split(",")) : new Uint16Array(pack.cells.i.length);
|
||||
// data[28] had deprecated cells.crossroad
|
||||
pack.cells.routes = data[36] ? JSON.parse(data[36]) : {};
|
||||
|
||||
if (data[31]) {
|
||||
const namesDL = data[31].split("/");
|
||||
|
|
@ -406,9 +403,9 @@ async function parseLoadedData(data, mapVersion) {
|
|||
nameBases[i] = {name: e[0], min: e[1], max: e[2], d: e[3], m: e[4], b};
|
||||
});
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
void (function restoreLayersState() {
|
||||
{
|
||||
const isVisible = selection => selection.node() && selection.style("display") !== "none";
|
||||
const isVisibleNode = node => node && node.style.display !== "none";
|
||||
const hasChildren = selection => selection.node()?.hasChildNodes();
|
||||
|
|
@ -451,14 +448,14 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (isVisibleNode(byId("vignette"))) turnOn("toggleVignette");
|
||||
|
||||
getCurrentPreset();
|
||||
})();
|
||||
}
|
||||
|
||||
void (function restoreEvents() {
|
||||
{
|
||||
scaleBar.on("mousemove", () => tip("Click to open Units Editor")).on("click", () => editUnits());
|
||||
legend
|
||||
.on("mousemove", () => tip("Drag to change the position. Click to hide the legend"))
|
||||
.on("click", () => clearLegend());
|
||||
})();
|
||||
}
|
||||
|
||||
{
|
||||
// dynamically import and run auto-update script
|
||||
|
|
@ -480,7 +477,7 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (textureHref) updateTextureSelectValue(textureHref);
|
||||
}
|
||||
|
||||
void (function checkDataIntegrity() {
|
||||
{
|
||||
const cells = pack.cells;
|
||||
|
||||
if (pack.cells.i.length !== pack.cells.state.length) {
|
||||
|
|
@ -685,20 +682,25 @@ async function parseLoadedData(data, mapVersion) {
|
|||
// sort markers by index
|
||||
pack.markers.sort((a, b) => a.i - b.i);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
fitMapToScreen();
|
||||
{
|
||||
// remove href from emblems, to trigger rendering on load
|
||||
emblems.selectAll("use").attr("href", null);
|
||||
}
|
||||
|
||||
// remove href from emblems, to trigger rendering on load
|
||||
emblems.selectAll("use").attr("href", null);
|
||||
{
|
||||
// draw data layers (not kept in svg)
|
||||
if (rulers && layerIsOn("toggleRulers")) rulers.draw();
|
||||
if (layerIsOn("toggleGrid")) drawGrid();
|
||||
}
|
||||
|
||||
// draw data layers (no kept in svg)
|
||||
if (rulers && layerIsOn("toggleRulers")) rulers.draw();
|
||||
if (layerIsOn("toggleGrid")) drawGrid();
|
||||
|
||||
if (window.restoreDefaultEvents) restoreDefaultEvents();
|
||||
focusOn(); // based on searchParams focus on point, cell or burg
|
||||
invokeActiveZooming();
|
||||
{
|
||||
if (window.restoreDefaultEvents) restoreDefaultEvents();
|
||||
focusOn(); // based on searchParams focus on point, cell or burg
|
||||
invokeActiveZooming();
|
||||
fitMapToScreen();
|
||||
}
|
||||
|
||||
WARN && console.warn(`TOTAL: ${rn((performance.now() - uploadMap.timeStart) / 1000, 2)}s`);
|
||||
showStatistics();
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ window.Markers = (function () {
|
|||
while (quantity && candidates.length) {
|
||||
const [cell] = extractAnyElement(candidates);
|
||||
const marker = addMarker({icon, type, dx, dy, px}, {cell});
|
||||
if (!marker) continue;
|
||||
add("marker" + marker.i, cell);
|
||||
quantity--;
|
||||
}
|
||||
|
|
@ -150,6 +151,7 @@ window.Markers = (function () {
|
|||
}
|
||||
|
||||
function addMarker(base, marker) {
|
||||
if (marker.cell === undefined) return;
|
||||
const i = last(pack.markers)?.i + 1 || 0;
|
||||
const [x, y] = getMarkerCoordinates(marker.cell);
|
||||
marker = {...base, x, y, ...marker, i};
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ function editBurg(id) {
|
|||
byId("burgEmblem").addEventListener("click", openEmblemEdit);
|
||||
byId("burgTogglePreview").addEventListener("click", toggleBurgPreview);
|
||||
byId("burgEditEmblem").addEventListener("click", openEmblemEdit);
|
||||
byId("burgLocate").addEventListener("click", zoomIntoBurg);
|
||||
byId("burgRelocate").addEventListener("click", toggleRelocateBurg);
|
||||
byId("burglLegend").addEventListener("click", editBurgLegend);
|
||||
byId("burgLock").addEventListener("click", toggleBurgLockButton);
|
||||
|
|
@ -397,6 +398,14 @@ function editBurg(id) {
|
|||
byId("burgTogglePreview").className = options.showBurgPreview ? "icon-map" : "icon-map-o";
|
||||
}
|
||||
|
||||
function zoomIntoBurg() {
|
||||
const id = +elSelected.attr("data-id");
|
||||
const burg = pack.burgs[id];
|
||||
const x = burg.x;
|
||||
const y = burg.y;
|
||||
zoomTo(x, y, 8, 2000);
|
||||
}
|
||||
|
||||
function toggleRelocateBurg() {
|
||||
const toggler = byId("toggleCells");
|
||||
byId("burgRelocate").classList.toggle("pressed");
|
||||
|
|
|
|||
|
|
@ -259,10 +259,11 @@ function updateCellInfo(point, i, g) {
|
|||
const f = cells.f[i];
|
||||
infoLat.innerHTML = toDMS(getLatitude(y, 4), "lat");
|
||||
infoLon.innerHTML = toDMS(getLongitude(x, 4), "lon");
|
||||
infoGeozone.innerHTML = getGeozone(getLatitude(y, 4));
|
||||
|
||||
infoCell.innerHTML = i;
|
||||
infoArea.innerHTML = cells.area[i] ? si(getArea(cells.area[i])) + " " + getAreaUnit() : "n/a";
|
||||
infoEvelation.innerHTML = getElevation(pack.features[f], pack.cells.h[i]);
|
||||
infoElevation.innerHTML = getElevation(pack.features[f], pack.cells.h[i]);
|
||||
infoDepth.innerHTML = getDepth(pack.features[f], point);
|
||||
infoTemp.innerHTML = convertTemperature(grid.cells.temp[g]);
|
||||
infoPrec.innerHTML = cells.h[i] >= 20 ? getFriendlyPrecipitation(i) : "n/a";
|
||||
|
|
@ -286,6 +287,18 @@ function updateCellInfo(point, i, g) {
|
|||
infoBiome.innerHTML = biomesData.name[cells.biome[i]];
|
||||
}
|
||||
|
||||
function getGeozone(latitude) {
|
||||
if (latitude > 66.5) return "Arctic";
|
||||
if (latitude > 35) return "Temperate North";
|
||||
if (latitude > 23.5) return "Subtropical North";
|
||||
if (latitude > 1) return "Tropical North";
|
||||
if (latitude > -1) return "Equatorial";
|
||||
if (latitude > -23.5) return "Tropical South";
|
||||
if (latitude > -35) return "Subtropical South";
|
||||
if (latitude > -66.5) return "Temperate South";
|
||||
return "Antarctic";
|
||||
}
|
||||
|
||||
// convert coordinate to DMS format
|
||||
function toDMS(coord, c) {
|
||||
const degrees = Math.floor(Math.abs(coord));
|
||||
|
|
@ -429,17 +442,17 @@ function highlightEmblemElement(type, el) {
|
|||
|
||||
// assign lock behavior
|
||||
document.querySelectorAll("[data-locked]").forEach(function (e) {
|
||||
e.addEventListener("mouseover", function (event) {
|
||||
e.addEventListener("mouseover", function (e) {
|
||||
e.stopPropagation();
|
||||
if (this.className === "icon-lock")
|
||||
tip("Click to unlock the option and allow it to be randomized on new map generation");
|
||||
else tip("Click to lock the option and always use the current value on new map generation");
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
e.addEventListener("click", function () {
|
||||
const id = this.id.slice(5);
|
||||
if (this.className === "icon-lock") unlock(id);
|
||||
else lock(id);
|
||||
const ids = this.dataset.ids ? this.dataset.ids.split(",") : [this.id.slice(5)];
|
||||
const fn = this.className === "icon-lock" ? unlock : lock;
|
||||
ids.forEach(fn);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
*
|
||||
* Update the version MANUALLY on each merge to main:
|
||||
* 1. MAJOR version: Incompatible changes that break existing maps
|
||||
* 2. MINOR version: Backwards-compatible changes requiring old .map files to be updated
|
||||
* 3. PATCH version: Backwards-compatible bug fixes not affecting .map file format
|
||||
* 2. MINOR version: Additions or changes that are backward-compatible but may require old .map files to be updated
|
||||
* 3. PATCH version: Backward-compatible bug fixes and small features that do not affect the .map file format
|
||||
*
|
||||
* Example: 1.102.0 -> Major version 1, Minor version 102, Patch version 0
|
||||
* Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2
|
||||
*/
|
||||
const VERSION = "1.104.0";
|
||||
const VERSION = "1.103.5";
|
||||
if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format or parsing function");
|
||||
|
||||
{
|
||||
document.title += " v" + VERSION;
|
||||
|
|
@ -80,6 +81,23 @@ const VERSION = "1.104.0";
|
|||
}
|
||||
}
|
||||
|
||||
function parseMapVersion(version) {
|
||||
let [major, minor, patch] = version.split(".");
|
||||
|
||||
if (patch === undefined) {
|
||||
// e.g. 1.732
|
||||
minor = minor.slice(0, 2);
|
||||
patch = minor.slice(2);
|
||||
}
|
||||
|
||||
// e.g. 0.7b
|
||||
major = parseInt(major) || 0;
|
||||
minor = parseInt(minor) || 0;
|
||||
patch = parseInt(patch) || 0;
|
||||
|
||||
return `${major}.${minor}.${patch}`;
|
||||
}
|
||||
|
||||
function isValidVersion(versionString) {
|
||||
if (!versionString) return false;
|
||||
const [major, minor, patch] = versionString.split(".");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue