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>
<td>Cultures number</td> <td>Cultures number</td>
<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>
<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> </td>
</tr> </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"> <tr data-tip="Define how many states and capitals should be generated">
<td> <td>
<i data-locked=0 id="lock_regions" class="icon-lock-open"></i> <i data-locked=0 id="lock_regions" class="icon-lock-open"></i>

39
main.js
View file

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

View file

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

View file

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

View file

@ -487,6 +487,8 @@ function editMarker() {
buttons: { buttons: {
Remove: function() { Remove: function() {
$(this).dialog("close"); $(this).dialog("close");
const index = notes.findIndex(n => n.id === elSelected.attr("id"));
if (index != -1) notes.splice(index, 1);
elSelected.remove(); elSelected.remove();
$("#markerEditor").dialog("close"); $("#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 === "densityInput" || id === "densityOutput") changeCellsDensity(+value);
else if (id === "culturesInput") culturesOutput.value = value; else if (id === "culturesInput") culturesOutput.value = value;
else if (id === "culturesOutput") culturesInput.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 === "regionsInput" || id === "regionsOutput") changeStatesNumber(value);
else if (id === "provincesInput") provincesOutput.value = value; else if (id === "provincesInput") provincesOutput.value = value;
else if (id === "provincesOutput") provincesOutput.value = value; else if (id === "provincesOutput") provincesOutput.value = value;
@ -795,6 +796,12 @@ function changeCellsDensity(value) {
else densityOutput.style.color = "#038603"; 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) { function changeStatesNumber(value) {
regionsInput.value = regionsOutput.value = value; regionsInput.value = regionsOutput.value = value;
burgLabels.select("#capitals").attr("data-size", Math.max(rn(6 - value / 20), 3)); 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("power")) powerInput.value = powerOutput.value = gauss(3, 2, 0, 10);
if (!locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1); if (!locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1);
if (!locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30); if (!locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30);
changeCultureSet();
// 'Configure World' settings // 'Configure World' settings
if (!locked("prec")) precInput.value = precOutput.value = gauss(100, 20, 5, 500); if (!locked("prec")) precInput.value = precOutput.value = gauss(100, 20, 5, 500);

View file

@ -202,7 +202,12 @@ function regenerateReligions() {
} }
function regenerateMarkers() { 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)); addMarkers(gauss(1, .5, .3, 5, 2));
} }