mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
refactor file save type to .gz and update the data in ui.
This commit is contained in:
parent
3f205cd499
commit
d25f626b8b
9 changed files with 40 additions and 39 deletions
32
index.html
32
index.html
|
|
@ -2329,8 +2329,8 @@
|
||||||
<div id="sticked">
|
<div id="sticked">
|
||||||
<button id="newMapButton" data-tip="Generate a new map based on options" data-shortcut="F2">New Map</button>
|
<button id="newMapButton" data-tip="Generate a new map based on options" data-shortcut="F2">New Map</button>
|
||||||
<button id="exportButton" data-tip="Select format to download image or export map data">Export</button>
|
<button id="exportButton" data-tip="Select format to download image or export map data">Export</button>
|
||||||
<button id="saveButton" data-tip="Save fully-functional map in .map format">Save</button>
|
<button id="saveButton" data-tip="Save fully-functional map in .gz format">Save</button>
|
||||||
<button id="loadButton" data-tip="Load fully-functional map in .map format">Load</button>
|
<button id="loadButton" data-tip="Load fully-functional map in .gz or .map format">Load</button>
|
||||||
<button id="zoomReset" data-tip="Reset map zoom" data-shortcut="0 (zero)">Reset Zoom</button>
|
<button id="zoomReset" data-tip="Reset map zoom" data-shortcut="0 (zero)">Reset Zoom</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5884,10 +5884,10 @@
|
||||||
<div id="saveMapData" style="display: none" class="dialog">
|
<div id="saveMapData" style="display: none" class="dialog">
|
||||||
<div style="margin-top: 0.3em">
|
<div style="margin-top: 0.3em">
|
||||||
<strong>Save map to</strong>
|
<strong>Save map to</strong>
|
||||||
<button onclick="downloadMap()" data-tip="Download .map file to your local disk" data-shortcut="Ctrl + S">
|
<button onclick="downloadMap()" data-tip="Download .gz file to your local disk" data-shortcut="Ctrl + S">
|
||||||
machine
|
machine
|
||||||
</button>
|
</button>
|
||||||
<button onclick="saveToDropbox()" data-tip="Save .map file to your Dropbox" data-shortcut="Ctrl + C">
|
<button onclick="saveToDropbox()" data-tip="Save .gz file to your Dropbox" data-shortcut="Ctrl + C">
|
||||||
dropbox
|
dropbox
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -5899,8 +5899,8 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
Maps are saved in <i>.map</i> format, that can be loaded back via the <i>Load</i> in menu. There is no way to
|
Maps are saved in <i>.gz</i> format, that can be loaded back via the <i>Load</i> in menu. There is no way to
|
||||||
restore the progress if file is lost. Please keep old <i>.map</i> files on your machine or cloud storage as
|
restore the progress if file is lost. Please keep old <i>.gz or .map</i> files on your machine or cloud storage as
|
||||||
backups.
|
backups.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5908,8 +5908,8 @@
|
||||||
<div id="loadMapData" style="display: none" class="dialog">
|
<div id="loadMapData" style="display: none" class="dialog">
|
||||||
<div>
|
<div>
|
||||||
<strong>Load map from</strong>
|
<strong>Load map from</strong>
|
||||||
<button onclick="mapToLoad.click()" data-tip="Load .map file from your local disk">machine</button>
|
<button onclick="mapToLoad.click()" data-tip="Load .gz or .map file from your local disk">machine</button>
|
||||||
<button onclick="loadURL()" data-tip="Load .map file from URL (server should allow CORS)">URL</button>
|
<button onclick="loadURL()" data-tip="Load .gz or .map file from URL (server should allow CORS)">URL</button>
|
||||||
<button onclick="quickLoad()" data-tip="Load map from browser storage (if saved before)">storage</button>
|
<button onclick="quickLoad()" data-tip="Load map from browser storage (if saved before)">storage</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="loadFromDropbox">
|
<div id="loadFromDropbox">
|
||||||
|
|
@ -5926,7 +5926,7 @@
|
||||||
|
|
||||||
<select id="loadFromDropboxSelect" style="width: 22em"></select>
|
<select id="loadFromDropboxSelect" style="width: 22em"></select>
|
||||||
<div id="loadFromDropboxButtons" style="margin-bottom: 0.6em">
|
<div id="loadFromDropboxButtons" style="margin-bottom: 0.6em">
|
||||||
<button onclick="loadFromDropbox()" data-tip="Load .map file from your Dropbox">Load</button>
|
<button onclick="loadFromDropbox()" data-tip="Load .gz or .map file from your Dropbox">Load</button>
|
||||||
<button
|
<button
|
||||||
onclick="createSharableDropboxLink()"
|
onclick="createSharableDropboxLink()"
|
||||||
data-tip="Select file and create a link to share with your friends"
|
data-tip="Select file and create a link to share with your friends"
|
||||||
|
|
@ -5995,7 +5995,7 @@
|
||||||
<div id="resampleDialog" style="display: none" class="dialog">
|
<div id="resampleDialog" style="display: none" class="dialog">
|
||||||
<div style="width: 34em; max-width: 80vw; font-weight: bold; padding: 6px">
|
<div style="width: 34em; max-width: 80vw; font-weight: bold; padding: 6px">
|
||||||
This operation is destructive and irreversible. It will create a completely new map based on the current one.
|
This operation is destructive and irreversible. It will create a completely new map based on the current one.
|
||||||
Don't forget to save the current project as a .map file first!
|
Don't forget to save the current project as a .gz file first!
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
@ -6116,10 +6116,10 @@
|
||||||
data-main="Сlick the arrow button for options. Zoom in to see the map in details"
|
data-main="Сlick the arrow button for options. Zoom in to see the map in details"
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
<div id="mapOverlay" style="display: none">Drop a .map file to open</div>
|
<div id="mapOverlay" style="display: none">Drop a .gz or .map file to open</div>
|
||||||
|
|
||||||
<div id="fileInputs" style="display: none">
|
<div id="fileInputs" style="display: none">
|
||||||
<input type="file" accept=".map" id="mapToLoad" />
|
<input type="file" accept=".map,.gz" id="mapToLoad" />
|
||||||
<input type="file" accept=".txt,.csv" id="burgsListToLoad" />
|
<input type="file" accept=".txt,.csv" id="burgsListToLoad" />
|
||||||
<input type="file" accept=".txt" id="legendsToLoad" />
|
<input type="file" accept=".txt" id="legendsToLoad" />
|
||||||
<input type="file" accept="image/*" id="imageToLoad" />
|
<input type="file" accept="image/*" id="imageToLoad" />
|
||||||
|
|
@ -7963,15 +7963,15 @@
|
||||||
<script src="modules/ui/stylePresets.js?v=1.89.11"></script>
|
<script src="modules/ui/stylePresets.js?v=1.89.11"></script>
|
||||||
|
|
||||||
<script src="modules/ui/general.js?v=1.87.03"></script>
|
<script src="modules/ui/general.js?v=1.87.03"></script>
|
||||||
<script src="modules/ui/options.js?v=1.91.00"></script>
|
<script src="modules/ui/options.js?v=1.93.00"></script>
|
||||||
<script src="main.js?v=1.92.00"></script>
|
<script src="main.js?v=1.93.00"></script>
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></script>
|
<script defer src="modules/relief-icons.js"></script>
|
||||||
<script defer src="modules/ui/style.js"></script>
|
<script defer src="modules/ui/style.js"></script>
|
||||||
<script defer src="modules/ui/editors.js?v=1.92.00"></script>
|
<script defer src="modules/ui/editors.js?v=1.92.00"></script>
|
||||||
<script defer src="modules/ui/tools.js?v=1.92.00"></script>
|
<script defer src="modules/ui/tools.js?v=1.92.00"></script>
|
||||||
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
||||||
<script defer src="modules/ui/heightmap-editor.js?v=1.92.00"></script>
|
<script defer src="modules/ui/heightmap-editor.js?v=1.93.00"></script>
|
||||||
<script defer src="modules/ui/provinces-editor.js?v=1.92.00"></script>
|
<script defer src="modules/ui/provinces-editor.js?v=1.92.00"></script>
|
||||||
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
|
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
|
||||||
<script defer src="modules/ui/namesbase-editor.js?v=1.89.26"></script>
|
<script defer src="modules/ui/namesbase-editor.js?v=1.89.26"></script>
|
||||||
|
|
@ -8001,7 +8001,7 @@
|
||||||
<script defer src="modules/ui/markers-editor.js"></script>
|
<script defer src="modules/ui/markers-editor.js"></script>
|
||||||
<script defer src="modules/ui/3d.js?v=1.89.36"></script>
|
<script defer src="modules/ui/3d.js?v=1.89.36"></script>
|
||||||
<script defer src="modules/ui/submap.js?v=1.92.00"></script>
|
<script defer src="modules/ui/submap.js?v=1.92.00"></script>
|
||||||
<script defer src="modules/ui/hotkeys.js?v=1.88.00"></script>
|
<script defer src="modules/ui/hotkeys.js?v=1.93.00"></script>
|
||||||
<script defer src="modules/coa-renderer.js?v=1.91.00"></script>
|
<script defer src="modules/coa-renderer.js?v=1.91.00"></script>
|
||||||
<script defer src="libs/rgbquant.min.js"></script>
|
<script defer src="libs/rgbquant.min.js"></script>
|
||||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||||
|
|
|
||||||
10
main.js
10
main.js
|
|
@ -270,7 +270,7 @@ async function checkLoadParameters() {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
const params = url.searchParams;
|
const params = url.searchParams;
|
||||||
|
|
||||||
// of there is a valid maplink, try to load .map file from URL
|
// of there is a valid maplink, try to load .gz/.map file from URL
|
||||||
if (params.get("maplink")) {
|
if (params.get("maplink")) {
|
||||||
WARN && console.warn("Load map from URL");
|
WARN && console.warn("Load map from URL");
|
||||||
const maplink = params.get("maplink");
|
const maplink = params.get("maplink");
|
||||||
|
|
@ -574,9 +574,9 @@ void (function addDragToUpload() {
|
||||||
overlay.style.display = "none";
|
overlay.style.display = "none";
|
||||||
if (e.dataTransfer.items == null || e.dataTransfer.items.length !== 1) return; // no files or more than one
|
if (e.dataTransfer.items == null || e.dataTransfer.items.length !== 1) return; // no files or more than one
|
||||||
const file = e.dataTransfer.items[0].getAsFile();
|
const file = e.dataTransfer.items[0].getAsFile();
|
||||||
if (file.name.indexOf(".map") == -1) {
|
if (!file.name.endsWith(".map") && !file.name.endsWith(".gz")) {
|
||||||
// not a .map file
|
// not a .gz/.map file
|
||||||
alertMessage.innerHTML = "Please upload a <b>.map</b> file you have previously downloaded";
|
alertMessage.innerHTML = "Please upload a <b>.gz or .map</b> file you have previously downloaded";
|
||||||
$("#alert").dialog({
|
$("#alert").dialog({
|
||||||
resizable: false,
|
resizable: false,
|
||||||
title: "Invalid file format",
|
title: "Invalid file format",
|
||||||
|
|
@ -596,7 +596,7 @@ void (function addDragToUpload() {
|
||||||
if (closeDialogs) closeDialogs();
|
if (closeDialogs) closeDialogs();
|
||||||
uploadMap(file, () => {
|
uploadMap(file, () => {
|
||||||
overlay.style.display = "none";
|
overlay.style.display = "none";
|
||||||
overlay.innerHTML = "Drop a .map file to open";
|
overlay.innerHTML = "Drop a .gz or .map file to open";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// update old .map version to the current one
|
// update old .gz/.map version to the current one
|
||||||
export function resolveVersionConflicts(version) {
|
export function resolveVersionConflicts(version) {
|
||||||
if (version < 1) {
|
if (version < 1) {
|
||||||
// v1.0 added a new religions layer
|
// v1.0 added a new religions layer
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
// Functions to load and parse .map files
|
// Functions to load and parse .gz/.map files
|
||||||
async function quickLoad() {
|
async function quickLoad() {
|
||||||
const blob = await ldb.get("lastMap");
|
const blob = await ldb.get("lastMap");
|
||||||
if (blob) loadMapPrompt(blob);
|
if (blob) loadMapPrompt(blob);
|
||||||
|
|
@ -170,7 +170,7 @@ function showUploadMessage(type, mapData, mapVersion) {
|
||||||
let message, title, canBeLoaded;
|
let message, title, canBeLoaded;
|
||||||
|
|
||||||
if (type === "invalid") {
|
if (type === "invalid") {
|
||||||
message = `The file does not look like a valid <i>.map</i> file.<br>Please check the data format`;
|
message = `The file does not look like a valid <i>.gz or .map</i> file.<br>Please check the data format`;
|
||||||
title = "Invalid file";
|
title = "Invalid file";
|
||||||
canBeLoaded = false;
|
canBeLoaded = false;
|
||||||
} else if (type === "ancient") {
|
} else if (type === "ancient") {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
// functions to save project as .map file
|
// functions to save project as .gz file
|
||||||
|
|
||||||
// prepare map data for saving
|
// prepare map data for saving
|
||||||
function getMapData() {
|
function getMapData() {
|
||||||
|
|
@ -126,7 +126,7 @@ async function compressMapData(mapData){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Download .map file
|
// Download .gz file
|
||||||
async function downloadMap() {
|
async function downloadMap() {
|
||||||
if (customization)
|
if (customization)
|
||||||
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
|
|
@ -136,7 +136,7 @@ async function downloadMap() {
|
||||||
const blob = new Blob([mapData], {type: "text/plain"});
|
const blob = new Blob([mapData], {type: "text/plain"});
|
||||||
const URL = window.URL.createObjectURL(blob);
|
const URL = window.URL.createObjectURL(blob);
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
link.download = getFileName() + ".map";
|
link.download = getFileName() + ".gz";
|
||||||
link.href = URL;
|
link.href = URL;
|
||||||
link.click();
|
link.click();
|
||||||
tip(`${link.download} is saved. Open "Downloads" screen (CTRL + J) to check`, true, "success", 7000);
|
tip(`${link.download} is saved. Open "Downloads" screen (CTRL + J) to check`, true, "success", 7000);
|
||||||
|
|
@ -148,13 +148,13 @@ async function saveToDropbox() {
|
||||||
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
closeDialogs("#alert");
|
closeDialogs("#alert");
|
||||||
const mapData = await compressMapData(getMapData());
|
const mapData = await compressMapData(getMapData());
|
||||||
const filename = getFileName() + ".map";
|
const filename = getFileName() + ".gz";
|
||||||
try {
|
try {
|
||||||
await Cloud.providers.dropbox.save(filename, mapData);
|
await Cloud.providers.dropbox.save(filename, mapData);
|
||||||
tip("Map is saved to your Dropbox", true, "success", 8000);
|
tip("Map is saved to your Dropbox", true, "success", 8000);
|
||||||
} catch (msg) {
|
} catch (msg) {
|
||||||
ERROR && console.error(msg);
|
ERROR && console.error(msg);
|
||||||
tip("Cannot save .map to your Dropbox", true, "error", 8000);
|
tip("Cannot save .gz to your Dropbox", true, "error", 8000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,19 +188,19 @@ async function quickSave() {
|
||||||
const mapData = await compressMapData(getMapData());
|
const mapData = await compressMapData(getMapData());
|
||||||
const blob = new Blob([mapData], {type: "text/plain"});
|
const blob = new Blob([mapData], {type: "text/plain"});
|
||||||
await ldb.set("lastMap", blob); // auto-save map
|
await ldb.set("lastMap", blob); // auto-save map
|
||||||
tip("Map is saved to browser memory. Please also save as .map file to secure progress", true, "success", 2000);
|
tip("Map is saved to browser memory. Please also save as .gz file to secure progress", true, "success", 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveReminder = function () {
|
const saveReminder = function () {
|
||||||
if (localStorage.getItem("noReminder")) return;
|
if (localStorage.getItem("noReminder")) return;
|
||||||
const message = [
|
const message = [
|
||||||
"Please don't forget to save your work as a .map file",
|
"Please don't forget to save your work as a .gz file",
|
||||||
"Please remember to save work as a .map file",
|
"Please remember to save work as a .gz file",
|
||||||
"Saving in .map format will ensure your data won't be lost in case of issues",
|
"Saving in .gz format will ensure your data won't be lost in case of issues",
|
||||||
"Safety is number one priority. Please save the map",
|
"Safety is number one priority. Please save the map",
|
||||||
"Don't forget to save your map on a regular basis!",
|
"Don't forget to save your map on a regular basis!",
|
||||||
"Just a gentle reminder for you to save the map",
|
"Just a gentle reminder for you to save the map",
|
||||||
"Please don't forget to save your progress (saving as .map is the best option)",
|
"Please don't forget to save your progress (saving as .gz is the best option)",
|
||||||
"Don't want to be reminded about need to save? Press CTRL+Q"
|
"Don't want to be reminded about need to save? Press CTRL+Q"
|
||||||
];
|
];
|
||||||
const interval = 15 * 60 * 1000; // remind every 15 minutes
|
const interval = 15 * 60 * 1000; // remind every 15 minutes
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ function editHeightmap(options) {
|
||||||
<p><i>Erase</i> mode also allows you Convert an Image into a heightmap or use Template Editor.</p>
|
<p><i>Erase</i> mode also allows you Convert an Image into a heightmap or use Template Editor.</p>
|
||||||
<p>You can <i>keep</i> the data, but you won't be able to change the coastline.</p>
|
<p>You can <i>keep</i> the data, but you won't be able to change the coastline.</p>
|
||||||
<p>Try <i>risk</i> mode to change the coastline and keep the data. The data will be restored as much as possible, but it can cause unpredictable errors.</p>
|
<p>Try <i>risk</i> mode to change the coastline and keep the data. The data will be restored as much as possible, but it can cause unpredictable errors.</p>
|
||||||
<p>Please <span class="pseudoLink" onclick="dowloadMap();">save the map</span> before editing the heightmap!</p>
|
<p>Please <span class="pseudoLink" onclick="downloadMap();">save the map</span> before editing the heightmap!</p>
|
||||||
<p style="margin-bottom: 0">Check out ${link(
|
<p style="margin-bottom: 0">Check out ${link(
|
||||||
"https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization",
|
"https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization",
|
||||||
"wiki"
|
"wiki"
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ function handleKeyup(event) {
|
||||||
else if (code === "Delete") removeElementOnKey();
|
else if (code === "Delete") removeElementOnKey();
|
||||||
else if (code === "KeyO" && document.getElementById("canvas3d")) toggle3dOptions();
|
else if (code === "KeyO" && document.getElementById("canvas3d")) toggle3dOptions();
|
||||||
else if (ctrl && code === "KeyQ") toggleSaveReminder();
|
else if (ctrl && code === "KeyQ") toggleSaveReminder();
|
||||||
else if (ctrl && code === "KeyS") dowloadMap();
|
else if (ctrl && code === "KeyS") downloadMap();
|
||||||
else if (ctrl && code === "KeyC") saveToDropbox();
|
else if (ctrl && code === "KeyC") saveToDropbox();
|
||||||
else if (ctrl && code === "KeyZ" && undo?.offsetParent) undo.click();
|
else if (ctrl && code === "KeyZ" && undo?.offsetParent) undo.click();
|
||||||
else if (ctrl && code === "KeyY" && redo?.offsetParent) redo.click();
|
else if (ctrl && code === "KeyY" && redo?.offsetParent) redo.click();
|
||||||
|
|
|
||||||
|
|
@ -844,8 +844,8 @@ async function connectToDropbox() {
|
||||||
|
|
||||||
function loadURL() {
|
function loadURL() {
|
||||||
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
||||||
const inner = `Provide URL to a .map file:
|
const inner = `Provide URL to a .gz or .map file:
|
||||||
<input id="mapURL" type="url" style="width: 24em" placeholder="https://e-cloud.com/test.map">
|
<input id="mapURL" type="url" style="width: 24em" placeholder="https://e-cloud.com/test.gz">
|
||||||
<br><i>Please note server should allow CORS for file to be loaded. If CORS is not allowed, save file to Dropbox and provide a direct link</i>`;
|
<br><i>Please note server should allow CORS for file to be loaded. If CORS is not allowed, save file to Dropbox and provide a direct link</i>`;
|
||||||
alertMessage.innerHTML = inner;
|
alertMessage.innerHTML = inner;
|
||||||
$("#alert").dialog({
|
$("#alert").dialog({
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,12 @@ const version = "1.93.00"; // generator version, update each time
|
||||||
const discord = "https://discordapp.com/invite/X7E84HU";
|
const discord = "https://discordapp.com/invite/X7E84HU";
|
||||||
const patreon = "https://www.patreon.com/azgaar";
|
const patreon = "https://www.patreon.com/azgaar";
|
||||||
|
|
||||||
alertMessage.innerHTML = /* html */ `The Fantasy Map Generator is updated up to version <strong>${version}</strong>. This version is compatible with <a href="${changelog}" target="_blank">previous versions</a>, loaded <i>.map</i> files will be auto-updated.
|
alertMessage.innerHTML = /* html */ `The Fantasy Map Generator is updated up to version <strong>${version}</strong>. This version is compatible with <a href="${changelog}" target="_blank">previous versions</a>, loaded <i>.gz or .map</i> files will be auto-updated.
|
||||||
${storedVersion ? "<span>Reload the page to fetch fresh code.</span>" : ""}
|
${storedVersion ? "<span>Reload the page to fetch fresh code.</span>" : ""}
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<strong>Latest changes:</strong>
|
<strong>Latest changes:</strong>
|
||||||
|
<li>Map save file extension is changed to .gz, .map files are still loadable</li>
|
||||||
<li>New label placement algorithm for states</li>
|
<li>New label placement algorithm for states</li>
|
||||||
<li>North and South Poles temperature can be set independently</li>
|
<li>North and South Poles temperature can be set independently</li>
|
||||||
<li>More than 70 new heraldic charges</li>
|
<li>More than 70 new heraldic charges</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue