This commit is contained in:
Azgaar 2019-09-04 22:28:51 +03:00
parent 92a50d9810
commit baf23bee37
6 changed files with 122 additions and 63 deletions

View file

@ -1801,7 +1801,13 @@
<p>Join our <a href='https://discordapp.com/invite/X7E84HU' target='_blank'>Discord server</a> and <a href="https://www.reddit.com/r/FantasyMapGenerator/" target="_blank">Reddit community</a> to ask questions, get help and share created maps. You may support the project on <a href='https://www.patreon.com/azgaar' target='_blank'>Patreon</a>.</p>
<p>The project is under active development. For older versions see the <a href="https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog" target="_blank">changelog</a>. To track the development progress see the <a href="https://trello.com/b/7x832DG4/fantasy-map-generator" target="_blank">devboard</a>. Please report bugs <a href="https://github.com/Azgaar/Fantasy-Map-Generator/issues" target="_blank">here</a>. You can also contact me directly via <a href="mailto:maxganiev@yandex.ru" target="_blank">email</a>.</p>
<p>A special thanks to all supporters! <i data-tip="Click to see supporters names" class="collapsible icon-down-open pointer"></i></p>
<p style="display:none">Supporters: Aaron Meyer, Ahmad Amerih, AstralJacks, aymeric, Billy Dean Goehring, Branndon Edwards, Chase Mayers, Curt Flood, cyninge, Dino Princip, E.M. White, es, Fondue, Fritjof Olsson, Gatsu, Johan Fröberg, Jonathan Moore, Joseph Miranda, Kate, KC138, Luke Nelson, Markus Finster, Massimo Vella, Mikey, Nathan Mitchell, Paavi1, Pat, Ryan Westcott, Sasquatch, Shawn Spencer, Sizz_TV, Timothée CALLET, UTG community, Vlad Tomash, Wil Sisney, William Merriott, Xariun, Gun Metal Games, Scott Marner, Spencer Sherman, Valerii Matskevych, Alloyed Clavicle, Stewart Walsh, Ruthlyn Mollett (Javan), Benjamin Mair-Pratt, Diagonath, Alexander Thomas, Ashley Wilson-Savoury, William Henry, Preston Brooks, JOSHUA QUALTIERI and many others!</p>
<p style="display:none">Supporters: Aaron Meyer, Ahmad Amerih, AstralJacks, aymeric, Billy Dean Goehring, Branndon Edwards,
Chase Mayers, Curt Flood, cyninge, Dino Princip, E.M. White, es, Fondue, Fritjof Olsson, Gatsu, Johan Fröberg, Jonathan Moore,
Joseph Miranda, Kate, KC138, Luke Nelson, Markus Finster, Massimo Vella, Mikey, Nathan Mitchell, Paavi1, Pat, Ryan Westcott,
Sasquatch, Shawn Spencer, Sizz_TV, Timothée CALLET, UTG community, Vlad Tomash, Wil Sisney, William Merriott, Xariun,
Gun Metal Games, Scott Marner, Spencer Sherman, Valerii Matskevych, Alloyed Clavicle, Stewart Walsh, Ruthlyn Mollett (Javan),
Benjamin Mair-Pratt, Diagonath, Alexander Thomas, Ashley Wilson-Savoury, William Henry, Preston Brooks, JOSHUA QUALTIERI,
Hilton Williams, Katharina Haase, Hisham Bedri, Ian arless, Karnat, Bird, Kevin and many others!</p>
<ul class="share-buttons">
<li><a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fazgaar.github.io%2FFantasy-Map-Generator%2F&quote=" data-tip="Share on Facebook" target="_blank"><img alt="Share on Facebook" src="images/Facebook.png" /></a></li>
@ -1816,14 +1822,16 @@
<button id="newMapButton" data-tip="Generate a new map based on options. Shortcut: F7">New Map</button>
<button id="saveButton" data-tip="Select file format to save map">Save</button>
<div id="saveDropdown">
<div id="saveMap" data-tip="Save as fully functional map in .map format. Shortcut: Ctrl + M">.map</div>
<div id="saveSVG" data-tip="Download the map as .svg image (open in browser or Inkscape). Shortcut: Ctrl + S">.svg</div>
<div id="savePNG" data-tip="Download visible part of the map as image. Texture will not be shown. Shortcut: Ctrl + P">.png</div>
<div id="saveMap" data-tip="Download the map as fully functional .map file to your machine. Shortcut: Ctrl + M">.map</div>
<div id="saveSVG" data-tip="Download the map as vector image (open in browser or Inkscape). Shortcut: Ctrl + S">.svg</div>
<div id="savePNG" data-tip="Download visible part of the map as .png image. Texture will not be shown. Shortcut: Ctrl + P">.png</div>
<!-- <div id="saveDropbox" data-tip="Save fully functional .map file to Dropbox. Shortcut: Ctrl + B">Dropbox</div> -->
</div>
<button id="loadButton" data-tip="Load fully functional map in a .map format">Load</button>
<div id="loadDropdown">
<div id="loadURL" data-tip="Load .map file from URL: Ctrl + U">from URL</div>
<div id="loadMap" data-tip="Load .map file from local disk. Shortcut: Ctrl + L">from file</div>
<div id="loadMap" data-tip="Load .map file from local disk. Shortcut: Ctrl + L">from disk</div>
<div id="loadURL" data-tip="Load .map file from URL (server should allow CORS). Shortcut: Ctrl + U">from URL</div>
<!-- <div id="loadDropbox" data-tip="Load .map file from Dropbox. Shortcut: Ctrl + D">from Dropbox</div> -->
</div>
<button id="zoomReset" data-tip="Reset map zoom. Shortcut: 0">Reset Zoom</button>
</div>
@ -2976,4 +2984,5 @@
<script defer src="modules/ui/editors.js"></script>
<script defer src="libs/quantize.min.js"></script>
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
<!-- <script defer src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="a0ls5yab5ly1ot5"></script> -->
</body>

View file

@ -395,6 +395,7 @@ function findBurgForMFCG(params) {
if (pack.burgs.length < 2) {console.error("Cannot select a burg for MFCG"); return;}
const size = +params.get("size");
const name = params.get("name");
let coast = +params.get("coast");
let port = +params.get("port");
let river = +params.get("river");
@ -415,14 +416,15 @@ function findBurgForMFCG(params) {
// select a burg with closest population from selection
const selected = d3.scan(selection, (a, b) => Math.abs(a.population - size) - Math.abs(b.population - size));
const b = selection[selected].i;
const b = selection[selected].i;
if (!b) {console.error("Cannot select a burg for MFCG"); return;}
if (size) burgs[b].population = size;
if (name) burgs[b].name = name;
const label = burgLabels.select("[data-id='" + b + "']");
if (label.size()) {
tip("Here stands the glorious city of " + burgs[b].name, true, "success", 10000);
label.classed("drag", true).on("mouseover", function() {
tip("Here stands the glorious city of " + burgs[b].name, true, "success", 12000);
label.text(burgs[b].name).classed("drag", true).on("mouseover", function() {
d3.select(this).classed("drag", false);
label.on("mouseover", null);
});

View file

@ -151,61 +151,69 @@ function GFontToDataURI(url) {
});
}
// Save in .map format
function saveMap() {
if (customization) {tip("Map cannot be saved when is in edit mode, please exit the mode and retry", false, "error"); return;}
// prepare map data for saving
function getMapURL() {
console.time("saveMap");
return new Promise(resolve => {
const date = new Date();
const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator";
const params = [version, license, dateString, seed, graphWidth, graphHeight].join("|");
const options = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value,
barSize.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate.value, urbanization.value,
mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(winds)].join("|");
const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
const notesData = JSON.stringify(notes);
// set transform values to default
svg.attr("width", graphWidth).attr("height", graphHeight);
const transform = d3.zoomTransform(svg.node());
viewbox.attr("transform", null);
const svg_xml = (new XMLSerializer()).serializeToString(svg.node());
// restore initial values
svg.attr("width", svgWidth).attr("height", svgHeight);
zoom.transform(svg, transform);
const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features});
const features = JSON.stringify(pack.features);
const cultures = JSON.stringify(pack.cultures);
const states = JSON.stringify(pack.states);
const burgs = JSON.stringify(pack.burgs);
const religions = JSON.stringify(pack.religions);
const provinces = JSON.stringify(pack.provinces);
// data format as below
const data = [params, options, coords, biomes, notesData, svg_xml,
gridGeneral, grid.cells.h, grid.cells.prec, grid.cells.f, grid.cells.t, grid.cells.temp,
features, cultures, states, burgs,
pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl,
pack.cells.pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state,
pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces].join("\r\n");
const dataBlob = new Blob([data], {type: "text/plain"});
const URL = window.URL.createObjectURL(dataBlob);
console.timeEnd("saveMap");
resolve(URL);
});
}
// Save in .map format
async function saveMap() {
if (customization) {tip("Map cannot be saved when is in edit mode, please exit the mode and retry", false, "error"); return;}
closeDialogs();
const date = new Date();
const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator";
const params = [version, license, dateString, seed, graphWidth, graphHeight].join("|");
const options = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value,
barSize.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate.value, urbanization.value,
mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(winds)].join("|");
const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
const notesData = JSON.stringify(notes);
// set transform values to default
svg.attr("width", graphWidth).attr("height", graphHeight);
const transform = d3.zoomTransform(svg.node());
viewbox.attr("transform", null);
const svg_xml = (new XMLSerializer()).serializeToString(svg.node());
const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features});
const features = JSON.stringify(pack.features);
const cultures = JSON.stringify(pack.cultures);
const states = JSON.stringify(pack.states);
const burgs = JSON.stringify(pack.burgs);
const religions = JSON.stringify(pack.religions);
const provinces = JSON.stringify(pack.provinces);
// data format as below
const data = [params, options, coords, biomes, notesData, svg_xml,
gridGeneral, grid.cells.h, grid.cells.prec, grid.cells.f, grid.cells.t, grid.cells.temp,
features, cultures, states, burgs,
pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl,
pack.cells.pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state,
pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces].join("\r\n");
const dataBlob = new Blob([data], {type: "text/plain"});
const dataURL = window.URL.createObjectURL(dataBlob);
const URL = await getMapURL();
const link = document.createElement("a");
link.download = "fantasy_map_" + Date.now() + ".map";
link.href = dataURL;
link.href = URL;
document.body.appendChild(link);
link.click();
tip(`${link.download} is saved. Open "Downloads" screen (crtl + J) to check`, true, "warning");
// restore initial values
svg.attr("width", svgWidth).attr("height", svgHeight);
zoom.transform(svg, transform);
window.setTimeout(function() {
window.URL.revokeObjectURL(dataURL);
clearMainTip();
}, 3000);
console.timeEnd("saveMap");
tip(`${link.download} is saved. Open "Downloads" screen (crtl + J) to check`, true, "success", 7000);
window.setTimeout(() => window.URL.revokeObjectURL(URL), 5000);
}
function uploadFile(file, callback) {

View file

@ -108,7 +108,7 @@ function editBurgs() {
function getCultureOptions(culture) {
let options = "";
pack.cultures.slice(1).forEach(c => options += `<option ${c.i === culture ? "selected" : ""} value="${c.i}">${c.name}</option>`);
pack.cultures.forEach(c => options += `<option ${c.i === culture ? "selected" : ""} value="${c.i}">${c.name}</option>`);
return options;
}

View file

@ -219,7 +219,7 @@ function editCultures() {
cults.select("#culture"+culture).remove();
debug.select("#cultureCenter"+culture).remove();
pack.burgs.filter(b => b.culture === culture).forEach(b => b.culture = 0);
pack.burgs.filter(b => b.culture == culture).forEach(b => b.culture = 0);
pack.cells.culture.forEach((c, i) => {if(c === culture) pack.cells.culture[i] = 0;});
pack.cultures[culture].removed = true;

View file

@ -997,9 +997,12 @@ document.getElementById("sticked").addEventListener("click", function(event) {
else if (id === "saveMap") saveMap();
else if (id === "saveSVG") saveAsImage("svg");
else if (id === "savePNG") saveAsImage("png");
if (id === "saveMap" || id === "saveSVG" || id === "savePNG") toggleSavePane();
if (id === "loadURL") {loadURL(); toggleLoadPane()}
if (id === "loadMap") {mapToLoad.click(); toggleLoadPane()}
else if (id === "saveDropbox") saveDropbox();
if (id === "saveMap" || id === "saveSVG" || id === "savePNG" || id === "saveDropbox") toggleSavePane();
if (id === "loadMap") mapToLoad.click()
if (id === "loadURL") loadURL();
if (id === "loadDropbox") loadDropbox();
if (id === "loadURL" || id === "loadMap" || id === "loadDropbox") toggleLoadPane();
});
function regeneratePrompt() {
@ -1038,6 +1041,21 @@ function toggleSavePane() {
}
}
// async function saveDropbox() {
// const filename = "fantasy_map_" + Date.now() + ".map";
// const options = {
// files: [{'url': '...', 'filename': 'fantasy_map.map'}],
// success: function () {alert("Success! Files saved to your Dropbox.")},
// progress: function (progress) {console.log(progress)},
// cancel: function (cancel) {console.log(cancel)},
// error: function (error) {console.log(error)}
// };
// // working file: "https://dl.dropbox.com/s/llg93mwyonyzdmu/test.map?dl=1";
// const URL = await getMapURL();
// Dropbox.save(URL, filename, options);
// }
function toggleLoadPane() {
if (loadDropdown.style.display === "block") {loadDropdown.style.display = "none"; return;}
loadDropdown.style.display = "block";
@ -1045,7 +1063,9 @@ function toggleLoadPane() {
function loadURL() {
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
const inner = `Provide URL to a .map file: <input id="mapURL" type="url" style="width: 254px" placeholder="http://www.e-cloud.com/fantasy_map.map"">`;
const inner = `Provide URL to a .map file:
<input id="mapURL" type="url" style="width: 254px" placeholder="https://e-cloud.com/test.map">
<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;
$("#alert").dialog({resizable: false, title: "Load map from URL", width: 280,
buttons: {
@ -1060,6 +1080,26 @@ function loadURL() {
});
}
// function loadDropbox() {
// const options = {
// success: function(file) {send_files(file)},
// cancel: function() {},
// linkType: "preview",
// multiselect: false,
// extensions:['.map'],
// };
// Dropbox.choose(options);
// function send_files(file) {
// const subject = "Shared File Links";
// let body = "";
// for (let i=0; i < file.length; i++) {
// body += file[i].name + "\n" + file[i].link + "\n\n";
// }
// location.href = 'mailto:coworker@example.com?Subject=' + escape(subject) + '&body='+ escape(body),'200','200';
// }
// }
// load map
document.getElementById("mapToLoad").addEventListener("change", function() {
const fileToLoad = this.files[0];