This commit is contained in:
Azgaar 2019-09-18 21:30:48 +03:00
parent 7a9c431bb1
commit 5eb24252e1
7 changed files with 171 additions and 61 deletions

View file

@ -1553,13 +1553,31 @@
</td>
<td>Cultures number</td>
<td>
<input id="culturesInput" data-stored="cultures" type="range" min=1 max=30 value=14>
<input id="culturesInput" data-stored="cultures" type="range" min=1 max=32 value=14>
</td>
<td>
<input id="culturesOutput" data-stored="cultures" type="number" min=1 max=30 value=14>
<input id="culturesOutput" data-stored="cultures" type="number" min=1 max=32 value=14>
</td>
</tr>
<tr data-tip="Select a set of cultures to be used for names and cultures generation">
<td>
<i data-locked=0 id="lock_culturesSet" class="icon-lock-open"></i>
</td>
<td>Cultures set</td>
<td>
<select id="culturesSet" data-stored="culturesSet">
<option value="world" data-max="32" selected>All-world</option>
<option value="european" data-max="15">European</option>
<option value="oriental" data-max="13">Oriental</option>
<option value="english" data-max="10">English</option>
<!-- <option value="high" data-max="16">High Fantasy</option> -->
<!-- <option value="dark" data-max="16">Dark Fantasy</option> -->
</select>
</td>
<td></td>
</tr>
<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>

31
main.js
View file

@ -603,7 +603,7 @@ function generate() {
drawStates();
drawBorders();
BurgsAndStates.drawStateLabels();
addZone();
addZones();
addMarkers();
Names.getMapName();
@ -1176,19 +1176,36 @@ function rankCells() {
}
// add a zone as an example: rebels along one border
function addZone() {
const cells = pack.cells, states = pack.states;
function addZones() {
console.time("addZones");
const data = [], cells = pack.cells, states = pack.states;
void function addRebels() {
const state = states.find(s => s.i && s.neighbors.size > 0 && s.neighbors.values().next().value);
if (!state) return;
const neib = state.neighbors.values().next().value;
const data = cells.i.filter(i => cells.state[i] === state.i && cells.c[i].some(c => cells.state[c] === neib));
const cellsArray = cells.i.filter(i => cells.state[i] === state.i && cells.c[i].some(c => cells.state[c] === neib));
const rebels = rw({Rebels:5, Insurgents:2, Recusants:1, Mutineers:1, Rioters:1, Dissenters:1, Secessionists:1, Insurrection:2, Rebellion:1, Conspiracy:2});
const rebels = rw({"Rebels":5, "Insurgents":2, "Recusants":1,
"Mutineers":1, "Rioters":1, "Dissenters":1, "Secessionists":1,
"Insurrection":2, "Rebellion":1, "Conspiracy":2});
const name = getAdjective(states[neib].name) + " " + rebels;
data.push({name, cells:cellsArray, fill:"url(#hatch3)"});
}()
const zone = zones.append("g").attr("id", "zone0").attr("data-description", name).attr("data-cells", data).attr("fill", "url(#hatch3)");
zone.selectAll("polygon").data(data).enter().append("polygon").attr("points", d => getPackPolygon(d)).attr("id", d => "zone0_"+d);
// void function addDisease() {
// }()
void function drawZones() {
zones.selectAll("g").data(data).enter().append("g")
.attr("id", (d, i) => "zone"+i).attr("data-description", d => d.name).attr("data-cells", d => d.cells.join(",")).attr("fill", d => d.fill)
.selectAll("polygon").data(d => d.cells).enter().append("polygon")
.attr("points", d => getPackPolygon(d)).attr("id", function(d) {return this.parentNode.id+"_"+d});
}()
console.timeEnd("addZones");
}
// add some markers as an example

View file

@ -64,11 +64,14 @@
}
function getRandomCultures(c) {
const d = getDefault();
const d = getDefault(), n = d.length-1;
const count = Math.min(c, d.length);
const cultures = [];
while (cultures.length < c) {
let culture = d[0];
do {culture = d[rand(d.length-1)];} while (Math.random() > culture.odd || cultures.find(c => c.name === culture.name))
while (cultures.length < count) {
let culture = d[rand(n)];
do {
culture = d[rand(n)];
} while (Math.random() > culture.odd || cultures.find(c => c.name === culture.name))
cultures.push(culture);
}
return cultures;
@ -113,6 +116,61 @@
}
const getDefault = function() {
if (culturesSet.value === "european") {
return [
{name:"Shwazen", base:0, odd: 1},
{name:"Angshire", base:1, odd: 1},
{name:"Luari", base:2, odd: 1},
{name:"Tallian", base:3, odd: 1},
{name:"Astellian", base:4, odd: 1},
{name:"Slovan", base:5, odd: 1},
{name:"Norse", base:6, odd: 1},
{name:"Elladan", base:7, odd: 1},
{name:"Romian", base:8, odd: .2},
{name:"Soumi", base:9, odd: 1},
{name:"Portuzian", base:13, odd: 1},
{name:"Vengrian", base: 15, odd: 1},
{name:"Turchian", base: 16, odd: .05},
{name:"Euskati", base: 20, odd: .05},
{name:"Keltan", base: 22, odd: .05}
];
}
if (culturesSet.value === "oriental") {
return [
{name:"Koryo", base:10, odd: 1},
{name:"Hantzu", base:11, odd: 1},
{name:"Yamoto", base:12, odd: 1},
{name:"Turchian", base: 16, odd: 1},
{name:"Berberan", base: 17, odd: .2},
{name:"Eurabic", base: 18, odd: 1},
{name:"Efratic", base: 23, odd: .1},
{name:"Tehrani", base: 24, odd: 1},
{name:"Maui", base: 25, odd: .2},
{name:"Carnatic", base: 26, odd: .5},
{name:"Vietic", base: 29, odd: .8},
{name:"Guantzu", base:30, odd: .5},
{name:"Ulus", base:31, odd: 1}
];
}
if (culturesSet.value === "english") {
const getName = () => Names.getBase(1, 5, 9, "", 0);
return [
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1},
{name:getName(), base:1, odd: 1}
];
}
// all-world
return [
{name:"Shwazen", base:0, odd: .7},
{name:"Angshire", base:1, odd: 1},
@ -123,28 +181,28 @@
{name:"Norse", base:6, odd: .7},
{name:"Elladan", base:7, odd: .7},
{name:"Romian", base:8, odd: .7},
{name:"Soumi", base:9, odd: .4},
{name:"Koryo", base:10, odd: .5},
{name:"Hantzu", base:11, odd: .5},
{name:"Yamoto", base:12, odd: .5},
{name:"Soumi", base:9, odd: .3},
{name:"Koryo", base:10, odd: .1},
{name:"Hantzu", base:11, odd: .1},
{name:"Yamoto", base:12, odd: .1},
{name:"Portuzian", base:13, odd: .4},
{name:"Nawatli", base:14, odd: .2},
{name:"Nawatli", base:14, odd: .1},
{name:"Vengrian", base: 15, odd: .2},
{name:"Turchian", base: 16, odd: .2},
{name:"Berberan", base: 17, odd: .2},
{name:"Berberan", base: 17, odd: .1},
{name:"Eurabic", base: 18, odd: .2},
{name:"Inuk", base: 19, odd: .1},
{name:"Euskati", base: 20, odd: .1},
{name:"Inuk", base: 19, odd: .05},
{name:"Euskati", base: 20, odd: .05},
{name:"Negarian", base: 21, odd: .05},
{name:"Keltan", base: 22, odd: .1},
{name:"Efratic", base: 23, odd: .1},
{name:"Keltan", base: 22, odd: .05},
{name:"Efratic", base: 23, odd: .05},
{name:"Tehrani", base: 24, odd: .1},
{name:"Maui", base: 25, odd: .05},
{name:"Carnatic", base: 26, odd: .1},
{name:"Inqan", base: 27, odd: .1},
{name:"Carnatic", base: 26, odd: .05},
{name:"Inqan", base: 27, odd: .05},
{name:"Kiswaili", base: 28, odd: .1},
{name:"Vietic", base: 29, odd: .1},
{name:"Guantzu", base:30, odd: 1},
{name:"Guantzu", base:30, odd: .1},
{name:"Ulus", base:31, odd: .1}
];
}

View file

@ -126,8 +126,9 @@
// exclude endings inappropriate for states name
if (name.includes(" ")) name = capitalize(name.replace(/ /g, "").toLowerCase()); // don't allow multiword state names
if (name.length > 6 && name.slice(-4) === "berg") name = name.slice(0,-4); // remove -berg for any
if (name.length > 5 && name.slice(-3) === "ton") name = name.slice(0,-3); // remove -ton for any
if (base === 5 && ["sk", "ev", "ov"].includes(name.slice(-2))) name = name.slice(0,-2); // remove -sk/-ev/-ov for Ruthenian
else if (base === 1 && name.length > 5 && name.slice(-3) === "ton") name = name.slice(0,-3); // remove -ton for English
else if (base === 12) return vowel(name.slice(-1)) ? name : name + "u"; // Japanese ends on any vowel or -u
else if (base === 18 && Math.random() < .4) name = vowel(name.slice(0,1).toLowerCase()) ? "Al" + name.toLowerCase() : "Al " + name; // Arabic starts with -Al
@ -139,25 +140,26 @@
} else if (Math.random() < .4) return name; // 60% for cc and vc
// define suffix
let suffix = "";
let suffix = "ia"; // standard suffix
const rnd = Math.random(), l = name.length;
if (base === 3) suffix = rnd < .03 && l < 7 ? "terra" : "ia"; // Italian
else if (base === 4) suffix = rnd < .03 && l < 7 ? "terra" : "ia"; // Spanish
else if (base === 13) suffix = rnd < .03 && l < 7 ? "terra" : "ia"; // Portuguese
else if (base === 2) suffix = rnd < .03 && l < 7 ? "terre" : "ia"; // French
else if (base === 0) suffix = rnd < .5 && l < 7 ? "land" : "ia"; // German
else if (base === 1) suffix = rnd < .4 && l < 7 ? "land" : "ia"; // English
else if (base === 6) suffix = rnd < .3 && l < 7 ? "land" : "ia"; // Nordic
else if (base === 7) suffix = rnd < .1 ? "eia" : "ia"; // Greek
else if (base === 9) suffix = rnd < .35 ? "maa" : "ia"; // Finnic
else if (base === 15) suffix = rnd < .6 && l < 6 ? "orszag" : "ia"; // Hungarian
if (base === 3 && rnd < .03 && l < 7) suffix = "terra"; // Italian
else if (base === 4 && rnd < .03 && l < 7) suffix = "terra"; // Spanish
else if (base === 13 && rnd < .03 && l < 7) suffix = "terra"; // Portuguese
else if (base === 2 && rnd < .03 && l < 7) suffix = "terre"; // French
else if (base === 0 && rnd < .5 && l < 7) suffix = "land"; // German
else if (base === 1 && rnd < .4 && l < 7 ) suffix = "land"; // English
else if (base === 6 && rnd < .3 && l < 7) suffix = "land"; // Nordic
else if (base === 7 && rnd < .1) suffix = "eia"; // Greek
else if (base === 9 && rnd < .35) suffix = "maa"; // Finnic
else if (base === 15 && rnd < .6 && l < 6) suffix = "orszag"; // Hungarian
else if (base === 16) suffix = rnd < .5 ? "stan" : "ya"; // Turkish
else if (base === 10) suffix = "guk"; // Korean
else if (base === 11) suffix = " Guo"; // Chinese
else if (base === 14) suffix = rnd < .6 && l < 7 ? "tlan" : "co"; // Nahuatl
else if (base === 17) suffix = rnd < .8 ? "a" : "ia"; // Berber
else if (base === 18) suffix = rnd < .8 ? "a" : "ia"; // Arabic
else suffix = "ia" // other
else if (base === 14) suffix = rnd < .6 && l < 6 ? "tlan" : "co"; // Nahuatl
else if (base === 17 && rnd < .8) suffix = "a"; // Berber
else if (base === 18 && rnd < .8) suffix = "a"; // Arabic
return validateSuffix(name, suffix);
}
@ -194,30 +196,30 @@
// name, min length, max length, letters to allow duplication, multi-word name rate
return [
{name: "German", min: 5, max: 12, d: "lt", m: 0},
{name: "English", min: 6, max: 11, d: "", m: 0.1},
{name: "French", min: 5, max: 13, d: "nlrs", m: 0.1},
{name: "Italian", min: 5, max: 12, d: "cltr", m: 0.1},
{name: "English", min: 6, max: 11, d: "", m: .1},
{name: "French", min: 5, max: 13, d: "nlrs", m: .1},
{name: "Italian", min: 5, max: 12, d: "cltr", m: .1},
{name: "Castillian", min: 5, max: 11, d: "lr", m: 0},
{name: "Ruthenian", min: 5, max: 10, d: "", m: 0},
{name: "Nordic", min: 6, max: 10, d: "kln", m: 0.1},
{name: "Greek", min: 5, max: 11, d: "s", m: 0.1},
{name: "Roman", min: 6, max: 11, d: "ln", m: 0.1},
{name: "Nordic", min: 6, max: 10, d: "kln", m: .1},
{name: "Greek", min: 5, max: 11, d: "s", m: .1},
{name: "Roman", min: 6, max: 11, d: "ln", m: .1},
{name: "Finnic", min: 5, max: 11, d: "akiut", m: 0},
{name: "Korean", min: 5, max: 11, d: "", m: 0},
{name: "Chinese", min: 5, max: 10, d: "", m: 0},
{name: "Japanese", min: 4, max: 10, d: "", m: 0},
{name: "Portuguese", min: 5, max: 11, d: "", m: 0.1},
{name: "Portuguese", min: 5, max: 11, d: "", m: .1},
{name: "Nahuatl", min: 6, max: 13, d: "l", m: 0},
{name: "Hungarian", min: 6, max: 13, d: "", m: 0.1},
{name: "Hungarian", min: 6, max: 13, d: "", m: .1},
{name: "Turkish", min: 4, max: 10, d: "", m: 0},
{name: "Berber", min: 4, max: 10, d: "s", m: 0.2},
{name: "Arabic", min: 4, max: 9, d: "ae", m: 0.2},
{name: "Berber", min: 4, max: 10, d: "s", m: .2},
{name: "Arabic", min: 4, max: 9, d: "ae", m: .2},
{name: "Inuit", min: 5, max: 15, d: "alutsn", m: 0},
{name: "Basque", min: 4, max: 11, d: "r", m: 0.1},
{name: "Nigerian", min: 4, max: 10, d: "", m: 0.3},
{name: "Basque", min: 4, max: 11, d: "r", m: .1},
{name: "Nigerian", min: 4, max: 10, d: "", m: .3},
{name: "Celtic", min: 4, max: 12, d: "nld", m: 0},
{name: "Mesopotamian", min: 4, max: 9, d: "srpl", m: 0.1},
{name: "Iranian", min: 5, max: 11, d: "", m: 0.1},
{name: "Mesopotamian", min: 4, max: 9, d: "srpl", m: .1},
{name: "Iranian", min: 5, max: 11, d: "", m: .1},
{name: "Hawaiian", min: 5, max: 10, d: "auo", m: 1},
{name: "Karnataka", min: 5, max: 11, d: "tnl", m: 0},
{name: "Quechua", min: 6, max: 12, d: "l", m: 0},

View file

@ -487,6 +487,8 @@ function editMarker() {
buttons: {
Remove: function() {
$(this).dialog("close");
const index = notes.findIndex(n => n.id === elSelected.attr("id"));
if (index != -1) notes.splice(index, 1);
elSelected.remove();
$("#markerEditor").dialog("close");
},

View file

@ -670,6 +670,7 @@ optionsContent.addEventListener("input", function(event) {
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 === "culturesSet") changeCultureSet();
else if (id === "regionsInput" || id === "regionsOutput") changeStatesNumber(value);
else if (id === "provincesInput") provincesOutput.value = value;
else if (id === "provincesOutput") provincesOutput.value = value;
@ -795,6 +796,12 @@ function changeCellsDensity(value) {
else densityOutput.style.color = "#038603";
}
function changeCultureSet() {
const max = culturesSet.selectedOptions[0].dataset.max;
culturesInput.max = culturesOutput.max = max
if (+culturesOutput.value > +max) culturesInput.value = culturesOutput.value = max;
}
function changeStatesNumber(value) {
regionsInput.value = regionsOutput.value = value;
burgLabels.select("#capitals").attr("data-size", Math.max(rn(6 - value / 20), 3));
@ -880,6 +887,7 @@ function randomizeOptions() {
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);
changeCultureSet();
// 'Configure World' settings
if (!locked("prec")) precInput.value = precOutput.value = gauss(100, 20, 5, 500);

View file

@ -202,7 +202,12 @@ function regenerateReligions() {
}
function regenerateMarkers() {
markers.selectAll("use").remove();
// remove existing markers and assigned notes
markers.selectAll("use").each(function() {
const index = notes.findIndex(n => n.id === this.id);
if (index != -1) notes.splice(index, 1);
}).remove();
addMarkers(gauss(1, .5, .3, 5, 2));
}