v 0.8.14b

This commit is contained in:
Azgaar 2019-05-04 20:12:47 +03:00
parent edc3fc1826
commit f81fd8a94c
8 changed files with 100 additions and 41 deletions

View file

@ -378,6 +378,11 @@ input[type="color"]::-webkit-color-swatch-wrapper {
font-size: smaller;
}
#optionsContent output {
text-align: right;
font-size: smaller;
}
#optionsContent input[type="number"] {
border: 0;
text-align: right;

View file

@ -807,14 +807,14 @@
</td>
</tr>
<tr data-tip="Cells density controls underlying graph size and hightly affects performance">
<tr data-tip="Set number of points to be used for graph generation. Highly affects performance">
<td></td>
<td>Cells density</td>
<td>Points number</td>
<td>
<input id="densityInput" type="range" min=1 max=3 value=1>
<input id="densityInput" type="range" min=1 max=10 value=1>
</td>
<td>
<input id="densityOutput" type="number" min=1 max=3 value=1>
<output id="densityOutput">10K</output>
</td>
</tr>
@ -852,7 +852,7 @@
</td>
</tr>
<tr data-tip="Define how many States should be generated">
<tr data-tip="Define how many states and capitals should be generated">
<td>
<i data-locked=0 id="lock_regions" class="icon-lock-open"></i>
</td>
@ -865,7 +865,7 @@
</td>
</tr>
<tr data-tip="Define how much states and cultures size can vary. Defines expansionism value">
<tr data-tip="Define how much states and cultures can vary in size. Defines expansionism value">
<td>
<i data-locked=0 id="lock_power" class="icon-lock-open"></i>
</td>
@ -891,16 +891,16 @@
</td>
</tr>
<tr data-tip="Define how densely settled areas (burgs) should be placed">
<tr data-tip="Define how many towns (non-capital burgs) should be generated">
<td>
<i data-locked=0 id="lock_manors" class="icon-lock-open"></i>
</td>
<td>Burgs density</td>
<td>Towns number</td>
<td>
<input id="manorsInput" data-stored="manors" type="range" min=0.1 max=5 step=.1 value=1>
<input id="manorsInput" data-stored="manors" type="range" min=0 max=1000 step=1 value=1000>
</td>
<td>
<input id="manorsOutput" data-stored="manors" type="number" min=0.1 max=5 step=.1 value=1>
<output id="manorsOutput" data-stored="manors" value="auto"></output>
</td>
</tr>

View file

@ -1153,7 +1153,7 @@ function showStatistics() {
console.log(stats);
}
function regenerateMap() {
const regenerateMap = debounce(function() {
closeDialogs("#worldConfigurator");
customization = 0;
undraw();
@ -1161,7 +1161,7 @@ function regenerateMap() {
generate();
restoreLayers();
if ($("#worldConfigurator").is(":visible")) editWorld();
}
}, 500);
// Clear the map
function undraw() {

View file

@ -106,12 +106,12 @@
const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for towns placement
const sorted = cells.i.filter(i => score[i] > 0 && cells.culture[i]).sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes
// burgs number depends on ratio between populated and all cells and burgsDensity input (expected mean ~300))
const burgsCount = rn(sorted.length / grid.points.length * manorsInput.value * 1000);
let burgsCount = manorsInput.value == 1000 ? rn(sorted.length / 10 / densityInput.value ** .8) : +manorsInput.value;
burgsCount += burgs.length;
const spacing = (graphWidth + graphHeight) * 9 / burgsCount; // base min distance between towns
const burgsTree = burgs[0];
for (let i = 0; burgs.length <= burgsCount && i < sorted.length; i++) {
for (let i = 0; burgs.length < burgsCount && i < sorted.length; i++) {
const id = sorted[i], x = cells.p[id][0], y = cells.p[id][1];
const s = spacing * Math.random() + 0.5; // randomize to make the placement not uniform
if (burgsTree.find(x, y, s) !== undefined) continue; // to close to existing burg
@ -124,7 +124,7 @@
cells.burg[id] = burg;
}
if (burgs.length <= burgsCount) console.error(`Cannot place all burgs. Requested ${burgsCount}, placed ${burgs.length-1}`);
if (burgs.length < burgsCount) console.error(`Cannot place all burgs. Requested ${burgsCount}, placed ${burgs.length-1}`);
//const min = d3.min(score.filter(s => s)), max = d3.max(score);
//terrs.selectAll("polygon").data(sorted).enter().append("polygon").attr("points", d => getPackPolygon(d)).attr("fill", d => color(1 - normalize(score[d], min, max)));

View file

@ -174,9 +174,40 @@
addStep("Trough", "3-4", "25-35", "5-95", "80-90");
addStep("Range", "5-6", "30-40", "10-90", "35-65");
}
function getBlobPower() {
switch (+densityInput.value) {
case 1: return .98;
case 2: return .985;
case 3: return .987;
case 4: return .9892;
case 5: return .9911;
case 6: return .9921;
case 7: return .9934;
case 8: return .9942;
case 9: return .9946;
case 10: return .995;
}
}
function getLinePower() {
switch (+densityInput.value) {
case 1: return .81;
case 2: return .82;
case 3: return .83;
case 4: return .84;
case 5: return .855;
case 6: return .87;
case 7: return .885;
case 8: return .91;
case 9: return .92;
case 10: return .93;
}
}
const addHill = function(count, height, rangeX, rangeY) {
count = getNumberInRange(count);
const power = getBlobPower();
while (count >= 1 || Math.random() < count) {addOneHill(); count--;}
function addOneHill() {
@ -198,7 +229,7 @@
for (const c of cells.c[q]) {
if (change[c]) continue;
change[c] = change[q] ** .98 * (Math.random() * .2 + .9);
change[c] = change[q] ** power * (Math.random() * .2 + .9);
if (change[c] > 1) queue.push(c);
}
}
@ -227,7 +258,7 @@
const queue = [start];
while (queue.length) {
const q = queue.shift();
h = h ** .98 * (Math.random() * .2 + .9);
h = h ** getBlobPower() * (Math.random() * .2 + .9);
if (h < 1) return;
cells.c[q].forEach(function(c, i) {
@ -242,13 +273,14 @@
const addRange = function(count, height, rangeX, rangeY) {
count = getNumberInRange(count);
while (count >= 1 || Math.random() < count) {addOneRange(); count--;}
const power = getLinePower();
while (count >= 1 || Math.random() < count) {addOneRange(); count--;}
function addOneRange() {
const used = new Uint8Array(cells.h.length);
let h = lim(getNumberInRange(height));
// find start and end points
// find start and end points
const startX = getPointInRange(rangeX, graphWidth);
const startY = getPointInRange(rangeY, graphHeight);
@ -260,7 +292,7 @@
limit++;
} while ((dist < graphWidth / 8 || dist > graphWidth / 3) && limit < 50)
let range = getRange(findGridCell(startX, startY), findGridCell(endX, endY));
let range = getRange(findGridCell(startX, startY), findGridCell(endX, endY));
// get main ridge
function getRange(cur, end) {
@ -291,11 +323,11 @@
frontier.forEach(i => {
cells.h[i] = lim(cells.h[i] + h * (Math.random() * .3 + .85));
});
h = h ** .82 - 1;
h = h ** power - 1;
if (h < 2) break;
frontier.forEach(f => {
cells.c[f].forEach(i => {
if (!used[i]) {queue.push(i); used[i] = 1;}
if (!used[i]) {queue.push(i); used[i] = 1;}
});
});
}
@ -316,13 +348,14 @@
const addTrough = function(count, height, rangeX, rangeY) {
count = getNumberInRange(count);
while (count >= 1 || Math.random() < count) {addOneTrough(); count--;}
const power = getLinePower();
while (count >= 1 || Math.random() < count) {addOneTrough(); count--;}
function addOneTrough() {
const used = new Uint8Array(cells.h.length);
let h = lim(getNumberInRange(height));
// find start and end points
// find start and end points
let limit = 0, startX, startY, start, dist = 0, endX, endY;
do {
startX = getPointInRange(rangeX, graphWidth);
@ -370,11 +403,11 @@
frontier.forEach(i => {
cells.h[i] = lim(cells.h[i] - h * (Math.random() * .3 + .85));
});
h = h ** .8 - 1;
h = h ** power - 1;
if (h < 2) break;
frontier.forEach(f => {
cells.c[f].forEach(i => {
if (!used[i]) {queue.push(i); used[i] = 1;}
if (!used[i]) {queue.push(i); used[i] = 1;}
});
});
}
@ -405,7 +438,7 @@
const start = findGridCell(startX, startY), end = findGridCell(endX, endY);
let range = getRange(start, end);
const query = [];
const query = [];
function getRange(cur, end) {
const range = [];

View file

@ -77,10 +77,11 @@ function showMapTooltip(e, i, g) {
tip(""); // clear tip
const tag = e.target.tagName;
const path = e.composedPath ? e.composedPath() : getComposedPath(e.target); // apply polyfill
if (!path[path.length - 8]) return;
const group = path[path.length - 7].id;
const subgroup = path[path.length - 8].id;
const land = pack.cells.h[i] >= 20;
// specific elements
if (group === "rivers") {tip("Click to edit the River"); return;}
if (group === "routes") {tip("Click to edit the Route"); return;}

View file

@ -590,7 +590,7 @@ const optionsContent = document.getElementById("optionsContent");
optionsContent.addEventListener("input", function(event) {
const id = event.target.id, value = event.target.value;
if (id === "mapWidthInput" || id === "mapHeightInput") mapSizeInputChange();
else if (id === "densityInput" || id === "densityOutput") changeCellsDensity(value);
else if (id === "densityInput" || id === "densityOutput") changeCellsDensity(+value);
else if (id === "culturesInput") culturesOutput.value = value;
else if (id === "culturesOutput") culturesInput.value = value;
else if (id === "regionsInput" || id === "regionsOutput") changeStatesNumber(value);
@ -598,8 +598,7 @@ optionsContent.addEventListener("input", function(event) {
else if (id === "powerOutput") powerInput.value = value;
else if (id === "neutralInput") neutralOutput.value = value;
else if (id === "neutralOutput") neutralInput.value = value;
else if (id === "manorsInput") manorsOutput.value = value;
else if (id === "manorsOutput") manorsInput.value = value;
else if (id === "manorsInput") changeBurgsNumberSlider(value);
else if (id === "uiSizeInput" || id === "uiSizeOutput") changeUIsize(value);
else if (id === "tooltipSizeInput" || id === "tooltipSizeOutput") changeTooltipSize(value);
else if (id === "transparencyInput") changeDialogsTransparency(value);
@ -608,9 +607,10 @@ optionsContent.addEventListener("input", function(event) {
});
optionsContent.addEventListener("change", function(event) {
if (event.target.dataset.stored) lock(event.target.dataset.stored);
if (event.target.dataset.stored) lock(event.target.dataset.stored);
const id = event.target.id, value = event.target.value;
if (id === "zoomExtentMin" || id === "zoomExtentMax") changeZoomExtent(value);
else if (id === "optionsSeed") generateMapWithSeed();
});
optionsContent.addEventListener("click", function(event) {
@ -625,7 +625,7 @@ function mapSizeInputChange() {
changeMapSize();
autoResize = false;
localStorage.setItem("mapWidth", mapWidthInput.value);
localStorage.setItem("mapHeight", mapHeightInput.value);
localStorage.setItem("mapHeight", mapHeightInput.value);
}
// change svg size on manual size change or window resize, do not change graph size
@ -658,7 +658,7 @@ function toggleFullscreen() {
mapWidthInput.value = graphWidth;
mapHeightInput.value = graphHeight;
}
changeMapSize();
changeMapSize();
}
function generateMapWithSeed() {
@ -703,10 +703,10 @@ function restoreDefaultZoomExtent() {
}
function changeCellsDensity(value) {
densityInput.value = densityOutput.value = value;
if (value == 3) densityOutput.style.color = "red";
else if (value == 2) densityOutput.style.color = "yellow";
else if (value == 1) densityOutput.style.color = "green";
densityOutput.value = value * 10 + "K";
if (value > 5) densityOutput.style.color = "#b12117";
else if (value > 1) densityOutput.style.color = "#dfdf12";
else densityOutput.style.color = "#038603";
}
function changeStatesNumber(value) {
@ -715,6 +715,10 @@ function changeStatesNumber(value) {
labels.select("#countries").attr("data-size", Math.max(rn(18 - value / 6), 4));
}
function changeBurgsNumberSlider(value) {
manorsOutput.value = value == 1000 ? "auto" : value;
}
function changeUIsize(value) {
uiSizeInput.value = uiSizeOutput.value = value;
document.getElementsByTagName("body")[0].style.fontSize = value * 11 + "px";
@ -785,7 +789,7 @@ function applyStoredOptions() {
function randomizeOptions() {
Math.seedrandom(seed); // reset seed to initial one
if (!locked("regions")) regionsInput.value = regionsOutput.value = rand(12, 17);
if (!locked("manors")) manorsInput.value = manorsOutput.value = rn(0.5 + Math.random(), 1);
if (!locked("manors")) {manorsInput.value = 1000; manorsOutput.value = "auto";}
if (!locked("power")) powerInput.value = powerOutput.value = rand(0, 4);
if (!locked("neutral")) neutralInput.value = neutralOutput.value = rn(0.8 + Math.random(), 1);
if (!locked("cultures")) culturesInput.value = culturesOutput.value = rand(10, 15);

View file

@ -433,4 +433,20 @@ function getAbsolutePath(href) {
var link = document.createElement("a");
link.href = href;
return link.href;
}
}
// from https://davidwalsh.name/javascript-debounce-function
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
}
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
}
};