-
-
-
+
+
+
diff --git a/charges/mullet6Pierced.svg b/charges/mullet6Pierced.svg
index 03be315a..a58b68e4 100644
--- a/charges/mullet6Pierced.svg
+++ b/charges/mullet6Pierced.svg
@@ -1,6 +1,6 @@
diff --git a/charges/mulletPierced.svg b/charges/mulletPierced.svg
index f1f67375..88f706b9 100644
--- a/charges/mulletPierced.svg
+++ b/charges/mulletPierced.svg
@@ -1,6 +1,6 @@
diff --git a/index.css b/index.css
index 2fff4e78..4390c271 100644
--- a/index.css
+++ b/index.css
@@ -2003,8 +2003,8 @@ svg.button {
}
#alertMessage ul {
- padding-left: 15px;
- margin: 10px 0;
+ padding-left: 1.2em;
+ margin: 1em 0;
}
.pseudoLink {
diff --git a/index.html b/index.html
index 06032157..5a33c573 100644
--- a/index.html
+++ b/index.html
@@ -1289,6 +1289,7 @@
+
diff --git a/main.js b/main.js
index c4f56173..37d89739 100644
--- a/main.js
+++ b/main.js
@@ -338,7 +338,7 @@ function applyDefaultBiomesSystem() {
}
function showWelcomeMessage() {
- const post = link("https://www.reddit.com/r/FantasyMapGenerator/comments/ft5b41/update_v15/", "Main changes:"); // announcement on Reddit
+ const post = "Main changes:" //link("https://www.reddit.com/r/FantasyMapGenerator/comments/ft5b41/update_v15/", "Main changes:");
const changelog = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog", "previous version");
const reddit = link("https://www.reddit.com/r/FantasyMapGenerator", "Reddit community");
const discord = link("https://discordapp.com/invite/X7E84HU", "Discord server");
@@ -347,18 +347,19 @@ function showWelcomeMessage() {
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version ${version}.
This version is compatible with ${changelog}, loaded .map files will be auto-updated.
${post}
- - Emblems generation
- - Emblem editor integrated with ${link("https://azgaar.github.io/Armoria", "Armoria")}
+ - State, province and burg Emblems generation
+ - Emblem editor integrated with ${link("https://azgaar.github.io/Armoria", "Armoria")} — our new dedicated Heraldry generator and editor
- Burg editor screen update
- Speak name functionality
+
Join our ${discord} and ${reddit} to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.
Thanks for all supporters on ${patreon}!`;
$("#alert").dialog(
{resizable: false, title: "Fantasy Map Generator update", width: "28em",
buttons: {OK: function() {$(this).dialog("close")}},
- position: {my: "center", at: "center", of: "svg"},
+ position: {my: "center center-80", at: "center", of: "svg"},
close: () => localStorage.setItem("version", version)}
);
}
diff --git a/modules/coa-generator.js b/modules/coa-generator.js
index 1afc64c0..2bdb195e 100644
--- a/modules/coa-generator.js
+++ b/modules/coa-generator.js
@@ -23,7 +23,7 @@
conventional: {
lozenge: 2, fusil: 4, mascle: 4, rustre: 2, lozengeFaceted: 3, lozengePloye: 1, roundel: 4, roundel2: 3, annulet: 4,
mullet: 5, mulletPierced: 1, mulletFaceted: 1, mullet4: 3, mullet6: 4, mullet6Pierced: 1, mullet6Faceted: 1, mullet7: 1, mullet8: 1, mullet10: 1,
- estoile: 1, compassRose: 1, billet: 5, delf: 0, triangle: 3, trianglePierced: 1, goutte: 4, heart: 4, pique: 2, сarreau: 1, trefle: 2,
+ estoile: 1, compassRose: 1, billet: 5, delf: 0, triangle: 3, trianglePierced: 1, goutte: 4, heart: 4, pique: 2, carreau: 1, trefle: 2,
fleurDeLis: 6, sun: 3, sunInSplendour: 1, crescent: 5, fountain: 1
},
crosses: {
@@ -398,10 +398,10 @@
function definePattern(pattern, element, size = "") {
let t1 = null, t2 = null;
- if (P(.15)) size = "-small";
- else if (P(.05)) size = "-smaller";
- else if (P(.035)) size = "-big";
- else if (P(.001)) size = "-smallest";
+ if (P(.1)) size = "-small";
+ else if (P(.1)) size = "-smaller";
+ else if (P(.01)) size = "-big";
+ else if (P(.005)) size = "-smallest";
// apply standard tinctures
if (P(.5) && ["vair", "vairInPale", "vairEnPointe"].includes(pattern)) {t1 = "azure"; t2 = "argent";}
diff --git a/modules/coa-renderer.js b/modules/coa-renderer.js
index d4ce075e..03716d7a 100644
--- a/modules/coa-renderer.js
+++ b/modules/coa-renderer.js
@@ -839,11 +839,7 @@
const divisionClip = division ? `${getTemplate(division.division, division.line)}` : "";
const loadedCharges = await getCharges(coa, id, shieldPath);
const loadedPatterns = getPatterns(coa, id);
- const blacklight = `
-
-
-
- `;
+ const blacklight = ``;
const field = ``;
const divisionGroup = division ? templateDivision() : "";
const overlay = ``;
@@ -855,6 +851,7 @@
// insert coa svg to defs
document.getElementById("coas").insertAdjacentHTML("beforeend", svg);
+ return true;
function templateDivision() {
let svg = "";
@@ -1000,10 +997,10 @@
}
function getSizeMod(size) {
- if (size === "small") return .5;
- if (size === "smaller") return .25;
- if (size === "smallest") return .125;
- if (size === "big") return 2;
+ if (size === "small") return .8;
+ if (size === "smaller") return .5;
+ if (size === "smallest") return .25;
+ if (size === "big") return 1.6;
return 1;
}
@@ -1027,7 +1024,7 @@
}
// render coa if does not exist
- const trigger = function(id, coa) {
+ const trigger = async function(id, coa) {
if (coa === "custom") {
console.warn("Cannot render custom emblem", coa);
return;
@@ -1036,7 +1033,7 @@
console.warn(`Emblem ${id} is undefined`);
return;
}
- if (!document.getElementById(id)) draw(id, coa);
+ if (!document.getElementById(id)) return draw(id, coa);
}
const add = function(type, i, coa, x, y) {
diff --git a/modules/ui/emblems-editor.js b/modules/ui/emblems-editor.js
index 0d9b4b58..a2a14520 100644
--- a/modules/ui/emblems-editor.js
+++ b/modules/ui/emblems-editor.js
@@ -271,41 +271,41 @@ function editEmblem(type, id, el) {
}
async function getURL(svg, size) {
- const clone = svg.cloneNode(true); // clone svg
- clone.setAttribute("width", size);
- clone.setAttribute("height", size);
- const serialized = (new XMLSerializer()).serializeToString(clone);
+ const serialized = getSVG(svg, size);
const blob = new Blob([serialized], {type: 'image/svg+xml;charset=utf-8'});
const url = window.URL.createObjectURL(blob);
window.setTimeout(() => window.URL.revokeObjectURL(url), 6000);
return url;
}
- function downloadGallery() {
+ function getSVG(svg, size) {
+ const clone = svg.cloneNode(true);
+ clone.setAttribute("width", size);
+ clone.setAttribute("height", size);
+ return (new XMLSerializer()).serializeToString(clone);
+ }
+
+ async function downloadGallery() {
const name = getFileName("Emblems Gallery");
const validStates = pack.states.filter(s => s.i && !s.removed && s.coa);
const validProvinces = pack.provinces.filter(p => p.i && !p.removed && p.coa);
const validBurgs = pack.burgs.filter(b => b.i && !b.removed && b.coa);
- triggerCOALoad(validStates, validProvinces, validBurgs);
- const timeout = (validStates.length + validProvinces.length + validBurgs.length) * 8;
- tip("Preparing to download...", true, "warn", timeout);
- d3.timeout(runDownload, timeout);
+ await renderAllEmblems(validStates, validProvinces, validBurgs);
+ runDownload();
function runDownload() {
const back = `Go Back`;
const stateSection = ``;
const provinceSections = validStates.map(state => {
const stateProvinces = validProvinces.filter(p => p.state === state.i);
const figures = stateProvinces.map(province => {
const el = document.getElementById("provinceCOA"+province.i);
- const svg = getSVG(el, province.coa, 200);
- return `${province.fullName}${svg}`;
+ return `${province.fullName}${getSVG(el, 200)}`;
}).join("");
return stateProvinces.length ? `${back}
${state.fullName} provinces
${figures}` : "";
}).join("");
@@ -316,8 +316,7 @@ function editEmblem(type, id, el) {
const provinceBurgs = stateBurgs.filter(b => pack.cells.province[b.cell] === province.i);
const provinceBurgFigures = provinceBurgs.map(burg => {
const el = document.getElementById("burgCOA"+burg.i);
- const svg = getSVG(el, burg.coa, 200);
- return `${burg.name}${svg}`;
+ return `${burg.name}${getSVG(el, 200)}`;
}).join("");
return provinceBurgs.length ? `${back}
${province.fullName} burgs
${provinceBurgFigures}` : "";
}).join("");
@@ -325,8 +324,7 @@ function editEmblem(type, id, el) {
const stateBurgOutOfProvinces = stateBurgs.filter(b => !pack.cells.province[b.cell]);
const stateBurgOutOfProvincesFigures = stateBurgOutOfProvinces.map(burg => {
const el = document.getElementById("burgCOA"+burg.i);
- const svg = getSVG(el, burg.coa, 200);
- return `${burg.name}${svg}`;
+ return `${burg.name}${getSVG(el, 200)}`;
}).join("");
if (stateBurgOutOfProvincesFigures) stateBurgSections += `${state.fullName} burgs under direct control
${stateBurgOutOfProvincesFigures}`;
return stateBurgSections;
@@ -335,8 +333,7 @@ function editEmblem(type, id, el) {
const neutralBurgs = validBurgs.filter(b => !b.state);
const neutralsSection = neutralBurgs.length ? "Independent burgs
" + neutralBurgs.map(burg => {
const el = document.getElementById("burgCOA"+burg.i);
- const svg = getSVG(el, burg.coa, 200);
- return `${burg.name}${svg}`;
+ return `${burg.name}${getSVG(el, 200)}`;
}).join("") + "" : "";
const FMG = `Azgaar's Fantasy Map Generator`;
@@ -367,10 +364,15 @@ function editEmblem(type, id, el) {
}
}
- function triggerCOALoad(states, provinces, burgs) {
- states.forEach(state => COArenderer.trigger("stateCOA"+state.i, state.coa));
- provinces.forEach(province => COArenderer.trigger("provinceCOA"+province.i, province.coa));
- burgs.forEach(burg => COArenderer.trigger("burgCOA"+burg.i, burg.coa));
+ async function renderAllEmblems(states, provinces, burgs) {
+ tip("Preparing for download...", true, "warn");
+
+ const statePromises = states.map(state => COArenderer.trigger("stateCOA"+state.i, state.coa));
+ const provincePromises = provinces.map(province => COArenderer.trigger("provinceCOA"+province.i, province.coa));
+ const burgPromises = burgs.map(burg => COArenderer.trigger("burgCOA"+burg.i, burg.coa));
+ const promises = [...statePromises, ...provincePromises, ...burgPromises];
+
+ return Promise.allSettled(promises).then(res => clearMainTip());
}
function dragEmblem() {
diff --git a/modules/ui/general.js b/modules/ui/general.js
index 90070057..4ad5a21f 100644
--- a/modules/ui/general.js
+++ b/modules/ui/general.js
@@ -19,6 +19,12 @@ document.getElementById("dialogs").addEventListener("mousemove", showDataTip);
document.getElementById("optionsContainer").addEventListener("mousemove", showDataTip);
document.getElementById("exitCustomization").addEventListener("mousemove", showDataTip);
+/**
+ * @param {string} tip Tooltip text
+ * @param {boolean} main Show above other tooltips
+ * @param {string} type Message type (color): error, warn, success
+ * @param {number} time Timeout to auto hide, ms
+ */
function tip(tip = "Tip is undefined", main, type, time) {
tooltip.innerHTML = tip;
tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #5e5c5c80, #ffffff00)";
diff --git a/modules/ui/tools.js b/modules/ui/tools.js
index 5269e185..51abcab0 100644
--- a/modules/ui/tools.js
+++ b/modules/ui/tools.js
@@ -14,6 +14,7 @@ toolsContent.addEventListener("click", function(event) {
if (button === "editDiplomacyButton") editDiplomacy(); else
if (button === "editCulturesButton") editCultures(); else
if (button === "editReligions") editReligions(); else
+ if (button === "editEmblemButton") openEmblemEditor(); else
if (button === "editNamesBaseButton") editNamesbase(); else
if (button === "editUnitsButton") editUnits(); else
if (button === "editNotesButton") editNotes(); else
@@ -72,6 +73,26 @@ function processFeatureRegeneration(event, button) {
if (button === "regenerateZones") regenerateZones(event);
}
+async function openEmblemEditor() {
+ let type, id, el;
+
+ if (pack.states[1]?.coa) {
+ type = "state";
+ id = "stateCOA1";
+ el = pack.states[1];
+ } else if (pack.burgs[1]?.coa) {
+ type = "burg";
+ id = "burgCOA1";
+ el = pack.burgs[1];
+ } else {
+ tip("No emblems to edit, please generate states and burgs first", false, "error");
+ return;
+ }
+
+ await COArenderer.trigger(id, el.coa);
+ editEmblem(type, id, el);
+}
+
function regenerateRivers() {
Rivers.generate();
Rivers.specify();