From b156f3cdf96846881f2687bf83c09cf1192bad85 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 25 Sep 2021 21:49:34 +0300 Subject: [PATCH] markers - generate from config file --- index.css | 27 +- index.html | 102 +--- main.js | 5 +- modules/load.js | 6 +- modules/markers-generator.js | 1084 ++++++++++++---------------------- modules/ui/tools.js | 114 ++-- 6 files changed, 499 insertions(+), 839 deletions(-) diff --git a/index.css b/index.css index 2630019b..e949d983 100644 --- a/index.css +++ b/index.css @@ -439,7 +439,32 @@ button.options:hover { cursor: pointer; } -input[type='color'] { +#options button i.icon-cog { + position: absolute; + padding: 0.1em 0.3em; + background-color: var(--bg-lighter); + border-radius: 50%; + visibility: hidden; + opacity: 0; + transition: 0.4s ease-in-out; +} + +#options button i.icon-cog:hover { + color: #111; + background-color: var(--bg-light); + transform: rotateZ(180deg); +} + +#options button i.icon-cog:active { + transform: translateY(1px); +} + +#options button:hover i.icon-cog { + visibility: visible; + opacity: 1; +} + +input[type="color"] { -webkit-appearance: none; cursor: pointer; border: 1px solid #a9a9a9; diff --git a/index.html b/index.html index f3dce305..10704deb 100644 --- a/index.html +++ b/index.html @@ -334,21 +334,12 @@ -
- - - - - - - -
-
Azgaar's
-
Fantasy Map Generator
-
v
-

LOADING...

-
-
+
+
Azgaar's
+
Fantasy Map Generator
+
v. 1.66
+

LOADING...

+
@@ -2016,68 +2007,25 @@
-

Click to regenerate:

-
- - - - - - - - - - - - - - - - -
+

Click to regenerate:

+
+ + + + + + + + + + + + + + + + +

Click to add:

diff --git a/main.js b/main.js index 737f972d..9be651b8 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,10 @@ // https://github.com/Azgaar/Fantasy-Map-Generator "use strict"; -// set debug options +const version = "1.662"; // generator version +document.title += " v" + version; + +// Switches to disable/enable logging features const PRODUCTION = location.hostname && location.hostname !== "localhost" && location.hostname !== "127.0.0.1"; const DEBUG = localStorage.getItem("debug"); const INFO = DEBUG || !PRODUCTION; diff --git a/modules/load.js b/modules/load.js index 5ab04034..0d90f389 100644 --- a/modules/load.js +++ b/modules/load.js @@ -877,8 +877,10 @@ function parseLoadedData(data) { borders.attr('style', null); } - // ecomonics: - // calculate salesTax for all states + if (version < 1.7) { + // v 1.7 changed markers data + // TODO: get markers data from svg + } })(); void (function checkDataIntegrity() { diff --git a/modules/markers-generator.js b/modules/markers-generator.js index eaa9ec02..5999f965 100644 --- a/modules/markers-generator.js +++ b/modules/markers-generator.js @@ -4,7 +4,6 @@ window.Markers = (function () { let config = []; let occupied = []; -<<<<<<< HEAD function getDefaultConfig() { const culturesSet = document.getElementById("culturesSet").value; const isFantasy = culturesSet.includes("Fantasy"); @@ -63,47 +62,10 @@ window.Markers = (function () { const generate = function () { setConfig(getDefaultConfig()); -======= - const generate = function () { ->>>>>>> 01fbfca0 (markers - generate tool + lock tooltip) pack.markers = []; generateTypes(); }; -<<<<<<< HEAD - const regenerate = () => { - pack.markers = pack.markers.filter(({i, lock, cell}) => { - if (lock) { - occupied[cell] = true; - return true; - } - const id = `marker${i}`; - document.getElementById(id)?.remove(); - const index = notes.findIndex(note => note.id === id); - if (index != -1) notes.splice(index, 1); - return false; - }); - - generateTypes(); - }; - - const add = marker => { - const base = config.find(c => c.type === marker.type); - if (base) { - const {icon, type, dx, dy, px} = base; - marker = addMarker({icon, type, dx, dy, px}, marker); - base.add("marker" + marker.i, marker.cell); - return marker; - } - - const i = last(pack.markers)?.i + 1 || 0; - pack.markers.push({...marker, i}); - occupied[marker.cell] = true; - return {...marker, i}; - }; - - function generateTypes() { -======= const regenerate = requestedMultiplier => { if (requestedMultiplier === 0) return; if (requestedMultiplier) multiplier = requestedMultiplier; @@ -111,49 +73,48 @@ window.Markers = (function () { }; const generateTypes = () => { ->>>>>>> 01fbfca0 (markers - generate tool + lock tooltip) TIME && console.time("addMarkers"); - config.forEach(({type, icon, dx, dy, px, min, each, multiplier, list, add}) => { - if (multiplier === 0) return; + const culturesSet = document.getElementById("culturesSet").value; + // TODO: don't put multiple markers to the same cell - let candidates = Array.from(list(pack)); - let quantity = getQuantity(candidates, min, each, multiplier); - // uncomment for debugging: - // console.log(`${icon} ${type}: each ${each} of ${candidates.length}, min ${min} candidates. Got ${quantity}`); + addVolcanoes(); + addHotSprings(); + addMines(); + addBridges(); + addInns(); + addLighthouses(); + addWaterfalls(); + addBattlefields(); + addDungeons(); + addLakeMonsters(); + addSeaMonsters(); + addHillMonsters(); + addSacredMountains(); + addSacredForests(); + addSacredPineries(); + addSacredPalmGroves(); + addBrigands(); + addPirates(); + addStatues(); + addRuines(); + if (culturesSet.includes("Fantasy")) addPortals(); - while (quantity && candidates.length) { - const [cell] = extractAnyElement(candidates); - const marker = addMarker({icon, type, dx, dy, px}, {cell}); - add("marker" + marker.i, cell); - quantity--; - } - }); - - occupied = []; TIME && console.timeEnd("addMarkers"); - } + }; -<<<<<<< HEAD - function getQuantity(array, min, each, multiplier) { - if (!array.length || array.length < min / multiplier) return 0; - const requestQty = Math.ceil((array.length / each) * multiplier); - return array.length < requestQty ? array.length : requestQty; - } -======= const getQuantity = (array, min, each) => { if (!array.length || array.length < min / multiplier) return 0; const requestQty = Math.ceil((array.length / each) * multiplier); return array.length < requestQty ? array.length : requestQty; }; ->>>>>>> 01fbfca0 (markers - generate tool + lock tooltip) - function extractAnyElement(array) { + const extractAnyElement = array => { const index = Math.floor(Math.random() * array.length); return array.splice(index, 1); - } + }; - function getMarkerCoordinates(cell) { + const getMarkerCoordinates = cell => { const {cells, burgs} = pack; const burgId = cells.burg[cell]; @@ -163,70 +124,69 @@ window.Markers = (function () { } return cells.p[cell]; - } + }; - function addMarker(base, marker) { - const i = last(pack.markers)?.i + 1 || 0; - const [x, y] = getMarkerCoordinates(marker.cell); - marker = {...base, x, y, ...marker, i}; - pack.markers.push(marker); - occupied[marker.cell] = true; - return marker; - } - - function deleteMarker(markerId) { - const noteId = "marker" + markerId; - notes = notes.filter(note => note.id !== noteId); - pack.markers = pack.markers.filter(m => m.i !== markerId); - } - - function listVolcanoes({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 70); - } - - function addVolcano(id, cell) { + function addVolcanoes() { const {cells} = pack; - const proper = Names.getCulture(cells.culture[cell]); - const name = P(0.3) ? "Mount " + proper : P(0.7) ? proper + " Volcano" : proper; - const status = P(0.6) ? "Dormant" : P(0.4) ? "Active" : "Erupting"; - notes.push({id, name, legend: `${status} volcano. Height: ${getFriendlyHeight(cells.p[cell])}.`}); + let mountains = Array.from(cells.i.filter(i => cells.h[i] >= 70).sort((a, b) => cells.h[b] - cells.h[a])); + let quantity = getQuantity(mountains, 10, 300); + if (!quantity) return; + const highestMountains = mountains.slice(0, 20); + + while (quantity) { + const [cell] = extractAnyElement(highestMountains); + const id = addMarker({cell, icon: "🌋", type: "volcano", dx: 52, px: 13}); + const proper = Names.getCulture(cells.culture[cell]); + const name = P(0.3) ? "Mount " + proper : Math.random() > 0.3 ? proper + " Volcano" : proper; + notes.push({id, name, legend: `Active volcano. Height: ${getFriendlyHeight(cells.p[cell])}`}); + quantity--; + } } - function listHotSprings({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] > 50); - } - - function addHotSpring(id, cell) { + function addHotSprings() { const {cells} = pack; - const proper = Names.getCulture(cells.culture[cell]); - const temp = convertTemperature(gauss(35, 15, 20, 100)); - const status = P(0.6) ? "geothermal" : P(0.4) ? "springwater" : "natural"; - notes.push({ - id, - name: proper + " Hot Springs", - legend: `A ${status} hot springs area. Average temperature: ${temp}.` - }); + let springs = Array.from(cells.i.filter(i => cells.h[i] > 50).sort((a, b) => cells.h[b] - cells.h[a])); + let quantity = getQuantity(springs, 30, 800); + if (!quantity) return; + const highestSprings = springs.slice(0, 40); + + while (quantity) { + const [cell] = extractAnyElement(highestSprings); + const id = addMarker({cell, icon: "♨️", type: "hot_springs", dy: 52}); + const proper = Names.getCulture(cells.culture[cell]); + const temp = convertTemperature(gauss(35, 15, 20, 100)); + notes.push({id, name: proper + " Hot Springs", legend: `A hot springs area. Average temperature: ${temp}`}); + quantity--; + } } - function listMines({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] > 47 && cells.burg[i]); - } - - function addMine(id, cell) { + function addMines() { const {cells} = pack; + let hillyBurgs = Array.from(cells.i.filter(i => cells.h[i] > 47 && cells.burg[i])); + let quantity = getQuantity(hillyBurgs, 1, 15); + if (!quantity) return; + const resources = {salt: 5, gold: 2, silver: 4, copper: 2, iron: 3, lead: 1, tin: 1}; - const resource = rw(resources); - const burg = pack.burgs[cells.burg[cell]]; - const name = `${burg.name} — ${resource} mining town`; - const population = rn(burg.population * populationRate * urbanization); - const legend = `${burg.name} is a mining town of ${population} people just nearby the ${resource} mine.`; - notes.push({id, name, legend}); + + while (quantity && hillyBurgs.length) { + const [cell] = extractAnyElement(hillyBurgs); + const id = addMarker({cell, icon: "⛏️", type: "mine", dx: 48, px: 13}); + const resource = rw(resources); + const burg = pack.burgs[cells.burg[cell]]; + const name = `${burg.name} — ${resource} mining town`; + const population = rn(burg.population * populationRate * urbanization); + const legend = `${burg.name} is a mining town of ${population} people just nearby the ${resource} mine`; + notes.push({id, name, legend}); + quantity--; + } } - function listBridges({cells, burgs}) { + function addBridges() { + const {cells, burgs} = pack; + const meanFlux = d3.mean(cells.fl.filter(fl => fl)); return cells.i.filter( i => @@ -237,43 +197,28 @@ window.Markers = (function () { cells.r[i] && cells.fl[i] > meanFlux ); + let quantity = getQuantity(bridges, 1, 5); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(bridges); + const id = addMarker({cell, icon: "🌉", type: "bridge", px: 14}); + const burg = pack.burgs[cells.burg[cell]]; + const river = pack.rivers.find(r => r.i === pack.cells.r[cell]); + const riverName = river ? `${river.name} ${river.type}` : "river"; + const name = river && P(0.2) ? river.name : burg.name; + notes.push({id, name: `${name} Bridge`, legend: `A stone bridge over the ${riverName} near ${burg.name}`}); + quantity--; + } } - function addBridge(id, cell) { + function addInns() { const {cells} = pack; - const burg = pack.burgs[cells.burg[cell]]; - const river = pack.rivers.find(r => r.i === pack.cells.r[cell]); - const riverName = river ? `${river.name} ${river.type}` : "river"; - const name = river && P(0.2) ? `${river.name} Bridge` : `${burg.name} Bridge`; - const weightedAdjectives = { - stone: 10, - wooden: 1, - lengthy: 2, - formidable: 2, - rickety: 1, - beaten: 1, - weathered: 1 - }; - const barriers = [ - "its collapse during the flood", - "being rumoured to attract trolls", - "the drying up of local trade", - "banditry infested the area", - "the old waypoints crumbled" - ]; - const legend = P(0.7) - ? `A ${rw(weightedAdjectives)} bridge spans over the ${riverName} near ${burg.name}.` - : `An old crossing of the ${riverName}, rarely used since ${ra(barriers)}.`; + let taverns = Array.from(cells.i.filter(i => cells.h[i] >= 20 && cells.road[i] > 4 && cells.pop[i] > 10)); + let quantity = getQuantity(taverns, 1, 100); + if (!quantity) return; - notes.push({id, name, legend}); - } - - function listInns({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.road[i] > 4 && cells.pop[i] > 10); - } - - function addInn(id, cell) { const colors = [ "Dark", "Light", @@ -516,187 +461,137 @@ window.Markers = (function () { "sap" ]; - const typeName = P(0.3) ? "inn" : "tavern"; - const isAnimalThemed = P(0.7); - const animal = ra(animals); - const name = isAnimalThemed - ? P(0.6) - ? ra(colors) + " " + animal - : ra(adjectives) + " " + animal - : ra(adjectives) + " " + capitalize(typeName); - const meal = isAnimalThemed && P(0.3) ? animal : ra(courses); - const course = `${ra(methods)} ${meal}`.toLowerCase(); - const drink = `${P(0.5) ? ra(types) : ra(colors)} ${ra(drinks)}`.toLowerCase(); - const legend = `A big and famous roadside ${typeName}. Delicious ${course} with ${drink} is served here.`; - notes.push({id, name: "The " + name, legend}); + while (quantity) { + const [cell] = extractAnyElement(taverns); + const id = addMarker({cell, icon: "🍻", type: "inn", px: 14}); + const type = P(0.3) ? "inn" : "tavern"; + const isAnimalThemed = P(0.7); + const animal = ra(animals); + const name = isAnimalThemed ? (P(0.6) ? ra(colors) + " " + animal : ra(adjectives) + " " + animal) : ra(adjectives) + " " + capitalize(type); + const meal = isAnimalThemed && P(0.3) ? animal : ra(courses); + const course = `${ra(methods)} ${meal}`.toLowerCase(); + const drink = `${P(0.5) ? ra(types) : ra(colors)} ${ra(drinks)}`.toLowerCase(); + const legend = `A big and famous roadside ${type}. Delicious ${course} with ${drink} is served here`; + notes.push({id, name: "The " + name, legend}); + quantity--; + } } - function listLighthouses({cells}) { - return cells.i.filter( - i => !occupied[i] && cells.harbor[i] > 6 && cells.c[i].some(c => cells.h[c] < 20 && cells.road[c]) - ); - } - - function addLighthouse(id, cell) { + function addLighthouses() { const {cells} = pack; - const proper = cells.burg[cell] ? pack.burgs[cells.burg[cell]].name : Names.getCulture(cells.culture[cell]); - notes.push({ - id, - name: getAdjective(proper) + " Lighthouse" + name, - legend: `A lighthouse to serve as a beacon for ships in the open sea.` - }); + const lighthouses = Array.from(cells.i.filter(i => cells.harbor[i] > 6 && cells.c[i].some(c => cells.h[c] < 20 && cells.road[c]))); + let quantity = getQuantity(lighthouses, 1, 2); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(lighthouses); + const id = addMarker({cell, icon: "🚨", type: "lighthouse", px: 14}); + const proper = cells.burg[cell] ? pack.burgs[cells.burg[cell]].name : Names.getCulture(cells.culture[cell]); + notes.push({id, name: getAdjective(proper) + " Lighthouse" + name, legend: `A lighthouse to keep the navigation safe`}); + quantity--; + } } - function listWaterfalls({cells}) { - return cells.i.filter( - i => cells.r[i] && !occupied[i] && cells.h[i] >= 50 && cells.c[i].some(c => cells.h[c] < 40 && cells.r[c]) - ); - } - - function addWaterfall(id, cell) { + function addWaterfalls() { const {cells} = pack; - const descriptions = [ - "A gorgeous waterfall flows here.", - "The rapids of an exceptionally beautiful waterfall.", - "An impressive waterfall has cut through the land.", - "The cascades of a stunning waterfall.", - "A river drops down from a great height forming a wonderous waterfall.", - "A breathtaking waterfall cuts through the landscape." - ]; + const waterfalls = Array.from(cells.i.filter(i => cells.r[i] && cells.h[i] >= 50 && cells.c[i].some(c => cells.h[c] < 40 && cells.r[c]))); + const quantity = getQuantity(waterfalls, 1, 5); + if (!quantity) return; - const proper = cells.burg[cell] ? pack.burgs[cells.burg[cell]].name : Names.getCulture(cells.culture[cell]); - notes.push({id, name: getAdjective(proper) + " Waterfall" + name, legend: `${ra(descriptions)}`}); + for (let i = 0; i < waterfalls.length && i < quantity; i++) { + const cell = waterfalls[i]; + const id = addMarker({cell, icon: "⟱", type: "waterfall", dy: 54, px: 16}); + const proper = cells.burg[cell] ? pack.burgs[cells.burg[cell]].name : Names.getCulture(cells.culture[cell]); + notes.push({id, name: getAdjective(proper) + " Waterfall" + name, legend: `An extremely beautiful waterfall`}); + } } - function listBattlefields({cells}) { - return cells.i.filter( - i => !occupied[i] && cells.state[i] && cells.pop[i] > 2 && cells.h[i] < 50 && cells.h[i] > 25 - ); - } - - function addBattlefield(id, cell) { + function addBattlefields() { const {cells, states} = pack; - const state = states[cells.state[cell]]; - if (!state.campaigns) state.campaigns = BurgsAndStates.generateCampaign(state); - const campaign = ra(state.campaigns); - const date = generateDate(campaign.start, campaign.end); - const name = Names.getCulture(cells.culture[cell]) + " Battlefield"; - const legend = `A historical battle of the ${campaign.name}. \r\nDate: ${date} ${options.era}.`; - notes.push({id, name, legend}); + let battlefields = Array.from(cells.i.filter(i => cells.state[i] && cells.pop[i] > 2 && cells.h[i] < 50 && cells.h[i] > 25)); + let quantity = getQuantity(battlefields, 50, 700); + if (!quantity) return; + + while (quantity && battlefields.length) { + const [cell] = extractAnyElement(battlefields); + const id = addMarker({cell, icon: "⚔️", type: "battlefield", dy: 52}); + const campaign = ra(states[cells.state[cell]].campaigns); + const date = generateDate(campaign.start, campaign.end); + const name = Names.getCulture(cells.culture[cell]) + " Battlefield"; + const legend = `A historical battle of the ${campaign.name}. \r\nDate: ${date} ${options.era}`; + notes.push({id, name, legend}); + quantity--; + } } - function listDungeons({cells}) { - return cells.i.filter(i => !occupied[i] && cells.pop[i] && cells.pop[i] < 3); - } - - function addDungeon(id, cell) { - const dungeonSeed = `${seed}${cell}`; - const name = "Dungeon"; - const legend = `
Undiscovered dungeon. See One page dungeon
`; - notes.push({id, name, legend}); - } - - function listLakeMonsters({features}) { - return features - .filter(feature => feature.type === "lake" && feature.group === "freshwater" && !occupied[feature.firstCell]) - .map(feature => feature.firstCell); - } - - function addLakeMonster(id, cell) { - const lake = pack.features[pack.cells.f[cell]]; - - // Check that the feature is a lake in case the user clicked on a wrong - // square - if (lake.type !== "lake") return; - - const name = `${lake.name} Monster`; - const length = gauss(10, 5, 5, 100); - const subjects = [ - "Locals", - "Elders", - "Inscriptions", - "Tipplers", - "Legends", - "Whispers", - "Rumors", - "Journeying folk", - "Tales" - ]; - const legend = `${ra(subjects)} say a relic monster of ${length} ${heightUnit.value} long inhabits ${ - lake.name - } Lake. Truth or lie, folks are afraid to fish in the lake.`; - notes.push({id, name, legend}); - } - - function listSeaMonsters({cells, features}) { - return cells.i.filter( - i => !occupied[i] && cells.h[i] < 20 && cells.road[i] && features[cells.f[i]].type === "ocean" - ); - } - - function addSeaMonster(id, cell) { - const name = `${Names.getCultureShort(0)} Monster`; - const length = gauss(25, 10, 10, 100); - const legend = `Old sailors tell stories of a gigantic sea monster inhabiting these dangerous waters. Rumors say it can be ${length} ${heightUnit.value} long.`; - notes.push({id, name, legend}); - } - - function listHillMonsters({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 50 && cells.pop[i]); - } - - function addHillMonster(id, cell) { + function addDungeons() { const {cells} = pack; - const adjectives = [ - "great", - "big", - "huge", - "prime", - "golden", - "proud", - "lucky", - "fat", - "giant", - "hungry", - "magical", - "superior", - "terrifying", - "horrifying", - "feared" - ]; - const subjects = [ - "Locals", - "Elders", - "Inscriptions", - "Tipplers", - "Legends", - "Whispers", - "Rumors", - "Journeying folk", - "Tales" - ]; - const species = [ - "Ogre", - "Troll", - "Cyclops", - "Giant", - "Monster", - "Beast", - "Dragon", - "Undead", - "Ghoul", - "Vampire", - "Hag", - "Banshee", - "Bearded Devil", - "Roc", - "Hydra", - "Warg" - ]; + let dungeons = Array.from(cells.i.filter(i => cells.pop[i] && cells.pop[i] < 3)); + let quantity = getQuantity(dungeons, 30, 200); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(dungeons); + const id = addMarker({cell, icon: "🗝️", type: "dungeon", dy: 51, px: 13}); + + const dungeonSeed = `${seed}${cell}`; + const name = "Dungeon"; + const legend = `
Undiscovered dungeon. See One page dungeon
`; + notes.push({id, name, legend}); + quantity--; + } + } + + function addLakeMonsters() { + const {features} = pack; + + const lakes = features.filter(feature => feature.type === "lake" && feature.group === "freshwater"); + let quantity = getQuantity(lakes, 2, 10); + if (!quantity) return; + + while (quantity) { + const [lake] = extractAnyElement(lakes); + const cell = lake.firstCell; + const id = addMarker({cell, icon: "🐉", type: "lake_monster", dy: 48}); + const name = `${lake.name} Monster`; + const length = gauss(10, 5, 5, 100); + const legend = `Rumors said a relic monster of ${length} ${heightUnit.value} long inhabits ${lake.name} Lake. Truth or lie, but folks are affraid to fish in the lake`; + notes.push({id, name, legend}); + quantity--; + } + } + + function addSeaMonsters() { + const {cells, features} = pack; + + const sea = Array.from(cells.i.filter(i => cells.h[i] < 20 && cells.road[i] && features[cells.f[i]].type === "ocean")); + let quantity = getQuantity(sea, 50, 700); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(sea); + const id = addMarker({cell, icon: "🦑", type: "sea_monster"}); + const name = `${Names.getCultureShort(0)} Monster`; + const length = gauss(25, 10, 10, 100); + const legend = `Old sailors tell stories of a gigantic sea monster inhabiting these dangerous waters. Rumors say it can be ${length} ${heightUnit.value} long`; + notes.push({id, name, legend}); + quantity--; + } + } + + function addHillMonsters() { + const {cells} = pack; + + const hills = Array.from(cells.i.filter(i => cells.h[i] >= 50 && cells.pop[i])); + let quantity = getQuantity(hills, 30, 600); + if (!quantity) return; + + const subjects = ["Locals", "Old folks", "Old books", "Tipplers"]; + const species = ["Ogre", "Troll", "Cyclops", "Giant", "Monster", "Beast", "Dragon", "Undead", "Ghoul", "Vampire"]; const modusOperandi = [ "steals cattle at night", "prefers eating children", @@ -711,99 +606,98 @@ window.Markers = (function () { "attacks unsuspecting victims" ]; - const monster = ra(species); - const toponym = Names.getCulture(cells.culture[cell]); - const name = `${toponym} ${monster}`; - const legend = `${ra(subjects)} speak of a ${ra(adjectives)} ${monster} who inhabits ${toponym} hills and ${ra( - modusOperandi - )}.`; - notes.push({id, name, legend}); + while (quantity) { + const [cell] = extractAnyElement(hills); + const id = addMarker({cell, icon: "👹", type: "hill_monster", dy: 54, px: 13}); + const monster = ra(species); + const toponym = Names.getCulture(cells.culture[cell]); + const name = `${toponym} ${monster}`; + const legend = `${ra(subjects)} tell tales of an old ${monster} who inhabits ${toponym} hills and ${ra(modusOperandi)}`; + notes.push({id, name, legend}); + quantity--; + } } - // Sacred mountains spawn on lonely mountains - function listSacredMountains({cells}) { - return cells.i.filter( - i => - !occupied[i] && - cells.h[i] >= 70 && - cells.c[i].some(c => cells.culture[c]) && - cells.c[i].every(c => cells.h[c] < 60) - ); + function addSacredMountains() { + const {cells, cultures} = pack; + + let lonelyMountains = Array.from(cells.i.filter(i => cells.h[i] >= 70 && cells.c[i].some(c => cells.culture[c]) && cells.c[i].every(c => cells.h[c] < 60))); + let quantity = getQuantity(lonelyMountains, 1, 5); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(lonelyMountains); + const id = addMarker({cell, icon: "🗻", type: "sacred_mountain", dy: 48}); + const culture = cells.c[cell].map(c => cells.culture[c]).find(c => c); + const name = `${Names.getCulture(culture)} Mountain`; + const height = getFriendlyHeight(cells.p[cell]); + const legend = `A sacred mountain of ${cultures[culture].name} culture. Height: ${height}`; + notes.push({id, name, legend}); + quantity--; + } } - function addSacredMountain(id, cell) { - const {cells, religions} = pack; + function addSacredForests() { + const {cells, cultures} = pack; - const culture = cells.c[cell].map(c => cells.culture[c]).find(c => c); - const religion = cells.religion[cell]; - const name = `${Names.getCulture(culture)} Mountain`; - const height = getFriendlyHeight(cells.p[cell]); - const legend = `A sacred mountain of ${religions[religion].name}. Height: ${height}.`; - notes.push({id, name, legend}); + let temperateForests = Array.from(cells.i.filter(i => cells.culture[i] && [6, 8].includes(cells.biome[i]))); + let quantity = getQuantity(temperateForests, 30, 1000); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(temperateForests); + const id = addMarker({cell, icon: "🌳", type: "sacred_forest"}); + const culture = cells.culture[cell]; + const name = `${Names.getCulture(culture)} Forest`; + const legend = `A sacred forest of ${cultures[culture].name} culture`; + notes.push({id, name, legend}); + quantity--; + } } - // Sacred forests spawn on temperate forests - function listSacredForests({cells}) { - return cells.i.filter( - i => !occupied[i] && cells.culture[i] && cells.religion[i] && [6, 8].includes(cells.biome[i]) - ); + function addSacredPineries() { + const {cells, cultures} = pack; + + let borealForests = Array.from(cells.i.filter(i => cells.culture[i] && cells.biome[i] === 9)); + let quantity = getQuantity(borealForests, 30, 800); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(borealForests); + const id = addMarker({cell, icon: "🌲", type: "pinery", px: 13}); + const culture = cells.culture[cell]; + const name = `${Names.getCulture(culture)} Pinery`; + const legend = `A sacred pinery of ${cultures[culture].name} culture`; + notes.push({id, name, legend}); + quantity--; + } } - function addSacredForest(id, cell) { - const {cells, cultures, religions} = pack; + function addSacredPalmGroves() { + const {cells, cultures} = pack; - const culture = cells.culture[cell]; - const religion = cells.religion[cell]; - const name = `${Names.getCulture(culture)} Forest`; - const legend = `A forest sacred to local ${religions[religion].name}.`; - notes.push({id, name, legend}); + let oasises = Array.from(cells.i.filter(i => cells.culture[i] && cells.biome[i] === 1 && cells.pop[i] > 1 && cells.road[i])); + let quantity = getQuantity(oasises, 1, 100); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(oasises); + const id = addMarker({cell, icon: "🌴", type: "palm_grove", px: 13}); + const culture = cells.culture[cell]; + const name = `${Names.getCulture(culture)} Palm Grove`; + const legend = `A sacred palm grove of ${cultures[culture].name} culture`; + notes.push({id, name, legend}); + quantity--; + } } - // Sacred pineries spawn on boreal forests - function listSacredPineries({cells}) { - return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.religion[i] && cells.biome[i] === 9); - } - - function addSacredPinery(id, cell) { - const {cells, cultures, religions} = pack; - - const culture = cells.culture[cell]; - const religion = cells.religion[cell]; - const name = `${Names.getCulture(culture)} Pinery`; - const legend = `A pinery sacred to local ${religions[religion].name}.`; - notes.push({id, name, legend}); - } - - // Sacred palm groves spawn on oasises - function listSacredPalmGroves({cells}) { - return cells.i.filter( - i => - !occupied[i] && - cells.culture[i] && - cells.religion[i] && - cells.biome[i] === 1 && - cells.pop[i] > 1 && - cells.road[i] - ); - } - - function addSacredPalmGrove(id, cell) { - const {cells, cultures, religions} = pack; - - const culture = cells.culture[cell]; - const religion = cells.religion[cell]; - const name = `${Names.getCulture(culture)} Palm Grove`; - const legend = `A palm grove sacred to local ${religions[religion].name}.`; - notes.push({id, name, legend}); - } - - function listBrigands({cells}) { - return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.road[i] > 4); - } - - function addBrigands(id, cell) { + function addBrigands() { const {cells} = pack; + let roads = Array.from(cells.i.filter(i => cells.culture[i] && cells.road[i] > 4)); + let quantity = getQuantity(roads, 50, 100); + if (!quantity) return; + const animals = [ "Apes", "Badgers", @@ -838,58 +732,55 @@ window.Markers = (function () { ]; const types = {brigands: 4, bandits: 3, robbers: 1, highwaymen: 1}; - const culture = cells.culture[cell]; - const biome = cells.biome[cell]; - const height = cells.p[cell]; - const locality = - height >= 70 - ? "highlander" - : [1, 2].includes(biome) - ? "desert" - : [3, 4].includes(biome) - ? "mounted" - : [5, 6, 7, 8, 9].includes(biome) - ? "forest" - : biome === 12 - ? "swamp" - : "angry"; - const name = `${Names.getCulture(culture)} ${ra(animals)}`; - const legend = `A gang of ${locality} ${rw(types)}.`; - notes.push({id, name, legend}); + while (quantity) { + const [cell] = extractAnyElement(roads); + const id = addMarker({cell, icon: "💰", type: "brigands", px: 13}); + const culture = cells.culture[cell]; + const biome = cells.biome[cell]; + const height = cells.p[cell]; + const locality = + height >= 70 + ? "highlander" + : [1, 2].includes(biome) + ? "desert" + : [3, 4].includes(biome) + ? "mounted" + : [5, 6, 7, 8, 9].includes(biome) + ? "forest" + : biome === 12 + ? "swamp" + : "angry"; + const name = `${Names.getCulture(culture)} ${ra(animals)}`; + const legend = `A gang of ${locality} ${rw(types)}`; + notes.push({id, name, legend}); + quantity--; + } } - // Pirates spawn on sea routes - function listPirates({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] < 20 && cells.road[i]); - } - - function addPirates(id, cell) { - const name = `Pirates`; - const legend = `Pirate ships have been spotted in these waters.`; - notes.push({id, name, legend}); - } - - function listStatues({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.h[i] < 40); - } - - function addStatue(id, cell) { + function addPirates() { const {cells} = pack; - const variants = [ - "Statue", - "Obelisk", - "Monument", - "Column", - "Monolith", - "Pillar", - "Megalith", - "Stele", - "Runestone", - "Sculpture", - "Effigy", - "Idol" - ]; + let searoutes = Array.from(cells.i.filter(i => cells.h[i] < 20 && cells.road[i])); + let quantity = getQuantity(searoutes, 40, 300); + if (!quantity) return; + + while (quantity) { + const [cell] = extractAnyElement(searoutes); + const id = addMarker({cell, type: "pirates", icon: "🏴‍☠️", dx: 51}); + const name = `Pirates`; + const legend = `Pirate ships have been spotted in these waters`; + notes.push({id, name, legend}); + quantity--; + } + } + + function addStatues() { + const {cells} = pack; + let statues = Array.from(cells.i.filter(i => cells.h[i] >= 20 && cells.h[i] < 40)); + let quantity = getQuantity(statues, 80, 1200); + if (!quantity) return; + + const types = ["Statue", "Obelisk", "Monument", "Column", "Monolith", "Pillar", "Megalith", "Stele", "Runestone"]; const scripts = { cypriot: "𐠁𐠂𐠃𐠄𐠅𐠈𐠊𐠋𐠌𐠍𐠎𐠏𐠐𐠑𐠒𐠓𐠔𐠕𐠖𐠗𐠘𐠙𐠚𐠛𐠜𐠝𐠞𐠟𐠠𐠡𐠢𐠣𐠤𐠥𐠦𐠧𐠨𐠩𐠪𐠫𐠬𐠭𐠮𐠯𐠰𐠱𐠲𐠳𐠴𐠵𐠷𐠸𐠼𐠿 ", geez: "ሀለሐመሠረሰቀበተኀነአከወዐዘየደገጠጰጸፀፈፐ ", @@ -898,16 +789,19 @@ window.Markers = (function () { mongolian: "᠀᠐᠑᠒ᠠᠡᠦᠧᠨᠩᠪᠭᠮᠯᠰᠱᠲᠳᠵᠻᠼᠽᠾᠿᡀᡁᡆᡍᡎᡏᡐᡑᡒᡓᡔᡕᡖᡗᡙᡜᡝᡞᡟᡠᡡᡭᡮᡯᡰᡱᡲᡳᡴᢀᢁᢂᢋᢏᢐᢑᢒᢓᢛᢜᢞᢟᢠᢡᢢᢤᢥᢦ" }; - const culture = cells.culture[cell]; + while (quantity) { + const [cell] = extractAnyElement(statues); + const id = addMarker({cell, icon: "🗿", type: "statues"}); + const culture = cells.culture[cell]; - const variant = ra(variants); - const name = `${Names.getCulture(culture)} ${variant}`; - const script = scripts[ra(Object.keys(scripts))]; - const inscription = Array(rand(40, 100)) - .fill(null) - .map(() => ra(script)) - .join(""); - const legend = `An ancient ${variant.toLowerCase()}. It has an inscription, but no one can translate it: + const type = ra(types); + const name = `${Names.getCulture(culture)} ${type}`; + const script = scripts[ra(Object.keys(scripts))]; + const inscription = Array(rand(40, 100)) + .fill(null) + .map(() => ra(script)) + .join(""); + const legend = `An ancient ${type.toLowerCase()}. It has an inscription, but no one can translate it:
${inscription}
`; notes.push({id, name, legend}); } @@ -916,22 +810,11 @@ window.Markers = (function () { return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.h[i] >= 20 && cells.h[i] < 60); } - function addRuins(id, cell) { - const types = [ - "City", - "Town", - "Settlement", - "Pyramid", - "Fort", - "Stronghold", - "Temple", - "Sacred site", - "Mausoleum", - "Outpost", - "Fortification", - "Fortress", - "Castle" - ]; + function addRuines() { + const {cells} = pack; + let ruins = Array.from(cells.i.filter(i => cells.culture[i] && cells.h[i] >= 20 && cells.h[i] < 60)); + let quantity = getQuantity(ruins, 80, 1200); + if (!quantity) return; const ruinType = ra(types); const name = `Ruined ${ruinType}`; @@ -939,253 +822,46 @@ window.Markers = (function () { notes.push({id, name, legend}); } - function listCircuses({cells}) { - return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.h[i] >= 20 && pack.cells.road[i]); - } + while (quantity) { + const [cell] = extractAnyElement(ruins); + const id = addMarker({cell, icon: "🏺", type: "ruins"}); - function addCircuses(id, cell) { - const adjectives = [ - "Fantastical", - "Wonderous", - "Incomprehensible", - "Magical", - "Extraordinary", - "Unmissable", - "World-famous", - "Breathtaking" - ]; - - const adjective = ra(adjectives); - const name = `Travelling ${adjective} Circus`; - const legend = `Roll up, roll up, this ${adjective.toLowerCase()} circus is here for a limited time only.`; - notes.push({id, name, legend}); - } - - function listJousts({cells, burgs}) { - return cells.i.filter(i => !occupied[i] && cells.burg[i] && burgs[cells.burg[i]].population > 20); - } - - function addJousts(id, cell) { - const {cells, burgs} = pack; - const types = ["Joust", "Competition", "Melee", "Tournament", "Contest"]; - const virtues = ["cunning", "might", "speed", "the greats", "acumen", "brutality"]; - - if (!cells.burg[cell]) return; - const burgName = burgs[cells.burg[cell]].name; - const type = ra(types); - const virtue = ra(virtues); - - const name = `${burgName} ${type}`; - const legend = `Warriors from around the land gather for a ${type.toLowerCase()} of ${virtue} in ${burgName}, with fame, fortune and favour on offer to the victor.`; - notes.push({id, name, legend}); - } - - function listCanoes({cells}) { - return cells.i.filter(i => !occupied[i] && cells.r[i]); - } - - function addCanoes(id, cell) { - const river = pack.rivers.find(r => r.i === pack.cells.r[cell]); - - const name = `Minor Jetty`; - const riverName = river ? `${river.name} ${river.type}` : "river"; - const legend = `A small location along the ${riverName} to launch boats from sits here, along with a weary looking owner, willing to sell passage along the river.`; - notes.push({id, name, legend}); - } - - function listMigrations({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.pop[i] <= 2); - } - - function addMigrations(id, cell) { - const animals = [ - "Antelopes", - "Apes", - "Badgers", - "Bears", - "Beavers", - "Bisons", - "Boars", - "Buffalo", - "Cats", - "Cranes", - "Crocodiles", - "Crows", - "Deer", - "Dogs", - "Eagles", - "Elk", - "Foxes", - "Goats", - "Geese", - "Hares", - "Hawks", - "Herons", - "Horses", - "Hyenas", - "Ibises", - "Jackals", - "Jaguars", - "Larks", - "Leopards", - "Lions", - "Mantises", - "Martens", - "Mooses", - "Mules", - "Owls", - "Panthers", - "Rats", - "Ravens", - "Rooks", - "Scorpions", - "Sharks", - "Sheep", - "Snakes", - "Spiders", - "Tigers", - "Wolves", - "Wolverines", - "Camels", - "Falcons", - "Hounds", - "Oxen" - ]; - const animalChoice = ra(animals); - - const name = `${animalChoice} migration`; - const legend = `A huge group of ${animalChoice.toLowerCase()} are migrating, whether part of their annual routine, or something more extraordinary.`; - notes.push({id, name, legend}); - } - - function listDances({cells, burgs}) { - return cells.i.filter(i => !occupied[i] && cells.burg[i] && burgs[cells.burg[i]].population > 15); - } - - function addDances(id, cell) { - const {cells, burgs} = pack; - const burgName = burgs[cells.burg[cell]].name; - const socialTypes = [ - "gala", - "dance", - "performance", - "ball", - "soiree", - "jamboree", - "exhibition", - "carnival", - "festival", - "jubilee" - ]; - const people = [ - "great and the good", - "nobility", - "local elders", - "foreign dignitaries", - "spiritual leaders", - "suspected revolutionaries" - ]; - const socialType = ra(socialTypes); - - const name = `${burgName} ${socialType}`; - const legend = `A ${socialType} has been organised at ${burgName} as a chance to gather the ${ra( - people - )} of the area together to be merry, make alliances and scheme around the crisis.`; - notes.push({id, name, legend}); - } - - function listMirage({cells}) { - return cells.i.filter(i => !occupied[i] && cells.biome[i] === 1); - } - - function addMirage(id, cell) { - const adjectives = ["Entrancing", "Diaphanous", "Illusory", "Distant", "Perculiar"]; - - const mirageAdjective = ra(adjectives); - const name = `${mirageAdjective} mirage`; - const legend = `This ${mirageAdjective.toLowerCase()} mirage has been luring travellers out of their way for eons.`; - notes.push({id, name, legend}); - } - - function listCaves({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 50 && cells.pop[i]); - } - - function addCaves(id, cell) { - const {cells} = pack; - - const formations = { - Cave: 10, - Cavern: 8, - Chasm: 6, - Ravine: 6, - Fracture: 5, - Grotto: 4, - Pit: 4, - Sinkhole: 2, - Hole: 2 - }; - const status = { - "a good spot to hid treasure": 5, - "the home of strange monsters": 5, - "totally empty": 4, - "endlessly deep and unexplored": 4, - "completely flooded": 2, - "slowly filling with lava": 1 - }; - - let formation = rw(formations); - const toponym = Names.getCulture(cells.culture[cell]); - if (cells.biome[cell] === 11) { - formation = "Glacial " + formation; + const type = ra(types); + const name = `Ruined ${type}`; + const legend = `Ruins of an ancient ${type.toLowerCase()}. A good place for a treasures hunt`; + notes.push({id, name, legend}); + quantity--; } - const name = `${toponym} ${formation}`; - const legend = `The ${name}. Locals claim that it is ${rw(status)}.`; - notes.push({id, name, legend}); } - function listPortals({burgs}) { - return burgs - .slice(1, Math.ceil(burgs.length / 10) + 1) - .filter(({cell}) => !occupied[cell]) - .map(burg => burg.cell); + function addPortals() { + const {burgs} = pack; + + let quantity = rand(5, 15); + if (burgs.length < quantity + 1) return; + let portals = burgs.slice(1, quantity + 1).map(burg => [burg.name, burg.cell]); + + while (quantity) { + const [portal] = extractAnyElement(portals); + const [burgName, cell] = portal; + const id = addMarker({cell, icon: "🌀", type: "portals", px: 14}); + const name = `${burgName} Portal`; + const legend = `An element of the magic portal system connecting major cities. Portals installed centuries ago, but still work fine`; + notes.push({id, name, legend}); + quantity--; + } } - function addPortal(id, cell) { - const {cells, burgs} = pack; - - if (!cells.burg[cell]) return; - const burgName = burgs[cells.burg[cell]].name; - - const name = `${burgName} Portal`; - const legend = `An element of the magic portal system connecting major cities. The portals were installed centuries ago, but still work fine.`; - notes.push({id, name, legend}); + function addMarker({cell, type, icon, dx, dy, px}) { + const i = pack.markers.length; + const [x, y] = getMarkerCoordinates(cell); + const marker = {i, icon, type, x, y}; + if (dx) marker.dx = dx; + if (dy) marker.dy = dy; + if (px) marker.px = px; + pack.markers.push(marker); + return "marker" + i; } -<<<<<<< HEAD - function listRifts({cells}) { - return cells.i.filter(i => !occupied[i] && pack.cells.pop[i] <= 3 && biomesData.habitability[pack.cells.biome[i]]); - } - - function addRifts(id, cell) { - const types = ["Demonic", "Interdimensional", "Abyssal", "Cosmic", "Cataclysmic", "Subterranean", "Ancient"]; - - const descriptions = [ - "all known nearby beings to flee in terror", - "cracks in reality itself to form", - "swarms of foes to spill forth", - "nearby plants to wither and decay", - "an emmissary to step through with an all-powerful relic" - ]; - - const riftType = ra(types); - const name = `${riftType} Rift`; - const legend = `A rumoured ${riftType.toLowerCase()} rift in this area is causing ${ra(descriptions)}.`; - notes.push({id, name, legend}); - } - - return {add, generate, regenerate, getConfig, setConfig, deleteMarker}; -======= return {generate, regenerate}; ->>>>>>> 01fbfca0 (markers - generate tool + lock tooltip) })(); diff --git a/modules/ui/tools.js b/modules/ui/tools.js index 06ca0ff8..73e8536b 100644 --- a/modules/ui/tools.js +++ b/modules/ui/tools.js @@ -1,36 +1,36 @@ -"use strict"; // module to control the Tools options (click to edit, to re-geenerate, tp add) +'use strict'; toolsContent.addEventListener("click", function (event) { if (customization) return tip("Please exit the customization mode first", false, "warning"); if (!["BUTTON", "I"].includes(event.target.tagName)) return; const button = event.target.id; - // click on open Editor buttons - if (button === "editHeightmapButton") editHeightmap(); - else if (button === "editBiomesButton") editBiomes(); - else if (button === "editStatesButton") editStates(); - else if (button === "editProvincesButton") editProvinces(); - else if (button === "editDiplomacyButton") editDiplomacy(); - else if (button === "editCulturesButton") editCultures(); - else if (button === "editReligions") editReligions(); + // Click to open Editor buttons + if (button === 'editHeightmapButton') editHeightmap(); + else if (button === 'editBiomesButton') editBiomes(); + else if (button === 'editStatesButton') editStates(); + else if (button === 'editProvincesButton') editProvinces(); + else if (button === 'editDiplomacyButton') editDiplomacy(); + else if (button === 'editCulturesButton') editCultures(); + else if (button === 'editReligions') editReligions(); else if (button === 'editResources') editResources(); - else if (button === "editEmblemButton") openEmblemEditor(); - else if (button === "editNamesBaseButton") editNamesbase(); - else if (button === "editUnitsButton") editUnits(); - else if (button === "editNotesButton") editNotes(); - else if (button === "editZonesButton") editZones(); - else if (button === "overviewChartsButton") overviewCharts(); - else if (button === "overviewBurgsButton") overviewBurgs(); - else if (button === "overviewRiversButton") overviewRivers(); - else if (button === "overviewMilitaryButton") overviewMilitary(); - else if (button === "overviewMarkersButton") overviewMarkers(); - else if (button === "overviewCellsButton") viewCellDetails(); + else if (button === 'editEmblemButton') openEmblemEditor(); + else if (button === 'editNamesBaseButton') editNamesbase(); + else if (button === 'editUnitsButton') editUnits(); + else if (button === 'editNotesButton') editNotes(); + else if (button === 'editZonesButton') editZones(); + else if (button === 'overviewBurgsButton') overviewBurgs(); + else if (button === 'overviewRiversButton') overviewRivers(); + else if (button === 'overviewMilitaryButton') overviewMilitary(); + else if (button === 'overviewCellsButton') viewCellDetails(); - // click on Regenerate buttons - if (event.target.parentNode.id === "regenerateFeature") { - const dontAsk = sessionStorage.getItem("regenerateFeatureDontAsk"); - if (dontAsk) return processFeatureRegeneration(event, button); + // Click to Regenerate buttons + if (event.target.parentNode.id === 'regenerateFeature') { + if (sessionStorage.getItem('regenerateFeatureDontAsk')) { + processFeatureRegeneration(event, button); + return; + } alertMessage.innerHTML = /* html */ `Regeneration will remove all the custom changes for the element.

Are you sure you want to proceed?`; $("#alert").dialog({ @@ -59,18 +59,12 @@ toolsContent.addEventListener("click", function (event) { }); } - // click on Configure regenerate buttons - if (button === "configRegenerateMarkers") configMarkersGeneration(); - - // click on Add buttons - if (button === "addLabel") toggleAddLabel(); - else if (button === "addBurgTool") toggleAddBurg(); - else if (button === "addRiver") toggleAddRiver(); - else if (button === "addRoute") toggleAddRoute(); - else if (button === "addMarker") toggleAddMarker(); - // click to create a new map buttons - else if (button === "openSubmapMenu") UISubmap.openSubmapMenu(); - else if (button === "openResampleMenu") UISubmap.openResampleMenu(); + // Click to Add buttons + if (button === 'addLabel') toggleAddLabel(); + else if (button === 'addBurgTool') toggleAddBurg(); + else if (button === 'addRiver') toggleAddRiver(); + else if (button === 'addRoute') toggleAddRoute(); + else if (button === 'addMarker') toggleAddMarker(); }); function processFeatureRegeneration(event, button) { @@ -82,20 +76,20 @@ function processFeatureRegeneration(event, button) { if (!layerIsOn("toggleRelief")) toggleRelief(); } else if (button === "regenerateRoutes") { Routes.regenerate(); - if (!layerIsOn("toggleRoutes")) toggleRoutes(); - } else if (button === "regenerateRivers") regenerateRivers(); - else if (button === "regeneratePopulation") recalculatePopulation(); - else if (button === "regenerateStates") regenerateStates(); - else if (button === "regenerateProvinces") regenerateProvinces(); - else if (button === "regenerateBurgs") regenerateBurgs(); + if (!layerIsOn('toggleRoutes')) toggleRoutes(); + } else if (button === 'regenerateRivers') regenerateRivers(); + else if (button === 'regeneratePopulation') recalculatePopulation(); + else if (button === 'regenerateStates') regenerateStates(); + else if (button === 'regenerateProvinces') regenerateProvinces(); + else if (button === 'regenerateBurgs') regenerateBurgs(); else if (button === 'regenerateResources') regenerateResources(); - else if (button === "regenerateEmblems") regenerateEmblems(); - else if (button === "regenerateReligions") regenerateReligions(); - else if (button === "regenerateCultures") regenerateCultures(); - else if (button === "regenerateMilitary") regenerateMilitary(); - else if (button === "regenerateIce") regenerateIce(); - else if (button === "regenerateMarkers") regenerateMarkers(); - else if (button === "regenerateZones") regenerateZones(event); + else if (button === 'regenerateEmblems') regenerateEmblems(); + else if (button === 'regenerateReligions') regenerateReligions(); + else if (button === 'regenerateCultures') regenerateCultures(); + else if (button === 'regenerateMilitary') regenerateMilitary(); + else if (button === 'regenerateIce') regenerateIce(); + else if (button === 'regenerateMarkers') regenerateMarkers(event); + else if (button === 'regenerateZones') regenerateZones(event); } async function openEmblemEditor() { @@ -443,11 +437,23 @@ function regenerateIce() { drawIce(); } -function regenerateMarkers() { - Markers.regenerate(); - turnButtonOn("toggleMarkers"); - drawMarkers(); - if (document.getElementById("markersOverviewRefresh").offsetParent) markersOverviewRefresh.click(); +function regenerateMarkers(event) { + if (isCtrlClick(event)) prompt("Please provide markers number multiplier", {default: 1, step: 0.01, min: 0, max: 100}, v => addNumberOfMarkers(v)); + else addNumberOfMarkers(); + + function addNumberOfMarkers(multiplier) { + pack.markers = pack.markers.filter(marker => { + if (marker.lock) return true; + document.getElementById(`marker${marker.i}`)?.remove(); + const index = notes.findIndex(note => note.id === marker.id); + if (index != -1) notes.splice(index, 1); + return false; + }); + + Markers.regenerate(multiplier); + turnButtonOn("toggleMarkers"); + drawMarkers(); + } } function regenerateZones(event) {