mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
v1.3.14a
This commit is contained in:
parent
aae37eb702
commit
29117db1cf
8 changed files with 45 additions and 58 deletions
|
|
@ -1855,7 +1855,7 @@
|
||||||
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Military forces will be regenerated as well, burgs will remain as they are">States</button>
|
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Military forces will be regenerated as well, burgs will remain as they are">States</button>
|
||||||
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
||||||
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
||||||
<button id="regenerateMilitary" data-tip="Click to recalculate military forces and regenerate regiments based on current military options">Military</button>
|
<button id="regenerateMilitary" data-tip="Click to recalculate military forces based on current military options">Military</button>
|
||||||
<button id="regenerateMarkers" data-tip="Click to regenerate markers. Hold Ctrl and click to set markers number multiplier">Markers</button>
|
<button id="regenerateMarkers" data-tip="Click to regenerate markers. Hold Ctrl and click to set markers number multiplier">Markers</button>
|
||||||
<button id="regenerateZones" data-tip="Click to regenerate zones. Hold Ctrl and click to set zones number multiplier">Zones</button>
|
<button id="regenerateZones" data-tip="Click to regenerate zones. Hold Ctrl and click to set zones number multiplier">Zones</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
2
main.js
2
main.js
|
|
@ -1073,7 +1073,7 @@ function reMarkFeatures() {
|
||||||
if (type === "lake") group = defineLakeGroup(start, cellNumber, temp[cells.g[start]]);
|
if (type === "lake") group = defineLakeGroup(start, cellNumber, temp[cells.g[start]]);
|
||||||
else if (type === "ocean") group = defineOceanGroup(cellNumber);
|
else if (type === "ocean") group = defineOceanGroup(cellNumber);
|
||||||
else if (type === "island") group = defineIslandGroup(start, cellNumber);
|
else if (type === "island") group = defineIslandGroup(start, cellNumber);
|
||||||
features.push({i, land, border, type, cells: cellNumber, firstCell: start, group, ports:0});
|
features.push({i, land, border, type, cells: cellNumber, firstCell: start, group});
|
||||||
queue[0] = cells.f.findIndex(f => !f); // find unmarked cell
|
queue[0] = cells.f.findIndex(f => !f); // find unmarked cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,37 @@
|
||||||
const specifyBurgs = function() {
|
const specifyBurgs = function() {
|
||||||
console.time("specifyBurgs");
|
console.time("specifyBurgs");
|
||||||
const cells = pack.cells, vertices = pack.vertices, features = pack.features;
|
const cells = pack.cells, vertices = pack.vertices, features = pack.features;
|
||||||
checkAccessibility();
|
|
||||||
|
// separate arctic seas for correct searoutes generation
|
||||||
|
void function checkAccessibility() {
|
||||||
|
const oceanCells = cells.i.filter(i => cells.h[i] < 20 && features[cells.f[i]].type === "ocean");
|
||||||
|
const marked = [];
|
||||||
|
let firstCell = oceanCells.find(i => !marked[i]);
|
||||||
|
|
||||||
|
while (firstCell !== undefined) {
|
||||||
|
const queue = [firstCell];
|
||||||
|
const f = features[cells.f[firstCell]]; // old feature
|
||||||
|
const i = last(features).i+1; // new feature id to assign
|
||||||
|
const biome = cells.biome[firstCell];
|
||||||
|
marked[firstCell] = 1;
|
||||||
|
let cellNumber = 1;
|
||||||
|
|
||||||
|
while (queue.length) {
|
||||||
|
for (const c of cells.c[queue.pop()]) {
|
||||||
|
if (cells.biome[c] !== biome || cells.h[c] >= 20) continue;
|
||||||
|
if (marked[c]) continue;
|
||||||
|
queue.push(c);
|
||||||
|
cells.f[c] = i;
|
||||||
|
marked[c] = 1;
|
||||||
|
cellNumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const group = biome ? "frozen " + f.group : f.group;
|
||||||
|
features.push({i, parent:f.i, land:false, border:f.border, type:"ocean", cells: cellNumber, firstCell, group});
|
||||||
|
firstCell = oceanCells.find(i => !marked[i]);
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
for (const b of pack.burgs) {
|
for (const b of pack.burgs) {
|
||||||
if (!b.i) continue;
|
if (!b.i) continue;
|
||||||
|
|
@ -154,7 +184,6 @@
|
||||||
// port is a capital with any harbor OR town with good harbor
|
// port is a capital with any harbor OR town with good harbor
|
||||||
const port = features[f].cells > 1 && ((b.capital && cells.harbor[i]) || cells.harbor[i] === 1);
|
const port = features[f].cells > 1 && ((b.capital && cells.harbor[i]) || cells.harbor[i] === 1);
|
||||||
b.port = port ? f : 0; // port is defined by water body id it lays on
|
b.port = port ? f : 0; // port is defined by water body id it lays on
|
||||||
if (port) {features[f].ports += 1; features[b.feature].ports += 1;}
|
|
||||||
} else b.port = 0;
|
} else b.port = 0;
|
||||||
|
|
||||||
// define burg population (keep urbanization at about 10% rate)
|
// define burg population (keep urbanization at about 10% rate)
|
||||||
|
|
@ -180,43 +209,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// de-assign port status if it's the only one on feature
|
// de-assign port status if it's the only one on feature
|
||||||
|
const ports = pack.burgs.filter(b => !b.removed && b.port > 0);
|
||||||
for (const f of features) {
|
for (const f of features) {
|
||||||
if (!f.i || f.land || f.ports !== 1) continue;
|
if (!f.i || f.land || f.border) continue;
|
||||||
const port = pack.burgs.find(b => b.port === f.i);
|
const featurePorts = ports.filter(b => b.port === f.i);
|
||||||
port.port = 0;
|
if (featurePorts.length === 1) featurePorts[0].port = 0;
|
||||||
f.port = 0;
|
|
||||||
features[port.feature].ports -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// separate arctic seas for correct searoutes generation
|
|
||||||
function checkAccessibility() {
|
|
||||||
const oceanCells = cells.i.filter(i => cells.h[i] < 20 && features[cells.f[i]].type === "ocean");
|
|
||||||
const marked = [];
|
|
||||||
let firstCell = oceanCells.find(i => !marked[i]);
|
|
||||||
|
|
||||||
while (firstCell !== undefined) {
|
|
||||||
const queue = [firstCell];
|
|
||||||
const f = features[cells.f[firstCell]]; // old feature
|
|
||||||
const i = last(features).i+1; // new feature id to assign
|
|
||||||
const biome = cells.biome[firstCell];
|
|
||||||
marked[firstCell] = 1;
|
|
||||||
let cellNumber = 1;
|
|
||||||
|
|
||||||
while (queue.length) {
|
|
||||||
for (const c of cells.c[queue.pop()]) {
|
|
||||||
if (cells.biome[c] !== biome || cells.h[c] >= 20) continue;
|
|
||||||
if (marked[c]) continue;
|
|
||||||
queue.push(c);
|
|
||||||
cells.f[c] = i;
|
|
||||||
marked[c] = 1;
|
|
||||||
cellNumber++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const group = biome ? "frozen " + f.group : f.group;
|
|
||||||
features.push({i, parent:f.i, land:false, border:true, type:"ocean", cells: cellNumber, firstCell, group, ports:0});
|
|
||||||
firstCell = oceanCells.find(i => !marked[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.timeEnd("specifyBurgs");
|
console.timeEnd("specifyBurgs");
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
const expansionRate = Math.min(Math.max((s.expansionism / expn) / (s.area / area), .25), 4); // how much state expansionism is realized
|
const expansionRate = Math.min(Math.max((s.expansionism / expn) / (s.area / area), .25), 4); // how much state expansionism is realized
|
||||||
const diplomacyRate = d.some(d => d === "Enemy") ? 1 : d.some(d => d === "Rival") ? .8 : d.some(d => d === "Suspicion") ? .5 : .1; // peacefulness
|
const diplomacyRate = d.some(d => d === "Enemy") ? 1 : d.some(d => d === "Rival") ? .8 : d.some(d => d === "Suspicion") ? .5 : .1; // peacefulness
|
||||||
const neighborsRate = Math.min(Math.max(s.neighbors.map(n => n ? pack.states[n].diplomacy[s.i] : "Suspicion").reduce((s, r) => s += rate[r], .5), .3), 3); // neighbors rate
|
const neighborsRate = Math.min(Math.max(s.neighbors.map(n => n ? pack.states[n].diplomacy[s.i] : "Suspicion").reduce((s, r) => s += rate[r], .5), .3), 3); // neighbors rate
|
||||||
s.alert = rn(expansionRate * diplomacyRate * neighborsRate, 2); // war alert rate (army modifier)
|
s.alert = Math.min(Math.max(rn(expansionRate * diplomacyRate * neighborsRate, 2), .1), 5); // war alert rate (army modifier)
|
||||||
temp.platoons = [];
|
temp.platoons = [];
|
||||||
|
|
||||||
// apply overall state modifiers for unit types based on state features
|
// apply overall state modifiers for unit types based on state features
|
||||||
|
|
@ -43,9 +43,6 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const portsMod = d3.max(pack.features.map(f => f.land ? 0 : f.ports)) * .75;
|
|
||||||
const normalizeNaval = ports => normalize(ports, 0, portsMod);
|
|
||||||
|
|
||||||
for (const i of cells.i) {
|
for (const i of cells.i) {
|
||||||
if (!cells.pop[i]) continue;
|
if (!cells.pop[i]) continue;
|
||||||
const s = states[cells.state[i]]; // cell state
|
const s = states[cells.state[i]]; // cell state
|
||||||
|
|
@ -111,10 +108,7 @@
|
||||||
if (isNaN(perc) || perc <= 0) continue;
|
if (isNaN(perc) || perc <= 0) continue;
|
||||||
let army = m * perc; // basic army for rural cell
|
let army = m * perc; // basic army for rural cell
|
||||||
|
|
||||||
if (u.type === "naval") {
|
if (u.type === "naval" && !b.port) continue; // only ports produce naval units
|
||||||
if (!b.port || !pack.features[b.port] || b.port < 1) continue; // only ports have naval units
|
|
||||||
army *= normalizeNaval(pack.features[b.port].ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nomadic) { // "nomadic" biomes special rules
|
if (nomadic) { // "nomadic" biomes special rules
|
||||||
if (u.type === "melee") army /= 3; else
|
if (u.type === "melee") army /= 3; else
|
||||||
|
|
|
||||||
|
|
@ -933,12 +933,6 @@ function parseLoadedData(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 1.3) {
|
if (version < 1.3) {
|
||||||
// v 1.3 added ports attribute to pack.features
|
|
||||||
for (const f of pack.features) {
|
|
||||||
if (!f.i) continue;
|
|
||||||
f.ports = pack.burgs.filter(b => !b.removed && b.port === f.i).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// v 1.3 added global options object
|
// v 1.3 added global options object
|
||||||
const winds = options.slice(); // previostly wnd was saved in settings[19]
|
const winds = options.slice(); // previostly wnd was saved in settings[19]
|
||||||
const year = rand(100, 2000);
|
const year = rand(100, 2000);
|
||||||
|
|
|
||||||
|
|
@ -172,9 +172,10 @@ function removeBurg(id) {
|
||||||
if (label) label.remove();
|
if (label) label.remove();
|
||||||
if (icon) icon.remove();
|
if (icon) icon.remove();
|
||||||
if (anchor) anchor.remove();
|
if (anchor) anchor.remove();
|
||||||
pack.burgs[id].removed = true;
|
|
||||||
const cell = pack.burgs[id].cell;
|
const cells = pack.cells, burg = pack.burgs[id];
|
||||||
pack.cells.burg[cell] = 0;
|
burg.removed = true;
|
||||||
|
cells.burg[burg.cell] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleCapital(burg) {
|
function toggleCapital(burg) {
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ function overviewMilitary() {
|
||||||
const population = rn((s.rural + s.urban * urbanization.value) * populationRate.value);
|
const population = rn((s.rural + s.urban * urbanization.value) * populationRate.value);
|
||||||
const total = line.dataset.total = options.military.reduce((s, u) => s + getForces(u) * u.crew, 0);
|
const total = line.dataset.total = options.military.reduce((s, u) => s + getForces(u) * u.crew, 0);
|
||||||
const rate = line.dataset.rate = total / population * 100;
|
const rate = line.dataset.rate = total / population * 100;
|
||||||
line.querySelector("div[data-type='total']>b").innerHTML = si(total);
|
line.querySelector("div[data-type='total']").innerHTML = si(total);
|
||||||
line.querySelector("div[data-type='rate']").innerHTML = rn(rate, 2) + "%";
|
line.querySelector("div[data-type='rate']").innerHTML = rn(rate, 2) + "%";
|
||||||
|
|
||||||
updateFooter();
|
updateFooter();
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ function regenerateBurgs() {
|
||||||
moveBurgToGroup(burg, "cities");
|
moveBurgToGroup(burg, "cities");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pack.features.forEach(f => {if (f.port) f.port = 0}); // reset features ports counter
|
||||||
BurgsAndStates.specifyBurgs();
|
BurgsAndStates.specifyBurgs();
|
||||||
BurgsAndStates.defineBurgFeatures();
|
BurgsAndStates.defineBurgFeatures();
|
||||||
BurgsAndStates.drawBurgs();
|
BurgsAndStates.drawBurgs();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue