mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
v1.0.06
This commit is contained in:
parent
59785125b0
commit
52e8f28cd0
17 changed files with 158 additions and 77 deletions
|
|
@ -689,7 +689,7 @@ table.matrix-table td.Ally {
|
|||
color: #000000;
|
||||
}
|
||||
|
||||
table.matrix-table td.Sympathy {
|
||||
table.matrix-table td.Friendly {
|
||||
background-color:#d4f8aa;
|
||||
}
|
||||
|
||||
|
|
@ -1391,7 +1391,7 @@ div.states > div.biomeArea {
|
|||
}
|
||||
|
||||
#unitsBody>div>input[type="number"] {
|
||||
width: 3.6em;
|
||||
width: 4em;
|
||||
}
|
||||
|
||||
#unitsBody>div>input,
|
||||
|
|
|
|||
16
index.html
16
index.html
|
|
@ -21,7 +21,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="libs/jquery-ui.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<svg id="map" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="map" width="100%" height="100%">
|
||||
<defs>
|
||||
<g id="filters">
|
||||
<filter id="blurFilter" x="-1" y="-1" width="100" height="100">
|
||||
|
|
@ -2735,20 +2735,24 @@
|
|||
<div style="margin-left: 18px" data-tip="Click to sort by religion form" class="sortable alphabetically hide" data-sortby="form">Form </div>
|
||||
<div style="margin-left: 42px" data-tip="Click to sort by supreme deity" class="sortable alphabetically hide" data-sortby="deity">Supreme Deity </div>
|
||||
<div style="margin-left: 92px" data-tip="Click to sort by religion area" class="sortable hide" data-sortby="area">Area </div>
|
||||
<div style="margin-left: 17px" data-tip="Click to sort by religion population" class="sortable hide" data-sortby="population">Population </div>
|
||||
<div style="margin-left: 17px" data-tip="Click to sort by number of believers (religion area population)" class="sortable hide" data-sortby="population">Believers </div>
|
||||
</div>
|
||||
<div id="religionsBody" class="table" data-type="absolute"></div>
|
||||
|
||||
<div id="religionsFooter" class="totalLine">
|
||||
<div data-tip="Religions number" style="margin-left: 12px">Religions: <span id="religionsFooterNumber">0</span></div>
|
||||
<div data-tip="Total number of organized religions" style="margin-left: 12px">Organized: <span id="religionsOrganized">0</span></div>
|
||||
<div data-tip="Total number of heresies" style="margin-left: 12px">Heresies: <span id="religionsHeresies">0</span></div>
|
||||
<div data-tip="Total number of cults" style="margin-left: 12px">Cults: <span id="religionsCults">0</span></div>
|
||||
<div data-tip="Total number of folk religions" style="margin-left: 12px">Folk: <span id="religionsFolk">0</span></div>
|
||||
<div data-tip="Total land area" style="margin-left: 12px">Land Area: <span id="religionsFooterArea">0</span></div>
|
||||
<div data-tip="Total population" style="margin-left: 12px">Population: <span id="religionsFooterPopulation">0</span></div>
|
||||
<div data-tip="Total number of believers (population)" style="margin-left: 12px">Believers: <span id="religionsFooterPopulation">0</span></div>
|
||||
</div>
|
||||
|
||||
<div id="religionsBottom">
|
||||
<button id="religionsEditorRefresh" data-tip="Refresh the Editor" class="icon-cw"></button>
|
||||
<button id="religionsLegend" data-tip="Toggle Legend box" class="icon-list-bullet"></button>
|
||||
<button id="religionsPercentage" data-tip="Toggle percentage / absolute values display mode" class="icon-percent"></button>
|
||||
<button id="religionsExtinct" data-tip="Show/hide extinct religions (religions without believers)" class="icon-adjust"></button>
|
||||
|
||||
<button id="religionsManually" data-tip="Manually re-assign religions" class="icon-brush"></button>
|
||||
<div id="religionsManuallyButtons" style="display: none">
|
||||
|
|
@ -2785,8 +2789,8 @@
|
|||
<i data-locked="0" id="lock_distanceScale" class="icon-lock-open"></i>
|
||||
<div data-tip="Select how many distance units are in one pixel">
|
||||
<div>1 map pixel =</div>
|
||||
<input id="distanceScaleOutput" type="range" min=.1 max=10 step=.1 value=3>
|
||||
<input id="distanceScaleInput" data-stored="distanceScale" type="number" min=.1 max=10 step=.1 step=.1 value=3 data-value=3>
|
||||
<input id="distanceScaleOutput" type="range" min=.01 max=20 step=.1 value=3>
|
||||
<input id="distanceScaleInput" data-stored="distanceScale" type="number" min=.01 max=100 step=.01 value=3 data-value=3>
|
||||
<span id="distanceUnitOutput"></span>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
4
main.js
4
main.js
|
|
@ -284,7 +284,7 @@ function applyDefaultStyle() {
|
|||
|
||||
coastline.attr("opacity", .5).attr("stroke", "#1f3846").attr("stroke-width", .7).attr("filter", "url(#dropShadow)");
|
||||
styleCoastlineAuto.checked = true;
|
||||
relig.attr("opacity", .8).attr("stroke", "#777777").attr("stroke-width", 0).attr("filter", null).attr("fill-rule", "evenodd");
|
||||
relig.attr("opacity", .6).attr("stroke", "#777777").attr("stroke-width", .2).attr("filter", null).attr("fill-rule", "evenodd");
|
||||
cults.attr("opacity", .6).attr("stroke", "#777777").attr("stroke-width", .5).attr("filter", null).attr("fill-rule", "evenodd");
|
||||
icons.selectAll("g").attr("opacity", null).attr("fill", "#ffffff").attr("stroke", "#3e3e4b").attr("filter", null).attr("mask", null);
|
||||
landmass.attr("opacity", 1).attr("fill", "#eef6fb").attr("filter", null);
|
||||
|
|
@ -1186,7 +1186,7 @@ function addMarkers() {
|
|||
.attr("xlink:href", "#marker_volcano").attr("data-id", "#marker_volcano")
|
||||
.attr("data-x", x).attr("data-y", y).attr("x", x - 15).attr("y", y - 30)
|
||||
.attr("data-size", 1).attr("width", 30).attr("height", 30);
|
||||
const height = getFriendlyHeight(cells.h[cell]);
|
||||
const height = getFriendlyHeight([x, y]);
|
||||
const proper = Names.getCulture(cells.culture[cell]);
|
||||
const name = Math.random() < .3 ? "Mount " + proper : Math.random() > .3 ? proper + " Volcano" : proper;
|
||||
notes.push({id, name, legend:`Active volcano. Height: ${height}`});
|
||||
|
|
|
|||
|
|
@ -588,9 +588,9 @@
|
|||
const valid = states.filter(s => s.i && !states.removed);
|
||||
if (valid.length < 2) return;
|
||||
|
||||
const neibs = {"Ally":1, "Sympathy":2, "Neutral":1, "Suspicion":10, "Rival":9}; // relations to neighbors
|
||||
const neibsOfNeibs = {"Ally":10, "Sympathy":8, "Neutral":5, "Suspicion":1}; // relations to neighbors of neighbors
|
||||
const far = {"Sympathy":1, "Neutral":12, "Suspicion":2, "Unknown":6}; // relations to other
|
||||
const neibs = {"Ally":1, "Friendly":2, "Neutral":1, "Suspicion":10, "Rival":9}; // relations to neighbors
|
||||
const neibsOfNeibs = {"Ally":10, "Friendly":8, "Neutral":5, "Suspicion":1}; // relations to neighbors of neighbors
|
||||
const far = {"Friendly":1, "Neutral":12, "Suspicion":2, "Unknown":6}; // relations to other
|
||||
const navals = {"Neutral":1, "Suspicion":2, "Rival":1, "Unknown":1}; // relations of naval powers
|
||||
|
||||
valid.forEach(s => s.diplomacy = new Array(states.length).fill("x")); // clear all relationships
|
||||
|
|
|
|||
|
|
@ -14,17 +14,18 @@
|
|||
|
||||
const input = document.getElementById("templateInput");
|
||||
if (!locked("template")) {
|
||||
const rnd = Math.random();
|
||||
if (rnd < .05) input.value = "Volcano"; else // 5%
|
||||
if (rnd < .25) input.value = "High Island"; else // 20%
|
||||
if (rnd < .35) input.value = "Low Island"; else // 10%
|
||||
if (rnd < .55) input.value = "Continents"; else // 20%
|
||||
if (rnd < .85) input.value = "Archipelago"; else // 30%
|
||||
if (rnd < .90) input.value = "Mediterranean"; else // 5%
|
||||
if (rnd < .95) input.value = "Peninsula"; else // 5%
|
||||
if (rnd < .97) input.value = "Pangea"; else // 2%
|
||||
if (rnd < .99) input.value = "Isthmus"; else // 2%
|
||||
input.value = "Atoll"; // 1%
|
||||
const templates = {
|
||||
"Volcano": 5,
|
||||
"High Island": 22,
|
||||
"Low Island": 10,
|
||||
"Continents": 20,
|
||||
"Archipelago": 32,
|
||||
"Mediterranean":3,
|
||||
"Peninsula": 3,
|
||||
"Pangea": 2,
|
||||
"Isthmus": 2,
|
||||
"Atoll": 1};
|
||||
input.value = rw(templates);
|
||||
}
|
||||
|
||||
switch (input.value) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
Heresy:{"Heresy":1}
|
||||
};
|
||||
|
||||
const methods = {"Random + type":3, "Random + ism":1, "Supreme + ism":5, "Faith of + Supreme":3, "Place + ism":1, "Culture + ism":1, "Place + ian + type":6, "Culture + type":4};
|
||||
const methods = {"Random + type":3, "Random + ism":1, "Supreme + ism":5, "Faith of + Supreme":3, "Place + ism":1, "Culture + ism":2, "Place + ian + type":6, "Culture + type":4};
|
||||
|
||||
const types = {
|
||||
"Shamanism":{"Beliefs":3, "Shamanism":2, "Spirits":1},
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
const form = rw(forms.Folk);
|
||||
const name = c.name + " " + rw(types[form]);
|
||||
const deity = form === "Animism" ? null : getDeityName(c.i);
|
||||
const color = `url(#hatch${rand(8,13)})`;
|
||||
const color = getRandomColor(); // `url(#hatch${rand(8,13)})`;
|
||||
religions.push({i: c.i, name, color, culture: c.i, type:"Folk", form, deity});
|
||||
});
|
||||
|
||||
|
|
@ -85,18 +85,25 @@
|
|||
const culture = cells.culture[center];
|
||||
|
||||
const deity = form === "Non-theism" ? null : getDeityName(culture);
|
||||
const [name, expansion] = getReligionName(form, deity, center);
|
||||
let [name, expansion] = getReligionName(form, deity, center);
|
||||
if (expansion === "state" && !state) expansion = "global";
|
||||
if (expansion === "culture" && !culture) expansion = "global";
|
||||
|
||||
if (expansion === "state" && Math.random() > .5) center = states[state].center;
|
||||
if (expansion === "culture" && Math.random() > .5) center = cultures[culture].center;
|
||||
|
||||
if (expansion === "state" && state && Math.random() > .5) center = states[state].center;
|
||||
if (expansion === "culture" && culture && Math.random() > .5) center = cultures[culture].center;
|
||||
if (!cells.burg[center] && cells.c[center].some(c => cells.burg[c])) center = cells.c[center].find(c => cells.burg[c]);
|
||||
const x = cells.p[center][0], y = cells.p[center][1];
|
||||
|
||||
const s = spacing * gauss(1, .3, .2, 2, 2); // randomize to make the placement not uniform
|
||||
if (religionsTree.find(x, y, s) !== undefined) continue; // to close to existing religion
|
||||
|
||||
// add "Old" to name of the folk religion on this culture
|
||||
const folk = religions.find(r => expansion === "culture" && r.culture === culture && r.type === "Folk");
|
||||
if (folk && folk.name.slice(0,3) !== "Old") folk.name = "Old " + folk.name;
|
||||
|
||||
const expansionism = rand(3, 8);
|
||||
const color = `url(#hatch${rand(0,5)})`;
|
||||
const color = getRandomColor(); // `url(#hatch${rand(0,5)})`;
|
||||
religions.push({i: religions.length, name, color, culture, type:"Organized", form, deity, expansion, expansionism, center});
|
||||
religionsTree.add([x, y]);
|
||||
//debug.append("circle").attr("cx", x).attr("cy", y).attr("r", 2).attr("fill", "blue");
|
||||
|
|
@ -116,7 +123,8 @@
|
|||
const deity = getDeityName(culture);
|
||||
const name = getCultName(form, center);
|
||||
const expansionism = gauss(1.1, .5, 0, 5);
|
||||
religions.push({i: religions.length, name, color: "url(#hatch7)", culture, type:"Cult", form, deity, expansion:"global", expansionism, center});
|
||||
const color = getRandomColor(); // "url(#hatch7)";
|
||||
religions.push({i: religions.length, name, color, culture, type:"Cult", form, deity, expansion:"global", expansionism, center});
|
||||
religionsTree.add([x, y]);
|
||||
//debug.append("circle").attr("cx", x).attr("cy", y).attr("r", 2).attr("fill", "red");
|
||||
}
|
||||
|
|
@ -137,7 +145,8 @@
|
|||
const culture = cells.culture[center];
|
||||
const name = getCultName("Heresy", center);
|
||||
const expansionism = gauss(1.2, .5, 0, 5);
|
||||
religions.push({i: religions.length, name, color:"url(#hatch6)", culture, type:"Heresy", form:"Heresy", deity: r.deity, expansion:"global", expansionism, center});
|
||||
const color = getRandomColor(); // "url(#hatch6)";
|
||||
religions.push({i: religions.length, name, color, culture, type:"Heresy", form:"Heresy", deity: r.deity, expansion:"global", expansionism, center});
|
||||
religionsTree.add([x, y]);
|
||||
//debug.append("circle").attr("cx", x).attr("cy", y).attr("r", 2).attr("fill", "green");
|
||||
}
|
||||
|
|
@ -175,34 +184,37 @@
|
|||
|
||||
religions.filter(r => r.type === "Organized" || r.type === "Cult").forEach(r => {
|
||||
cells.religion[r.center] = r.i;
|
||||
queue.queue({e:r.center, p:0, r:r.i});
|
||||
queue.queue({e:r.center, p:0, r:r.i, s: cells.state[r.center], c:r.culture});
|
||||
cost[r.center] = 1;
|
||||
});
|
||||
|
||||
const neutral = cells.i.length / 5000 * 200 * gauss(1, .3, .2, 2, 2) * neutralInput.value; // limit cost for organized religions growth
|
||||
const popCost = d3.max(cells.pop) / 3; // enougth population to spered religion without penalty
|
||||
|
||||
while (queue.length) {
|
||||
const next = queue.dequeue(), n = next.e, p = next.p, r = next.r;
|
||||
const next = queue.dequeue(), n = next.e, p = next.p, r = next.r, c = next.c, s = next.s;
|
||||
const expansion = religions[r].expansion;
|
||||
|
||||
cells.c[n].forEach(function(e) {
|
||||
const cultureCost = expansion === "culture" ? religions[r].culture == cells.culture[e] ? 0 : 20000 : 10;
|
||||
const stateCost = expansion === "state" ? cells.state[religions[r].center] == cells.state[e] ? 0 : 20000 : 10;
|
||||
const biomeCost = cells.road[e] ? 0 : biomesData.cost[cells.biome[e]];
|
||||
if (expansion === "culture" && c !== cells.culture[e]) return;
|
||||
if (expansion === "state" && s !== cells.state[e]) return;
|
||||
|
||||
const cultureCost = c !== cells.culture[e] ? 10 : 0;
|
||||
const stateCost = s !== cells.state[e] ? 10 : 0;
|
||||
const biomeCost = cells.road[e] ? 1 : biomesData.cost[cells.biome[e]];
|
||||
const populationCost = Math.max(rn(popCost - cells.pop[e]), 0);
|
||||
const heightCost = Math.max(cells.h[e], 20) - 20;
|
||||
const waterCost = cells.h[e] < 20 ? cells.road[e] ? 50 : 1000 : 0;
|
||||
const totalCost = p + (cultureCost + stateCost + biomeCost + heightCost + waterCost) / religions[r].expansionism;
|
||||
|
||||
const totalCost = p + (cultureCost + stateCost + biomeCost + populationCost + heightCost + waterCost) / religions[r].expansionism;
|
||||
if (totalCost > neutral) return;
|
||||
|
||||
if (!cost[e] || totalCost < cost[e]) {
|
||||
if (cells.h[e] >= 20 && cells.culture[e]) cells.religion[e] = r; // assign religion to cell
|
||||
cost[e] = totalCost;
|
||||
queue.queue({e, p:totalCost, r});
|
||||
queue.queue({e, p:totalCost, r, c, s});
|
||||
}
|
||||
});
|
||||
}
|
||||
//debug.selectAll(".text").data(cost).enter().append("text").attr("x", (d, e) => cells.p[e][0]-1).attr("y", (d, e) => cells.p[e][1]-1).text(d => d ? rn(d) : "").attr("font-size", 2);
|
||||
console.timeEnd("expandReligions");
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +300,7 @@
|
|||
if (m === "Random + ism") return [trimVowels(random()) + "ism", "global"];
|
||||
if (m === "Supreme + ism" && deity) return [trimVowels(supreme()) + "ism", "global"];
|
||||
if (m === "Faith of + Supreme" && deity) return ["Faith of " + supreme(), "global"];
|
||||
if (m === "Place + ism") return [place() + "ism", "global"];
|
||||
if (m === "Place + ism") return [place() + "ism", "state"];
|
||||
if (m === "Culture + ism") return [trimVowels(culture()) + "ism", "culture"];
|
||||
if (m === "Place + ian + type") return [place("adj") + " " + type(), "state"];
|
||||
if (m === "Culture + type") return [culture() + " " + type(), "culture"];
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ function parseLoadedData(data) {
|
|||
|
||||
if (version < 1) {
|
||||
// 1.0 adds a new religions layer
|
||||
relig = viewbox.insert("g", "#terrain").attr("id", "cults");
|
||||
relig = viewbox.insert("g", "#terrain").attr("id", "relig");
|
||||
Religions.generate();
|
||||
|
||||
// 1.0 adds a legend box
|
||||
|
|
@ -503,6 +503,16 @@ function parseLoadedData(data) {
|
|||
biomesData.color.push("#0b9131");
|
||||
biomesData.habitability.push(12);
|
||||
}
|
||||
|
||||
if (version == 1) {
|
||||
// v 1.0 initial code had a bug with religion layer id
|
||||
if (!relig.size()) relig = viewbox.insert("g", "#terrain").attr("id", "relig");
|
||||
|
||||
// v 1.0 initially has Sympathy status then relaced with Friendly
|
||||
for (const s of pack.states) {
|
||||
s.diplomacy = s.diplomacy.map(r => r === "Sympathy" ? "Friendly" : r);
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
changeMapSize();
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ function editBiomes() {
|
|||
|
||||
if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
|
||||
applySorting(biomesHeader);
|
||||
$("#biomesEditor").dialog();
|
||||
$("#biomesEditor").dialog({width: fitContent()});
|
||||
}
|
||||
|
||||
function biomeHighlightOn(event) {
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ function editCultures() {
|
|||
|
||||
if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
|
||||
applySorting(culturesHeader);
|
||||
$("#culturesEditor").dialog();
|
||||
$("#culturesEditor").dialog({width: fitContent()});
|
||||
}
|
||||
|
||||
function getTypeOptions(type) {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ function editDiplomacy() {
|
|||
if (layerIsOn("toggleReligions")) toggleReligions();
|
||||
|
||||
const body = document.getElementById("diplomacyBodySection");
|
||||
const statuses = ["Ally", "Sympathy", "Neutral", "Suspicion", "Enemy", "Unknown", "Rival", "Vassal", "Suzerain"];
|
||||
const statuses = ["Ally", "Friendly", "Neutral", "Suspicion", "Enemy", "Unknown", "Rival", "Vassal", "Suzerain"];
|
||||
const colors = ["#00b300", "#d4f8aa", "#edeee8", "#f3c7c4", "#e64b40", "#a9a9a9", "#ad5a1f", "#87CEFA", "#00008B"];
|
||||
refreshDiplomacyEditor();
|
||||
|
||||
tip("Click on a state to see its diplomatical relations", false, "warning");
|
||||
tip("Click on a state to see its diplomatic relations", false, "warning");
|
||||
viewbox.style("cursor", "crosshair").on("click", selectStateOnMapClick);
|
||||
|
||||
if (modules.editDiplomacy) return;
|
||||
|
|
@ -213,11 +213,7 @@ function editDiplomacy() {
|
|||
message += `<tr><th>${s.name}</th>` + s.diplomacy.filter((v, i) => valid.includes(i)).map(r => `<td class='${r}'>${r}</td>`).join("") + "</tr>";
|
||||
});
|
||||
message += `</table>`;
|
||||
console.log(alertMessage.innerHTML)
|
||||
console.log(message)
|
||||
alertMessage.innerHTML = message;
|
||||
console.log(alertMessage.innerHTML)
|
||||
|
||||
$("#alert").dialog({title: "Relations matrix", width: fitContent(), position: {my: "center", at: "center", of: "svg"}, buttons: {}});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ function moved() {
|
|||
if (i === undefined) return;
|
||||
showNotes(d3.event, i);
|
||||
const g = findGridCell(point[0], point[1]); // grid cell id
|
||||
if (tooltip.dataset.main) showMainTip(); else showMapTooltip(d3.event, i, g);
|
||||
if (tooltip.dataset.main) showMainTip(); else showMapTooltip(point, d3.event, i, g);
|
||||
if (toolsContent.style.display === "block" && cellInfo.style.display === "block") updateCellInfo(point, i, g);
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ function showNotes(e, i) {
|
|||
}
|
||||
|
||||
// show viewbox tooltip if main tooltip is blank
|
||||
function showMapTooltip(e, i, g) {
|
||||
function showMapTooltip(point, e, i, g) {
|
||||
tip(""); // clear tip
|
||||
const tag = e.target.tagName;
|
||||
const path = e.composedPath ? e.composedPath() : getComposedPath(e.target); // apply polyfill
|
||||
|
|
@ -116,7 +116,7 @@ function showMapTooltip(e, i, g) {
|
|||
tip(prov + state);
|
||||
} else
|
||||
if (layerIsOn("toggleCultures") && pack.cells.culture[i]) tip("Culture: " + pack.cultures[pack.cells.culture[i]].name); else
|
||||
if (layerIsOn("toggleHeight")) tip("Height: " + getFriendlyHeight(pack.cells.h[i]));
|
||||
if (layerIsOn("toggleHeight")) tip("Height: " + getFriendlyHeight(point));
|
||||
}
|
||||
|
||||
// get cell info on mouse move
|
||||
|
|
@ -127,7 +127,8 @@ function updateCellInfo(point, i, g) {
|
|||
infoCell.innerHTML = i;
|
||||
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
|
||||
infoArea.innerHTML = cells.area[i] ? si(cells.area[i] * distanceScaleInput.value ** 2) + unit : "n/a";
|
||||
infoHeight.innerHTML = getFriendlyHeight(cells.h[i]) + " (" + cells.h[i] + ")";
|
||||
const h = pack.cells.h[i] < 20 ? grid.cells.h[pack.cells.g[i]] : pack.cells.h[i];
|
||||
infoHeight.innerHTML = getFriendlyHeight(point) + " (" + h + ")";
|
||||
infoTemp.innerHTML = convertTemperature(grid.cells.temp[g]);
|
||||
infoPrec.innerHTML = cells.h[i] >= 20 ? getFriendlyPrecipitation(i) : "n/a";
|
||||
infoState.innerHTML = cells.h[i] >= 20 ? cells.state[i] ? `${pack.states[cells.state[i]].fullName} (${cells.state[i]})` : "neutral lands (0)" : "no";
|
||||
|
|
@ -142,12 +143,16 @@ function updateCellInfo(point, i, g) {
|
|||
}
|
||||
|
||||
// get user-friendly (real-world) height value from map data
|
||||
function getFriendlyHeight(h) {
|
||||
function getFriendlyHeight(p) {
|
||||
const unit = heightUnit.value;
|
||||
let unitRatio = 3.281; // default calculations are in feet
|
||||
if (unit === "m") unitRatio = 1; // if meter
|
||||
else if (unit === "f") unitRatio = 0.5468; // if fathom
|
||||
|
||||
const packH = pack.cells.h[findCell(p[0], p[1])];
|
||||
const gridH = grid.cells.h[findGridCell(p[0], p[1])];
|
||||
const h = packH < 20 ? gridH : packH;
|
||||
|
||||
let height = -990;
|
||||
if (h >= 20) height = Math.pow(h - 18, +heightExponentInput.value);
|
||||
else if (h < 20 && h > 0) height = (h - 20) / h * 50;
|
||||
|
|
|
|||
|
|
@ -82,8 +82,7 @@ function editHeightmap() {
|
|||
heightmapInfoX.innerHTML = rn(p[0]);
|
||||
heightmapInfoY.innerHTML = rn(p[1]);
|
||||
heightmapInfoCell.innerHTML = cell;
|
||||
const h = grid.cells.h[cell];
|
||||
heightmapInfoHeight.innerHTML = `${h} (${getFriendlyHeight(h)})`;
|
||||
heightmapInfoHeight.innerHTML = `${grid.cells.h[cell]} (${getHeight(grid.cells.h[cell])})`;
|
||||
if (tooltip.dataset.main) showMainTip();
|
||||
|
||||
// move radius circle if drag mode is active
|
||||
|
|
@ -92,6 +91,20 @@ function editHeightmap() {
|
|||
moveCircle(p[0], p[1], brushRadius.valueAsNumber, "#333");
|
||||
}
|
||||
|
||||
// get user-friendly (real-world) height value from map data
|
||||
function getHeight(h) {
|
||||
const unit = heightUnit.value;
|
||||
let unitRatio = 3.281; // default calculations are in feet
|
||||
if (unit === "m") unitRatio = 1; // if meter
|
||||
else if (unit === "f") unitRatio = 0.5468; // if fathom
|
||||
|
||||
let height = -990;
|
||||
if (h >= 20) height = Math.pow(h - 18, +heightExponentInput.value);
|
||||
else if (h < 20 && h > 0) height = (h - 20) / h * 50;
|
||||
|
||||
return rn(height * unitRatio) + " " + unit;
|
||||
}
|
||||
|
||||
// Exit customization mode
|
||||
function finalizeHeightmap() {
|
||||
if (terrs.selectAll("*").size() < 200) {
|
||||
|
|
|
|||
|
|
@ -183,33 +183,49 @@ function editMarker() {
|
|||
["1F4B0", "💰", "Money bag"],
|
||||
["1F6A8", "🚨", "Revolving Light"],
|
||||
["1F309", "🌉", "Bridge at Night"],
|
||||
["1F4A8", "💨", "Dashing away"],
|
||||
["1F334", "🌴", "Palm"],
|
||||
["1F335", "🌵", "Cactus"],
|
||||
["1F33E", "🌾", "Sheaf"],
|
||||
["1F5FB", "🗻", "Mountain"],
|
||||
["1F30B", "🌋", "Volcano"],
|
||||
["270A", "✊", "Raised Fist"],
|
||||
["1F44A", "👊", "Oncoming Fist"],
|
||||
["1F4AA", "💪", "Flexed Biceps"],
|
||||
["1F47C", "👼", "Baby Angel"],
|
||||
["1F40E", "🐎", "Horse"],
|
||||
["1F434", "🐴", "Horse Face"],
|
||||
["1F42E", "🐮", "Cow"],
|
||||
["1F43A", "🐺", "Wolf Face"],
|
||||
["1F435", "🐵", "Monkey face"],
|
||||
["1F437", "🐷", "Pig face"],
|
||||
["1F414", "🐔", "Chiken"],
|
||||
["1F411", "🐑", "Eve"],
|
||||
["1F414", "🐔", "Chicken"],
|
||||
["1F411", "🐑", "Ewe"],
|
||||
["1F42B", "🐫", "Camel"],
|
||||
["1F418", "🐘", "Elephant"],
|
||||
["1F422", "🐢", "Turtle"],
|
||||
["1F40C", "🐌", "Snail"],
|
||||
["1F40D", "🐍", "Snake"],
|
||||
["1F41D", "🐝", "Honeybee"],
|
||||
["1F41C", "🐜", "Ant"],
|
||||
["1F41B", "🐛", "Bug"],
|
||||
["1F426", "🐦", "Bird"],
|
||||
["1F438", "🐸", "Frog Face"],
|
||||
["1F433", "🐳", "Whale"],
|
||||
["1F42C", "🐬", "Dolphin"],
|
||||
["1F420", "🐟", "Fish"],
|
||||
["1F480", "💀", "Skull"],
|
||||
["1F432", "🐲", "Dragon Head"],
|
||||
["1F479", "👹", "Ogre"],
|
||||
["1F47A", "👺", "Goblin"],
|
||||
["1F47B", "👻", "Ghost"],
|
||||
["1F47E", "👾", "Alien"],
|
||||
["1F480", "💀", "Skull"],
|
||||
["1F383", "🎃", "Jack-O-Lantern"],
|
||||
["1F384", "🎄", "Christmas Tree"],
|
||||
["1F334", "🌴", "Palm"],
|
||||
["1F335", "🌵", "Cactus"],
|
||||
["2618", "☘️", "Shamrock"],
|
||||
["1F340", "🍀", "Four Leaf Clover"],
|
||||
["1F341", "🍁", "Maple Leaf"],
|
||||
["1F33F", "🌿", "Herb"],
|
||||
["1F33E", "🌾", "Sheaf"],
|
||||
["1F344", "🍄", "Mushroom"],
|
||||
["1F374", "🍴", "Fork and knife"],
|
||||
["1F372", "🍲", "Food"],
|
||||
["1F35E", "🍞", "Bread"],
|
||||
|
|
@ -223,24 +239,37 @@ function editMarker() {
|
|||
["1F377", "🍷", "Wine glass"],
|
||||
["1F3BB", "🎻", "Violin"],
|
||||
["1F3B8", "🎸", "Guitar"],
|
||||
["1F52A", "🔪", "Knife"],
|
||||
["1F52B", "🔫", "Pistol"],
|
||||
["1F4A3", "💣", "Bomb"],
|
||||
["1F4A5", "💥", "Collision"],
|
||||
["1F4A8", "💨", "Dashing away"],
|
||||
["1F301", "🌁", "Foggy"],
|
||||
["2744", "❄️", "Snowflake"],
|
||||
["26A1", "⚡", "Electricity"],
|
||||
["1F320", "🌠", "Shooting star"],
|
||||
["1F319", "🌙", "Crescent moon"],
|
||||
["1F525", "🔥", "Fire"],
|
||||
["1F4A7", "💧", "Droplet"],
|
||||
["1F30A", "🌊", "Wave"],
|
||||
["23F0", "⏰", "Alarm Clock"],
|
||||
["231B", "⌛", "Hourglass"],
|
||||
["1F3C6", "🏆", "Goblet"],
|
||||
["26F2", "⛲", "Fountain"],
|
||||
["26F5", "⛵", "Sailboat"],
|
||||
["26FA", "⛺", "Tend"],
|
||||
["26FA", "⛺", "Campfire"],
|
||||
["2764", "❤", "Red Heart"],
|
||||
["1F498", "💘", "Heart With Arrow"],
|
||||
["1F489", "💉", "Syringe"],
|
||||
["1F4D5", "📕", "Closed Book"],
|
||||
["1F4D6", "📚", "Books"],
|
||||
["1F381", "🎁", "Wrapped Gift"],
|
||||
["1F3AF", "🎯", "Archery"],
|
||||
["1F52E", "🔮", "Magic ball"],
|
||||
["1F3AD", "🎭", "Performing arts"],
|
||||
["1F3A8", "🎨", "Artist palette"],
|
||||
["1F457", "👗", "Dress"],
|
||||
["1F392", "🎒", "Backpack"],
|
||||
["1F451", "👑", "Crown"],
|
||||
["1F48D", "💍", "Ring"],
|
||||
["1F48E", "💎", "Gem"],
|
||||
|
|
@ -259,7 +288,6 @@ function editMarker() {
|
|||
["21F6", "⇶", "Three arrows"],
|
||||
["2699", "⚙", "Gear"],
|
||||
["269B", "⚛", "Atom"],
|
||||
["0024", "$", "Dollar"],
|
||||
["2680", "⚀", "Die1"],
|
||||
["2681", "⚁", "Die2"],
|
||||
["2682", "⚂", "Die3"],
|
||||
|
|
|
|||
|
|
@ -873,13 +873,13 @@ function randomizeOptions() {
|
|||
if (!locked("regions")) regionsInput.value = regionsOutput.value = gauss(15, 3, 2, 30);
|
||||
if (!locked("provinces")) provincesInput.value = provincesOutput.value = gauss(40, 20, 20, 100);
|
||||
if (!locked("manors")) {manorsInput.value = 1000; manorsOutput.value = "auto";}
|
||||
if (!locked("religions")) religionsInput.value = religionsOutput.value = gauss(6, 2, 3, 20);
|
||||
if (!locked("religions")) religionsInput.value = religionsOutput.value = gauss(5, 2, 2, 10);
|
||||
if (!locked("power")) powerInput.value = powerOutput.value = gauss(3, 2, 0, 10);
|
||||
if (!locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1);
|
||||
if (!locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30);
|
||||
|
||||
// 'Configure World' settings
|
||||
if (!locked("prec")) precInput.value = precOutput.value = gauss(100, 40, 0, 500);
|
||||
if (!locked("prec")) precInput.value = precOutput.value = gauss(100, 20, 5, 500);
|
||||
const tMax = +temperatureEquatorOutput.max, tMin = +temperatureEquatorOutput.min; // temperature extremes
|
||||
if (!locked("temperatureEquator")) temperatureEquatorOutput.value = temperatureEquatorInput.value = rand(tMax-6, tMax);
|
||||
if (!locked("temperaturePole")) temperaturePoleOutput.value = temperaturePoleInput.value = rand(tMin, tMin+10);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ function editReligions() {
|
|||
document.getElementById("religionsEditorRefresh").addEventListener("click", refreshReligionsEditor);
|
||||
document.getElementById("religionsLegend").addEventListener("click", toggleLegend);
|
||||
document.getElementById("religionsPercentage").addEventListener("click", togglePercentageMode);
|
||||
document.getElementById("religionsExtinct").addEventListener("click", toggleExtinct);
|
||||
document.getElementById("religionsManually").addEventListener("click", enterReligionsManualAssignent);
|
||||
document.getElementById("religionsManuallyApply").addEventListener("click", applyReligionsManualAssignent);
|
||||
document.getElementById("religionsManuallyCancel").addEventListener("click", () => exitReligionsManualAssignment());
|
||||
|
|
@ -56,11 +57,13 @@ function editReligions() {
|
|||
|
||||
for (const r of pack.religions) {
|
||||
if (r.removed) continue;
|
||||
|
||||
const area = r.area * (distanceScaleInput.value ** 2);
|
||||
const rural = r.rural * populationRate.value;
|
||||
const urban = r.urban * populationRate.value * urbanization.value;
|
||||
const population = rn(rural + urban);
|
||||
const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}`;
|
||||
if (r.i && !population && body.dataset.extinct !== "show") continue; // hide extinct religions
|
||||
const populationTip = `Believers: ${si(population)}; Rural areas: ${si(rural)}; Urban areas: ${si(urban)}`;
|
||||
totalArea += area;
|
||||
totalPopulation += population;
|
||||
|
||||
|
|
@ -98,7 +101,11 @@ function editReligions() {
|
|||
body.innerHTML = lines;
|
||||
|
||||
// update footer
|
||||
religionsFooterNumber.innerHTML = pack.religions.filter(r => r.i && !r.removed).length;
|
||||
const valid = pack.religions.filter(r => r.i && !r.removed);
|
||||
religionsOrganized.innerHTML = valid.filter(r => r.type === "Organized").length;
|
||||
religionsHeresies.innerHTML = valid.filter(r => r.type === "Heresy").length;
|
||||
religionsCults.innerHTML = valid.filter(r => r.type === "Cult").length;
|
||||
religionsFolk.innerHTML = valid.filter(r => r.type === "Folk").length;
|
||||
religionsFooterArea.innerHTML = si(totalArea) + unit;
|
||||
religionsFooterPopulation.innerHTML = si(totalPopulation);
|
||||
religionsFooterArea.dataset.area = totalArea;
|
||||
|
|
@ -118,7 +125,7 @@ function editReligions() {
|
|||
|
||||
if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
|
||||
applySorting(religionsHeader);
|
||||
$("#religionsEditor").dialog();
|
||||
$("#religionsEditor").dialog({width: fitContent()});
|
||||
}
|
||||
|
||||
function getTypeOptions(type) {
|
||||
|
|
@ -204,7 +211,7 @@ function editReligions() {
|
|||
}
|
||||
|
||||
function drawReligionCenters() {
|
||||
const tooltip = "Drag to move the religion center";
|
||||
const tooltip = "Drag to move the religion center (it won't affect religions distribution)";
|
||||
debug.select("#religionCenters").remove();
|
||||
const religionCenters = debug.append("g").attr("id", "religionCenters")
|
||||
.attr("stroke-width", 2).attr("stroke", "#444444").style("cursor", "move");
|
||||
|
|
@ -252,6 +259,11 @@ function editReligions() {
|
|||
}
|
||||
}
|
||||
|
||||
function toggleExtinct() {
|
||||
body.dataset.extinct = body.dataset.extinct !== "show" ? "show" : "hide";
|
||||
religionsEditorAddLines();
|
||||
}
|
||||
|
||||
function enterReligionsManualAssignent() {
|
||||
if (!layerIsOn("toggleReligions")) toggleReligions();
|
||||
customization = 7;
|
||||
|
|
@ -398,8 +410,8 @@ function editReligions() {
|
|||
|
||||
function downloadReligionsData() {
|
||||
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
|
||||
let data = "Id,Religion,Color,Type,Form,Deity,Area "+unit+",Population\n"; // headers
|
||||
|
||||
let data = "Id,Religion,Color,Type,Form,Deity,Area "+unit+",Believers\n"; // headers
|
||||
|
||||
body.querySelectorAll(":scope > div").forEach(function(el) {
|
||||
data += el.dataset.id + ",";
|
||||
data += el.dataset.name + ",";
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ function editStates() {
|
|||
|
||||
if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
|
||||
applySorting(statesHeader);
|
||||
$("#statesEditor").dialog();
|
||||
$("#statesEditor").dialog({width: fitContent()});
|
||||
}
|
||||
|
||||
function getCultureOptions(culture) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ function editZones() {
|
|||
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => zoneHighlightOff(ev)));
|
||||
|
||||
if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();}
|
||||
$("#zonesEditor").dialog();
|
||||
$("#zonesEditor").dialog({width: fitContent()});
|
||||
}
|
||||
|
||||
function zoneHighlightOn(event) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue