latest version

This commit is contained in:
howlingsails 2022-08-16 18:26:34 -07:00
parent 41432ac944
commit c477c8dfcd
36 changed files with 3979 additions and 832 deletions

BIN
_maps/.DS_Store vendored Normal file

Binary file not shown.

BIN
_maps/working/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
[{"name":"Wildlands","i":0,"base":1,"origin":null,"shield":"round"},{"name":"Dhommeam (Dwarf)","base":35,"shield":"erebor","center":2793,"i":1,"color":"#ffed6f","type":"Highland","expansionism":0.5,"origin":0,"code":"DD"},{"name":"Dunirr (Dwarf)","base":35,"shield":"ironHills","center":5754,"i":2,"color":"#dababf","type":"Generic","expansionism":0.1,"origin":0,"code":"DU"},{"name":"Mudtoe (Dwarf)","base":35,"shield":"erebor","center":183,"i":3,"color":"#ee4395","type":"Highland","expansionism":0.4,"origin":0,"code":"MD"},{"name":"Khazadur (Dwarf)","base":35,"shield":"erebor","center":3542,"i":4,"color":"#eb8de7","type":"Highland","expansionism":0.5,"origin":0,"code":"KD"},{"name":"Yotunn (Giant)","base":38,"shield":"pavise","center":702,"i":5,"color":"#80b1d3","type":"Hunting","expansionism":0.6,"origin":0,"code":"YG"},{"name":"Shazgob (Orc)","base":37,"shield":"moriaOrc","center":5639,"i":6,"color":"#fccde5","type":"Hunting","expansionism":0.7,"origin":0,"code":"SO"},{"name":"Gul (Orc)","base":37,"shield":"moriaOrc","center":6040,"i":7,"color":"#2f96e0","type":"Highland","expansionism":0.5,"origin":0,"code":"GO"},{"name":"Gongrem (Dwarf)","base":35,"shield":"erebor","center":2190,"i":8,"color":"#b3de69","type":"Highland","expansionism":0.3,"origin":0,"code":"GD"},{"name":"Gralcek (Human)","base":16,"shield":"round","center":3704,"i":9,"color":"#bc80bd","type":"Generic","expansionism":0.1,"origin":0,"code":"GH"},{"name":"Fruthos (Human)","base":32,"shield":"fantasy5","center":6517,"i":10,"color":"#ccebc5","type":"River","expansionism":0.4,"origin":0,"code":"FH"},{"name":"Rulor (Human)","base":32,"shield":"roman","center":2763,"i":11,"color":"#ff8c38","type":"Lake","expansionism":0.4,"origin":0,"code":"RH"},{"name":"Mazoga (Orc)","base":37,"shield":"moriaOrc","center":5278,"i":12,"color":"#6e40aa","type":"Highland","expansionism":0.5,"origin":0,"code":"MO"},{"name":"Heenzurm (Goblin)","base":36,"shield":"moriaOrc","center":3211,"i":13,"color":"#28ea8d","type":"Hunting","expansionism":0.9,"origin":0,"code":"HG"},{"name":"Zildud (Orc)","base":37,"shield":"moriaOrc","center":249,"i":14,"color":"#aff05b","type":"Highland","expansionism":0.5,"origin":0,"code":"ZO"},{"name":"Ginikirr (Dwarf)","base":35,"shield":"erebor","center":2794,"i":15,"color":"#8dd3c7","type":"Highland","expansionism":0.4,"origin":0,"code":"GI"},{"name":"Lothian (Elf)","base":33,"shield":"wedged","center":3477,"i":16,"color":"#c6b9c1","type":"River","expansionism":0.4,"origin":0,"code":"LE"},{"name":"Zakaos (Giant)","base":38,"shield":"pavise","center":439,"i":17,"color":"#fdb462","type":"Generic","expansionism":0.1,"origin":0,"code":"ZG"},{"name":"Lagakh (Orc)","base":37,"shield":"urukHai","center":2558,"i":18,"color":"#fb8072","type":"Highland","expansionism":0.5,"origin":0,"code":"LO"}]

View file

@ -0,0 +1 @@
[{"name":"Wildlands","i":0,"base":1,"origin":null,"shield":"round"},{"name":"Dhommeam (Dwarf)","base":35,"shield":"erebor","center":2793,"i":1,"color":"#ffed6f","type":"Highland","expansionism":0.5,"origin":0,"code":"DD"},{"name":"Dunirr (Dwarf)","base":35,"shield":"ironHills","center":5759,"i":2,"color":"#dababf","type":"Generic","expansionism":0.1,"origin":0,"code":"DU"},{"name":"Mudtoe (Dwarf)","base":35,"shield":"erebor","center":603,"i":3,"color":"#ee4395","type":"Highland","expansionism":0.4,"origin":0,"code":"MD"},{"name":"Khazadur (Dwarf)","base":35,"shield":"erebor","center":2608,"i":4,"color":"#eb8de7","type":"Nomadic","expansionism":1.4,"origin":0,"code":"KD"},{"name":"Yotunn (Giant)","base":38,"shield":"pavise","center":701,"i":5,"color":"#80b1d3","type":"River","expansionism":0.3,"origin":0,"code":"YG"},{"name":"Shazgob (Orc)","base":37,"shield":"moriaOrc","center":5644,"i":6,"color":"#fccde5","type":"Hunting","expansionism":0.7,"origin":0,"code":"SO"},{"name":"Gul (Orc)","base":37,"shield":"moriaOrc","center":6045,"i":7,"color":"#2f96e0","type":"Highland","expansionism":0.5,"origin":0,"code":"GO"},{"name":"Gongrem (Dwarf)","base":35,"shield":"erebor","center":2190,"i":8,"color":"#b3de69","type":"Highland","expansionism":0.3,"origin":0,"code":"GD"},{"name":"Gralcek (Human)","base":16,"shield":"round","center":3922,"i":9,"color":"#bc80bd","type":"Hunting","expansionism":0.8,"origin":0,"code":"GH"},{"name":"Fruthos (Human)","base":32,"shield":"fantasy5","center":6399,"i":10,"color":"#ccebc5","type":"Naval","expansionism":0.6,"origin":0,"code":"FH"},{"name":"Rulor (Human)","base":32,"shield":"roman","center":2632,"i":11,"color":"#ff8c38","type":"Nomadic","expansionism":0.9,"origin":0,"code":"RH"},{"name":"Mazoga (Orc)","base":37,"shield":"moriaOrc","center":4222,"i":12,"color":"#6e40aa","type":"Hunting","expansionism":0.9,"origin":0,"code":"MO"},{"name":"Heenzurm (Goblin)","base":36,"shield":"moriaOrc","center":3211,"i":13,"color":"#28ea8d","type":"Hunting","expansionism":0.9,"origin":0,"code":"HG"},{"name":"Zildud (Orc)","base":37,"shield":"moriaOrc","center":5769,"i":14,"color":"#aff05b","type":"Highland","expansionism":0.5,"origin":0,"code":"ZO"},{"name":"Ginikirr (Dwarf)","base":35,"shield":"erebor","center":2794,"i":15,"color":"#8dd3c7","type":"Highland","expansionism":0.4,"origin":0,"code":"GI"},{"name":"Lothian (Elf)","base":33,"shield":"wedged","center":3480,"i":16,"color":"#c6b9c1","type":"River","expansionism":0.4,"origin":0,"code":"LE"},{"name":"Zakaos (Giant)","base":38,"shield":"pavise","center":417,"i":17,"color":"#fdb462","type":"Nomadic","expansionism":1.2,"origin":0,"code":"ZG"},{"name":"Lagakh (Orc)","base":37,"shield":"urukHai","center":2558,"i":18,"color":"#fb8072","type":"Highland","expansionism":0.5,"origin":0,"code":"LO"}]

View file

@ -0,0 +1 @@
[{"name":"Wildlands","i":0,"base":1,"origin":null,"shield":"round"},{"name":"Dhommeam (Dwarf)","base":35,"shield":"erebor","center":2793,"i":1,"color":"#ffed6f","type":"Highland","expansionism":0.5,"origin":0,"code":"DD"},{"name":"Dunirr (Dwarf)","base":35,"shield":"ironHills","center":5754,"i":2,"color":"#dababf","type":"Generic","expansionism":0.1,"origin":0,"code":"DU"},{"name":"Mudtoe (Dwarf)","base":35,"shield":"erebor","center":183,"i":3,"color":"#ee4395","type":"Highland","expansionism":0.4,"origin":0,"code":"MD"},{"name":"Khazadur (Dwarf)","base":35,"shield":"erebor","center":3542,"i":4,"color":"#eb8de7","type":"Highland","expansionism":0.5,"origin":0,"code":"KD"},{"name":"Yotunn (Giant)","base":38,"shield":"pavise","center":702,"i":5,"color":"#80b1d3","type":"Hunting","expansionism":0.6,"origin":0,"code":"YG"},{"name":"Shazgob (Orc)","base":37,"shield":"moriaOrc","center":5639,"i":6,"color":"#fccde5","type":"Hunting","expansionism":0.7,"origin":0,"code":"SO"},{"name":"Gul (Orc)","base":37,"shield":"moriaOrc","center":6040,"i":7,"color":"#2f96e0","type":"Highland","expansionism":0.5,"origin":0,"code":"GO"},{"name":"Gongrem (Dwarf)","base":35,"shield":"erebor","center":2190,"i":8,"color":"#b3de69","type":"Highland","expansionism":0.3,"origin":0,"code":"GD"},{"name":"Gralcek (Human)","base":16,"shield":"round","center":3704,"i":9,"color":"#bc80bd","type":"Generic","expansionism":0.1,"origin":0,"code":"GH"},{"name":"Fruthos (Human)","base":32,"shield":"fantasy5","center":6517,"i":10,"color":"#ccebc5","type":"River","expansionism":0.4,"origin":0,"code":"FH"},{"name":"Rulor (Human)","base":32,"shield":"roman","center":2763,"i":11,"color":"#ff8c38","type":"Lake","expansionism":0.4,"origin":0,"code":"RH"},{"name":"Mazoga (Orc)","base":37,"shield":"moriaOrc","center":5278,"i":12,"color":"#6e40aa","type":"Highland","expansionism":0.5,"origin":0,"code":"MO"},{"name":"Heenzurm (Goblin)","base":36,"shield":"moriaOrc","center":3211,"i":13,"color":"#28ea8d","type":"Hunting","expansionism":0.9,"origin":0,"code":"HG"},{"name":"Zildud (Orc)","base":37,"shield":"moriaOrc","center":249,"i":14,"color":"#aff05b","type":"Highland","expansionism":0.5,"origin":0,"code":"ZO"},{"name":"Ginikirr (Dwarf)","base":35,"shield":"erebor","center":2794,"i":15,"color":"#8dd3c7","type":"Highland","expansionism":0.4,"origin":0,"code":"GI"},{"name":"Lothian (Elf)","base":33,"shield":"wedged","center":3477,"i":16,"color":"#c6b9c1","type":"River","expansionism":0.4,"origin":0,"code":"LE"},{"name":"Zakaos (Giant)","base":38,"shield":"pavise","center":439,"i":17,"color":"#fdb462","type":"Generic","expansionism":0.1,"origin":0,"code":"ZG"},{"name":"Lagakh (Orc)","base":37,"shield":"urukHai","center":2558,"i":18,"color":"#fb8072","type":"Highland","expansionism":0.5,"origin":0,"code":"LO"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
undefined

View file

@ -0,0 +1 @@
undefined

View file

@ -0,0 +1 @@
undefined

View file

@ -0,0 +1 @@
530

View file

@ -0,0 +1 @@
530

View file

@ -0,0 +1 @@
530

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -85,7 +85,7 @@ a {
} }
#prec text { #prec text {
font-size: 32px; font-size: 24px;
stroke: none; stroke: none;
text-shadow: 1px 1px 1px #9daac9; text-shadow: 1px 1px 1px #9daac9;
user-select: none; user-select: none;
@ -297,12 +297,17 @@ i.icon-lock {
} }
} }
#provinceLabels,
#burgLabels { #burgLabels {
dominant-baseline: alphabetic; dominant-baseline: alphabetic;
text-anchor: middle; text-anchor: middle;
font-size: 0.1em;
}
#provinceLabels {
dominant-baseline: alphabetic;
text-anchor: leftOver;
font-size: 0.2em;
text-shadow: 1px 1px #e7ffa1;
} }
#routeLength, #routeLength,
#coastlineArea { #coastlineArea {
background-color: #eeeeee; background-color: #eeeeee;

View file

@ -1046,7 +1046,7 @@
<option value="english" data-max="10">English</option> <option value="english" data-max="10">English</option>
<option value="antique" data-max="10">Antique</option> <option value="antique" data-max="10">Antique</option>
<option value="highFantasy" data-max="17">High Fantasy</option> <option value="highFantasy" data-max="17">High Fantasy</option>
<option value="darkFantasy" data-max="18">Dark Fantasy</option> <option value="darkFantasy" data-max="32">Dark Fantasy</option>
<option value="random" data-max="100">Random</option> <option value="random" data-max="100">Random</option>
</select> </select>
</td> </td>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -6,9 +6,19 @@ function getMapData() {
TIME && console.time("createMapData"); TIME && console.time("createMapData");
const date = new Date(); const date = new Date();
const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); const dateString =
const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator"; date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
const params = [version, license, dateString, seed, graphWidth, graphHeight, mapId].join("|"); const license =
"File can be loaded in azgaar.github.io/Fantasy-Map-Generator";
const params = [
version,
license,
dateString,
seed,
graphWidth,
graphHeight,
mapId,
].join("|");
const settings = [ const settings = [
distanceUnitInput.value, distanceUnitInput.value,
distanceScaleInput.value, distanceScaleInput.value,
@ -34,10 +44,14 @@ function getMapData() {
+hideLabels.checked, +hideLabels.checked,
stylePreset.value, stylePreset.value,
+rescaleLabels.checked, +rescaleLabels.checked,
urbanDensity urbanDensity,
].join("|"); ].join("|");
const coords = JSON.stringify(mapCoordinates); const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|"); const biomes = [
biomesData.color,
biomesData.habitability,
biomesData.name,
].join("|");
const notesData = JSON.stringify(notes); const notesData = JSON.stringify(notes);
const rulersString = rulers.toString(); const rulersString = rulers.toString();
const fonts = JSON.stringify(getUsedFonts(svg.node())); const fonts = JSON.stringify(getUsedFonts(svg.node()));
@ -54,8 +68,15 @@ function getMapData() {
const serializedSVG = new XMLSerializer().serializeToString(cloneEl); const serializedSVG = new XMLSerializer().serializeToString(cloneEl);
const {spacing, cellsX, cellsY, boundary, points, features} = grid; const { spacing, cellsX, cellsY, boundary, points, features } = grid;
const gridGeneral = JSON.stringify({spacing, cellsX, cellsY, boundary, points, features}); const gridGeneral = JSON.stringify({
spacing,
cellsX,
cellsY,
boundary,
points,
features,
});
const packFeatures = JSON.stringify(pack.features); const packFeatures = JSON.stringify(pack.features);
const cultures = JSON.stringify(pack.cultures); const cultures = JSON.stringify(pack.cultures);
const states = JSON.stringify(pack.states); const states = JSON.stringify(pack.states);
@ -75,7 +96,7 @@ function getMapData() {
.join("/"); .join("/");
// round population to save space // round population to save space
const pop = Array.from(pack.cells.pop).map(p => rn(p, 4)); const pop = Array.from(pack.cells.pop).map((p) => rn(p, 4));
// data format as below // data format as below
const mapData = [ const mapData = [
@ -114,31 +135,120 @@ function getMapData() {
rivers, rivers,
rulersString, rulersString,
fonts, fonts,
markers markers,
].join("\r\n"); ].join("\r\n");
TIME && console.timeEnd("createMapData"); TIME && console.timeEnd("createMapData");
return mapData; return mapData;
} }
// Download .map file // Download .map file
function dowloadMap() { function downloadMapOrig() {
if (customization) return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
closeDialogs("#alert");
const mapData = getMapData(); const mapData = getMapData();
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() + ".map";
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); }
function downloadMarkers() {
const mapData = JSON.stringify(pack.markers);
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-markers.json";
link.href = URL;
link.click();
}
function downloadBurgs() {
const mapData = JSON.stringify(pack.burgs);
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-burgs.json";
link.href = URL;
link.click();
}
function downloadReligions() {
const mapData = JSON.stringify(pack.religions);
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-religions.json";
link.href = URL;
link.click();
}
function downloadCultures() {
const mapData = JSON.stringify(pack.cultures);
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-cultures.json";
link.href = URL;
link.click();
}
function downloadStates() {
const mapData = JSON.stringify(pack.states);
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-states.json";
link.href = URL;
link.click();
}
function downloadNotes() {
const mapData = JSON.stringify(pack.notes);
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-notes.json";
link.href = URL;
link.click();
}
function downloadPopRates() {
const mapData = populationRate * urbanization;
const blob = new Blob([mapData], { type: "text/plain" });
const URL = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = getFileName() + "-poprate.txt";
link.href = URL;
link.click();
}
function dowloadMap() {
if (customization)
return tip(
"Map cannot be saved when edit mode is active, please exit the mode and retry",
false,
"error"
);
closeDialogs("#alert");
downloadMapOrig();
downloadMarkers();
downloadBurgs();
downloadCultures();
downloadNotes();
downloadReligions();
downloadPopRates();
downloadStates();
window.URL.revokeObjectURL(URL); window.URL.revokeObjectURL(URL);
} }
async function saveToDropbox() { async function saveToDropbox() {
if (customization) return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error"); if (customization)
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 = getMapData(); const mapData = getMapData();
const filename = getFileName() + ".map"; const filename = getFileName() + ".map";
@ -152,12 +262,22 @@ async function saveToDropbox() {
} }
function quickSave() { function quickSave() {
if (customization) return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error"); if (customization)
return tip(
"Map cannot be saved when edit mode is active, please exit the mode and retry",
false,
"error"
);
const mapData = getMapData(); const mapData = getMapData();
const blob = new Blob([mapData], {type: "text/plain"}); const blob = new Blob([mapData], { type: "text/plain" });
if (blob) ldb.set("lastMap", blob); // auto-save map if (blob) 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 .map file to secure progress",
true,
"success",
2000
);
} }
const saveReminder = function () { const saveReminder = function () {
@ -170,7 +290,7 @@ const saveReminder = function () {
"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 .map 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
@ -184,12 +304,22 @@ saveReminder();
function toggleSaveReminder() { function toggleSaveReminder() {
if (saveReminder.status) { if (saveReminder.status) {
tip("Save reminder is turned off. Press CTRL+Q again to re-initiate", true, "warn", 2000); tip(
"Save reminder is turned off. Press CTRL+Q again to re-initiate",
true,
"warn",
2000
);
clearInterval(saveReminder.reminder); clearInterval(saveReminder.reminder);
localStorage.setItem("noReminder", true); localStorage.setItem("noReminder", true);
saveReminder.status = 0; saveReminder.status = 0;
} else { } else {
tip("Save reminder is turned on. Press CTRL+Q to turn off", true, "warn", 2000); tip(
"Save reminder is turned on. Press CTRL+Q to turn off",
true,
"warn",
2000
);
localStorage.removeItem("noReminder"); localStorage.removeItem("noReminder");
saveReminder(); saveReminder();
} }

View file

@ -7,89 +7,170 @@ function editBurg(id) {
const burg = id || d3.event.target.dataset.id; const burg = id || d3.event.target.dataset.id;
elSelected = burgLabels.select("[data-id='" + burg + "']"); elSelected = burgLabels.select("[data-id='" + burg + "']");
burgLabels.selectAll("text").call(d3.drag().on("start", dragBurgLabel)).classed("draggable", true); burgLabels
.selectAll("text")
.call(d3.drag().on("start", dragBurgLabel))
.classed("draggable", true);
updateBurgValues(); updateBurgValues();
$("#burgEditor").dialog({ $("#burgEditor").dialog({
title: "Edit Burg", title: "Edit Burg",
resizable: false, resizable: false,
close: closeBurgEditor, close: closeBurgEditor,
position: {my: "left top", at: "left+10 top+10", of: "svg", collision: "fit"} position: {
my: "left top",
at: "left+10 top+10",
of: "svg",
collision: "fit",
},
}); });
if (modules.editBurg) return; if (modules.editBurg) return;
modules.editBurg = true; modules.editBurg = true;
// add listeners // add listeners
document.getElementById("burgGroupShow").addEventListener("click", showGroupSection); document
document.getElementById("burgGroupHide").addEventListener("click", hideGroupSection); .getElementById("burgGroupShow")
document.getElementById("burgSelectGroup").addEventListener("change", changeGroup); .addEventListener("click", showGroupSection);
document.getElementById("burgInputGroup").addEventListener("change", createNewGroup); document
document.getElementById("burgAddGroup").addEventListener("click", toggleNewGroupInput); .getElementById("burgGroupHide")
document.getElementById("burgRemoveGroup").addEventListener("click", removeBurgsGroup); .addEventListener("click", hideGroupSection);
document
.getElementById("burgSelectGroup")
.addEventListener("change", changeGroup);
document
.getElementById("burgInputGroup")
.addEventListener("change", createNewGroup);
document
.getElementById("burgAddGroup")
.addEventListener("click", toggleNewGroupInput);
document
.getElementById("burgRemoveGroup")
.addEventListener("click", removeBurgsGroup);
document.getElementById("burgName").addEventListener("input", changeName); document.getElementById("burgName").addEventListener("input", changeName);
document.getElementById("burgNameReRandom").addEventListener("click", generateNameRandom); document
.getElementById("burgNameReRandom")
.addEventListener("click", generateNameRandom);
document.getElementById("burgType").addEventListener("input", changeType); document.getElementById("burgType").addEventListener("input", changeType);
document.getElementById("burgCulture").addEventListener("input", changeCulture); document
document.getElementById("burgNameReCulture").addEventListener("click", generateNameCulture); .getElementById("burgCulture")
document.getElementById("burgPopulation").addEventListener("change", changePopulation); .addEventListener("input", changeCulture);
burgBody.querySelectorAll(".burgFeature").forEach(el => el.addEventListener("click", toggleFeature)); document
document.getElementById("mfcgBurgSeed").addEventListener("change", changeSeed); .getElementById("burgNameReCulture")
document.getElementById("regenerateMFCGBurgSeed").addEventListener("click", randomizeSeed); .addEventListener("click", generateNameCulture);
document
.getElementById("burgPopulation")
.addEventListener("change", changePopulation);
burgBody
.querySelectorAll(".burgFeature")
.forEach((el) => el.addEventListener("click", toggleFeature));
document
.getElementById("mfcgBurgSeed")
.addEventListener("change", changeSeed);
document
.getElementById("regenerateMFCGBurgSeed")
.addEventListener("click", randomizeSeed);
document.getElementById("burgStyleShow").addEventListener("click", showStyleSection); document
document.getElementById("burgStyleHide").addEventListener("click", hideStyleSection); .getElementById("burgStyleShow")
document.getElementById("burgEditLabelStyle").addEventListener("click", editGroupLabelStyle); .addEventListener("click", showStyleSection);
document.getElementById("burgEditIconStyle").addEventListener("click", editGroupIconStyle); document
document.getElementById("burgEditAnchorStyle").addEventListener("click", editGroupAnchorStyle); .getElementById("burgStyleHide")
.addEventListener("click", hideStyleSection);
document
.getElementById("burgEditLabelStyle")
.addEventListener("click", editGroupLabelStyle);
document
.getElementById("burgEditIconStyle")
.addEventListener("click", editGroupIconStyle);
document
.getElementById("burgEditAnchorStyle")
.addEventListener("click", editGroupAnchorStyle);
document.getElementById("burgEmblem").addEventListener("click", openEmblemEdit); document
document.getElementById("burgToggleMFCGMap").addEventListener("click", toggleMFCGMap); .getElementById("burgEmblem")
document.getElementById("burgEditEmblem").addEventListener("click", openEmblemEdit); .addEventListener("click", openEmblemEdit);
document.getElementById("burgRelocate").addEventListener("click", toggleRelocateBurg); document
document.getElementById("burglLegend").addEventListener("click", editBurgLegend); .getElementById("burgToggleMFCGMap")
document.getElementById("burgLock").addEventListener("click", toggleBurgLockButton); .addEventListener("click", toggleMFCGMap);
document.getElementById("burgRemove").addEventListener("click", removeSelectedBurg); document
.getElementById("burgEditEmblem")
.addEventListener("click", openEmblemEdit);
document
.getElementById("burgRelocate")
.addEventListener("click", toggleRelocateBurg);
document
.getElementById("burglLegend")
.addEventListener("click", editBurgLegend);
document
.getElementById("burgLock")
.addEventListener("click", toggleBurgLockButton);
document
.getElementById("burgRemove")
.addEventListener("click", removeSelectedBurg);
function updateBurgValues() { function updateBurgValues() {
const id = +elSelected.attr("data-id"); const id = +elSelected.attr("data-id");
const b = pack.burgs[id]; const b = pack.burgs[id];
const province = pack.cells.province[b.cell]; const province = pack.cells.province[b.cell];
const provinceName = province ? pack.provinces[province].fullName + ", " : ""; const provinceName = province
const stateName = pack.states[b.state].fullName || pack.states[b.state].name; ? pack.provinces[province].fullName + ", "
document.getElementById("burgProvinceAndState").innerHTML = provinceName + stateName; : "";
const stateName =
pack.states[b.state].fullName || pack.states[b.state].name;
document.getElementById("burgProvinceAndState").innerHTML =
provinceName + stateName;
document.getElementById("burgName").value = b.name; document.getElementById("burgName").value = b.name;
document.getElementById("burgType").value = b.type || "Generic"; document.getElementById("burgType").value = b.type || "Generic";
document.getElementById("burgPopulation").value = rn(b.population * populationRate * urbanization); document.getElementById("burgPopulation").value = rn(
document.getElementById("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none"; b.population * populationRate * urbanization
);
document.getElementById("burgEditAnchorStyle").style.display = +b.port
? "inline-block"
: "none";
// update list and select culture // update list and select culture
const cultureSelect = document.getElementById("burgCulture"); const cultureSelect = document.getElementById("burgCulture");
cultureSelect.options.length = 0; cultureSelect.options.length = 0;
const cultures = pack.cultures.filter(c => !c.removed); const cultures = pack.cultures.filter((c) => !c.removed);
cultures.forEach(c => cultureSelect.options.add(new Option(c.name, c.i, false, c.i === b.culture))); cultures.forEach((c) =>
cultureSelect.options.add(
new Option(c.name, c.i, false, c.i === b.culture)
)
);
const temperature = grid.cells.temp[pack.cells.g[b.cell]]; const temperature = grid.cells.temp[pack.cells.g[b.cell]];
document.getElementById("burgTemperature").innerHTML = convertTemperature(temperature); document.getElementById("burgTemperature").innerHTML =
document.getElementById("burgTemperatureLikeIn").innerHTML = getTemperatureLikeness(temperature); convertTemperature(temperature);
document.getElementById("burgElevation").innerHTML = getHeight(pack.cells.h[b.cell]); document.getElementById("burgTemperatureLikeIn").innerHTML =
getTemperatureLikeness(temperature);
document.getElementById("burgElevation").innerHTML = getHeight(
pack.cells.h[b.cell]
);
// toggle features // toggle features
if (b.capital) document.getElementById("burgCapital").classList.remove("inactive"); if (b.capital)
document.getElementById("burgCapital").classList.remove("inactive");
else document.getElementById("burgCapital").classList.add("inactive"); else document.getElementById("burgCapital").classList.add("inactive");
if (b.port) document.getElementById("burgPort").classList.remove("inactive"); if (b.port)
document.getElementById("burgPort").classList.remove("inactive");
else document.getElementById("burgPort").classList.add("inactive"); else document.getElementById("burgPort").classList.add("inactive");
if (b.citadel) document.getElementById("burgCitadel").classList.remove("inactive"); if (b.citadel)
document.getElementById("burgCitadel").classList.remove("inactive");
else document.getElementById("burgCitadel").classList.add("inactive"); else document.getElementById("burgCitadel").classList.add("inactive");
if (b.walls) document.getElementById("burgWalls").classList.remove("inactive"); if (b.walls)
document.getElementById("burgWalls").classList.remove("inactive");
else document.getElementById("burgWalls").classList.add("inactive"); else document.getElementById("burgWalls").classList.add("inactive");
if (b.plaza) document.getElementById("burgPlaza").classList.remove("inactive"); if (b.plaza)
document.getElementById("burgPlaza").classList.remove("inactive");
else document.getElementById("burgPlaza").classList.add("inactive"); else document.getElementById("burgPlaza").classList.add("inactive");
if (b.temple) document.getElementById("burgTemple").classList.remove("inactive"); if (b.temple)
document.getElementById("burgTemple").classList.remove("inactive");
else document.getElementById("burgTemple").classList.add("inactive"); else document.getElementById("burgTemple").classList.add("inactive");
if (b.shanty) document.getElementById("burgShanty").classList.remove("inactive"); if (b.shanty)
document.getElementById("burgShanty").classList.remove("inactive");
else document.getElementById("burgShanty").classList.add("inactive"); else document.getElementById("burgShanty").classList.add("inactive");
//toggle lock //toggle lock
@ -101,7 +182,9 @@ function editBurg(id) {
select.options.length = 0; // remove all options select.options.length = 0; // remove all options
burgLabels.selectAll("g").each(function () { burgLabels.selectAll("g").each(function () {
select.options.add(new Option(this.id, this.id, false, this.id === group)); select.options.add(
new Option(this.id, this.id, false, this.id === group)
);
}); });
// set emlem image // set emlem image
@ -157,7 +240,7 @@ function editBurg(id) {
"Mogadishu", "Mogadishu",
"Bangkok", "Bangkok",
"Aden", "Aden",
"Khartoum" "Khartoum",
]; // 21 - 30 ]; // 21 - 30
if (temperature > 30) return "Mecca"; if (temperature > 30) return "Mecca";
return cities[temperature + 5] || null; return cities[temperature + 5] || null;
@ -172,17 +255,25 @@ function editBurg(id) {
const x = d3.event.x, const x = d3.event.x,
y = d3.event.y; y = d3.event.y;
this.setAttribute("transform", `translate(${dx + x},${dy + y})`); this.setAttribute("transform", `translate(${dx + x},${dy + y})`);
tip('Use dragging for fine-tuning only, to actually move burg use "Relocate" button', false, "warning"); tip(
'Use dragging for fine-tuning only, to actually move burg use "Relocate" button',
false,
"warning"
);
}); });
} }
function showGroupSection() { function showGroupSection() {
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none")); document
.querySelectorAll("#burgBottom > button")
.forEach((el) => (el.style.display = "none"));
document.getElementById("burgGroupSection").style.display = "inline-block"; document.getElementById("burgGroupSection").style.display = "inline-block";
} }
function hideGroupSection() { function hideGroupSection() {
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block")); document
.querySelectorAll("#burgBottom > button")
.forEach((el) => (el.style.display = "inline-block"));
document.getElementById("burgGroupSection").style.display = "none"; document.getElementById("burgGroupSection").style.display = "none";
document.getElementById("burgInputGroup").style.display = "none"; document.getElementById("burgInputGroup").style.display = "none";
document.getElementById("burgInputGroup").value = ""; document.getElementById("burgInputGroup").value = "";
@ -216,7 +307,11 @@ function editBurg(id) {
.replace(/[^\w\s]/gi, ""); .replace(/[^\w\s]/gi, "");
if (document.getElementById(group)) { if (document.getElementById(group)) {
tip("Element with this id already exists. Please provide a unique name", false, "error"); tip(
"Element with this id already exists. Please provide a unique name",
false,
"error"
);
return; return;
} }
@ -244,7 +339,9 @@ function editBurg(id) {
const count = elSelected.node().parentNode.childElementCount; const count = elSelected.node().parentNode.childElementCount;
if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) { if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) {
document.getElementById("burgSelectGroup").selectedOptions[0].remove(); document.getElementById("burgSelectGroup").selectedOptions[0].remove();
document.getElementById("burgSelectGroup").options.add(new Option(group, group, false, true)); document
.getElementById("burgSelectGroup")
.options.add(new Option(group, group, false, true));
toggleNewGroupInput(); toggleNewGroupInput();
document.getElementById("burgInputGroup").value = ""; document.getElementById("burgInputGroup").value = "";
labelG.id = group; labelG.id = group;
@ -254,16 +351,24 @@ function editBurg(id) {
} }
// create new groups // create new groups
document.getElementById("burgSelectGroup").options.add(new Option(group, group, false, true)); document
.getElementById("burgSelectGroup")
.options.add(new Option(group, group, false, true));
toggleNewGroupInput(); toggleNewGroupInput();
document.getElementById("burgInputGroup").value = ""; document.getElementById("burgInputGroup").value = "";
const newLabelG = document.querySelector("#burgLabels").appendChild(labelG.cloneNode(false)); const newLabelG = document
.querySelector("#burgLabels")
.appendChild(labelG.cloneNode(false));
newLabelG.id = group; newLabelG.id = group;
const newIconG = document.querySelector("#burgIcons").appendChild(iconG.cloneNode(false)); const newIconG = document
.querySelector("#burgIcons")
.appendChild(iconG.cloneNode(false));
newIconG.id = group; newIconG.id = group;
if (anchor) { if (anchor) {
const newAnchorG = document.querySelector("#anchors").appendChild(anchorG.cloneNode(false)); const newAnchorG = document
.querySelector("#anchors")
.appendChild(anchorG.cloneNode(false));
newAnchorG.id = group; newAnchorG.id = group;
} }
moveBurgToGroup(id, group); moveBurgToGroup(id, group);
@ -277,11 +382,17 @@ function editBurg(id) {
for (let i = 0; i < group.children.length; i++) { for (let i = 0; i < group.children.length; i++) {
burgsInGroup.push(+group.children[i].dataset.id); burgsInGroup.push(+group.children[i].dataset.id);
} }
const burgsToRemove = burgsInGroup.filter(b => !(pack.burgs[b].capital || pack.burgs[b].lock)); const burgsToRemove = burgsInGroup.filter(
(b) => !(pack.burgs[b].capital || pack.burgs[b].lock)
);
const capital = burgsToRemove.length < burgsInGroup.length; const capital = burgsToRemove.length < burgsInGroup.length;
alertMessage.innerHTML = `Are you sure you want to remove alertMessage.innerHTML = `Are you sure you want to remove
${basic || capital ? "all unlocked elements in the group" : "the entire burg group"}? ${
basic || capital
? "all unlocked elements in the group"
: "the entire burg group"
}?
<br>Please note that capital or locked burgs will not be deleted. <br>Please note that capital or locked burgs will not be deleted.
<br><br>Burgs to be removed: ${burgsToRemove.length}`; <br><br>Burgs to be removed: ${burgsToRemove.length}`;
$("#alert").dialog({ $("#alert").dialog({
@ -292,7 +403,7 @@ function editBurg(id) {
$(this).dialog("close"); $(this).dialog("close");
$("#burgEditor").dialog("close"); $("#burgEditor").dialog("close");
hideGroupSection(); hideGroupSection();
burgsToRemove.forEach(b => removeBurg(b)); burgsToRemove.forEach((b) => removeBurg(b));
if (!basic && !capital) { if (!basic && !capital) {
// entirely remove group // entirely remove group
@ -306,8 +417,8 @@ function editBurg(id) {
}, },
Cancel: function () { Cancel: function () {
$(this).dialog("close"); $(this).dialog("close");
} },
} },
}); });
} }
@ -342,7 +453,10 @@ function editBurg(id) {
function changePopulation() { function changePopulation() {
const id = +elSelected.attr("data-id"); const id = +elSelected.attr("data-id");
pack.burgs[id].population = rn(burgPopulation.value / populationRate / urbanization, 4); pack.burgs[id].population = rn(
burgPopulation.value / populationRate / urbanization,
4
);
} }
function toggleFeature() { function toggleFeature() {
@ -356,7 +470,9 @@ function editBurg(id) {
if (b[feature]) this.classList.remove("inactive"); if (b[feature]) this.classList.remove("inactive");
else if (!b[feature]) this.classList.add("inactive"); else if (!b[feature]) this.classList.add("inactive");
if (b.port) document.getElementById("burgEditAnchorStyle").style.display = "inline-block"; if (b.port)
document.getElementById("burgEditAnchorStyle").style.display =
"inline-block";
else document.getElementById("burgEditAnchorStyle").style.display = "none"; else document.getElementById("burgEditAnchorStyle").style.display = "none";
} }
@ -379,12 +495,16 @@ function editBurg(id) {
} }
function showStyleSection() { function showStyleSection() {
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none")); document
.querySelectorAll("#burgBottom > button")
.forEach((el) => (el.style.display = "none"));
document.getElementById("burgStyleSection").style.display = "inline-block"; document.getElementById("burgStyleSection").style.display = "inline-block";
} }
function hideStyleSection() { function hideStyleSection() {
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block")); document
.querySelectorAll("#burgBottom > button")
.forEach((el) => (el.style.display = "inline-block"));
document.getElementById("burgStyleSection").style.display = "none"; document.getElementById("burgStyleSection").style.display = "none";
} }
@ -408,21 +528,25 @@ function editBurg(id) {
const burgGeneratorURL = getBurgLink(burg); const burgGeneratorURL = getBurgLink(burg);
document.getElementById("mfcgPreview").setAttribute("src", mfcgURL); document.getElementById("mfcgPreview").setAttribute("src", mfcgURL);
document.getElementById("mfcgLink").setAttribute("href", mfcgURL); document.getElementById("mfcgLink").setAttribute("href", mfcgURL);
document.getElementById("burgGenerator").setAttribute("href", burgGeneratorURL); document
debug .getElementById("burgGenerator")
.setAttribute("href", burgGeneratorURL);
debug;
} }
function getBurgSeed(burg) { function getBurgSeed(burg) {
return burg.MFCG || Number(`${seed}${String(burg.i).padStart(4, 0)}`); return burg.MFCG || Number(`${seed}${String(burg.i).padStart(4, 0)}`);
} }
function getBurgLink(burg) { function getBurgLink(burg) {
const {cells} = pack; const { cells } = pack;
let burgCulture = pack.cultures[burg.culture].name.split('(')[1].split(')')[0]; let burgCulture = pack.cultures[burg.culture].name
.split("(")[1]
.split(")")[0];
const { name, population, cell } = burg;
const {name, population, cell} = burg;
const burgSeed = getBurgSeed(burg); const burgSeed = getBurgSeed(burg);
const sizeRaw = 0.43 * Math.pow((population * populationRate) / urbanDensity, 0.385); const sizeRaw =
0.43 * Math.pow((population * populationRate) / urbanDensity, 0.385);
const size = minmax(Math.ceil(sizeRaw), 2, 40); const size = minmax(Math.ceil(sizeRaw), 2, 40);
const people = rn(population * populationRate * urbanization); const people = rn(population * populationRate * urbanization);
const hub = +cells.road[cell] > 50; const hub = +cells.road[cell] > 50;
@ -435,6 +559,7 @@ function editBurg(id) {
const temple = +burg.temple; const temple = +burg.temple;
const shanty = +burg.shanty; const shanty = +burg.shanty;
const worldName = mapName.value;
const sea = coast && cells.haven[cell] ? getSeaDirections(cell) : ""; const sea = coast && cells.haven[cell] ? getSeaDirections(cell) : "";
function getSeaDirections(i) { function getSeaDirections(i) {
const p1 = cells.p[i]; const p1 = cells.p[i];
@ -445,24 +570,23 @@ function editBurg(id) {
return "&sea=" + norm; return "&sea=" + norm;
} }
let townSize = "tiny"; let townSize = "tiny";
if (people > 200) townSize = 'small'; if (people > 200) townSize = "small";
if (people > 900) townSize = 'medium'; if (people > 900) townSize = "medium";
if (people > 2_000) townSize = 'average'; if (people > 2_000) townSize = "average";
if (people > 5_500) townSize = 'big'; if (people > 5_500) townSize = "big";
const baseURL = "http://localhost:9090/town/"; const baseURL = "http://localhost:9090/town/";
const url = `${baseURL}${name}-${burgCulture}/${townSize}`; const url = `${baseURL}${worldName}_${name}-${burgCulture}/${townSize}`;
return url; return url;
} }
function getMFCGlink(burg) { function getMFCGlink(burg) {
const {cells} = pack; const { cells } = pack;
const {name, population, cell} = burg; const { name, population, cell } = burg;
const burgSeed = getBurgSeed(burg); const burgSeed = getBurgSeed(burg);
const sizeRaw = 0.43 * Math.pow((population * populationRate) / urbanDensity, 0.385); const sizeRaw =
const size = minmax(Math.ceil(sizeRaw), 2, 40)*3; 0.43 * Math.pow((population * populationRate) / urbanDensity, 0.385);
const size = minmax(Math.ceil(sizeRaw), 2, 40) * 3;
const people = rn(population * populationRate * urbanization); const people = rn(population * populationRate * urbanization);
const hub = +cells.road[cell] > 50; const hub = +cells.road[cell] > 50;
@ -485,7 +609,8 @@ function editBurg(id) {
return "&sea=" + norm; return "&sea=" + norm;
} }
const baseURL = "https://watabou.github.io/city-generator/?random=0&continuous=0"; const baseURL =
"https://watabou.github.io/city-generator/?random=0&continuous=0";
const url = `${baseURL}&name=${name}&population=${people}&size=${size}&seed=${burgSeed}&hub=${hub}&river=${river}&coast=${coast}&citadel=${citadel}&plaza=${plaza}&temple=${temple}&walls=${walls}&shantytown=${shanty}${sea}`; const url = `${baseURL}&name=${name}&population=${people}&size=${size}&seed=${burgSeed}&hub=${hub}&river=${river}&coast=${coast}&citadel=${citadel}&plaza=${plaza}&temple=${temple}&walls=${walls}&shantytown=${shanty}${sea}`;
return url; return url;
} }
@ -515,8 +640,11 @@ function editBurg(id) {
function toggleMFCGMap() { function toggleMFCGMap() {
options.showMFCGMap = !options.showMFCGMap; options.showMFCGMap = !options.showMFCGMap;
document.getElementById("mfcgPreviewSection").style.display = options.showMFCGMap ? "block" : "none"; document.getElementById("mfcgPreviewSection").style.display =
document.getElementById("burgToggleMFCGMap").className = options.showMFCGMap ? "icon-map" : "icon-map-o"; options.showMFCGMap ? "block" : "none";
document.getElementById("burgToggleMFCGMap").className = options.showMFCGMap
? "icon-map"
: "icon-map-o";
} }
function toggleRelocateBurg() { function toggleRelocateBurg() {
@ -524,7 +652,10 @@ function editBurg(id) {
document.getElementById("burgRelocate").classList.toggle("pressed"); document.getElementById("burgRelocate").classList.toggle("pressed");
if (document.getElementById("burgRelocate").classList.contains("pressed")) { if (document.getElementById("burgRelocate").classList.contains("pressed")) {
viewbox.style("cursor", "crosshair").on("click", relocateBurgOnClick); viewbox.style("cursor", "crosshair").on("click", relocateBurgOnClick);
tip("Click on map to relocate burg. Hold Shift for continuous move", true); tip(
"Click on map to relocate burg. Hold Shift for continuous move",
true
);
if (!layerIsOn("toggleCells")) { if (!layerIsOn("toggleCells")) {
toggleCells(); toggleCells();
toggler.dataset.forced = true; toggler.dataset.forced = true;
@ -547,12 +678,20 @@ function editBurg(id) {
const burg = pack.burgs[id]; const burg = pack.burgs[id];
if (cells.h[cell] < 20) { if (cells.h[cell] < 20) {
tip("Cannot place burg into the water! Select a land cell", false, "error"); tip(
"Cannot place burg into the water! Select a land cell",
false,
"error"
);
return; return;
} }
if (cells.burg[cell] && cells.burg[cell] !== id) { if (cells.burg[cell] && cells.burg[cell] !== id) {
tip("There is already a burg in this cell. Please select a free cell", false, "error"); tip(
"There is already a burg in this cell. Please select a free cell",
false,
"error"
);
return; return;
} }
@ -614,8 +753,8 @@ function editBurg(id) {
buttons: { buttons: {
Ok: function () { Ok: function () {
$(this).dialog("close"); $(this).dialog("close");
} },
} },
}); });
} else { } else {
alertMessage.innerHTML = "Are you sure you want to remove the burg?"; alertMessage.innerHTML = "Are you sure you want to remove the burg?";
@ -630,15 +769,18 @@ function editBurg(id) {
}, },
Cancel: function () { Cancel: function () {
$(this).dialog("close"); $(this).dialog("close");
} },
} },
}); });
} }
} }
function closeBurgEditor() { function closeBurgEditor() {
document.getElementById("burgRelocate").classList.remove("pressed"); document.getElementById("burgRelocate").classList.remove("pressed");
burgLabels.selectAll("text").call(d3.drag().on("drag", null)).classed("draggable", false); burgLabels
.selectAll("text")
.call(d3.drag().on("drag", null))
.classed("draggable", false);
unselect(); unselect();
} }
} }

View file

@ -7,7 +7,11 @@ restoreDefaultEvents(); // apply default viewbox events on load
// restore default viewbox events // restore default viewbox events
function restoreDefaultEvents() { function restoreDefaultEvents() {
svg.call(zoom); svg.call(zoom);
viewbox.style("cursor", "default").on(".drag", null).on("click", clicked).on("touchmove mousemove", moved); viewbox
.style("cursor", "default")
.on(".drag", null)
.on("click", clicked)
.on("touchmove mousemove", moved);
legend.call(d3.drag().on("start", dragLegendBox)); legend.call(d3.drag().on("start", dragLegendBox));
} }
@ -24,7 +28,11 @@ function clicked() {
if (grand.id === "emblems") editEmblem(); if (grand.id === "emblems") editEmblem();
else if (parent.id === "rivers") editRiver(el.id); else if (parent.id === "rivers") editRiver(el.id);
else if (grand.id === "routes") editRoute(); else if (grand.id === "routes") editRoute();
else if (el.tagName === "tspan" && grand.parentNode.parentNode.id === "labels") editLabel(); else if (
el.tagName === "tspan" &&
grand.parentNode.parentNode.id === "labels"
)
editLabel();
else if (grand.id === "burgLabels") editBurg(); else if (grand.id === "burgLabels") editBurg();
else if (grand.id === "burgIcons") editBurg(); else if (grand.id === "burgIcons") editBurg();
else if (parent.id === "ice") editIce(); else if (parent.id === "ice") editIce();
@ -71,7 +79,8 @@ function moveCircle(x, y, r = 20) {
} }
function removeCircle() { function removeCircle() {
if (document.getElementById("brushCircle")) document.getElementById("brushCircle").remove(); if (document.getElementById("brushCircle"))
document.getElementById("brushCircle").remove();
} }
// get browser-defined fit-content // get browser-defined fit-content
@ -92,8 +101,8 @@ function sortLines(header) {
if (!header.className.includes("icon-sort") && type === "name") order = "-up"; if (!header.className.includes("icon-sort") && type === "name") order = "-up";
const headers = header.parentNode; const headers = header.parentNode;
headers.querySelectorAll("div.sortable").forEach(e => { headers.querySelectorAll("div.sortable").forEach((e) => {
e.classList.forEach(c => { e.classList.forEach((c) => {
if (c.includes("icon-sort")) e.classList.remove(c); if (c.includes("icon-sort")) e.classList.remove(c);
}); });
}); });
@ -116,7 +125,7 @@ function applySorting(headers) {
const bn = name ? b.dataset[sortby] : +b.dataset[sortby]; const bn = name ? b.dataset[sortby] : +b.dataset[sortby];
return (an > bn ? 1 : an < bn ? -1 : 0) * desc; return (an > bn ? 1 : an < bn ? -1 : 0) * desc;
}) })
.forEach(line => list.appendChild(line)); .forEach((line) => list.appendChild(line));
} }
function addBurg(point) { function addBurg(point) {
@ -131,7 +140,10 @@ function addBurg(point) {
const feature = cells.f[cell]; const feature = cells.f[cell];
const temple = pack.states[state].form === "Theocracy"; const temple = pack.states[state].form === "Theocracy";
const population = Math.max((cells.s[cell] + cells.road[cell]) / 3 + i / 1000 + (cell % 100) / 1000, 0.1); const population = Math.max(
(cells.s[cell] + cells.road[cell]) / 3 + i / 1000 + (cell % 100) / 1000,
0.1
);
const type = BurgsAndStates.getType(cell, false); const type = BurgsAndStates.getType(cell, false);
// generate emblem // generate emblem
@ -139,7 +151,22 @@ function addBurg(point) {
coa.shield = COA.getShield(culture, state); coa.shield = COA.getShield(culture, state);
COArenderer.add("burg", i, coa, x, y); COArenderer.add("burg", i, coa, x, y);
pack.burgs.push({name, cell, x, y, state, i, culture, feature, capital: 0, port: 0, temple, population, coa, type}); pack.burgs.push({
name,
cell,
x,
y,
state,
i,
culture,
feature,
capital: 0,
port: 0,
temple,
population,
coa,
type,
});
cells.burg[cell] = i; cells.burg[cell] = i;
const townSize = burgIcons.select("#towns").attr("size") || 0.5; const townSize = burgIcons.select("#towns").attr("size") || 0.5;
@ -219,7 +246,11 @@ function toggleCapital(burg) {
return; return;
} }
if (pack.burgs[burg].capital) { if (pack.burgs[burg].capital) {
tip("To change capital please assign a capital status to another burg of this state", false, "error"); tip(
"To change capital please assign a capital status to another burg of this state",
false,
"error"
);
return; return;
} }
const old = pack.states[state].capital; const old = pack.states[state].capital;
@ -244,7 +275,12 @@ function togglePort(burg) {
const haven = pack.cells.haven[b.cell]; const haven = pack.cells.haven[b.cell];
const port = haven ? pack.cells.f[haven] : -1; const port = haven ? pack.cells.f[haven] : -1;
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn"); if (!haven)
tip(
"Port haven is not found, system won't be able to make a searoute",
false,
"warn"
);
b.port = port; b.port = port;
const g = b.capital ? "cities" : "towns"; const g = b.capital ? "cities" : "towns";
@ -281,13 +317,22 @@ function drawLegend(name, data) {
const vOffset = fontSize / 2; const vOffset = fontSize / 2;
// append items // append items
const boxes = legend.append("g").attr("stroke-width", 0.5).attr("stroke", "#111111").attr("stroke-dasharray", "none"); const boxes = legend
const labels = legend.append("g").attr("fill", "#000000").attr("stroke", "none"); .append("g")
.attr("stroke-width", 0.5)
.attr("stroke", "#111111")
.attr("stroke-dasharray", "none");
const labels = legend
.append("g")
.attr("fill", "#000000")
.attr("stroke", "none");
const columns = Math.ceil(data.length / itemsInCol); const columns = Math.ceil(data.length / itemsInCol);
for (let column = 0, i = 0; column < columns; column++) { for (let column = 0, i = 0; column < columns; column++) {
const linesInColumn = Math.ceil(data.length / columns); const linesInColumn = Math.ceil(data.length / columns);
const offset = column ? colOffset * 2 + legend.node().getBBox().width : colOffset; const offset = column
? colOffset * 2 + legend.node().getBBox().width
: colOffset;
for (let l = 0; l < linesInColumn && data[i]; l++, i++) { for (let l = 0; l < linesInColumn && data[i]; l++, i++) {
boxes boxes
@ -354,7 +399,7 @@ function redrawLegend() {
const data = legend const data = legend
.attr("data") .attr("data")
.split("|") .split("|")
.map(l => l.split(",")); .map((l) => l.split(","));
drawLegend(name, data); drawLegend(name, data);
} }
@ -383,7 +428,12 @@ function createPicker() {
const cl = () => tip("Click to close the picker"); const cl = () => tip("Click to close the picker");
const closePicker = () => contaiter.style("display", "none"); const closePicker = () => contaiter.style("display", "none");
const contaiter = d3.select("body").append("svg").attr("id", "pickerContainer").attr("width", "100%").attr("height", "100%"); const contaiter = d3
.select("body")
.append("svg")
.attr("id", "pickerContainer")
.attr("width", "100%")
.attr("height", "100%");
contaiter contaiter
.append("rect") .append("rect")
.attr("x", 0) .attr("x", 0)
@ -407,19 +457,39 @@ function createPicker() {
const h = controls.append("g"); const h = controls.append("g");
h.append("text").attr("x", 4).attr("y", 14).text("H:"); h.append("text").attr("x", 4).attr("y", 14).text("H:");
h.append("line").attr("x1", 18).attr("y1", 10).attr("x2", 107).attr("y2", 10); h.append("line").attr("x1", 18).attr("y1", 10).attr("x2", 107).attr("y2", 10);
h.append("circle").attr("cx", 75).attr("cy", 10).attr("r", 5).attr("id", "pickerH"); h.append("circle")
.attr("cx", 75)
.attr("cy", 10)
.attr("r", 5)
.attr("id", "pickerH");
h.on("mousemove", () => tip("Set palette hue")); h.on("mousemove", () => tip("Set palette hue"));
const s = controls.append("g"); const s = controls.append("g");
s.append("text").attr("x", 113).attr("y", 14).text("S:"); s.append("text").attr("x", 113).attr("y", 14).text("S:");
s.append("line").attr("x1", 124).attr("y1", 10).attr("x2", 206).attr("y2", 10); s.append("line")
s.append("circle").attr("cx", 181.4).attr("cy", 10).attr("r", 5).attr("id", "pickerS"); .attr("x1", 124)
.attr("y1", 10)
.attr("x2", 206)
.attr("y2", 10);
s.append("circle")
.attr("cx", 181.4)
.attr("cy", 10)
.attr("r", 5)
.attr("id", "pickerS");
s.on("mousemove", () => tip("Set palette saturation")); s.on("mousemove", () => tip("Set palette saturation"));
const l = controls.append("g"); const l = controls.append("g");
l.append("text").attr("x", 213).attr("y", 14).text("L:"); l.append("text").attr("x", 213).attr("y", 14).text("L:");
l.append("line").attr("x1", 226).attr("y1", 10).attr("x2", 306).attr("y2", 10); l.append("line")
l.append("circle").attr("cx", 282).attr("cy", 10).attr("r", 5).attr("id", "pickerL"); .attr("x1", 226)
.attr("y1", 10)
.attr("x2", 306)
.attr("y2", 10);
l.append("circle")
.attr("cx", 282)
.attr("cy", 10)
.attr("r", 5)
.attr("id", "pickerL");
l.on("mousemove", () => tip("Set palette lightness")); l.on("mousemove", () => tip("Set palette lightness"));
controls.selectAll("line").on("click", clickPickerControl); controls.selectAll("line").on("click", clickPickerControl);
@ -432,7 +502,9 @@ function createPicker() {
.attr("y", 20) .attr("y", 20)
.attr("width", 303) .attr("width", 303)
.attr("height", 20) .attr("height", 20)
.on("mousemove", () => tip("Color value in different color spaces. Edit to change")); .on("mousemove", () =>
tip("Color value in different color spaces. Edit to change")
);
const html = ` const html = `
<label style="margin-right: 6px">HSL: <label style="margin-right: 6px">HSL:
<input type="number" id="pickerHSL_H" data-space="hsl" min=0 max=360 value="231">, <input type="number" id="pickerHSL_H" data-space="hsl" min=0 max=360 value="231">,
@ -448,12 +520,20 @@ function createPicker() {
spaces.node().insertAdjacentHTML("beforeend", html); spaces.node().insertAdjacentHTML("beforeend", html);
spaces.selectAll("input").on("change", changePickerSpace); spaces.selectAll("input").on("change", changePickerSpace);
const colors = picker.append("g").attr("id", "pickerColors").attr("stroke", "#333333"); const colors = picker
const hatches = picker.append("g").attr("id", "pickerHatches").attr("stroke", "#333333"); .append("g")
.attr("id", "pickerColors")
.attr("stroke", "#333333");
const hatches = picker
.append("g")
.attr("id", "pickerHatches")
.attr("stroke", "#333333");
const hatching = d3.selectAll("g#hatching > pattern"); const hatching = d3.selectAll("g#hatching > pattern");
const number = hatching.size(); const number = hatching.size();
const clr = d3.range(number).map(i => d3.hsl((i / number) * 360, 0.7, 0.7).hex()); const clr = d3
.range(number)
.map((i) => d3.hsl((i / number) * 360, 0.7, 0.7).hex());
clr.forEach(function (d, i) { clr.forEach(function (d, i) {
colors colors
.append("rect") .append("rect")
@ -500,7 +580,12 @@ function createPicker() {
.attr("fill", "#ffffff") .attr("fill", "#ffffff")
.attr("stroke", "#5d4651") .attr("stroke", "#5d4651")
.on("mousemove", pos); .on("mousemove", pos);
picker.insert("text", ":first-child").attr("x", 291).attr("y", -10).attr("id", "pickerCloseText").text("✕"); picker
.insert("text", ":first-child")
.attr("x", 291)
.attr("y", -10)
.attr("id", "pickerCloseText")
.text("✕");
picker picker
.insert("rect", ":first-child") .insert("rect", ":first-child")
.attr("x", 288) .attr("x", 288)
@ -510,13 +595,32 @@ function createPicker() {
.attr("height", 14) .attr("height", 14)
.on("mousemove", cl) .on("mousemove", cl)
.on("click", closePicker); .on("click", closePicker);
picker.insert("text", ":first-child").attr("x", 12).attr("y", -10).attr("id", "pickerLabel").text("Color Picker").on("mousemove", pos); picker
picker.insert("rect", ":first-child").attr("x", 0).attr("y", -30).attr("width", width).attr("height", 30).attr("id", "pickerHeader").on("mousemove", pos); .insert("text", ":first-child")
picker.attr("transform", `translate(${(svgWidth - width) / 2},${(svgHeight - height) / 2})`); .attr("x", 12)
.attr("y", -10)
.attr("id", "pickerLabel")
.text("Color Picker")
.on("mousemove", pos);
picker
.insert("rect", ":first-child")
.attr("x", 0)
.attr("y", -30)
.attr("width", width)
.attr("height", 30)
.attr("id", "pickerHeader")
.on("mousemove", pos);
picker.attr(
"transform",
`translate(${(svgWidth - width) / 2},${(svgHeight - height) / 2})`
);
} }
function updateSelectedRect(fill) { function updateSelectedRect(fill) {
document.getElementById("picker").querySelector("rect.selected").classList.remove("selected"); document
.getElementById("picker")
.querySelector("rect.selected")
.classList.remove("selected");
document document
.getElementById("picker") .getElementById("picker")
.querySelector("rect[fill='" + fill.toLowerCase() + "']") .querySelector("rect[fill='" + fill.toLowerCase() + "']")
@ -574,7 +678,9 @@ function openPicker(fill, callback) {
updateSelectedRect(fill); updateSelectedRect(fill);
openPicker.updateFill = function () { openPicker.updateFill = function () {
const selected = document.getElementById("picker").querySelector("rect.selected"); const selected = document
.getElementById("picker")
.querySelector("rect.selected");
if (!selected) return; if (!selected) return;
callback(selected.getAttribute("fill")); callback(selected.getAttribute("fill"));
}; };
@ -649,8 +755,15 @@ function changePickerSpace() {
} }
const space = this.dataset.space; const space = this.dataset.space;
const i = Array.from(this.parentNode.querySelectorAll("input")).map(input => input.value); // inputs const i = Array.from(this.parentNode.querySelectorAll("input")).map(
const fill = space === "hex" ? d3.rgb(this.value) : space === "rgb" ? d3.rgb(i[0], i[1], i[2]) : d3.hsl(i[0], i[1] / 100, i[2] / 100); (input) => input.value
); // inputs
const fill =
space === "hex"
? d3.rgb(this.value)
: space === "rgb"
? d3.rgb(i[0], i[1], i[2])
: d3.hsl(i[0], i[1] / 100, i[2] / 100);
const hsl = d3.hsl(fill); const hsl = d3.hsl(fill);
if (isNaN(hsl.l)) { if (isNaN(hsl.l)) {
@ -671,11 +784,27 @@ function fog(id, path) {
if (defs.select("#fog #" + id).size()) return; if (defs.select("#fog #" + id).size()) return;
const fadeIn = d3.transition().duration(2000).ease(d3.easeSinInOut); const fadeIn = d3.transition().duration(2000).ease(d3.easeSinInOut);
if (defs.select("#fog path").size()) { if (defs.select("#fog path").size()) {
defs.select("#fog").append("path").attr("d", path).attr("id", id).attr("opacity", 0).transition(fadeIn).attr("opacity", 1); defs
.select("#fog")
.append("path")
.attr("d", path)
.attr("id", id)
.attr("opacity", 0)
.transition(fadeIn)
.attr("opacity", 1);
} else { } else {
defs.select("#fog").append("path").attr("d", path).attr("id", id).attr("opacity", 1); defs
.select("#fog")
.append("path")
.attr("d", path)
.attr("id", id)
.attr("opacity", 1);
const opacity = fogging.attr("opacity"); const opacity = fogging.attr("opacity");
fogging.style("display", "block").attr("opacity", 0).transition(fadeIn).attr("opacity", opacity); fogging
.style("display", "block")
.attr("opacity", 0)
.transition(fadeIn)
.attr("opacity", opacity);
} }
} }
@ -689,7 +818,7 @@ function unfog(id) {
} }
function getFileName(dataType) { function getFileName(dataType) {
const formatTime = time => (time < 10 ? "0" + time : time); const formatTime = (time) => (time < 10 ? "0" + time : time);
const name = mapName.value; const name = mapName.value;
const type = dataType ? dataType + " " : ""; const type = dataType ? dataType + " " : "";
const date = new Date(); const date = new Date();
@ -699,11 +828,13 @@ function getFileName(dataType) {
const hour = formatTime(date.getHours()); const hour = formatTime(date.getHours());
const minutes = formatTime(date.getMinutes()); const minutes = formatTime(date.getMinutes());
const dateString = [year, month, day, hour, minutes].join("-"); const dateString = [year, month, day, hour, minutes].join("-");
return name + " " + type + dateString; //return name + " " + type + dateString;
return name;
} }
function downloadFile(data, name, type = "text/plain") { function downloadFile(data, name, type = "text/plain") {
const dataBlob = new Blob([data], {type}); const dataBlob = new Blob([data], { type });
const url = window.URL.createObjectURL(dataBlob); const url = window.URL.createObjectURL(dataBlob);
const link = document.createElement("a"); const link = document.createElement("a");
link.download = name; link.download = name;
@ -716,7 +847,7 @@ function uploadFile(el, callback) {
const fileReader = new FileReader(); const fileReader = new FileReader();
fileReader.readAsText(el.files[0], "UTF-8"); fileReader.readAsText(el.files[0], "UTF-8");
el.value = ""; el.value = "";
fileReader.onload = loaded => callback(loaded.target.result); fileReader.onload = (loaded) => callback(loaded.target.result);
} }
function getBBox(element) { function getBBox(element) {
@ -724,7 +855,7 @@ function getBBox(element) {
const y = +element.getAttribute("y"); const y = +element.getAttribute("y");
const width = +element.getAttribute("width"); const width = +element.getAttribute("width");
const height = +element.getAttribute("height"); const height = +element.getAttribute("height");
return {x, y, width, height}; return { x, y, width, height };
} }
function highlightElement(element, zoom) { function highlightElement(element, zoom) {
@ -734,9 +865,20 @@ function highlightElement(element, zoom) {
const enter = d3.transition().duration(1000).ease(d3.easeBounceOut); const enter = d3.transition().duration(1000).ease(d3.easeBounceOut);
const exit = d3.transition().duration(500).ease(d3.easeLinear); const exit = d3.transition().duration(500).ease(d3.easeLinear);
const highlight = debug.append("rect").attr("x", box.x).attr("y", box.y).attr("width", box.width).attr("height", box.height); const highlight = debug
.append("rect")
.attr("x", box.x)
.attr("y", box.y)
.attr("width", box.width)
.attr("height", box.height);
highlight.classed("highlighted", 1).attr("transform", transform); highlight.classed("highlighted", 1).attr("transform", transform);
highlight.transition(enter).style("outline-offset", "0px").transition(exit).style("outline-color", "transparent").delay(1000).remove(); highlight
.transition(enter)
.style("outline-offset", "0px")
.transition(exit)
.style("outline-color", "transparent")
.delay(1000)
.remove();
if (zoom) { if (zoom) {
const tr = parseTransform(transform); const tr = parseTransform(transform);
@ -944,7 +1086,7 @@ function selectIcon(initial, callback) {
"🍻", "🍻",
"🍺", "🍺",
"🍲", "🍲",
"🍷" "🍷",
]; ];
let row = ""; let row = "";
@ -955,15 +1097,16 @@ function selectIcon(initial, callback) {
} }
} }
input.oninput = e => callback(input.value); input.oninput = (e) => callback(input.value);
table.onclick = e => { table.onclick = (e) => {
if (e.target.tagName === "TD") { if (e.target.tagName === "TD") {
input.value = e.target.innerHTML; input.value = e.target.innerHTML;
callback(input.value); callback(input.value);
} }
}; };
table.onmouseover = e => { table.onmouseover = (e) => {
if (e.target.tagName === "TD") tip(`Click to select ${e.target.innerHTML} icon`); if (e.target.tagName === "TD")
tip(`Click to select ${e.target.innerHTML} icon`);
}; };
$("#iconSelector").dialog({ $("#iconSelector").dialog({
@ -977,8 +1120,8 @@ function selectIcon(initial, callback) {
Close: function () { Close: function () {
callback(initial); callback(initial);
$(this).dialog("close"); $(this).dialog("close");
} },
} },
}); });
} }
@ -989,7 +1132,7 @@ function confirmationDialog(options) {
cancel = "Cancel", cancel = "Cancel",
confirm = "Continue", confirm = "Continue",
onCancel, onCancel,
onConfirm onConfirm,
} = options; } = options;
const buttons = { const buttons = {
@ -1000,11 +1143,11 @@ function confirmationDialog(options) {
[cancel]: function () { [cancel]: function () {
if (onCancel) onCancel(); if (onCancel) onCancel();
$(this).dialog("close"); $(this).dialog("close");
} },
}; };
document.getElementById("alertMessage").innerHTML = message; document.getElementById("alertMessage").innerHTML = message;
$("#alert").dialog({resizable: false, title, buttons}); $("#alert").dialog({ resizable: false, title, buttons });
} }
// add and register event listeners to clean up on editor closure // add and register event listeners to clean up on editor closure
@ -1016,12 +1159,19 @@ function listen(element, event, handler) {
// Calls the refresh functionality on all editors currently open. // Calls the refresh functionality on all editors currently open.
function refreshAllEditors() { function refreshAllEditors() {
TIME && console.time("refreshAllEditors"); TIME && console.time("refreshAllEditors");
if (document.getElementById("culturesEditorRefresh").offsetParent) culturesEditorRefresh.click(); if (document.getElementById("culturesEditorRefresh").offsetParent)
if (document.getElementById("biomesEditorRefresh").offsetParent) biomesEditorRefresh.click(); culturesEditorRefresh.click();
if (document.getElementById("diplomacyEditorRefresh").offsetParent) diplomacyEditorRefresh.click(); if (document.getElementById("biomesEditorRefresh").offsetParent)
if (document.getElementById("provincesEditorRefresh").offsetParent) provincesEditorRefresh.click(); biomesEditorRefresh.click();
if (document.getElementById("religionsEditorRefresh").offsetParent) religionsEditorRefresh.click(); if (document.getElementById("diplomacyEditorRefresh").offsetParent)
if (document.getElementById("statesEditorRefresh").offsetParent) statesEditorRefresh.click(); diplomacyEditorRefresh.click();
if (document.getElementById("zonesEditorRefresh").offsetParent) zonesEditorRefresh.click(); if (document.getElementById("provincesEditorRefresh").offsetParent)
provincesEditorRefresh.click();
if (document.getElementById("religionsEditorRefresh").offsetParent)
religionsEditorRefresh.click();
if (document.getElementById("statesEditorRefresh").offsetParent)
statesEditorRefresh.click();
if (document.getElementById("zonesEditorRefresh").offsetParent)
zonesEditorRefresh.click();
TIME && console.timeEnd("refreshAllEditors"); TIME && console.timeEnd("refreshAllEditors");
} }

View file

@ -3,13 +3,18 @@
// fit full-screen map if window is resized // fit full-screen map if window is resized
window.addEventListener("resize", function (e) { window.addEventListener("resize", function (e) {
if (localStorage.getItem("mapWidth") && localStorage.getItem("mapHeight")) return; if (localStorage.getItem("mapWidth") && localStorage.getItem("mapHeight"))
return;
mapWidthInput.value = window.innerWidth; mapWidthInput.value = window.innerWidth;
mapHeightInput.value = window.innerHeight; mapHeightInput.value = window.innerHeight;
changeMapSize(); changeMapSize();
}); });
if (location.hostname && location.hostname !== "localhost" && location.hostname !== "127.0.0.1") { if (
location.hostname &&
location.hostname !== "localhost" &&
location.hostname !== "127.0.0.1"
) {
window.onbeforeunload = () => "Are you sure you want to navigate away?"; window.onbeforeunload = () => "Are you sure you want to navigate away?";
} }
@ -18,15 +23,26 @@ const tooltip = document.getElementById("tooltip");
// show tip for non-svg elemets with data-tip // show tip for non-svg elemets with data-tip
document.getElementById("dialogs").addEventListener("mousemove", showDataTip); document.getElementById("dialogs").addEventListener("mousemove", showDataTip);
document.getElementById("optionsContainer").addEventListener("mousemove", showDataTip); document
document.getElementById("exitCustomization").addEventListener("mousemove", showDataTip); .getElementById("optionsContainer")
.addEventListener("mousemove", showDataTip);
document
.getElementById("exitCustomization")
.addEventListener("mousemove", showDataTip);
function tip(tip = "Tip is undefined", main, type, time) { function tip(tip = "Tip is undefined", main, type, time) {
tooltip.innerHTML = tip; tooltip.innerHTML = tip;
tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #5e5c5c80, #ffffff00)"; tooltip.style.background =
if (type === "error") tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #e11d1dcc, #ffffff00)"; "linear-gradient(0.1turn, #ffffff00, #5e5c5c80, #ffffff00)";
else if (type === "warn") tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #be5d08cc, #ffffff00)"; if (type === "error")
else if (type === "success") tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #127912cc, #ffffff00)"; tooltip.style.background =
"linear-gradient(0.1turn, #ffffff00, #e11d1dcc, #ffffff00)";
else if (type === "warn")
tooltip.style.background =
"linear-gradient(0.1turn, #ffffff00, #be5d08cc, #ffffff00)";
else if (type === "success")
tooltip.style.background =
"linear-gradient(0.1turn, #ffffff00, #127912cc, #ffffff00)";
if (main) { if (main) {
tooltip.dataset.main = tip; tooltip.dataset.main = tip;
@ -50,7 +66,8 @@ function clearMainTip() {
function showDataTip(e) { function showDataTip(e) {
if (!e.target) return; if (!e.target) return;
let dataTip = e.target.dataset.tip; let dataTip = e.target.dataset.tip;
if (!dataTip && e.target.parentNode.dataset.tip) dataTip = e.target.parentNode.dataset.tip; if (!dataTip && e.target.parentNode.dataset.tip)
dataTip = e.target.parentNode.dataset.tip;
if (!dataTip) return; if (!dataTip) return;
//const tooltip = lang === "en" ? dataTip : translate(e.target.dataset.t || e.target.parentNode.dataset.t, dataTip); //const tooltip = lang === "en" ? dataTip : translate(e.target.dataset.t || e.target.parentNode.dataset.t, dataTip);
tip(dataTip); tip(dataTip);
@ -59,9 +76,13 @@ function showDataTip(e) {
function showElementLockTip(event) { function showElementLockTip(event) {
const locked = event?.target?.classList?.contains("icon-lock"); const locked = event?.target?.classList?.contains("icon-lock");
if (locked) { if (locked) {
tip("Click to unlock the element and allow it to be changed by regeneration tools"); tip(
"Click to unlock the element and allow it to be changed by regeneration tools"
);
} else { } else {
tip("Click to lock the element and prevent changes to it by regeneration tools"); tip(
"Click to lock the element and prevent changes to it by regeneration tools"
);
} }
} }
@ -80,11 +101,14 @@ function mouseMove() {
// show note box on hover (if any) // show note box on hover (if any)
function showNotes(e, i) { function showNotes(e, i) {
if (notesEditor.offsetParent) return; if (notesEditor.offsetParent) return;
let id = e.target.id || e.target.parentNode.id || e.target.parentNode.parentNode.id; let id =
if (e.target.parentNode.parentNode.id === "burgLabels") id = "burg" + e.target.dataset.id; e.target.id || e.target.parentNode.id || e.target.parentNode.parentNode.id;
else if (e.target.parentNode.parentNode.id === "burgIcons") id = "burg" + e.target.dataset.id; if (e.target.parentNode.parentNode.id === "burgLabels")
id = "burg" + e.target.dataset.id;
else if (e.target.parentNode.parentNode.id === "burgIcons")
id = "burg" + e.target.dataset.id;
const note = notes.find(note => note.id === id); const note = notes.find((note) => note.id === id);
if (note !== undefined && note.legend !== "") { if (note !== undefined && note.legend !== "") {
document.getElementById("notes").style.display = "block"; document.getElementById("notes").style.display = "block";
document.getElementById("notesHeader").innerHTML = note.name; document.getElementById("notesHeader").innerHTML = note.name;
@ -96,6 +120,34 @@ function showNotes(e, i) {
} }
} }
function createMetaTip(point, e, i, g) {
const biome = pack.cells.biome[i];
const religion = pack.cells.religion[i];
const r = pack.religions[religion];
const religionType =
r.type === "Cult" || r.type == "Heresy" ? r.type : r.type + " religion";
const state = pack.cells.state[i];
const stateCulture = pack.cells.state[i].culture;
const stateName = pack.states[state].fullName;
const province = pack.cells.province[i];
const prov = province ? pack.provinces[province].fullName + ", " : "";
const culture = pack.cells.culture[i];
tip("Culture: " + pack.cultures[culture].name);
let tipText =
pack.cultures[culture].name +
" | " +
religionType +
": " +
r.name +
" | " +
stateName +
" - " +
prov +
" | Biome: " +
biomesData.name[biome];
tip(tipText);
}
// show viewbox tooltip if main tooltip is blank // show viewbox tooltip if main tooltip is blank
function showMapTooltip(point, e, i, g) { function showMapTooltip(point, e, i, g) {
tip(""); // clear tip tip(""); // clear tip
@ -106,12 +158,17 @@ function showMapTooltip(point, e, i, g) {
const land = pack.cells.h[i] >= 20; const land = pack.cells.h[i] >= 20;
// specific elements // specific elements
if (group === "armies") return tip(e.target.parentNode.dataset.name + ". Click to edit"); if (group === "armies")
return tip(e.target.parentNode.dataset.name + ". Click to edit");
if (group === "emblems" && e.target.tagName === "use") { if (group === "emblems" && e.target.tagName === "use") {
const parent = e.target.parentNode; const parent = e.target.parentNode;
const [g, type] = const [g, type] =
parent.id === "burgEmblems" ? [pack.burgs, "burg"] : parent.id === "provinceEmblems" ? [pack.provinces, "province"] : [pack.states, "state"]; parent.id === "burgEmblems"
? [pack.burgs, "burg"]
: parent.id === "provinceEmblems"
? [pack.provinces, "province"]
: [pack.states, "state"];
const i = +e.target.dataset.i; const i = +e.target.dataset.i;
if (event.shiftKey) highlightEmblemElement(type, g[i]); if (event.shiftKey) highlightEmblemElement(type, g[i]);
@ -119,16 +176,19 @@ function showMapTooltip(point, e, i, g) {
d3.select(parent).raise(); d3.select(parent).raise();
const name = g[i].fullName || g[i].name; const name = g[i].fullName || g[i].name;
tip(`${name} ${type} emblem. Click to edit. Hold Shift to show associated area or place`); tip(
`${name} ${type} emblem. Click to edit. Hold Shift to show associated area or place`
);
return; return;
} }
if (group === "rivers") { if (group === "rivers") {
const river = +e.target.id.slice(5); const river = +e.target.id.slice(5);
const r = pack.rivers.find(r => r.i === river); const r = pack.rivers.find((r) => r.i === river);
const name = r ? r.name + " " + r.type : ""; const name = r ? r.name + " " + r.type : "";
tip(name + ". Click to edit"); tip(name + ". Click to edit");
if (riversOverview.offsetParent) highlightEditorLine(riversOverview, river, 5000); if (riversOverview.offsetParent)
highlightEditorLine(riversOverview, river, 5000);
return; return;
} }
@ -141,22 +201,31 @@ function showMapTooltip(point, e, i, g) {
const b = pack.burgs[burg]; const b = pack.burgs[burg];
const population = si(b.population * populationRate * urbanization); const population = si(b.population * populationRate * urbanization);
tip(`${b.name}. Population: ${population}. Click to edit`); tip(`${b.name}. Population: ${population}. Click to edit`);
if (burgsOverview.offsetParent) highlightEditorLine(burgsOverview, burg, 5000); if (burgsOverview.offsetParent)
highlightEditorLine(burgsOverview, burg, 5000);
return; return;
} }
if (group === "labels") return tip("Click to edit the Label"); if (group === "labels") return tip("Click to edit the Label");
if (group === "markers") return tip("Click to edit the Marker and pin the marker note"); if (group === "markers")
return tip("Click to edit the Marker and pin the marker note");
if (group === "ruler") { if (group === "ruler") {
const tag = e.target.tagName; const tag = e.target.tagName;
const className = e.target.getAttribute("class"); const className = e.target.getAttribute("class");
if (tag === "circle" && className === "edge") return tip("Drag to adjust. Hold Ctrl and drag to add a point. Click to remove the point"); if (tag === "circle" && className === "edge")
if (tag === "circle" && className === "control") return tip("Drag to adjust. Hold Shift and drag to keep axial direction. Click to remove the point"); return tip(
"Drag to adjust. Hold Ctrl and drag to add a point. Click to remove the point"
);
if (tag === "circle" && className === "control")
return tip(
"Drag to adjust. Hold Shift and drag to keep axial direction. Click to remove the point"
);
if (tag === "circle") return tip("Drag to adjust the measurer"); if (tag === "circle") return tip("Drag to adjust the measurer");
if (tag === "polyline") return tip("Click on drag to add a control point"); if (tag === "polyline") return tip("Click on drag to add a control point");
if (tag === "path") return tip("Drag to move the measurer"); if (tag === "path") return tip("Drag to move the measurer");
if (tag === "text") return tip("Drag to move, click to remove the measurer"); if (tag === "text")
return tip("Drag to move, click to remove the measurer");
} }
if (subgroup === "burgIcons") return tip("Click to edit the Burg"); if (subgroup === "burgIcons") return tip("Click to edit the Burg");
@ -175,46 +244,55 @@ function showMapTooltip(point, e, i, g) {
if (group === "zones") { if (group === "zones") {
const zone = path[path.length - 8]; const zone = path[path.length - 8];
tip(zone.dataset.description); tip(zone.dataset.description);
if (zonesEditor.offsetParent) highlightEditorLine(zonesEditor, zone.id, 5000); if (zonesEditor.offsetParent)
highlightEditorLine(zonesEditor, zone.id, 5000);
return; return;
} }
if (group === "ice") return tip("Click to edit the Ice"); if (group === "ice") return tip("Click to edit the Ice");
// covering elements // covering elements
if (layerIsOn("togglePrec") && land) tip("Annual Precipitation: " + getFriendlyPrecipitation(i)); if (layerIsOn("togglePrec") && land)
tip("Annual Precipitation: " + getFriendlyPrecipitation(i));
else if (layerIsOn("togglePopulation")) tip(getPopulationTip(i)); else if (layerIsOn("togglePopulation")) tip(getPopulationTip(i));
else if (layerIsOn("toggleTemp")) tip("Temperature: " + convertTemperature(grid.cells.temp[g])); else if (layerIsOn("toggleTemp"))
tip("Temperature: " + convertTemperature(grid.cells.temp[g]));
else if (layerIsOn("toggleBiomes") && pack.cells.biome[i]) { else if (layerIsOn("toggleBiomes") && pack.cells.biome[i]) {
const biome = pack.cells.biome[i]; createMetaTip(point, e, i, g);
tip("Biome: " + biomesData.name[biome]);
if (biomesEditor.offsetParent) highlightEditorLine(biomesEditor, biome); if (biomesEditor.offsetParent) highlightEditorLine(biomesEditor, biome);
} else if (layerIsOn("toggleReligions") && pack.cells.religion[i]) { } else if (layerIsOn("toggleReligions") && pack.cells.religion[i]) {
const religion = pack.cells.religion[i]; createMetaTip(point, e, i, g);
const r = pack.religions[religion]; if (religionsEditor.offsetParent)
const type = r.type === "Cult" || r.type == "Heresy" ? r.type : r.type + " religion"; highlightEditorLine(religionsEditor, religion);
tip(type + ": " + r.name); } else if (
if (religionsEditor.offsetParent) highlightEditorLine(religionsEditor, religion); pack.cells.state[i] &&
} else if (pack.cells.state[i] && (layerIsOn("toggleProvinces") || layerIsOn("toggleStates"))) { (layerIsOn("toggleProvinces") || layerIsOn("toggleStates"))
const state = pack.cells.state[i]; ) {
const stateName = pack.states[state].fullName; createMetaTip(point, e, i, g);
const province = pack.cells.province[i];
const prov = province ? pack.provinces[province].fullName + ", " : "";
tip(prov + stateName);
if (statesEditor.offsetParent) highlightEditorLine(statesEditor, state); if (statesEditor.offsetParent) highlightEditorLine(statesEditor, state);
if (diplomacyEditor.offsetParent) highlightEditorLine(diplomacyEditor, state); if (diplomacyEditor.offsetParent)
if (militaryOverview.offsetParent) highlightEditorLine(militaryOverview, state); highlightEditorLine(diplomacyEditor, state);
if (provincesEditor.offsetParent) highlightEditorLine(provincesEditor, province); if (militaryOverview.offsetParent)
highlightEditorLine(militaryOverview, state);
if (provincesEditor.offsetParent)
highlightEditorLine(provincesEditor, province);
} else if (layerIsOn("toggleCultures") && pack.cells.culture[i]) { } else if (layerIsOn("toggleCultures") && pack.cells.culture[i]) {
const culture = pack.cells.culture[i]; createMetaTip(point, e, i, g);
tip("Culture: " + pack.cultures[culture].name); if (culturesEditor.offsetParent) {
if (culturesEditor.offsetParent) highlightEditorLine(culturesEditor, culture); highlightEditorLine(culturesEditor, culture);
} else if (layerIsOn("toggleHeight")) tip("Height: " + getFriendlyHeight(point)); }
} else if (layerIsOn("toggleHeight"))
tip("Height: " + getFriendlyHeight(point));
} }
function highlightEditorLine(editor, id, timeout = 15000) { function highlightEditorLine(editor, id, timeout = 15000) {
Array.from(editor.getElementsByClassName("states hovered")).forEach(el => el.classList.remove("hovered")); // clear all hovered Array.from(editor.getElementsByClassName("states hovered")).forEach((el) =>
const hovered = Array.from(editor.querySelectorAll("div")).find(el => el.dataset.id == id); el.classList.remove("hovered")
); // clear all hovered
const hovered = Array.from(editor.querySelectorAll("div")).find(
(el) => el.dataset.id == id
);
if (hovered) hovered.classList.add("hovered"); // add hovered class if (hovered) hovered.classList.add("hovered"); // add hovered class
if (timeout) if (timeout)
setTimeout(() => { setTimeout(() => {
@ -228,23 +306,48 @@ function updateCellInfo(point, i, g) {
const x = (infoX.innerHTML = rn(point[0])); const x = (infoX.innerHTML = rn(point[0]));
const y = (infoY.innerHTML = rn(point[1])); const y = (infoY.innerHTML = rn(point[1]));
const f = cells.f[i]; const f = cells.f[i];
infoLat.innerHTML = toDMS(mapCoordinates.latN - (y / graphHeight) * mapCoordinates.latT, "lat"); infoLat.innerHTML = toDMS(
infoLon.innerHTML = toDMS(mapCoordinates.lonW + (x / graphWidth) * mapCoordinates.lonT, "lon"); mapCoordinates.latN - (y / graphHeight) * mapCoordinates.latT,
"lat"
);
infoLon.innerHTML = toDMS(
mapCoordinates.lonW + (x / graphWidth) * mapCoordinates.lonT,
"lon"
);
infoCell.innerHTML = i; infoCell.innerHTML = i;
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value; const unit =
infoArea.innerHTML = cells.area[i] ? si(cells.area[i] * distanceScaleInput.value ** 2) + unit : "n/a"; areaUnit.value === "square"
? " " + distanceUnitInput.value + "²"
: " " + areaUnit.value;
infoArea.innerHTML = cells.area[i]
? si(cells.area[i] * distanceScaleInput.value ** 2) + unit
: "n/a";
infoEvelation.innerHTML = getElevation(pack.features[f], pack.cells.h[i]); infoEvelation.innerHTML = getElevation(pack.features[f], pack.cells.h[i]);
infoDepth.innerHTML = getDepth(pack.features[f], pack.cells.h[i], point); infoDepth.innerHTML = getDepth(pack.features[f], pack.cells.h[i], point);
infoTemp.innerHTML = convertTemperature(grid.cells.temp[g]); infoTemp.innerHTML = convertTemperature(grid.cells.temp[g]);
infoPrec.innerHTML = cells.h[i] >= 20 ? getFriendlyPrecipitation(i) : "n/a"; infoPrec.innerHTML = cells.h[i] >= 20 ? getFriendlyPrecipitation(i) : "n/a";
infoRiver.innerHTML = cells.h[i] >= 20 && cells.r[i] ? getRiverInfo(cells.r[i]) : "no"; infoRiver.innerHTML =
infoState.innerHTML = cells.h[i] >= 20 ? (cells.state[i] ? `${pack.states[cells.state[i]].fullName} (${cells.state[i]})` : "neutral lands (0)") : "no"; cells.h[i] >= 20 && cells.r[i] ? getRiverInfo(cells.r[i]) : "no";
infoProvince.innerHTML = cells.province[i] ? `${pack.provinces[cells.province[i]].fullName} (${cells.province[i]})` : "no"; infoState.innerHTML =
infoCulture.innerHTML = cells.culture[i] ? `${pack.cultures[cells.culture[i]].name} (${cells.culture[i]})` : "no"; cells.h[i] >= 20
infoReligion.innerHTML = cells.religion[i] ? `${pack.religions[cells.religion[i]].name} (${cells.religion[i]})` : "no"; ? cells.state[i]
? `${pack.states[cells.state[i]].fullName} (${cells.state[i]})`
: "neutral lands (0)"
: "no";
infoProvince.innerHTML = cells.province[i]
? `${pack.provinces[cells.province[i]].fullName} (${cells.province[i]})`
: "no";
infoCulture.innerHTML = cells.culture[i]
? `${pack.cultures[cells.culture[i]].name} (${cells.culture[i]})`
: "no";
infoReligion.innerHTML = cells.religion[i]
? `${pack.religions[cells.religion[i]].name} (${cells.religion[i]})`
: "no";
infoPopulation.innerHTML = getFriendlyPopulation(i); infoPopulation.innerHTML = getFriendlyPopulation(i);
infoBurg.innerHTML = cells.burg[i] ? pack.burgs[cells.burg[i]].name + " (" + cells.burg[i] + ")" : "no"; infoBurg.innerHTML = cells.burg[i]
? pack.burgs[cells.burg[i]].name + " (" + cells.burg[i] + ")"
: "no";
infoFeature.innerHTML = f ? pack.features[f].group + " (" + f + ")" : "n/a"; infoFeature.innerHTML = f ? pack.features[f].group + " (" + f + ")" : "n/a";
infoBiome.innerHTML = biomesData.name[cells.biome[i]]; infoBiome.innerHTML = biomesData.name[cells.biome[i]];
} }
@ -255,7 +358,8 @@ function toDMS(coord, c) {
const minutesNotTruncated = (Math.abs(coord) - degrees) * 60; const minutesNotTruncated = (Math.abs(coord) - degrees) * 60;
const minutes = Math.floor(minutesNotTruncated); const minutes = Math.floor(minutesNotTruncated);
const seconds = Math.floor((minutesNotTruncated - minutes) * 60); const seconds = Math.floor((minutesNotTruncated - minutes) * 60);
const cardinal = c === "lat" ? (coord >= 0 ? "N" : "S") : coord >= 0 ? "E" : "W"; const cardinal =
c === "lat" ? (coord >= 0 ? "N" : "S") : coord >= 0 ? "E" : "W";
return degrees + "° " + minutes + " " + seconds + "″ " + cardinal; return degrees + "° " + minutes + " " + seconds + "″ " + cardinal;
} }
@ -310,13 +414,15 @@ function getFriendlyPrecipitation(i) {
} }
function getRiverInfo(id) { function getRiverInfo(id) {
const r = pack.rivers.find(r => r.i == id); const r = pack.rivers.find((r) => r.i == id);
return r ? `${r.name} ${r.type} (${id})` : "n/a"; return r ? `${r.name} ${r.type} (${id})` : "n/a";
} }
function getCellPopulation(i) { function getCellPopulation(i) {
const rural = pack.cells.pop[i] * populationRate; const rural = pack.cells.pop[i] * populationRate;
const urban = pack.cells.burg[i] ? pack.burgs[pack.cells.burg[i]].population * populationRate * urbanization : 0; const urban = pack.cells.burg[i]
? pack.burgs[pack.cells.burg[i]].population * populationRate * urbanization
: 0;
return [rural, urban]; return [rural, urban];
} }
@ -328,7 +434,9 @@ function getFriendlyPopulation(i) {
function getPopulationTip(i) { function getPopulationTip(i) {
const [rural, urban] = getCellPopulation(i); const [rural, urban] = getCellPopulation(i);
return `Cell population: ${si(rural + urban)}; Rural: ${si(rural)}; Urban: ${si(urban)}`; return `Cell population: ${si(rural + urban)}; Rural: ${si(
rural
)}; Urban: ${si(urban)}`;
} }
function highlightEmblemElement(type, el) { function highlightEmblemElement(type, el) {
@ -337,7 +445,7 @@ function highlightEmblemElement(type, el) {
const animation = d3.transition().duration(1000).ease(d3.easeSinIn); const animation = d3.transition().duration(1000).ease(d3.easeSinIn);
if (type === "burg") { if (type === "burg") {
const {x, y} = el; const { x, y } = el;
debug debug
.append("circle") .append("circle")
.attr("cx", x) .attr("cx", x)
@ -357,11 +465,13 @@ function highlightEmblemElement(type, el) {
const [x, y] = el.pole || pack.cells.p[el.center]; const [x, y] = el.pole || pack.cells.p[el.center];
const obj = type === "state" ? cells.state : cells.province; const obj = type === "state" ? cells.state : cells.province;
const borderCells = cells.i.filter(id => obj[id] === i && cells.c[id].some(n => obj[n] !== i)); const borderCells = cells.i.filter(
(id) => obj[id] === i && cells.c[id].some((n) => obj[n] !== i)
);
const data = Array.from(borderCells) const data = Array.from(borderCells)
.filter((c, i) => !(i % 2)) .filter((c, i) => !(i % 2))
.map(i => cells.p[i]) .map((i) => cells.p[i])
.map(i => [i[0], i[1], Math.hypot(i[0] - x, i[1] - y)]); .map((i) => [i[0], i[1], Math.hypot(i[0] - x, i[1] - y)]);
debug debug
.selectAll("line") .selectAll("line")
@ -370,19 +480,19 @@ function highlightEmblemElement(type, el) {
.append("line") .append("line")
.attr("x1", x) .attr("x1", x)
.attr("y1", y) .attr("y1", y)
.attr("x2", d => d[0]) .attr("x2", (d) => d[0])
.attr("y2", d => d[1]) .attr("y2", (d) => d[1])
.attr("stroke", "#d0240f") .attr("stroke", "#d0240f")
.attr("stroke-width", 0.5) .attr("stroke-width", 0.5)
.attr("opacity", 0.2) .attr("opacity", 0.2)
.attr("stroke-dashoffset", d => d[2]) .attr("stroke-dashoffset", (d) => d[2])
.attr("stroke-dasharray", d => d[2]) .attr("stroke-dasharray", (d) => d[2])
.transition(animation) .transition(animation)
.attr("stroke-dashoffset", 0) .attr("stroke-dashoffset", 0)
.attr("opacity", 1) .attr("opacity", 1)
.transition(animation) .transition(animation)
.delay(1000) .delay(1000)
.attr("stroke-dashoffset", d => d[2]) .attr("stroke-dashoffset", (d) => d[2])
.attr("opacity", 0) .attr("opacity", 0)
.remove(); .remove();
} }
@ -390,8 +500,14 @@ function highlightEmblemElement(type, el) {
// assign lock behavior // assign lock behavior
document.querySelectorAll("[data-locked]").forEach(function (e) { document.querySelectorAll("[data-locked]").forEach(function (e) {
e.addEventListener("mouseover", function (event) { e.addEventListener("mouseover", function (event) {
if (this.className === "icon-lock") tip("Click to unlock the option and allow it to be randomized on new map generation"); if (this.className === "icon-lock")
else tip("Click to lock the option and always use the current value on new map generation"); 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(); event.stopPropagation();
}); });
@ -433,7 +549,7 @@ function stored(option) {
} }
// assign skeaker behaviour // assign skeaker behaviour
Array.from(document.getElementsByClassName("speaker")).forEach(el => { Array.from(document.getElementsByClassName("speaker")).forEach((el) => {
const input = el.previousElementSibling; const input = el.previousElementSibling;
el.addEventListener("click", () => speak(input.value)); el.addEventListener("click", () => speak(input.value));
}); });
@ -450,7 +566,7 @@ function speak(text) {
// apply drop-down menu option. If the value is not in options, add it // apply drop-down menu option. If the value is not in options, add it
function applyOption(select, id, name = id) { function applyOption(select, id, name = id) {
const custom = !Array.from(select.options).some(o => o.value == id); const custom = !Array.from(select.options).some((o) => o.value == id);
if (custom) select.options.add(new Option(name, id)); if (custom) select.options.add(new Option(name, id));
select.value = id; select.value = id;
} }
@ -460,11 +576,20 @@ function showInfo() {
const Discord = link("https://discordapp.com/invite/X7E84HU", "Discord"); const Discord = link("https://discordapp.com/invite/X7E84HU", "Discord");
const Reddit = link("https://www.reddit.com/r/FantasyMapGenerator", "Reddit"); const Reddit = link("https://www.reddit.com/r/FantasyMapGenerator", "Reddit");
const Patreon = link("https://www.patreon.com/azgaar", "Patreon"); const Patreon = link("https://www.patreon.com/azgaar", "Patreon");
const Trello = link("https://trello.com/b/7x832DG4/fantasy-map-generator", "Trello"); const Trello = link(
"https://trello.com/b/7x832DG4/fantasy-map-generator",
"Trello"
);
const Armoria = link("https://azgaar.github.io/Armoria", "Armoria"); const Armoria = link("https://azgaar.github.io/Armoria", "Armoria");
const QuickStart = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Quick-Start-Tutorial", "Quick start tutorial"); const QuickStart = link(
const QAA = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A", "Q&A page"); "https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Quick-Start-Tutorial",
"Quick start tutorial"
);
const QAA = link(
"https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A",
"Q&A page"
);
alertMessage.innerHTML = ` alertMessage.innerHTML = `
<b>Fantasy Map Generator</b> (FMG) is an open-source application, it means the code is published an anyone can use it. <b>Fantasy Map Generator</b> (FMG) is an open-source application, it means the code is published an anyone can use it.
@ -482,10 +607,22 @@ function showInfo() {
<b>Links:</b> <b>Links:</b>
<ul style="columns:2"> <ul style="columns:2">
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator", "GitHub repository")}</li> <li>${link(
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/LICENSE", "License")}</li> "https://github.com/Azgaar/Fantasy-Map-Generator",
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog", "Changelog")}</li> "GitHub repository"
<li>${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Hotkeys", "Hotkeys")}</li> )}</li>
<li>${link(
"https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/LICENSE",
"License"
)}</li>
<li>${link(
"https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog",
"Changelog"
)}</li>
<li>${link(
"https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Hotkeys",
"Hotkeys"
)}</li>
</ul>`; </ul>`;
$("#alert").dialog({ $("#alert").dialog({
@ -495,8 +632,8 @@ function showInfo() {
buttons: { buttons: {
OK: function () { OK: function () {
$(this).dialog("close"); $(this).dialog("close");
} },
}, },
position: {my: "center", at: "center", of: "svg"} position: { my: "center", at: "center", of: "svg" },
}); });
} }

File diff suppressed because it is too large Load diff