mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
1.0.41
This commit is contained in:
parent
7a9c431bb1
commit
5eb24252e1
7 changed files with 171 additions and 61 deletions
22
index.html
22
index.html
|
|
@ -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>
|
||||
|
|
|
|||
39
main.js
39
main.js
|
|
@ -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;
|
||||
const state = states.find(s => s.i && s.neighbors.size > 0 && s.neighbors.values().next().value);
|
||||
if (!state) return;
|
||||
function addZones() {
|
||||
console.time("addZones");
|
||||
const data = [], cells = pack.cells, states = pack.states;
|
||||
|
||||
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));
|
||||
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 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 name = getAdjective(states[neib].name) + " " + rebels;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue