From edfcad4e8ced3d99732f85dfb262a1b6a9427426 Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Mon, 7 Mar 2022 19:29:08 +0000 Subject: [PATCH 1/7] Generate a legend for manually added markers (#753) Markers added by procedural generation have custom notes depending on the type of marker (e.g. dungeons have a procedurally generated map); however, the notes for markers manually added by the user are empty. This patch separates the cell selection logic from the legend and name generation logic in markers-generator.js, so that the latter can be shared with manually added markers. There is some additional simplifications such as storing the dx/dy/px/min/each values directly in the markers table to simplify the writing of the generic "list and add" loop in `generateTypes()`. Currently, the legend is only generated when adding a marker of the same type as an existing marker, and only when a legend generation function is available for that type. To generate a marker of a type that is not currently present on the map, one must first change the type field of an existing marker (which will not get a procedural note), then use "Add additional marker of that type". The UI for this can be improved later. Co-authored-by: Basile Clement --- modules/markers-generator.js | 687 +++++++++++++++-------------------- modules/ui/tools.js | 8 +- 2 files changed, 306 insertions(+), 389 deletions(-) diff --git a/modules/markers-generator.js b/modules/markers-generator.js index 50acf34d..5e3ea465 100644 --- a/modules/markers-generator.js +++ b/modules/markers-generator.js @@ -9,27 +9,27 @@ window.Markers = (function () { const isFantasy = culturesSet.includes("Fantasy"); return [ - {type: "volcanoes", icon: "🌋", multiplier: 1, fn: addVolcanoes}, - {type: "hot-springs", icon: "♨️", multiplier: 1, fn: addHotSprings}, - {type: "mines", icon: "⛏️", multiplier: 1, fn: addMines}, - {type: "bridges", icon: "🌉", multiplier: 1, fn: addBridges}, - {type: "inns", icon: "🍻", multiplier: 1, fn: addInns}, - {type: "lighthouses", icon: "🚨", multiplier: 1, fn: addLighthouses}, - {type: "waterfalls", icon: "⟱", multiplier: 1, fn: addWaterfalls}, - {type: "battlefields", icon: "⚔️", multiplier: 1, fn: addBattlefields}, - {type: "dungeons", icon: "🗝️", multiplier: 1, fn: addDungeons}, - {type: "lake-monsters", icon: "🐉", multiplier: 1, fn: addLakeMonsters}, - {type: "sea-monsters", icon: "🦑", multiplier: 1, fn: addSeaMonsters}, - {type: "hill-monsters", icon: "👹", multiplier: 1, fn: addHillMonsters}, - {type: "sacred-mountains", icon: "🗻", multiplier: 1, fn: addSacredMountains}, - {type: "sacred-forests", icon: "🌳", multiplier: 1, fn: addSacredForests}, - {type: "sacred-pineries", icon: "🌲", multiplier: 1, fn: addSacredPineries}, - {type: "sacred-palm-groves", icon: "🌴", multiplier: 1, fn: addSacredPalmGroves}, - {type: "brigands", icon: "💰", multiplier: 1, fn: addBrigands}, - {type: "pirates", icon: "🏴‍☠️", multiplier: 1, fn: addPirates}, - {type: "statues", icon: "🗿", multiplier: 1, fn: addStatues}, - {type: "ruines", icon: "🏺", multiplier: 1, fn: addRuines}, - {type: "portals", icon: "🌀", multiplier: +isFantasy, fn: addPortals} + {type: "volcanoes", icon: "🌋", dx: 52, px: 13, min: 10, each: 500, multiplier: 1, fn: [listVolcanoes, addVolcano]}, + {type: "hot-springs", icon: "♨️", dy: 52, min: 30, each: 1200, multiplier: 1, fn: [listHotSprings, addHotSpring]}, + {type: "mines", icon: "⛏️", dx: 48, px: 13, min: 1, each: 15, multiplier: 1, fn: [listMines, addMine]}, + {type: "bridges", icon: "🌉", px: 14, min: 1, each: 5, multiplier: 1, fn: [listBridges, addBridge]}, + {type: "inns", icon: "🍻", px: 14, min: 1, each: 100, multiplier: 1, fn: [listInns, addInn]}, + {type: "lighthouses", icon: "🚨", px: 14, min: 1, each: 2, multiplier: 1, fn: [listLighthouses, addLighthouse]}, + {type: "waterfalls", icon: "⟱", dy: 54, px: 16, min: 1, each: 5, multiplier: 1, fn: [listWaterfalls, addWaterfall]}, + {type: "battlefields", icon: "⚔️", dy: 52, min: 50, each: 700, multiplier: 1, fn: [listBattlefields, addBattlefield]}, + {type: "dungeons", icon: "🗝️", dy: 51, px: 13, min: 30, each: 200, multiplier: 1, fn: [listDungeons, addDungeon]}, + {type: "lake-monsters", icon: "🐉", dy: 48, min: 2, each: 10, multiplier: 1, fn: [listLakeMonsters, addLakeMonster]}, + {type: "sea-monsters", icon: "🦑", min: 50, each: 700, multiplier: 1, fn: [listSeaMonsters, addSeaMonster]}, + {type: "hill-monsters", icon: "👹", dy: 54, px: 13, min: 30, each: 600, multiplier: 1, fn: [listHillMonsters, addHillMonster]}, + {type: "sacred-mountains", icon: "🗻", dy: 48, min: 1, each: 5, multiplier: 1, fn: [listSacredMountains, addSacredMountain]}, + {type: "sacred-forests", icon: "🌳", min: 30, each: 1000, multiplier: 1, fn: [listSacredForests, addSacredForest]}, + {type: "sacred-pineries", icon: "🌲", px: 13, min: 30, each: 800, multiplier: 1, fn: [listSacredPineries, addSacredPinery]}, + {type: "sacred-palm-groves", icon: "🌴", px: 13, min: 1, each: 100, multiplier: 1, fn: [listSacredPalmGroves, addSacredPalmGrove]}, + {type: "brigands", icon: "💰", px: 13, min: 50, each: 100, multiplier: 1, fn: [listBrigands, addBrigands]}, + {type: "pirates", icon: "🏴‍☠️", dx: 51, min: 40, each: 300, multiplier: 1, fn: [listPirates, addPirates]}, + {type: "statues", icon: "🗿", min: 80, each: 1200, multiplier: 1, fn: [listStatues, addStatue]}, + {type: "ruines", icon: "🏺", min: 80, each: 1200, multiplier: 1, fn: [listRuins, addRuins]}, + {type: "portals", icon: "🌀", px: 14, min: 16, each: 8, multiplier: +isFantasy, fn: [listPortals, addPortal]} ]; } @@ -61,12 +61,36 @@ window.Markers = (function () { 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.fn[1]("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() { TIME && console.time("addMarkers"); - config.forEach(({type, icon, multiplier, fn}) => { + config.forEach(({type, icon, dx, dy, px, min, each, multiplier, fn}) => { if (multiplier === 0) return; - fn(type, icon, multiplier); + + let candidates = Array.from(fn[0](pack)); + let quantity = getQuantity(candidates, min, each, multiplier); + + while (quantity && candidates.length) { + const [cell] = extractAnyElement(candidates); + const marker = addMarker({icon, type, dx, dy, px}, {cell}); + fn[1]("marker" + marker.i, cell); + quantity--; + } }); occupied = []; @@ -96,112 +120,84 @@ window.Markers = (function () { return cells.p[cell]; } - function addMarker({cell, type, icon, dx, dy, px}) { + function addMarker(base, marker) { const i = last(pack.markers)?.i + 1 || 0; - const [x, y] = getMarkerCoordinates(cell); - const marker = {i, icon, type, x, y, cell}; - if (dx) marker.dx = dx; - if (dy) marker.dy = dy; - if (px) marker.px = px; + const [x, y] = getMarkerCoordinates(marker.cell); + marker = {...base, x, y, ...marker, i}; pack.markers.push(marker); - occupied[cell] = true; - return "marker" + i; + occupied[marker.cell] = true; + return marker; } - function addVolcanoes(type, icon, multiplier) { - const {cells} = pack; - - let mountains = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] >= 70).sort((a, b) => cells.h[b] - cells.h[a])); - let quantity = getQuantity(mountains, 10, 500, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(mountains); - const id = addMarker({cell, icon, type, 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 listVolcanoes({cells}) { + return cells.i.filter(i => !occupied[i] && cells.h[i] >= 70); } - function addHotSprings(type, icon, multiplier) { + function addVolcano(id, cell) { const {cells} = pack; - let springs = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] > 50).sort((a, b) => cells.h[b] - cells.h[a])); - let quantity = getQuantity(springs, 30, 1200, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(springs); - const id = addMarker({cell, icon, type, 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--; - } + 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])}`}); } - function addMines(type, icon, multiplier) { + function listHotSprings({cells}) { + return cells.i.filter(i => !occupied[i] && cells.h[i] > 50); + } + + function addHotSpring(id, cell) { const {cells} = pack; - let hillyBurgs = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] > 47 && cells.burg[i])); - let quantity = getQuantity(hillyBurgs, 1, 15, multiplier); - if (!quantity) return; + 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}`}); + } + + function listMines({cells}) { + return cells.i.filter(i => !occupied[i] && cells.h[i] > 47 && cells.burg[i]); + } + + function addMine(id, cell) { + const {cells} = pack; const resources = {salt: 5, gold: 2, silver: 4, copper: 2, iron: 3, lead: 1, tin: 1}; - - while (quantity && hillyBurgs.length) { - const [cell] = extractAnyElement(hillyBurgs); - const id = addMarker({cell, icon, type, 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--; - } + 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}); } - function addBridges(type, icon, multiplier) { - const {cells, burgs} = pack; - + function listBridges({cells, burgs}) { const meanFlux = d3.mean(cells.fl.filter(fl => fl)); - let bridges = Array.from( - cells.i.filter(i => !occupied[i] && cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux) - ); - let quantity = getQuantity(bridges, 1, 5, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(bridges); - const id = addMarker({cell, icon, type, 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; - const weightedAdjectives = { - stone: 10, - wooden: 1, - lengthy: 2, - formidable: 2, - rickety: 1, - beaten: 1, - weathered: 1 - }; - notes.push({id, name: `${name} Bridge`, legend: `A ${rw(weightedAdjectives)} bridge spans over the ${riverName} near ${burg.name}`}); - quantity--; - } + return cells.i.filter(i => !occupied[i] && cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux); } - function addInns(type, icon, multiplier) { + function addBridge(id, cell) { const {cells} = pack; - let taverns = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.road[i] > 4 && cells.pop[i] > 10)); - let quantity = getQuantity(taverns, 1, 100, multiplier); - if (!quantity) return; + 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; + const weightedAdjectives = { + stone: 10, + wooden: 1, + lengthy: 2, + formidable: 2, + rickety: 1, + beaten: 1, + weathered: 1 + }; + notes.push({id, name: `${name} Bridge`, legend: `A ${rw(weightedAdjectives)} bridge spans over the ${riverName} near ${burg.name}`}); + } + 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", @@ -430,44 +426,34 @@ window.Markers = (function () { "sap" ]; - while (quantity) { - const [cell] = extractAnyElement(taverns); - const id = addMarker({cell, icon, type, px: 14}); - 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(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 ${typeName}. Delicious ${course} with ${drink} is served here`; - notes.push({id, name: "The " + name, legend}); - quantity--; - } + 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}); } - function addLighthouses(type, icon, multiplier) { - const {cells} = pack; - - const lighthouses = Array.from(cells.i.filter(i => !occupied[i] && cells.harbor[i] > 6 && cells.c[i].some(c => cells.h[c] < 20 && cells.road[c]))); - let quantity = getQuantity(lighthouses, 1, 2, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(lighthouses); - const id = addMarker({cell, icon, type, 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 serve as a beacon for ships in the open sea`}); - 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 addWaterfalls(type, icon, multiplier) { + function addLighthouse(id, cell) { const {cells} = pack; - const waterfalls = Array.from(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]))); - const quantity = getQuantity(waterfalls, 1, 5, multiplier); - 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) + " Lighthouse" + name, legend: `A lighthouse to serve as a beacon for ships in the open sea`}); + } + + 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) { + const {cells} = pack; const descriptions = [ "A gorgeous waterfall flows here", @@ -477,98 +463,73 @@ window.Markers = (function () { "A river drops down from a great height forming a wonderous waterfall", "A breathtaking waterfall cuts through the landscape" ]; - for (let i = 0; i < waterfalls.length && i < quantity; i++) { - const cell = waterfalls[i]; - const id = addMarker({cell, icon, type, 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: `${ra(descriptions)}`}); - } + + 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)}`}); } - function addBattlefields(type, icon, multiplier) { + 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) { const {cells, states} = pack; - let battlefields = Array.from(cells.i.filter(i => !occupied[i] && cells.state[i] && cells.pop[i] > 2 && cells.h[i] < 50 && cells.h[i] > 25)); - let quantity = getQuantity(battlefields, 50, 700, multiplier); - if (!quantity) return; - - while (quantity && battlefields.length) { - const [cell] = extractAnyElement(battlefields); - const id = addMarker({cell, icon, type, dy: 52}); - 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}); - quantity--; - } + 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}); } - function addDungeons(type, icon, multiplier) { + 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 legend = `Rumors 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) { const {cells} = pack; - let dungeons = Array.from(cells.i.filter(i => !occupied[i] && cells.pop[i] && cells.pop[i] < 3)); - let quantity = getQuantity(dungeons, 30, 200, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(dungeons); - const id = addMarker({cell, icon, type, 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(type, icon, multiplier) { - const {features} = pack; - - const lakes = features.filter(feature => feature.type === "lake" && feature.group === "freshwater" && !occupied[feature.firstCell]); - let quantity = getQuantity(lakes, 2, 10, multiplier); - if (!quantity) return; - - while (quantity) { - const [lake] = extractAnyElement(lakes); - const cell = lake.firstCell; - const id = addMarker({cell, icon, type, dy: 48}); - const name = `${lake.name} Monster`; - const length = gauss(10, 5, 5, 100); - const legend = `Rumors 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}); - quantity--; - } - } - - function addSeaMonsters(type, icon, multiplier) { - const {cells, features} = pack; - - const sea = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] < 20 && cells.road[i] && features[cells.f[i]].type === "ocean")); - let quantity = getQuantity(sea, 50, 700, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(sea); - const id = addMarker({cell, icon, type}); - 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(type, icon, multiplier) { - const {cells} = pack; - - const hills = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] >= 50 && cells.pop[i])); - let quantity = getQuantity(hills, 30, 600, multiplier); - if (!quantity) return; - const adjectives = [ "great", "big", @@ -619,100 +580,77 @@ window.Markers = (function () { "attacks unsuspecting victims" ]; - while (quantity) { - const [cell] = extractAnyElement(hills); - const id = addMarker({cell, icon, type, dy: 54, px: 13}); - 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}); - quantity--; - } + 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}); } - function addSacredMountains(type, icon, multiplier) { + // 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 addSacredMountain(id, cell) { const {cells, cultures} = pack; - let lonelyMountains = Array.from( - 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)) - ); - let quantity = getQuantity(lonelyMountains, 1, 5, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(lonelyMountains); - const id = addMarker({cell, icon, type, 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--; - } + 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}); } - function addSacredForests(type, icon, multiplier) { + // Sacred forests spawn on temperate forests + function listSacredForests({cells}) { + return cells.i.filter(i => !occupied[i] && cells.culture[i] && [6, 8].includes(cells.biome[i])); + } + + function addSacredForest(id, cell) { const {cells, cultures} = pack; - let temperateForests = Array.from(cells.i.filter(i => !occupied[i] && cells.culture[i] && [6, 8].includes(cells.biome[i]))); - let quantity = getQuantity(temperateForests, 30, 1000, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(temperateForests); - const id = addMarker({cell, icon, type}); - 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--; - } + 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}); } - function addSacredPineries(type, icon, multiplier) { + // Sacred pineries spawn on boreal forests + function listSacredPineries({cells}) { + return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.biome[i] === 9); + } + + function addSacredPinery(id, cell) { const {cells, cultures} = pack; - let borealForests = Array.from(cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.biome[i] === 9)); - let quantity = getQuantity(borealForests, 30, 800, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(borealForests); - const id = addMarker({cell, icon, type, 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--; - } + 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}); } - function addSacredPalmGroves(type, icon, multiplier) { + // Sacred palm groves spawn on oasises + function listSacredPalmGroves({cells}) { + return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.biome[i] === 1 && cells.pop[i] > 1 && cells.road[i]); + } + + function addSacredPalmGrove(id, cell) { const {cells, cultures} = pack; - let oasises = Array.from(cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.biome[i] === 1 && cells.pop[i] > 1 && cells.road[i])); - let quantity = getQuantity(oasises, 1, 100, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(oasises); - const id = addMarker({cell, icon, type, 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--; - } + 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}); } - function addBrigands(type, icon, multiplier) { + function listBrigands({cells}) { + return cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.road[i] > 4); + } + + function addBrigands(id, cell) { const {cells} = pack; - let roads = Array.from(cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.road[i] > 4)); - let quantity = getQuantity(roads, 50, 100, multiplier); - if (!quantity) return; - const animals = [ "Apes", "Badgers", @@ -747,53 +685,43 @@ window.Markers = (function () { ]; const types = {brigands: 4, bandits: 3, robbers: 1, highwaymen: 1}; - while (quantity) { - const [cell] = extractAnyElement(roads); - const id = addMarker({cell, icon, type, 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--; - } + 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}); } - function addPirates(type, icon, multiplier) { - const {cells} = pack; - - let searoutes = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] < 20 && cells.road[i])); - let quantity = getQuantity(searoutes, 40, 300, multiplier); - if (!quantity) return; - - while (quantity) { - const [cell] = extractAnyElement(searoutes); - const id = addMarker({cell, icon, type, dx: 51}); - const name = `Pirates`; - const legend = `Pirate ships have been spotted in these waters`; - 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 addStatues(type, icon, multiplier) { + 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) { const {cells} = pack; - let statues = Array.from(cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.h[i] < 40)); - let quantity = getQuantity(statues, 80, 1200, multiplier); - if (!quantity) return; const variants = ["Statue", "Obelisk", "Monument", "Column", "Monolith", "Pillar", "Megalith", "Stele", "Runestone", "Sculpture", "Effigy", "Idol"]; const scripts = { @@ -804,31 +732,25 @@ window.Markers = (function () { mongolian: "᠀᠐᠑᠒ᠠᠡᠦᠧᠨᠩᠪᠭᠮᠯᠰᠱᠲᠳᠵᠻᠼᠽᠾᠿᡀᡁᡆᡍᡎᡏᡐᡑᡒᡓᡔᡕᡖᡗᡙᡜᡝᡞᡟᡠᡡᡭᡮᡯᡰᡱᡲᡳᡴᢀᢁᢂᢋᢏᢐᢑᢒᢓᢛᢜᢞᢟᢠᢡᢢᢤᢥᢦ" }; - while (quantity) { - const [cell] = extractAnyElement(statues); - const id = addMarker({cell, icon, type}); - const culture = cells.culture[cell]; + 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 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:
${inscription}
`; - notes.push({id, name, legend}); - quantity--; - } + notes.push({id, name, legend}); } - function addRuines(type, icon, multiplier) { - const {cells} = pack; - let ruins = Array.from(cells.i.filter(i => !occupied[i] && cells.culture[i] && cells.h[i] >= 20 && cells.h[i] < 60)); - let quantity = getQuantity(ruins, 80, 1200, multiplier); - if (!quantity) return; + function listRuins({cells}) { + 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", @@ -845,37 +767,30 @@ window.Markers = (function () { "Castle" ]; - while (quantity) { - const [cell] = extractAnyElement(ruins); - const id = addMarker({cell, icon, type}); - - const ruinType = ra(types); - const name = `Ruined ${ruinType}`; - const legend = `Ruins of an ancient ${ruinType.toLowerCase()}. Untold riches may lie within.`; - notes.push({id, name, legend}); - quantity--; - } + const ruinType = ra(types); + const name = `Ruined ${ruinType}`; + const legend = `Ruins of an ancient ${ruinType.toLowerCase()}. Untold riches may lie within.`; + notes.push({id, name, legend}); } - function addPortals(type, icon, multiplier) { - const {burgs} = pack; - let portals = burgs + function listPortals({burgs}) { + return burgs .slice(1, Math.ceil(burgs.length / 10) + 1) .filter(({cell}) => !occupied[cell]) - .map(burg => [burg.name, burg.cell]); - let quantity = getQuantity(portals, 16, 8, multiplier); - if (!quantity) return; - - while (quantity) { - const [portal] = extractAnyElement(portals); - const [burgName, cell] = portal; - const id = addMarker({cell, icon, type, 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--; - } + .map(burg => burg.cell); } - return {generate, regenerate, getConfig, setConfig}; + function addPortal(id, cell) { + const {cells, burgs} = pack; + + // Portals can only be added to burgs + 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. Portals installed centuries ago, but still work fine`; + notes.push({id, name, legend}); + } + + return {add, generate, regenerate, getConfig, setConfig}; })(); diff --git a/modules/ui/tools.js b/modules/ui/tools.js index aeed31ff..aec92311 100644 --- a/modules/ui/tools.js +++ b/modules/ui/tools.js @@ -706,14 +706,16 @@ function addMarkerOnClick() { const point = d3.mouse(this); const x = rn(point[0], 2); const y = rn(point[1], 2); - const i = markers.length ? last(markers).i + 1 : 0; + // Find the current cell + const cell = findCell(point[0], point[1]); + + // Find the currently selected marker to use as a base const isMarkerSelected = markers.length && elSelected?.node()?.parentElement?.id === "markers"; const selectedMarker = isMarkerSelected ? markers.find(marker => marker.i === +elSelected.attr("id").slice(6)) : null; const baseMarker = selectedMarker || {icon: "❓"}; - const marker = {...baseMarker, i, x, y}; + const marker = Markers.add({...baseMarker, x, y, cell}); - markers.push(marker); const markersElement = document.getElementById("markers"); const rescale = +markersElement.getAttribute("rescale"); markersElement.insertAdjacentHTML("beforeend", drawMarker(marker, rescale)); From bc02850cf7cf7bceb6f63c02c5d01cff03514657 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 7 Mar 2022 22:59:43 +0300 Subject: [PATCH 2/7] split array to separate functions --- modules/markers-generator.js | 80 +++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/modules/markers-generator.js b/modules/markers-generator.js index 5e3ea465..6c3e0398 100644 --- a/modules/markers-generator.js +++ b/modules/markers-generator.js @@ -9,27 +9,27 @@ window.Markers = (function () { const isFantasy = culturesSet.includes("Fantasy"); return [ - {type: "volcanoes", icon: "🌋", dx: 52, px: 13, min: 10, each: 500, multiplier: 1, fn: [listVolcanoes, addVolcano]}, - {type: "hot-springs", icon: "♨️", dy: 52, min: 30, each: 1200, multiplier: 1, fn: [listHotSprings, addHotSpring]}, - {type: "mines", icon: "⛏️", dx: 48, px: 13, min: 1, each: 15, multiplier: 1, fn: [listMines, addMine]}, - {type: "bridges", icon: "🌉", px: 14, min: 1, each: 5, multiplier: 1, fn: [listBridges, addBridge]}, - {type: "inns", icon: "🍻", px: 14, min: 1, each: 100, multiplier: 1, fn: [listInns, addInn]}, - {type: "lighthouses", icon: "🚨", px: 14, min: 1, each: 2, multiplier: 1, fn: [listLighthouses, addLighthouse]}, - {type: "waterfalls", icon: "⟱", dy: 54, px: 16, min: 1, each: 5, multiplier: 1, fn: [listWaterfalls, addWaterfall]}, - {type: "battlefields", icon: "⚔️", dy: 52, min: 50, each: 700, multiplier: 1, fn: [listBattlefields, addBattlefield]}, - {type: "dungeons", icon: "🗝️", dy: 51, px: 13, min: 30, each: 200, multiplier: 1, fn: [listDungeons, addDungeon]}, - {type: "lake-monsters", icon: "🐉", dy: 48, min: 2, each: 10, multiplier: 1, fn: [listLakeMonsters, addLakeMonster]}, - {type: "sea-monsters", icon: "🦑", min: 50, each: 700, multiplier: 1, fn: [listSeaMonsters, addSeaMonster]}, - {type: "hill-monsters", icon: "👹", dy: 54, px: 13, min: 30, each: 600, multiplier: 1, fn: [listHillMonsters, addHillMonster]}, - {type: "sacred-mountains", icon: "🗻", dy: 48, min: 1, each: 5, multiplier: 1, fn: [listSacredMountains, addSacredMountain]}, - {type: "sacred-forests", icon: "🌳", min: 30, each: 1000, multiplier: 1, fn: [listSacredForests, addSacredForest]}, - {type: "sacred-pineries", icon: "🌲", px: 13, min: 30, each: 800, multiplier: 1, fn: [listSacredPineries, addSacredPinery]}, - {type: "sacred-palm-groves", icon: "🌴", px: 13, min: 1, each: 100, multiplier: 1, fn: [listSacredPalmGroves, addSacredPalmGrove]}, - {type: "brigands", icon: "💰", px: 13, min: 50, each: 100, multiplier: 1, fn: [listBrigands, addBrigands]}, - {type: "pirates", icon: "🏴‍☠️", dx: 51, min: 40, each: 300, multiplier: 1, fn: [listPirates, addPirates]}, - {type: "statues", icon: "🗿", min: 80, each: 1200, multiplier: 1, fn: [listStatues, addStatue]}, - {type: "ruines", icon: "🏺", min: 80, each: 1200, multiplier: 1, fn: [listRuins, addRuins]}, - {type: "portals", icon: "🌀", px: 14, min: 16, each: 8, multiplier: +isFantasy, fn: [listPortals, addPortal]} + {type: "volcanoes", icon: "🌋", dx: 52, px: 13, min: 10, each: 500, multiplier: 1, list: listVolcanoes, add: addVolcano}, + {type: "hot-springs", icon: "♨️", dy: 52, min: 30, each: 1200, multiplier: 1, list: listHotSprings, add: addHotSpring}, + {type: "mines", icon: "⛏️", dx: 48, px: 13, min: 1, each: 15, multiplier: 1, list: listMines, add: addMine}, + {type: "bridges", icon: "🌉", px: 14, min: 1, each: 5, multiplier: 1, list: listBridges, add: addBridge}, + {type: "inns", icon: "🍻", px: 14, min: 1, each: 100, multiplier: 1, list: listInns, add: addInn}, + {type: "lighthouses", icon: "🚨", px: 14, min: 1, each: 2, multiplier: 1, list: listLighthouses, add: addLighthouse}, + {type: "waterfalls", icon: "⟱", dy: 54, px: 16, min: 1, each: 5, multiplier: 1, list: listWaterfalls, add: addWaterfall}, + {type: "battlefields", icon: "⚔️", dy: 52, min: 50, each: 700, multiplier: 1, list: listBattlefields, add: addBattlefield}, + {type: "dungeons", icon: "🗝️", dy: 51, px: 13, min: 30, each: 200, multiplier: 1, list: listDungeons, add: addDungeon}, + {type: "lake-monsters", icon: "🐉", dy: 48, min: 2, each: 10, multiplier: 1, list: listLakeMonsters, add: addLakeMonster}, + {type: "sea-monsters", icon: "🦑", min: 50, each: 700, multiplier: 1, list: listSeaMonsters, add: addSeaMonster}, + {type: "hill-monsters", icon: "👹", dy: 54, px: 13, min: 30, each: 600, multiplier: 1, list: listHillMonsters, add: addHillMonster}, + {type: "sacred-mountains", icon: "🗻", dy: 48, min: 1, each: 5, multiplier: 1, list: listSacredMountains, add: addSacredMountain}, + {type: "sacred-forests", icon: "🌳", min: 30, each: 1000, multiplier: 1, list: listSacredForests, add: addSacredForest}, + {type: "sacred-pineries", icon: "🌲", px: 13, min: 30, each: 800, multiplier: 1, list: listSacredPineries, add: addSacredPinery}, + {type: "sacred-palm-groves", icon: "🌴", px: 13, min: 1, each: 100, multiplier: 1, list: listSacredPalmGroves, add: addSacredPalmGrove}, + {type: "brigands", icon: "💰", px: 13, min: 50, each: 100, multiplier: 1, list: listBrigands, add: addBrigands}, + {type: "pirates", icon: "🏴‍☠️", dx: 51, min: 40, each: 300, multiplier: 1, list: listPirates, add: addPirates}, + {type: "statues", icon: "🗿", min: 80, each: 1200, multiplier: 1, list: listStatues, add: addStatue}, + {type: "ruines", icon: "🏺", min: 80, each: 1200, multiplier: 1, list: listRuins, add: addRuins}, + {type: "portals", icon: "🌀", px: 14, min: 16, each: 8, multiplier: +isFantasy, list: listPortals, add: addPortal} ]; } @@ -66,7 +66,7 @@ window.Markers = (function () { if (base) { const {icon, type, dx, dy, px} = base; marker = addMarker({icon, type, dx, dy, px}, marker); - base.fn[1]("marker" + marker.i, marker.cell); + base.add("marker" + marker.i, marker.cell); return marker; } @@ -79,16 +79,16 @@ window.Markers = (function () { function generateTypes() { TIME && console.time("addMarkers"); - config.forEach(({type, icon, dx, dy, px, min, each, multiplier, fn}) => { + config.forEach(({type, icon, dx, dy, px, min, each, multiplier, list, add}) => { if (multiplier === 0) return; - let candidates = Array.from(fn[0](pack)); + let candidates = Array.from(list(pack)); let quantity = getQuantity(candidates, min, each, multiplier); while (quantity && candidates.length) { const [cell] = extractAnyElement(candidates); const marker = addMarker({icon, type, dx, dy, px}, {cell}); - fn[1]("marker" + marker.i, cell); + add("marker" + marker.i, cell); quantity--; } }); @@ -171,7 +171,9 @@ window.Markers = (function () { function listBridges({cells, burgs}) { const meanFlux = d3.mean(cells.fl.filter(fl => fl)); - return cells.i.filter(i => !occupied[i] && cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux); + return cells.i.filter( + i => !occupied[i] && cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux + ); } function addBridge(id, cell) { @@ -496,7 +498,9 @@ window.Markers = (function () { } function listLakeMonsters({features}) { - return features.filter(feature => feature.type === "lake" && feature.group === "freshwater" && !occupied[feature.firstCell]).map(feature => feature.firstCell); + return features + .filter(feature => feature.type === "lake" && feature.group === "freshwater" && !occupied[feature.firstCell]) + .map(feature => feature.firstCell); } function addLakeMonster(id, cell) { @@ -690,16 +694,16 @@ window.Markers = (function () { 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"; + ? "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}); @@ -717,7 +721,7 @@ window.Markers = (function () { } function listStatues({cells}) { - return cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.h[i] < 40); + return cells.i.filter(i => !occupied[i] && cells.h[i] >= 20 && cells.h[i] < 40); } function addStatue(id, cell) { From d19ea0896d571ea09cb08397b6bc96192430ec31 Mon Sep 17 00:00:00 2001 From: evolvedexperiment <55178666+evolvedexperiment@users.noreply.github.com> Date: Tue, 15 Mar 2022 10:50:48 +0200 Subject: [PATCH 3/7] Old World template by ReneHP (#758) --- index.html | 2 ++ modules/heightmap-templates.js | 53 +++++++++++++++++++++++++++++++++- modules/ui/options.js | 9 +++--- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 653052e6..a5733917 100644 --- a/index.html +++ b/index.html @@ -959,6 +959,7 @@ + @@ -2399,6 +2400,7 @@ +
diff --git a/modules/heightmap-templates.js b/modules/heightmap-templates.js index 3704a3e4..bd371e10 100644 --- a/modules/heightmap-templates.js +++ b/modules/heightmap-templates.js @@ -119,5 +119,56 @@ window.HeightmapTemplates = (function () { Hill 3-4 60-85 20-80 0-5 Hill 3-4 60-85 20-80 95-100`; - return {volcano, highIsland, lowIsland, continents, archipelago, atoll, mediterranean, peninsula, peninsula, pangea, isthmus, shattered, taklamakan}; + + const oldWorld = `Hill 4-6 20-40 15-85 30-45 + Hill 3-7 20-40 15-85 55-70 + Strait 2-7 vertical 0 0 + Pit 1-2 40-50 35-55 20-80 + Strait 2-7 vertical 0 0 + Range 2-3 20-25 15-35 20-30 + Range 2-3 20-25 15-35 65-80 + Range 2-3 20-25 45-85 20-45 + Range 2-3 20-25 45-85 65-80 + Multiply .9 80-100 0 0 + Strait 2-7 vertical 0 0 + Pit 2-3 40-50 45-65 20-80 + Trough 1-2 40-50 15-45 20-45 + Trough 1-3 40-50 15-45 45-80 + Trough 1-2 40-50 45-85 20-45 + Trough 1-2 40-50 45-85 45-80 + Multiply 1.2 17-20 0 0 + Strait 2-7 horizontal 0 0 + Multiply 1.2 17-50 0 0 + Range 1-2 20-25 15-45 45-65 + Range 1-2 20-25 65-85 45-80 + Multiply 1.1 50-80 0 0 + Hill 1-2 20 15-45 20-80 + Hill 1-2 20 65-85 20-80 + Multiply 1.2 15-30 0 0 + Strait 2-7 vertical 0 0 + Trough 1-2 40-50 35-65 65-80 + Range 1-2 20-25 15-35 20-45 + Strait 2-7 vertical 0 0 + Range 1-2 20-25 65-85 45-80 + Multiply .9 70-100 0 0 + Hill 1-2 20-25 15-45 65-80 + Hill 1-2 20-25 65-85 20-45 + Hill 1 20-25 15-45 45-65 + Hill 1 20-25 65-85 45-65 + Strait 2-7 vertical 0 0 + Trough 1-2 20-50 15-45 45-65 + Trough 1-2 20-50 65-85 45-65 + Strait 2-7 horizontal 0 0 + Multiply 0.8 70-100 0 0 + Hill 1-2 20-25 35-45 45-65 + Hill 1-2 20-25 65-70 45-65 + Pit 2-3 40-50 45-65 30-70 + Trough 1-2 40-50 15-85 65-80 + Trough 1-2 40-50 15-85 10-35 + Strait 2-5 vertical 0 0 + Multiply 1.1 45-90 0 0 + Strait 3-7 vertical 0 0 + Trough 1-2 40-50 45-65 45-65`; + + return {volcano, highIsland, lowIsland, continents, archipelago, atoll, mediterranean, peninsula, peninsula, pangea, isthmus, shattered, taklamakan, oldWorld}; })(); diff --git a/modules/ui/options.js b/modules/ui/options.js index b6658490..eef2cd09 100644 --- a/modules/ui/options.js +++ b/modules/ui/options.js @@ -579,17 +579,18 @@ function randomizeOptions() { function randomizeHeightmapTemplate() { const templates = { volcano: 3, - highIsland: 22, + highIsland: 19, lowIsland: 9, - continents: 19, - archipelago: 23, + continents: 16, + archipelago: 18, mediterranean: 5, peninsula: 3, pangea: 5, isthmus: 2, atoll: 1, shattered: 7, - taklamakan: 1 + taklamakan: 1, + oldWorld: 11 }; document.getElementById("templateInput").value = rw(templates); } From 94871b21bcbb24fdc1a78e5602c41cc74605c3a9 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Fri, 18 Mar 2022 23:13:14 +0300 Subject: [PATCH 4/7] remove premium tinymce tools --- modules/ui/notes-editor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ui/notes-editor.js b/modules/ui/notes-editor.js index 872437fa..b985a5e8 100644 --- a/modules/ui/notes-editor.js +++ b/modules/ui/notes-editor.js @@ -86,8 +86,8 @@ function editNotes(id, name) { selector: "#notesLegend", height: "90%", menubar: false, - plugins: `autolink lists link charmap print formatpainter casechange code fullscreen image link media table paste hr checklist wordcount`, - toolbar: `code | undo redo | bold italic strikethrough | forecolor backcolor | formatpainter removeformat | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | fontselect fontsizeselect | blockquote hr casechange checklist charmap | print fullscreen`, + plugins: `autolink lists link charmap print code fullscreen image link media table paste hr wordcount`, + toolbar: `code | undo redo | removeformat | bold italic strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | fontselect fontsizeselect | blockquote hr charmap | print fullscreen`, media_alt_source: false, media_poster: false, setup: editor => { From fc971e49022bb683bd697cab4fe4da91586f5db2 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 19 Mar 2022 20:03:16 +0300 Subject: [PATCH 5/7] rivers: if points data is wrong, ignore points --- modules/ui/layers.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/ui/layers.js b/modules/ui/layers.js index 653cc9e4..009828c4 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -1481,6 +1481,12 @@ function drawRivers() { const riverPaths = pack.rivers.map(({cells, points, i, widthFactor, sourceWidth}) => { if (!cells || cells.length < 2) return; + + if (points && points.length !== cells.length) { + console.error(`River ${i} has ${cells.length} cells, but only ${points.length} points defined. Resetting points data`); + points = undefined; + } + const meanderedPoints = addMeandering(cells, points); const path = getRiverPath(meanderedPoints, widthFactor, sourceWidth); return ``; From 8473b9ed01aa51564b21dc46d1278c01402e6994 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 19 Mar 2022 20:04:06 +0300 Subject: [PATCH 6/7] update supporters --- modules/ui/options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/options.js b/modules/ui/options.js index eef2cd09..ad90d7fe 100644 --- a/modules/ui/options.js +++ b/modules/ui/options.js @@ -105,7 +105,7 @@ function showSupporters() { Jonathan Williams,ojacid .,Brian Wilson,A Patreon of the Ahts,Shubham Jakhotiya,www15o,Jan Bundesmann,Angelique Badger,Joshua Xiong,Moist mongol, Frank Fewkes,jason baldrick,Game Master Pro,Andrew Kircher,Preston Mitchell,Chris Kohut,Emarandzeb,Trentin Bergeron,Damon Gallaty,Pleaseworkforonce, Jordan,William Markus,Sidr Dim,Alexander Whittaker,The Next Level,Patrick Valverde,Markus Peham,Daniel Cooper,the Beagles of Neorbus,Marley Moule, - Maximilian Schielke,Johnathan Xavier Hutchinson,Ele,Rita`; + Maximilian Schielke,Johnathan Xavier Hutchinson,Ele,Rita,Randy Ross,John Wick,RedSpaz,cameron cannon,Ian Grau-Fay,Kyle Barrett,Charlotte Wiland`; const array = supporters .replace(/(?:\r\n|\r|\n)/g, "") From 79b7df1c95f9c8666bacbbb879cd8e9165f682e3 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Tue, 22 Mar 2022 00:14:15 +0300 Subject: [PATCH 7/7] not allow to select text on svg --- index.css | 1 + 1 file changed, 1 insertion(+) diff --git a/index.css b/index.css index ed81773f..c8d5efb0 100644 --- a/index.css +++ b/index.css @@ -50,6 +50,7 @@ iframe { mask-mode: alpha; mask-clip: no-clip; fill-rule: evenodd; + user-select: none; } #canvas {