mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
feat: generate watabou preview links for villages (#1056)
Co-authored-by: Azgaar <azgaar.fmg@yandex.com>
This commit is contained in:
parent
56e6e47286
commit
d6c3c46a5e
9 changed files with 247 additions and 192 deletions
76
index.html
76
index.html
|
|
@ -3329,6 +3329,22 @@
|
||||||
<input id="burgPopulation" type="number" min="0" step="1" style="width: 8em" />
|
<input id="burgPopulation" type="number" min="0" step="1" style="width: 8em" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-tip="Burg mean annual temperature and real-world city for comparison">
|
||||||
|
<div class="label">Temperature:</div>
|
||||||
|
<span id="burgTemperature"></span>, like in
|
||||||
|
<span id="burgTemperatureLikeIn"></span>
|
||||||
|
<i
|
||||||
|
id="burgTemperatureGraph"
|
||||||
|
data-tip="Show temperature graph for the burg"
|
||||||
|
class="icon-chart-area pointer"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-tip="Burg height above mean sea level">
|
||||||
|
<div class="label">Elevation:</div>
|
||||||
|
<span id="burgElevation"></span> above sea level
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Features:</div>
|
<div class="label">Features:</div>
|
||||||
<span
|
<span
|
||||||
|
|
@ -3378,49 +3394,23 @@
|
||||||
style="font-size: 1em"
|
style="font-size: 1em"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Burg mean annual temperature and real-world city for comparison">
|
|
||||||
<div class="label">Temperature:</div>
|
|
||||||
<span id="burgTemperature"></span>, like in
|
|
||||||
<span id="burgTemperatureLikeIn"></span>
|
|
||||||
<i
|
|
||||||
id="burgTemperatureGraph"
|
|
||||||
data-tip="Show temperature graph for the burg"
|
|
||||||
class="icon-chart-area pointer"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Burg height above mean sea level">
|
|
||||||
<div class="label">Elevation:</div>
|
|
||||||
<span id="burgElevation"></span> above sea level
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div id="burgPreviewSection" data-tip="Burg map preview" style="display: flex; flex-direction: column">
|
||||||
id="mfcgPreviewSection"
|
<div style="display: flex; justify-content: space-between">
|
||||||
data-tip="Burg preview in the Medieval Fantasy City Generator. Default seed is a combination of map seed and burg id"
|
<span>Burg preview:</span>
|
||||||
style="display: flex; flex-direction: column"
|
<div style="display: flex; gap: 0.5em">
|
||||||
>
|
|
||||||
<div>
|
|
||||||
See in <a id="mfcgLink" target="_blank">City Generator by Watabou</a>.
|
|
||||||
<div id="mfcgBurgSeedSection">
|
|
||||||
Seed: <input id="mfcgBurgSeed" style="width: 10em" type="number" min="1" max="1e13" step="1" />
|
|
||||||
<i
|
<i
|
||||||
id="regenerateMFCGBurgSeed"
|
id="burgLinkEdit"
|
||||||
data-tip="Randomize Medieval Fantasy City Generator burg seed"
|
data-tip="Provide custom link to the burg map"
|
||||||
class="icon-arrows-cw pointer"
|
class="icon-pencil pointer"
|
||||||
style="margin-left: 0.1em"
|
style="margin-top: -0.1em"
|
||||||
></i>
|
></i>
|
||||||
|
<i id="burgLinkOpen" data-tip="Open burg map in a new tab" class="icon-link-ext pointer"></i>
|
||||||
</div>
|
</div>
|
||||||
<i
|
|
||||||
id="addCustomMFCGBurgLink"
|
|
||||||
data-tip="Provide custom link to the burg map"
|
|
||||||
class="icon-pencil pointer"
|
|
||||||
style="margin-left: 0.1em"
|
|
||||||
></i>
|
|
||||||
</div>
|
</div>
|
||||||
<iframe id="mfcgPreview" sandbox="allow-scripts"></iframe>
|
<div id="burgPreviewObject" style="max-width: 30em; pointer-events: none"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -3460,7 +3450,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="burgEditEmblem" data-tip="Edit emblem" class="icon-shield-alt"></button>
|
<button id="burgEditEmblem" data-tip="Edit emblem" class="icon-shield-alt"></button>
|
||||||
<button id="burgToggleMFCGMap" data-tip="Toggle MFCG map" class="icon-map"></button>
|
<button id="burgTogglePreview" data-tip="Toggle preview" class="icon-map"></button>
|
||||||
<button id="burgRelocate" data-tip="Relocate burg" class="icon-target"></button>
|
<button id="burgRelocate" data-tip="Relocate burg" class="icon-target"></button>
|
||||||
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
<button id="burglLegend" data-tip="Edit free text notes (legend) for this burg" class="icon-edit"></button>
|
||||||
<button id="burgLock" class="icon-lock-open" onmouseover="showElementLockTip(event)"></button>
|
<button id="burgLock" class="icon-lock-open" onmouseover="showElementLockTip(event)"></button>
|
||||||
|
|
@ -8044,7 +8034,7 @@
|
||||||
<script src="modules/names-generator.js?v=1.87.14"></script>
|
<script src="modules/names-generator.js?v=1.87.14"></script>
|
||||||
<script src="modules/cultures-generator.js?v=1.96.05"></script>
|
<script src="modules/cultures-generator.js?v=1.96.05"></script>
|
||||||
<script src="modules/renderers/state-labels.js?v=1.96.04"></script>
|
<script src="modules/renderers/state-labels.js?v=1.96.04"></script>
|
||||||
<script src="modules/burgs-and-states.js?v=1.92.00"></script>
|
<script src="modules/burgs-and-states.js?v=1.97.00"></script>
|
||||||
<script src="modules/routes-generator.js"></script>
|
<script src="modules/routes-generator.js"></script>
|
||||||
<script src="modules/religions-generator.js?v=1.93.08"></script>
|
<script src="modules/religions-generator.js?v=1.93.08"></script>
|
||||||
<script src="modules/military-generator.js?v=1.96.00"></script>
|
<script src="modules/military-generator.js?v=1.96.00"></script>
|
||||||
|
|
@ -8061,11 +8051,11 @@
|
||||||
|
|
||||||
<script src="modules/ui/general.js?v=1.96.00"></script>
|
<script src="modules/ui/general.js?v=1.96.00"></script>
|
||||||
<script src="modules/ui/options.js?v=1.96.00"></script>
|
<script src="modules/ui/options.js?v=1.96.00"></script>
|
||||||
<script src="main.js?v=1.96.00"></script>
|
<script src="main.js?v=1.97.00"></script>
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></script>
|
<script defer src="modules/relief-icons.js"></script>
|
||||||
<script defer src="modules/ui/style.js?v=1.96.00"></script>
|
<script defer src="modules/ui/style.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/editors.js?v=1.96.07"></script>
|
<script defer src="modules/ui/editors.js?v=1.97.00"></script>
|
||||||
<script defer src="modules/ui/tools.js?v=1.96.03"></script>
|
<script defer src="modules/ui/tools.js?v=1.96.03"></script>
|
||||||
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
||||||
<script defer src="modules/ui/heightmap-editor.js?v=1.96.00"></script>
|
<script defer src="modules/ui/heightmap-editor.js?v=1.96.00"></script>
|
||||||
|
|
@ -8082,12 +8072,12 @@
|
||||||
<script defer src="modules/ui/rivers-editor.js"></script>
|
<script defer src="modules/ui/rivers-editor.js"></script>
|
||||||
<script defer src="modules/ui/rivers-creator.js?v=1.89.13"></script>
|
<script defer src="modules/ui/rivers-creator.js?v=1.89.13"></script>
|
||||||
<script defer src="modules/ui/relief-editor.js"></script>
|
<script defer src="modules/ui/relief-editor.js"></script>
|
||||||
<script defer src="modules/ui/burg-editor.js?v=1.96.00"></script>
|
<script defer src="modules/ui/burg-editor.js?v=1.97.00"></script>
|
||||||
<script defer src="modules/ui/units-editor.js?v=1.96.00"></script>
|
<script defer src="modules/ui/units-editor.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/notes-editor.js?v=1.93.09"></script>
|
<script defer src="modules/ui/notes-editor.js?v=1.93.09"></script>
|
||||||
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
||||||
<script defer src="modules/ui/zones-editor.js"></script>
|
<script defer src="modules/ui/zones-editor.js"></script>
|
||||||
<script defer src="modules/ui/burgs-overview.js?v=1.96.00"></script>
|
<script defer src="modules/ui/burgs-overview.js?v=1.97.00"></script>
|
||||||
<script defer src="modules/ui/rivers-overview.js"></script>
|
<script defer src="modules/ui/rivers-overview.js"></script>
|
||||||
<script defer src="modules/ui/military-overview.js?v=1.96.07"></script>
|
<script defer src="modules/ui/military-overview.js?v=1.96.07"></script>
|
||||||
<script defer src="modules/ui/regiments-overview.js?v=1.89.20"></script>
|
<script defer src="modules/ui/regiments-overview.js?v=1.89.20"></script>
|
||||||
|
|
@ -8103,7 +8093,7 @@
|
||||||
<script defer src="libs/rgbquant.min.js"></script>
|
<script defer src="libs/rgbquant.min.js"></script>
|
||||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||||
<script defer src="modules/io/save.js?v=1.96.00"></script>
|
<script defer src="modules/io/save.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/load.js?v=1.96.06"></script>
|
<script defer src="modules/io/load.js?v=1.97.00"></script>
|
||||||
<script defer src="modules/io/cloud.js?v=1.96.00"></script>
|
<script defer src="modules/io/cloud.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/export.js?v=1.96.00"></script>
|
<script defer src="modules/io/export.js?v=1.96.00"></script>
|
||||||
|
|
||||||
|
|
|
||||||
5
main.js
5
main.js
|
|
@ -185,12 +185,13 @@ const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", onZoomDebouced);
|
||||||
// default options, based on Earth data
|
// default options, based on Earth data
|
||||||
let options = {
|
let options = {
|
||||||
pinNotes: false,
|
pinNotes: false,
|
||||||
showMFCGMap: true,
|
|
||||||
winds: [225, 45, 225, 315, 135, 315],
|
winds: [225, 45, 225, 315, 135, 315],
|
||||||
temperatureEquator: 27,
|
temperatureEquator: 27,
|
||||||
temperatureNorthPole: -30,
|
temperatureNorthPole: -30,
|
||||||
temperatureSouthPole: -15,
|
temperatureSouthPole: -15,
|
||||||
stateLabelsMode: "auto"
|
stateLabelsMode: "auto",
|
||||||
|
showBurgPreview: true,
|
||||||
|
villageMaxPopulation: 2000
|
||||||
};
|
};
|
||||||
|
|
||||||
let mapCoordinates = {}; // map coordinates on globe
|
let mapCoordinates = {}; // map coordinates on globe
|
||||||
|
|
|
||||||
|
|
@ -252,13 +252,15 @@ window.BurgsAndStates = (function () {
|
||||||
.filter(b => (newburg ? b.i == newburg.i : b.i && !b.removed))
|
.filter(b => (newburg ? b.i == newburg.i : b.i && !b.removed))
|
||||||
.forEach(b => {
|
.forEach(b => {
|
||||||
const pop = b.population;
|
const pop = b.population;
|
||||||
b.citadel = b.capital || (pop > 50 && P(0.75)) || P(0.5) ? 1 : 0;
|
b.citadel = Number(b.capital || (pop > 50 && P(0.75)) || (pop > 15 && P(0.5)) || P(0.1));
|
||||||
b.plaza = pop > 50 || (pop > 30 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.25) ? 1 : 0;
|
b.plaza = Number(pop > 20 || (pop > 10 && P(0.8)) || (pop > 4 && P(0.7)) || P(0.6));
|
||||||
b.walls = b.capital || pop > 30 || (pop > 20 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.2) ? 1 : 0;
|
b.walls = Number(b.capital || pop > 30 || (pop > 20 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.1));
|
||||||
b.shanty = pop > 60 || (pop > 40 && P(0.75)) || (pop > 20 && b.walls && P(0.4)) ? 1 : 0;
|
b.shanty = Number(pop > 60 || (pop > 40 && P(0.75)) || (pop > 20 && b.walls && P(0.4)));
|
||||||
const religion = cells.religion[b.cell];
|
const religion = cells.religion[b.cell];
|
||||||
const theocracy = pack.states[b.state].form === "Theocracy";
|
const theocracy = pack.states[b.state].form === "Theocracy";
|
||||||
b.temple = (religion && theocracy) || pop > 50 || (pop > 35 && P(0.75)) || (pop > 20 && P(0.5)) ? 1 : 0;
|
b.temple = Number(
|
||||||
|
(religion && theocracy && P(0.5)) || pop > 50 || (pop > 35 && P(0.75)) || (pop > 20 && P(0.5))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -860,7 +862,7 @@ window.BurgsAndStates = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base === 31 && (form === "Empire" || form === "Kingdom")) return "Khanate"; // Mongolian
|
if (base === 31 && (form === "Empire" || form === "Kingdom")) return "Khanate"; // Mongolian
|
||||||
if (base === 16 && (form === "Principality" )) return "Beylik"; // Turkic
|
if (base === 16 && form === "Principality") return "Beylik"; // Turkic
|
||||||
if (base === 5 && (form === "Empire" || form === "Kingdom")) return "Tsardom"; // Ruthenian
|
if (base === 5 && (form === "Empire" || form === "Kingdom")) return "Tsardom"; // Ruthenian
|
||||||
if (base === 16 && (form === "Empire" || form === "Kingdom")) return "Khaganate"; // Turkic
|
if (base === 16 && (form === "Empire" || form === "Kingdom")) return "Khaganate"; // Turkic
|
||||||
if (base === 12 && (form === "Kingdom" || form === "Grand Duchy")) return "Shogunate"; // Japanese
|
if (base === 12 && (form === "Kingdom" || form === "Grand Duchy")) return "Shogunate"; // Japanese
|
||||||
|
|
|
||||||
|
|
@ -827,4 +827,20 @@ export function resolveVersionConflicts(version) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version < 1.97) {
|
||||||
|
// v1.97.00 changed MFCG link to an arbitrary preview URL
|
||||||
|
options.villageMaxPopulation = 2000;
|
||||||
|
options.showBurgPreview = options.showMFCGMap;
|
||||||
|
delete options.showMFCGMap;
|
||||||
|
|
||||||
|
pack.burgs.forEach(burg => {
|
||||||
|
if (!burg.i || burg.removed) return;
|
||||||
|
|
||||||
|
if (burg.MFCG) {
|
||||||
|
burg.link = getBurgLink(burg);
|
||||||
|
delete burg.MFCG;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -456,7 +456,7 @@ async function parseLoadedData(data, mapVersion) {
|
||||||
{
|
{
|
||||||
// dynamically import and run auto-update script
|
// dynamically import and run auto-update script
|
||||||
const versionNumber = parseFloat(params[0]);
|
const versionNumber = parseFloat(params[0]);
|
||||||
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.96.00");
|
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.97.00");
|
||||||
resolveVersionConflicts(versionNumber);
|
resolveVersionConflicts(versionNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,38 +21,37 @@ function editBurg(id) {
|
||||||
modules.editBurg = true;
|
modules.editBurg = true;
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("burgGroupShow").addEventListener("click", showGroupSection);
|
byId("burgGroupShow").addEventListener("click", showGroupSection);
|
||||||
document.getElementById("burgGroupHide").addEventListener("click", hideGroupSection);
|
byId("burgGroupHide").addEventListener("click", hideGroupSection);
|
||||||
document.getElementById("burgSelectGroup").addEventListener("change", changeGroup);
|
byId("burgSelectGroup").addEventListener("change", changeGroup);
|
||||||
document.getElementById("burgInputGroup").addEventListener("change", createNewGroup);
|
byId("burgInputGroup").addEventListener("change", createNewGroup);
|
||||||
document.getElementById("burgAddGroup").addEventListener("click", toggleNewGroupInput);
|
byId("burgAddGroup").addEventListener("click", toggleNewGroupInput);
|
||||||
document.getElementById("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
|
byId("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
|
||||||
|
|
||||||
document.getElementById("burgName").addEventListener("input", changeName);
|
byId("burgName").addEventListener("input", changeName);
|
||||||
document.getElementById("burgNameReRandom").addEventListener("click", generateNameRandom);
|
byId("burgNameReRandom").addEventListener("click", generateNameRandom);
|
||||||
document.getElementById("burgType").addEventListener("input", changeType);
|
byId("burgType").addEventListener("input", changeType);
|
||||||
document.getElementById("burgCulture").addEventListener("input", changeCulture);
|
byId("burgCulture").addEventListener("input", changeCulture);
|
||||||
document.getElementById("burgNameReCulture").addEventListener("click", generateNameCulture);
|
byId("burgNameReCulture").addEventListener("click", generateNameCulture);
|
||||||
document.getElementById("burgPopulation").addEventListener("change", changePopulation);
|
byId("burgPopulation").addEventListener("change", changePopulation);
|
||||||
burgBody.querySelectorAll(".burgFeature").forEach(el => el.addEventListener("click", toggleFeature));
|
burgBody.querySelectorAll(".burgFeature").forEach(el => el.addEventListener("click", toggleFeature));
|
||||||
document.getElementById("mfcgBurgSeed").addEventListener("change", changeSeed);
|
byId("burgLinkOpen").addEventListener("click", openBurgLink);
|
||||||
document.getElementById("regenerateMFCGBurgSeed").addEventListener("click", randomizeSeed);
|
byId("burgLinkEdit").addEventListener("click", changeBurgLink);
|
||||||
document.getElementById("addCustomMFCGBurgLink").addEventListener("click", addCustomMfcgLink);
|
|
||||||
|
|
||||||
document.getElementById("burgStyleShow").addEventListener("click", showStyleSection);
|
byId("burgStyleShow").addEventListener("click", showStyleSection);
|
||||||
document.getElementById("burgStyleHide").addEventListener("click", hideStyleSection);
|
byId("burgStyleHide").addEventListener("click", hideStyleSection);
|
||||||
document.getElementById("burgEditLabelStyle").addEventListener("click", editGroupLabelStyle);
|
byId("burgEditLabelStyle").addEventListener("click", editGroupLabelStyle);
|
||||||
document.getElementById("burgEditIconStyle").addEventListener("click", editGroupIconStyle);
|
byId("burgEditIconStyle").addEventListener("click", editGroupIconStyle);
|
||||||
document.getElementById("burgEditAnchorStyle").addEventListener("click", editGroupAnchorStyle);
|
byId("burgEditAnchorStyle").addEventListener("click", editGroupAnchorStyle);
|
||||||
|
|
||||||
document.getElementById("burgEmblem").addEventListener("click", openEmblemEdit);
|
byId("burgEmblem").addEventListener("click", openEmblemEdit);
|
||||||
document.getElementById("burgToggleMFCGMap").addEventListener("click", toggleMFCGMap);
|
byId("burgTogglePreview").addEventListener("click", toggleBurgPreview);
|
||||||
document.getElementById("burgEditEmblem").addEventListener("click", openEmblemEdit);
|
byId("burgEditEmblem").addEventListener("click", openEmblemEdit);
|
||||||
document.getElementById("burgRelocate").addEventListener("click", toggleRelocateBurg);
|
byId("burgRelocate").addEventListener("click", toggleRelocateBurg);
|
||||||
document.getElementById("burglLegend").addEventListener("click", editBurgLegend);
|
byId("burglLegend").addEventListener("click", editBurgLegend);
|
||||||
document.getElementById("burgLock").addEventListener("click", toggleBurgLockButton);
|
byId("burgLock").addEventListener("click", toggleBurgLockButton);
|
||||||
document.getElementById("burgRemove").addEventListener("click", removeSelectedBurg);
|
byId("burgRemove").addEventListener("click", removeSelectedBurg);
|
||||||
document.getElementById("burgTemperatureGraph").addEventListener("click", showTemperatureGraph);
|
byId("burgTemperatureGraph").addEventListener("click", showTemperatureGraph);
|
||||||
|
|
||||||
function updateBurgValues() {
|
function updateBurgValues() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
|
|
@ -60,46 +59,46 @@ function editBurg(id) {
|
||||||
const province = pack.cells.province[b.cell];
|
const province = pack.cells.province[b.cell];
|
||||||
const provinceName = province ? pack.provinces[province].fullName + ", " : "";
|
const provinceName = province ? pack.provinces[province].fullName + ", " : "";
|
||||||
const stateName = pack.states[b.state].fullName || pack.states[b.state].name;
|
const stateName = pack.states[b.state].fullName || pack.states[b.state].name;
|
||||||
document.getElementById("burgProvinceAndState").innerHTML = provinceName + stateName;
|
byId("burgProvinceAndState").innerHTML = provinceName + stateName;
|
||||||
|
|
||||||
document.getElementById("burgName").value = b.name;
|
byId("burgName").value = b.name;
|
||||||
document.getElementById("burgType").value = b.type || "Generic";
|
byId("burgType").value = b.type || "Generic";
|
||||||
document.getElementById("burgPopulation").value = rn(b.population * populationRate * urbanization);
|
byId("burgPopulation").value = rn(b.population * populationRate * urbanization);
|
||||||
document.getElementById("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none";
|
byId("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none";
|
||||||
|
|
||||||
// update list and select culture
|
// update list and select culture
|
||||||
const cultureSelect = document.getElementById("burgCulture");
|
const cultureSelect = byId("burgCulture");
|
||||||
cultureSelect.options.length = 0;
|
cultureSelect.options.length = 0;
|
||||||
const cultures = pack.cultures.filter(c => !c.removed);
|
const cultures = pack.cultures.filter(c => !c.removed);
|
||||||
cultures.forEach(c => cultureSelect.options.add(new Option(c.name, c.i, false, c.i === b.culture)));
|
cultures.forEach(c => cultureSelect.options.add(new Option(c.name, c.i, false, c.i === b.culture)));
|
||||||
|
|
||||||
const temperature = grid.cells.temp[pack.cells.g[b.cell]];
|
const temperature = grid.cells.temp[pack.cells.g[b.cell]];
|
||||||
document.getElementById("burgTemperature").innerHTML = convertTemperature(temperature);
|
byId("burgTemperature").innerHTML = convertTemperature(temperature);
|
||||||
document.getElementById("burgTemperatureLikeIn").innerHTML = getTemperatureLikeness(temperature);
|
byId("burgTemperatureLikeIn").innerHTML = getTemperatureLikeness(temperature);
|
||||||
document.getElementById("burgElevation").innerHTML = getHeight(pack.cells.h[b.cell]);
|
byId("burgElevation").innerHTML = getHeight(pack.cells.h[b.cell]);
|
||||||
|
|
||||||
// toggle features
|
// toggle features
|
||||||
if (b.capital) document.getElementById("burgCapital").classList.remove("inactive");
|
if (b.capital) byId("burgCapital").classList.remove("inactive");
|
||||||
else document.getElementById("burgCapital").classList.add("inactive");
|
else byId("burgCapital").classList.add("inactive");
|
||||||
if (b.port) document.getElementById("burgPort").classList.remove("inactive");
|
if (b.port) byId("burgPort").classList.remove("inactive");
|
||||||
else document.getElementById("burgPort").classList.add("inactive");
|
else byId("burgPort").classList.add("inactive");
|
||||||
if (b.citadel) document.getElementById("burgCitadel").classList.remove("inactive");
|
if (b.citadel) byId("burgCitadel").classList.remove("inactive");
|
||||||
else document.getElementById("burgCitadel").classList.add("inactive");
|
else byId("burgCitadel").classList.add("inactive");
|
||||||
if (b.walls) document.getElementById("burgWalls").classList.remove("inactive");
|
if (b.walls) byId("burgWalls").classList.remove("inactive");
|
||||||
else document.getElementById("burgWalls").classList.add("inactive");
|
else byId("burgWalls").classList.add("inactive");
|
||||||
if (b.plaza) document.getElementById("burgPlaza").classList.remove("inactive");
|
if (b.plaza) byId("burgPlaza").classList.remove("inactive");
|
||||||
else document.getElementById("burgPlaza").classList.add("inactive");
|
else byId("burgPlaza").classList.add("inactive");
|
||||||
if (b.temple) document.getElementById("burgTemple").classList.remove("inactive");
|
if (b.temple) byId("burgTemple").classList.remove("inactive");
|
||||||
else document.getElementById("burgTemple").classList.add("inactive");
|
else byId("burgTemple").classList.add("inactive");
|
||||||
if (b.shanty) document.getElementById("burgShanty").classList.remove("inactive");
|
if (b.shanty) byId("burgShanty").classList.remove("inactive");
|
||||||
else document.getElementById("burgShanty").classList.add("inactive");
|
else byId("burgShanty").classList.add("inactive");
|
||||||
|
|
||||||
//toggle lock
|
//toggle lock
|
||||||
updateBurgLockIcon();
|
updateBurgLockIcon();
|
||||||
|
|
||||||
// select group
|
// select group
|
||||||
const group = elSelected.node().parentNode.id;
|
const group = elSelected.node().parentNode.id;
|
||||||
const select = document.getElementById("burgSelectGroup");
|
const select = byId("burgSelectGroup");
|
||||||
select.options.length = 0; // remove all options
|
select.options.length = 0; // remove all options
|
||||||
|
|
||||||
burgLabels.selectAll("g").each(function () {
|
burgLabels.selectAll("g").each(function () {
|
||||||
|
|
@ -109,20 +108,13 @@ function editBurg(id) {
|
||||||
// set emlem image
|
// set emlem image
|
||||||
const coaID = "burgCOA" + id;
|
const coaID = "burgCOA" + id;
|
||||||
COArenderer.trigger(coaID, b.coa);
|
COArenderer.trigger(coaID, b.coa);
|
||||||
document.getElementById("burgEmblem").setAttribute("href", "#" + coaID);
|
byId("burgEmblem").setAttribute("href", "#" + coaID);
|
||||||
|
|
||||||
if (options.showMFCGMap) {
|
if (options.showBurgPreview) {
|
||||||
document.getElementById("mfcgPreviewSection").style.display = "block";
|
byId("burgPreviewSection").style.display = "block";
|
||||||
updateMFCGFrame(b);
|
updateBurgPreview(b);
|
||||||
|
|
||||||
if (b.link) {
|
|
||||||
document.getElementById("mfcgBurgSeedSection").style.display = "none";
|
|
||||||
} else {
|
|
||||||
document.getElementById("mfcgBurgSeedSection").style.display = "inline-block";
|
|
||||||
document.getElementById("mfcgBurgSeed").value = getBurgSeed(b);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("mfcgPreviewSection").style.display = "none";
|
byId("burgPreviewSection").style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,15 +133,15 @@ function editBurg(id) {
|
||||||
|
|
||||||
function showGroupSection() {
|
function showGroupSection() {
|
||||||
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none"));
|
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none"));
|
||||||
document.getElementById("burgGroupSection").style.display = "inline-block";
|
byId("burgGroupSection").style.display = "inline-block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideGroupSection() {
|
function hideGroupSection() {
|
||||||
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block"));
|
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block"));
|
||||||
document.getElementById("burgGroupSection").style.display = "none";
|
byId("burgGroupSection").style.display = "none";
|
||||||
document.getElementById("burgInputGroup").style.display = "none";
|
byId("burgInputGroup").style.display = "none";
|
||||||
document.getElementById("burgInputGroup").value = "";
|
byId("burgInputGroup").value = "";
|
||||||
document.getElementById("burgSelectGroup").style.display = "inline-block";
|
byId("burgSelectGroup").style.display = "inline-block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeGroup() {
|
function changeGroup() {
|
||||||
|
|
@ -178,7 +170,7 @@ function editBurg(id) {
|
||||||
.replace(/ /g, "_")
|
.replace(/ /g, "_")
|
||||||
.replace(/[^\w\s]/gi, "");
|
.replace(/[^\w\s]/gi, "");
|
||||||
|
|
||||||
if (document.getElementById(group)) {
|
if (byId(group)) {
|
||||||
tip("Element with this id already exists. Please provide a unique name", false, "error");
|
tip("Element with this id already exists. Please provide a unique name", false, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -206,10 +198,10 @@ function editBurg(id) {
|
||||||
// just rename if only 1 element left
|
// just rename if only 1 element left
|
||||||
const count = elSelected.node().parentNode.childElementCount;
|
const count = elSelected.node().parentNode.childElementCount;
|
||||||
if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) {
|
if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) {
|
||||||
document.getElementById("burgSelectGroup").selectedOptions[0].remove();
|
byId("burgSelectGroup").selectedOptions[0].remove();
|
||||||
document.getElementById("burgSelectGroup").options.add(new Option(group, group, false, true));
|
byId("burgSelectGroup").options.add(new Option(group, group, false, true));
|
||||||
toggleNewGroupInput();
|
toggleNewGroupInput();
|
||||||
document.getElementById("burgInputGroup").value = "";
|
byId("burgInputGroup").value = "";
|
||||||
labelG.id = group;
|
labelG.id = group;
|
||||||
iconG.id = group;
|
iconG.id = group;
|
||||||
if (anchor) anchorG.id = group;
|
if (anchor) anchorG.id = group;
|
||||||
|
|
@ -217,9 +209,9 @@ function editBurg(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create new groups
|
// create new groups
|
||||||
document.getElementById("burgSelectGroup").options.add(new Option(group, group, false, true));
|
byId("burgSelectGroup").options.add(new Option(group, group, false, true));
|
||||||
toggleNewGroupInput();
|
toggleNewGroupInput();
|
||||||
document.getElementById("burgInputGroup").value = "";
|
byId("burgInputGroup").value = "";
|
||||||
|
|
||||||
addBurgsGroup(group);
|
addBurgsGroup(group);
|
||||||
moveBurgToGroup(id, group);
|
moveBurgToGroup(id, group);
|
||||||
|
|
@ -300,7 +292,10 @@ function editBurg(id) {
|
||||||
|
|
||||||
function changePopulation() {
|
function changePopulation() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
|
const burg = pack.burgs[id];
|
||||||
|
|
||||||
pack.burgs[id].population = rn(burgPopulation.value / populationRate / urbanization, 4);
|
pack.burgs[id].population = rn(burgPopulation.value / populationRate / urbanization, 4);
|
||||||
|
updateBurgPreview(burg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleFeature() {
|
function toggleFeature() {
|
||||||
|
|
@ -314,9 +309,9 @@ function editBurg(id) {
|
||||||
if (burg[feature]) this.classList.remove("inactive");
|
if (burg[feature]) this.classList.remove("inactive");
|
||||||
else if (!burg[feature]) this.classList.add("inactive");
|
else if (!burg[feature]) this.classList.add("inactive");
|
||||||
|
|
||||||
if (burg.port) document.getElementById("burgEditAnchorStyle").style.display = "inline-block";
|
if (burg.port) byId("burgEditAnchorStyle").style.display = "inline-block";
|
||||||
else document.getElementById("burgEditAnchorStyle").style.display = "none";
|
else byId("burgEditAnchorStyle").style.display = "none";
|
||||||
updateMFCGFrame(burg);
|
updateBurgPreview(burg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleBurgLockButton() {
|
function toggleBurgLockButton() {
|
||||||
|
|
@ -331,22 +326,22 @@ function editBurg(id) {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
const b = pack.burgs[id];
|
const b = pack.burgs[id];
|
||||||
if (b.lock) {
|
if (b.lock) {
|
||||||
document.getElementById("burgLock").classList.remove("icon-lock-open");
|
byId("burgLock").classList.remove("icon-lock-open");
|
||||||
document.getElementById("burgLock").classList.add("icon-lock");
|
byId("burgLock").classList.add("icon-lock");
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("burgLock").classList.remove("icon-lock");
|
byId("burgLock").classList.remove("icon-lock");
|
||||||
document.getElementById("burgLock").classList.add("icon-lock-open");
|
byId("burgLock").classList.add("icon-lock-open");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showStyleSection() {
|
function showStyleSection() {
|
||||||
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none"));
|
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none"));
|
||||||
document.getElementById("burgStyleSection").style.display = "inline-block";
|
byId("burgStyleSection").style.display = "inline-block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideStyleSection() {
|
function hideStyleSection() {
|
||||||
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block"));
|
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block"));
|
||||||
document.getElementById("burgStyleSection").style.display = "none";
|
byId("burgStyleSection").style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
function editGroupLabelStyle() {
|
function editGroupLabelStyle() {
|
||||||
|
|
@ -364,39 +359,38 @@ function editBurg(id) {
|
||||||
editStyle("anchors", g);
|
editStyle("anchors", g);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMFCGFrame(burg) {
|
function updateBurgPreview(burg) {
|
||||||
const mfcgURL = getMFCGlink(burg);
|
const src = getBurgLink(burg) + "&preview=1";
|
||||||
document.getElementById("mfcgPreview").setAttribute("src", mfcgURL + "&preview=1");
|
|
||||||
document.getElementById("mfcgLink").setAttribute("href", mfcgURL);
|
// recreate object to force reload (Chrome bug)
|
||||||
|
const container = byId("burgPreviewObject");
|
||||||
|
container.innerHTML = "";
|
||||||
|
const object = document.createElement("object");
|
||||||
|
object.style.width = "100%";
|
||||||
|
object.data = src;
|
||||||
|
container.insertBefore(object, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSeed() {
|
function openBurgLink() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
const burg = pack.burgs[id];
|
const burg = pack.burgs[id];
|
||||||
const burgSeed = +this.value;
|
|
||||||
burg.MFCG = burgSeed;
|
openURL(getBurgLink(burg));
|
||||||
updateMFCGFrame(burg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomizeSeed() {
|
function changeBurgLink() {
|
||||||
const id = +elSelected.attr("data-id");
|
const id = +elSelected.attr("data-id");
|
||||||
const burg = pack.burgs[id];
|
const burg = pack.burgs[id];
|
||||||
const burgSeed = rand(1e9 - 1);
|
|
||||||
burg.MFCG = burgSeed;
|
|
||||||
updateMFCGFrame(burg);
|
|
||||||
document.getElementById("mfcgBurgSeed").value = burgSeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addCustomMfcgLink() {
|
prompt(
|
||||||
const id = +elSelected.attr("data-id");
|
"Provide custom link to the burg map. It can be a link to Medieval Fantasy City Generator, a different tool, or just an image. Leave empty to use the default map",
|
||||||
const burg = pack.burgs[id];
|
{default: getBurgLink(burg), required: false},
|
||||||
const message =
|
link => {
|
||||||
"Enter custom link to the burg map. It can be a link to Medieval Fantasy City Generator or other tool. Keep empty to use MFCG seed";
|
if (link) burg.link = link;
|
||||||
prompt(message, {default: burg.link || "", required: false}, link => {
|
else delete burg.link;
|
||||||
if (link) burg.link = link;
|
updateBurgPreview(burg);
|
||||||
else delete burg.link;
|
}
|
||||||
updateMFCGFrame(burg);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEmblemEdit() {
|
function openEmblemEdit() {
|
||||||
|
|
@ -405,16 +399,16 @@ function editBurg(id) {
|
||||||
editEmblem("burg", "burgCOA" + id, burg);
|
editEmblem("burg", "burgCOA" + id, burg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMFCGMap() {
|
function toggleBurgPreview() {
|
||||||
options.showMFCGMap = !options.showMFCGMap;
|
options.showBurgPreview = !options.showBurgPreview;
|
||||||
document.getElementById("mfcgPreviewSection").style.display = options.showMFCGMap ? "block" : "none";
|
byId("burgPreviewSection").style.display = options.showBurgPreview ? "block" : "none";
|
||||||
document.getElementById("burgToggleMFCGMap").className = options.showMFCGMap ? "icon-map" : "icon-map-o";
|
byId("burgTogglePreview").className = options.showBurgPreview ? "icon-map" : "icon-map-o";
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleRelocateBurg() {
|
function toggleRelocateBurg() {
|
||||||
const toggler = document.getElementById("toggleCells");
|
const toggler = byId("toggleCells");
|
||||||
document.getElementById("burgRelocate").classList.toggle("pressed");
|
byId("burgRelocate").classList.toggle("pressed");
|
||||||
if (document.getElementById("burgRelocate").classList.contains("pressed")) {
|
if (byId("burgRelocate").classList.contains("pressed")) {
|
||||||
viewbox.style("cursor", "crosshair").on("click", relocateBurgOnClick);
|
viewbox.style("cursor", "crosshair").on("click", relocateBurgOnClick);
|
||||||
tip("Click on map to relocate burg. Hold Shift for continuous move", true);
|
tip("Click on map to relocate burg. Hold Shift for continuous move", true);
|
||||||
if (!layerIsOn("toggleCells")) {
|
if (!layerIsOn("toggleCells")) {
|
||||||
|
|
@ -534,7 +528,7 @@ function editBurg(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeBurgEditor() {
|
function closeBurgEditor() {
|
||||||
document.getElementById("burgRelocate").classList.remove("pressed");
|
byId("burgRelocate").classList.remove("pressed");
|
||||||
burgLabels.selectAll("text").call(d3.drag().on("drag", null)).classed("draggable", false);
|
burgLabels.selectAll("text").call(d3.drag().on("drag", null)).classed("draggable", false);
|
||||||
unselect();
|
unselect();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -514,7 +514,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
|
||||||
data += b.temple ? "temple," : ",";
|
data += b.temple ? "temple," : ",";
|
||||||
data += b.shanty ? "shanty town," : ",";
|
data += b.shanty ? "shanty town," : ",";
|
||||||
data += b.coa ? JSON.stringify(b.coa).replace(/"/g, "").replace(/,/g, ";") + "," : ",";
|
data += b.coa ? JSON.stringify(b.coa).replace(/"/g, "").replace(/,/g, ";") + "," : ",";
|
||||||
data += getMFCGlink(b);
|
data += getBurgLink(b);
|
||||||
|
|
||||||
data += "\n";
|
data += "\n";
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -288,16 +288,20 @@ function togglePort(burg) {
|
||||||
.attr("height", size);
|
.attr("height", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBurgSeed(burg) {
|
function getBurgLink(burg) {
|
||||||
return burg.MFCG || Number(`${seed}${String(burg.i).padStart(4, 0)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMFCGlink(burg) {
|
|
||||||
if (burg.link) return burg.link;
|
if (burg.link) return burg.link;
|
||||||
|
|
||||||
|
const population = burg.population * populationRate * urbanization;
|
||||||
|
if (population >= options.villageMaxPopulation || burg.citadel || burg.walls || burg.temple || burg.shanty)
|
||||||
|
return createMfcgLink(burg);
|
||||||
|
|
||||||
|
return createVillageGeneratorLink(burg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMfcgLink(burg) {
|
||||||
const {cells} = pack;
|
const {cells} = pack;
|
||||||
const {i, name, population: burgPopulation, cell} = burg;
|
const {i, name, population: burgPopulation, cell} = burg;
|
||||||
const seed = getBurgSeed(burg);
|
const burgSeed = burg.MFCG || seed + String(burg.i).padStart(4, 0);
|
||||||
|
|
||||||
const sizeRaw = 2.13 * Math.pow((burgPopulation * populationRate) / urbanDensity, 0.385);
|
const sizeRaw = 2.13 * Math.pow((burgPopulation * populationRate) / urbanDensity, 0.385);
|
||||||
const size = minmax(Math.ceil(sizeRaw), 6, 100);
|
const size = minmax(Math.ceil(sizeRaw), 6, 100);
|
||||||
|
|
@ -305,11 +309,19 @@ function getMFCGlink(burg) {
|
||||||
|
|
||||||
const river = cells.r[cell] ? 1 : 0;
|
const river = cells.r[cell] ? 1 : 0;
|
||||||
const coast = Number(burg.port > 0);
|
const coast = Number(burg.port > 0);
|
||||||
const sea = coast && cells.haven[cell] ? getSeaDirections(cell) : null;
|
const sea = (() => {
|
||||||
|
if (!coast || !cells.haven[cell]) return null;
|
||||||
|
|
||||||
|
// calculate see direction: 0 = south, 0.5 = west, 1 = north, 1.5 = east
|
||||||
|
const p1 = cells.p[cell];
|
||||||
|
const p2 = cells.p[cells.haven[cell]];
|
||||||
|
let deg = (Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180) / Math.PI - 90;
|
||||||
|
if (deg < 0) deg += 360;
|
||||||
|
return rn(normalize(deg, 0, 360) * 2, 2);
|
||||||
|
})();
|
||||||
|
|
||||||
const biome = cells.biome[cell];
|
|
||||||
const arableBiomes = river ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
const arableBiomes = river ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
||||||
const farms = +arableBiomes.includes(biome);
|
const farms = +arableBiomes.includes(cells.biome[cell]);
|
||||||
|
|
||||||
const citadel = +burg.citadel;
|
const citadel = +burg.citadel;
|
||||||
const urban_castle = +(citadel && each(2)(i));
|
const urban_castle = +(citadel && each(2)(i));
|
||||||
|
|
@ -321,19 +333,12 @@ function getMFCGlink(burg) {
|
||||||
const temple = +burg.temple;
|
const temple = +burg.temple;
|
||||||
const shantytown = +burg.shanty;
|
const shantytown = +burg.shanty;
|
||||||
|
|
||||||
function getSeaDirections(i) {
|
const url = new URL("https://watabou.github.io/city-generator/");
|
||||||
const p1 = cells.p[i];
|
url.search = new URLSearchParams({
|
||||||
const p2 = cells.p[cells.haven[i]];
|
|
||||||
let deg = (Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180) / Math.PI - 90;
|
|
||||||
if (deg < 0) deg += 360;
|
|
||||||
return rn(normalize(deg, 0, 360) * 2, 2); // 0 = south, 0.5 = west, 1 = north, 1.5 = east
|
|
||||||
}
|
|
||||||
|
|
||||||
const parameters = {
|
|
||||||
name,
|
name,
|
||||||
population,
|
population,
|
||||||
size,
|
size,
|
||||||
seed,
|
seed: burgSeed,
|
||||||
river,
|
river,
|
||||||
coast,
|
coast,
|
||||||
farms,
|
farms,
|
||||||
|
|
@ -345,14 +350,60 @@ function getMFCGlink(burg) {
|
||||||
walls,
|
walls,
|
||||||
shantytown,
|
shantytown,
|
||||||
gates: -1
|
gates: -1
|
||||||
};
|
});
|
||||||
const url = new URL("https://watabou.github.io/city-generator/");
|
|
||||||
url.search = new URLSearchParams(parameters);
|
|
||||||
if (sea) url.searchParams.append("sea", sea);
|
if (sea) url.searchParams.append("sea", sea);
|
||||||
|
|
||||||
return url.toString();
|
return url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createVillageGeneratorLink(burg) {
|
||||||
|
const {cells, features} = pack;
|
||||||
|
const {i, population, cell} = burg;
|
||||||
|
|
||||||
|
const pop = rn(population * populationRate * urbanization);
|
||||||
|
const burgSeed = seed + String(i).padStart(4, 0);
|
||||||
|
const tags = [];
|
||||||
|
|
||||||
|
if (cells.r[cell] && cells.haven[cell]) tags.push("estuary");
|
||||||
|
else if (cells.haven[cell] && features[cells.f[cell]].cells === 1) tags.push("island,district");
|
||||||
|
else if (burg.port) tags.push("coast");
|
||||||
|
else if (cells.conf[cell]) tags.push("confluence");
|
||||||
|
else if (cells.r[cell]) tags.push("river");
|
||||||
|
else if (pop < 200 && each(4)(cell)) tags.push("pond");
|
||||||
|
|
||||||
|
const roadsAround = cells.c[cell].filter(c => cells.h[c] >= 20 && cells.road[c]).length;
|
||||||
|
if (roadsAround > 1) tags.push("highway");
|
||||||
|
else if (roadsAround === 1) tags.push("dead end");
|
||||||
|
else tags.push("isolated");
|
||||||
|
|
||||||
|
const biome = cells.biome[cell];
|
||||||
|
const arableBiomes = cells.r[cell] ? [1, 2, 3, 4, 5, 6, 7, 8] : [5, 6, 7, 8];
|
||||||
|
if (!arableBiomes.includes(biome)) tags.push("uncultivated");
|
||||||
|
else if (each(6)(cell)) tags.push("farmland");
|
||||||
|
|
||||||
|
const temp = grid.cells.temp[cells.g[cell]];
|
||||||
|
if (temp <= 0 || temp > 28 || (temp > 25 && each(3)(cell))) tags.push("no orchards");
|
||||||
|
|
||||||
|
if (!burg.plaza) tags.push("no square");
|
||||||
|
|
||||||
|
if (pop < 100) tags.push("sparse");
|
||||||
|
else if (pop > 300) tags.push("dense");
|
||||||
|
|
||||||
|
const width = (() => {
|
||||||
|
if (pop > 1500) return 1600;
|
||||||
|
if (pop > 1000) return 1400;
|
||||||
|
if (pop > 500) return 1000;
|
||||||
|
if (pop > 200) return 800;
|
||||||
|
if (pop > 100) return 600;
|
||||||
|
return 400;
|
||||||
|
})();
|
||||||
|
const height = rn(width / 2.2);
|
||||||
|
|
||||||
|
const url = new URL("https://watabou.github.io/village-generator/");
|
||||||
|
url.search = new URLSearchParams({pop, name: "", seed: burgSeed, width, height, tags});
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// draw legend box
|
// draw legend box
|
||||||
function drawLegend(name, data) {
|
function drawLegend(name, data) {
|
||||||
legend.selectAll("*").remove(); // fully redraw every time
|
legend.selectAll("*").remove(); // fully redraw every time
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.96.07"; // generator version, update each time
|
const version = "1.97.00"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
@ -28,6 +28,7 @@ const version = "1.96.07"; // generator version, update each time
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<strong>Latest changes:</strong>
|
<strong>Latest changes:</strong>
|
||||||
|
<li>Preview villages map</li>
|
||||||
<li>Ability to render ocean heightmap</li>
|
<li>Ability to render ocean heightmap</li>
|
||||||
<li>Scale bar styling features</li>
|
<li>Scale bar styling features</li>
|
||||||
<li>Vignette visual layer and vignette styling options</li>
|
<li>Vignette visual layer and vignette styling options</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue