diff --git a/modules/markers-generator.js b/modules/markers-generator.js index 751b6879..6cf307fd 100644 --- a/modules/markers-generator.js +++ b/modules/markers-generator.js @@ -2,6 +2,7 @@ window.Markers = (function () { let config = []; + let occupied = []; function getDefaultConfig() { const culturesSet = document.getElementById("culturesSet").value; @@ -60,12 +61,13 @@ window.Markers = (function () { function generateTypes() { TIME && console.time("addMarkers"); - // TODO: don't put multiple markers to the same cell config.forEach(({type, icon, multiplier, fn}) => { if (multiplier === 0) return; fn(type, icon, multiplier); }); + + occupied = []; TIME && console.timeEnd("addMarkers"); } @@ -95,18 +97,19 @@ window.Markers = (function () { 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}; + const marker = {i, icon, type, x, y, cell}; if (dx) marker.dx = dx; if (dy) marker.dy = dy; if (px) marker.px = px; pack.markers.push(marker); + occupied[cell] = true; return "marker" + i; } function addVolcanoes(type, icon, multiplier) { const {cells} = pack; - let mountains = Array.from(cells.i.filter(i => cells.h[i] >= 70).sort((a, b) => cells.h[b] - cells.h[a])); + 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, 300, multiplier); if (!quantity) return; const highestMountains = mountains.slice(0, 20); @@ -124,7 +127,7 @@ window.Markers = (function () { function addHotSprings(type, icon, multiplier) { const {cells} = pack; - let springs = Array.from(cells.i.filter(i => cells.h[i] > 50).sort((a, b) => cells.h[b] - cells.h[a])); + 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, 800, multiplier); if (!quantity) return; const highestSprings = springs.slice(0, 40); @@ -142,7 +145,7 @@ window.Markers = (function () { function addMines(type, icon, multiplier) { const {cells} = pack; - let hillyBurgs = Array.from(cells.i.filter(i => cells.h[i] > 47 && cells.burg[i])); + 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; @@ -166,7 +169,7 @@ window.Markers = (function () { const meanFlux = d3.mean(cells.fl.filter(fl => fl)); let bridges = Array.from( - cells.i.filter(i => cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux) + 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; @@ -186,7 +189,7 @@ window.Markers = (function () { function addInns(type, icon, multiplier) { const {cells} = pack; - let taverns = Array.from(cells.i.filter(i => cells.h[i] >= 20 && cells.road[i] > 4 && cells.pop[i] > 10)); + 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; @@ -437,7 +440,7 @@ window.Markers = (function () { function addLighthouses(type, icon, multiplier) { const {cells} = pack; - const lighthouses = Array.from(cells.i.filter(i => cells.harbor[i] > 6 && cells.c[i].some(c => cells.h[c] < 20 && cells.road[c]))); + 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; @@ -453,7 +456,7 @@ window.Markers = (function () { function addWaterfalls(type, icon, multiplier) { const {cells} = pack; - 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 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; @@ -468,7 +471,7 @@ window.Markers = (function () { function addBattlefields(type, icon, multiplier) { const {cells, states} = pack; - let battlefields = Array.from(cells.i.filter(i => cells.state[i] && cells.pop[i] > 2 && cells.h[i] < 50 && cells.h[i] > 25)); + 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; @@ -487,7 +490,7 @@ window.Markers = (function () { function addDungeons(type, icon, multiplier) { const {cells} = pack; - let dungeons = Array.from(cells.i.filter(i => cells.pop[i] && cells.pop[i] < 3)); + 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; @@ -506,7 +509,7 @@ window.Markers = (function () { function addLakeMonsters(type, icon, multiplier) { const {features} = pack; - const lakes = features.filter(feature => feature.type === "lake" && feature.group === "freshwater"); + const lakes = features.filter(feature => feature.type === "lake" && feature.group === "freshwater" && !occupied[feature.firstCell]); let quantity = getQuantity(lakes, 2, 10, multiplier); if (!quantity) return; @@ -525,7 +528,7 @@ window.Markers = (function () { function addSeaMonsters(type, icon, multiplier) { 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")); + 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; @@ -543,7 +546,7 @@ window.Markers = (function () { function addHillMonsters(type, icon, multiplier) { const {cells} = pack; - const hills = Array.from(cells.i.filter(i => cells.h[i] >= 50 && cells.pop[i])); + 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; @@ -573,7 +576,9 @@ window.Markers = (function () { function addSacredMountains(type, icon, multiplier) { 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 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; @@ -592,7 +597,7 @@ window.Markers = (function () { function addSacredForests(type, icon, multiplier) { const {cells, cultures} = pack; - let temperateForests = Array.from(cells.i.filter(i => cells.culture[i] && [6, 8].includes(cells.biome[i]))); + 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; @@ -610,7 +615,7 @@ window.Markers = (function () { function addSacredPineries(type, icon, multiplier) { const {cells, cultures} = pack; - let borealForests = Array.from(cells.i.filter(i => cells.culture[i] && cells.biome[i] === 9)); + 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; @@ -628,7 +633,7 @@ window.Markers = (function () { function addSacredPalmGroves(type, icon, multiplier) { const {cells, cultures} = pack; - let oasises = Array.from(cells.i.filter(i => cells.culture[i] && cells.biome[i] === 1 && cells.pop[i] > 1 && cells.road[i])); + 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; @@ -646,7 +651,7 @@ window.Markers = (function () { function addBrigands(type, icon, multiplier) { const {cells} = pack; - let roads = Array.from(cells.i.filter(i => cells.culture[i] && cells.road[i] > 4)); + 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; @@ -712,7 +717,7 @@ window.Markers = (function () { function addPirates(type, icon, multiplier) { const {cells} = pack; - let searoutes = Array.from(cells.i.filter(i => cells.h[i] < 20 && cells.road[i])); + 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; @@ -728,7 +733,7 @@ window.Markers = (function () { function addStatues(type, icon, multiplier) { const {cells} = pack; - let statues = Array.from(cells.i.filter(i => cells.h[i] >= 20 && cells.h[i] < 40)); + 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; @@ -762,7 +767,7 @@ window.Markers = (function () { function addRuines(type, icon, multiplier) { const {cells} = pack; - let ruins = Array.from(cells.i.filter(i => cells.culture[i] && cells.h[i] >= 20 && cells.h[i] < 60)); + 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; @@ -782,7 +787,10 @@ window.Markers = (function () { function addPortals(type, icon, multiplier) { const {burgs} = pack; - let portals = burgs.slice(1, Math.ceil(burgs.length / 10) + 1).map(burg => [burg.name, burg.cell]); + let portals = 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; diff --git a/modules/ui/layers.js b/modules/ui/layers.js index ffa021fa..5988d537 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -1558,13 +1558,14 @@ const getPin = (shape = "bubble", fill = "#fff", stroke = "#000") => { }; function drawMarker(marker, rescale = 1) { - const {i, icon, x, y, dx = 50, dy = 50, px = 12, size = 30} = marker; + const {i, icon, x, y, dx = 50, dy = 50, px = 12, size = 30, pin, fill, stroke} = marker; const id = `marker${i}`; const zoomSize = rescale ? Math.max(rn(size / 5 + 24 / scale, 2), 1) : 1; const viewX = rn(x - zoomSize / 2, 1); const viewY = rn(y - zoomSize, 1); + const pinHTML = getPin(pin, fill, stroke); - return ``; + return ``; } function toggleLabels(event) { diff --git a/modules/ui/markers-editor.js b/modules/ui/markers-editor.js index 5664bbbe..907e1860 100644 --- a/modules/ui/markers-editor.js +++ b/modules/ui/markers-editor.js @@ -1,11 +1,10 @@ "use strict"; -function editMarker() { +function editMarker(markerI) { if (customization) return; closeDialogs(".stable"); - const element = d3.event.target.closest("svg"); - const marker = pack.markers.find(({i}) => Number(element.id.slice(6)) === i); - if (!marker) return; + const [element, marker] = getElement(markerI, d3.event); + if (!marker || !element) return; elSelected = d3.select(element).raise().call(d3.drag().on("start", dragMarker)).classed("draggable", true); @@ -53,6 +52,18 @@ function editMarker() { listen(markerRemove, "click", confirmMarkerDeletion) ]; + function getElement(markerI, event) { + if (event) { + const element = event.target?.closest("svg"); + const marker = pack.markers.find(({i}) => Number(element.id.slice(6)) === i); + return [element, marker]; + } + + const element = document.getElementById(`marker${markerI}`); + const marker = pack.markers.find(({i}) => i === markerI); + return [element, marker]; + } + function getSameTypeMarkers() { const currentType = marker.type; if (!currentType) return [marker]; @@ -76,8 +87,10 @@ function editMarker() { const size = marker.size || 30; const zoomSize = Math.max(rn(size / 5 + 24 / scale, 2), 1); + marker.x = rn(x + dx + zoomSize / 2, 1); marker.y = rn(y + dy + zoomSize, 1); + marker.cell = findCell(marker.x, marker.y); }); } @@ -230,6 +243,7 @@ function editMarker() { pack.markers = pack.markers.filter(m => m.i !== marker.i); element.remove(); $("#markerEditor").dialog("close"); + if (document.getElementById("markersOverviewRefresh").offsetParent) markersOverviewRefresh.click(); } function closeMarkerEditor() { diff --git a/modules/ui/markers-overview.js b/modules/ui/markers-overview.js index 3d4664a8..6dd0f412 100644 --- a/modules/ui/markers-overview.js +++ b/modules/ui/markers-overview.js @@ -22,16 +22,26 @@ function overviewMarkers() { }); const listeners = [ + listen(body, "click", handleLineClick), listen(markersOverviewRefresh, "click", addLines), - listen(markersAddFromOverview, "click", () => {}), + listen(markersAddFromOverview, "click", toggleAddMarker), listen(markersGenerationConfig, "click", configMarkersGeneration), listen(markersRemoveAll, "click", triggerRemoveAll) ]; + function handleLineClick(ev) { + const el = ev.target; + const i = +el.parentNode.dataset.i; + + if (el.classList.contains("icon-pencil")) return openEditor(i); + if (el.classList.contains("locks")) return toggleLockStatus(el, i); + if (el.classList.contains("icon-trash-empty")) return triggerRemove(i); + } + function addLines() { const lines = pack.markers .map(({i, type, icon, lock}) => { - return `