This commit is contained in:
Azgaar 2019-12-29 19:24:10 +03:00
parent 904951d6c0
commit 8a6108e203
5 changed files with 186 additions and 180 deletions

View file

@ -10,9 +10,9 @@
console.time('generateCultures');
cells = pack.cells;
cells.culture = new Uint16Array(cells.i.length); // cell cultures
let count = +culturesInput.value;
let count = Math.min(+culturesInput.value, +culturesSet.selectedOptions[0].dataset.max);
const populated = cells.i.filter(i => cells.s[i]).sort((a, b) => cells.s[b] - cells.s[a]); // cells sorted by population
const populated = cells.i.filter(i => cells.s[i]); // populated cells
if (populated.length < count * 25) {
count = Math.floor(populated.length / 50);
if (!count) {
@ -42,19 +42,28 @@
const centers = d3.quadtree();
const colors = getColors(count);
cultures.forEach(function(culture, i) {
const c = culture.center = placeCultureCenter();
centers.add(cells.p[c]);
culture.i = i+1;
delete culture.odd;
culture.color = colors[i];
culture.type = defineCultureType(c);
culture.expansionism = defineCultureExpansionism(culture.type);
culture.origin = 0;
culture.code = getCode(culture.name);
cells.culture[c] = i+1;
cultures.forEach(function(c, i) {
const cell = c.center = placeCenter(c.sort ? c.sort : (i) => cells.s[i]);
centers.add(cells.p[cell]);
c.i = i+1;
delete c.odd;
delete c.sort;
c.color = colors[i];
c.type = defineCultureType(cell);
c.expansionism = defineCultureExpansionism(c.type);
c.origin = 0;
c.code = getCode(c.name);
cells.culture[cell] = i+1;
});
function placeCenter(v) {
let c, spacing = (graphWidth + graphHeight) / 2 / count;
const sorted = [...populated].sort((a, b) => v(b) - v(a)), max = Math.floor(sorted.length / 2);
do {c = sorted[biased(0, max, 5)]; spacing *= .9;}
while (centers.find(cells.p[c][0], cells.p[c][1], spacing) !== undefined);
return c;
}
// the first culture with id 0 is for wildlands
cultures.unshift({name:"Wildlands", i:0, base:1, origin:null});
@ -76,27 +85,15 @@
return cultures;
}
// culture center tends to be placed in a density populated cell
function placeCultureCenter() {
let center, spacing = (graphWidth + graphHeight) / count;
do {
center = populated[biased(0, populated.length-1, 3)];
spacing = spacing * .8;
}
while (centers.find(cells.p[center][0], cells.p[center][1], spacing) !== undefined);
return center;
}
// set culture type based on culture center position
function defineCultureType(i) {
if (cells.h[i] < 70 && [1,2,4].includes(cells.biome[i])) return "Nomadic"; // high penalty in forest biomes and near coastline
if (cells.h[i] > 50) return "Highland"; // no penalty for hills and moutains, high for other elevations
const f = pack.features[cells.f[cells.haven[i]]]; // feature
if (f.type === "lake" && f.cells > 5) return "Lake" // low water cross penalty and high for non-along-coastline growth
if ((f.cells < 10 && cells.harbor[i]) || (cells.harbor[i] === 1 && P(.5))) return "Naval"; // low water cross penalty and high for non-along-coastline growth
const f = pack.features[cells.f[cells.haven[i]]]; // opposite feature
if (f.type === "lake" && f.cells > 5) return "Lake" // low water cross penalty and high for growth not along coastline
if (cells.harbor[i] && f.type !== "lake" && P(.1) || (cells.harbor[i] === 1 && P(.6)) || (pack.features[cells.f[i]].group === "isle" && P(.4))) return "Naval"; // low water cross penalty and high for non-along-coastline growth
if (cells.r[i] && cells.fl[i] > 100) return "River"; // no River cross penalty, penalty for non-River growth
const b = cells.biome[i];
if (b === 4 || b === 1 || b === 2) return "Nomadic"; // high penalty in forest biomes and near coastline
if (b === 3 || b === 9 || b === 10) return "Hunting"; // high penalty in non-native biomes
if (cells.t[i] > 2 && [3,7,8,9,10,12].includes(cells.biome[i])) return "Hunting"; // high penalty in non-native biomes
return "Generic";
}
@ -145,41 +142,49 @@
}
const getDefault = function(count) {
// generic sorting functions
const cells = pack.cells, s = cells.s, sMax = d3.max(s), t = cells.t, h = cells.h, temp = grid.cells.temp;
const n = cell => Math.ceil(s[cell] / sMax * 3) // normalized cell score
const td = (cell, goal) => {const d = Math.abs(temp[cells.g[cell]] - goal); return d ? d+1 : 1;} // temperature difference fee
const bd = (cell, biomes, fee = 4) => biomes.includes(cells.biome[cell]) ? 1 : fee; // biome difference fee
const sf = (cell, fee = 4) => cells.haven[cell] && pack.features[cells.f[cells.haven[cell]]].type !== "lake" ? 1 : fee; // not on sea coast fee
// https://en.wikipedia.org/wiki/List_of_cities_by_average_temperature
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}
{name:"Shwazen", base:0, odd: 1, sort: i => n(i) / td(i, 10) / bd(i, [6, 8])},
{name:"Angshire", base:1, odd: 1, sort: i => n(i) / td(i, 10) / sf(i)},
{name:"Luari", base:2, odd: 1, sort: i => n(i) / td(i, 12) / bd(i, [6, 8])},
{name:"Tallian", base:3, odd: 1, sort: i => n(i) / td(i, 15)},
{name:"Astellian", base:4, odd: 1, sort: i => n(i) / td(i, 16)},
{name:"Slovan", base:5, odd: 1, sort: i => n(i) / td(i, 6) * t[i]},
{name:"Norse", base:6, odd: 1, sort: i => n(i) / td(i, 5)},
{name:"Elladan", base:7, odd: 1, sort: i => n(i) / td(i, 18) * h[i]},
{name:"Romian", base:8, odd: .2, sort: i => n(i) / td(i, 15) / t[i]},
{name:"Soumi", base:9, odd: 1, sort: i => n(i) / td(i, 5) / bd(i, [9]) * t[i]},
{name:"Portuzian", base:13, odd: 1, sort: i => n(i) / td(i, 17) / sf(i)},
{name:"Vengrian", base: 15, odd: 1, sort: i => n(i) / td(i, 11) / bd(i, [4]) * t[i]},
{name:"Turchian", base: 16, odd: .05, sort: i => n(i) / td(i, 14)},
{name:"Euskati", base: 20, odd: .05, sort: i => n(i) / td(i, 15) * h[i]},
{name:"Keltan", base: 22, odd: .05, sort: i => n(i) / td(i, 11) / bd(i, [6, 8]) * t[i]}
];
}
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}
{name:"Koryo", base:10, odd: 1, sort: i => n(i) / td(i, 12) / t[i]},
{name:"Hantzu", base:11, odd: 1, sort: i => n(i) / td(i, 13)},
{name:"Yamoto", base:12, odd: 1, sort: i => n(i) / td(i, 15) / t[i]},
{name:"Turchian", base: 16, odd: 1, sort: i => n(i) / td(i, 12)},
{name:"Berberan", base: 17, odd: .2, sort: i => n(i) / td(i, 19) / bd(i, [1, 2, 3], 7) * t[i]},
{name:"Eurabic", base: 18, odd: 1, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i]},
{name:"Efratic", base: 23, odd: .1, sort: i => n(i) / td(i, 22) * t[i]},
{name:"Tehrani", base: 24, odd: 1, sort: i => n(i) / td(i, 18) * h[i]},
{name:"Maui", base: 25, odd: .2, sort: i => n(i) / td(i, 24) / sf(i) / t[i]},
{name:"Carnatic", base: 26, odd: .5, sort: i => n(i) / td(i, 26)},
{name:"Vietic", base: 29, odd: .8, sort: i => n(i) / td(i, 25) / bd(i, [7], 7) / t[i]},
{name:"Guantzu", base:30, odd: .5, sort: i => n(i) / td(i, 17)},
{name:"Ulus", base:31, odd: 1, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i]}
];
}
@ -201,106 +206,106 @@
if (culturesSet.value === "antique") {
return [
{name:"Roman", base:8, odd: 1},
{name:"Roman", base:8, odd: 1},
{name:"Roman", base:8, odd: 1},
{name:"Roman", base:8, odd: 1},
{name:"Hellenic", base:7, odd: 1}, // Greek
{name:"Hellenic", base:7, odd: 1}, // Greek
{name:"Macedonian", base:7, odd: .5}, // Greek
{name:"Celtic", base:22, odd: 1},
{name:"Germanic", base:0, odd: 1},
{name:"Persian", base:24, odd: .8}, // Iranian
{name:"Scythian", base:24, odd: .5}, // Iranian
{name:"Cantabrian", base: 20, odd: .5}, // Basque
{name:"Estian", base: 9, odd: .2}, // Finnic
{name:"Carthaginian", base: 17, odd: .3}, // Berber (the closest we have)
{name:"Mesopotamian", base: 23, odd: .2} // Mesopotamian
{name:"Roman", base:8, odd: 1, sort: i => n(i) / td(i, 14) / t[i]}, // Roman
{name:"Roman", base:8, odd: 1, sort: i => n(i) / td(i, 15) / sf(i)}, // Roman
{name:"Roman", base:8, odd: 1, sort: i => n(i) / td(i, 16) / sf(i)}, // Roman
{name:"Roman", base:8, odd: 1, sort: i => n(i) / td(i, 17) / t[i]}, // Roman
{name:"Hellenic", base:7, odd: 1, sort: i => n(i) / td(i, 18) / sf(i) * h[i]}, // Greek
{name:"Hellenic", base:7, odd: 1, sort: i => n(i) / td(i, 19) / sf(i) * h[i]}, // Greek
{name:"Macedonian", base:7, odd: .5, sort: i => n(i) / td(i, 12) * h[i]}, // Greek
{name:"Celtic", base:22, odd: 1, sort: i => n(i) / td(i, 11) ** .5 / bd(i, [6, 8])},
{name:"Germanic", base:0, odd: 1, sort: i => n(i) / td(i, 10) ** .5 / bd(i, [6, 8])},
{name:"Persian", base:24, odd: .8, sort: i => n(i) / td(i, 18) * h[i]}, // Iranian
{name:"Scythian", base:24, odd: .5, sort: i => n(i) / td(i, 11) ** .5 / bd(i, [4])}, // Iranian
{name:"Cantabrian", base: 20, odd: .5, sort: i => n(i) / td(i, 16) * h[i]}, // Basque
{name:"Estian", base: 9, odd: .2, sort: i => n(i) / td(i, 5) * t[i]}, // Finnic
{name:"Carthaginian", base: 17, odd: .3, sort: i => n(i) / td(i, 19) / sf(i)}, // Berber
{name:"Mesopotamian", base: 23, odd: .2, sort: i => n(i) / td(i, 22) / bd(i, [1, 2, 3])} // Mesopotamian
];
}
if (culturesSet.value === "highFantasy") {
return [
// fantasy races
{name:"Quenian", base: 33, odd: 1}, // Elves
{name:"Eldar", base: 33, odd: 1}, // Elves
{name:"Lorian", base: 33, odd: .5}, // Elves
{name:"Trow", base: 34, odd: .9}, // Dark Elves
{name:"Dokalfar", base: 34, odd: .3}, // Dark Elves
{name:"Durinn", base: 35, odd: 1}, // Dwarven
{name:"Khazadur", base: 35, odd: 1}, // Dwarven
{name:"Kobblin", base: 36, odd: 1}, // Goblin
{name:"Uruk", base: 37, odd: 1}, // Orc
{name:"Ugluk", base: 37, odd: .7}, // Orc
{name:"Yotunn", base: 38, odd: .9}, // Giant
{name:"Drake", base: 39, odd: .7}, // Draconic
{name:"Rakhnid", base: 40, odd: .9}, // Arachnid
{name:"Aj'Snaga", base: 41, odd: .9}, // Serpents
{name:"Quenian", base: 33, odd: 1, sort: i => n(i) / bd(i, [6,7,8,9], 10) * t[i]}, // Elves
{name:"Eldar", base: 33, odd: 1, sort: i => n(i) / bd(i, [6,7,8,9], 10) * t[i]}, // Elves
{name:"Lorian", base: 33, odd: .5, sort: i => n(i) / bd(i, [6,7,8,9], 10)}, // Elves
{name:"Trow", base: 34, odd: .9, sort: i => n(i) / bd(i, [7,8,9,12], 10) * t[i]}, // Dark Elves
{name:"Dokalfar", base: 34, odd: .3, sort: i => n(i) / bd(i, [7,8,9,12], 10) * t[i]}, // Dark Elves
{name:"Durinn", base: 35, odd: 1, sort: i => n(i) + h[i]}, // Dwarven
{name:"Khazadur", base: 35, odd: 1, sort: i => n(i) + h[i]}, // Dwarven
{name:"Kobblin", base: 36, odd: 1, sort: i => t[i] - s[i]}, // Goblin
{name:"Uruk", base: 37, odd: 1, sort: i => h[i] * t[i]}, // Orc
{name:"Ugluk", base: 37, odd: .7, sort: i => h[i] * t[i] / bd(i, [1,2,10,11])}, // Orc
{name:"Yotunn", base: 38, odd: .9, sort: i => td(i, -10)}, // Giant
{name:"Drake", base: 39, odd: .7, sort: i => -s[i]}, // Draconic
{name:"Rakhnid", base: 40, odd: .9, sort: i => t[i] - s[i]}, // Arachnid
{name:"Aj'Snaga", base: 41, odd: .9, sort: i => n(i) / bd(i, [12], 10)}, // Serpents
// common fantasy human
{name:"Gozdor", base:32, odd: 1},
{name:"Anor", base:32, odd: 1},
{name:"Dail", base:32, odd: 1},
{name:"Duland", base:32, odd: 1},
{name:"Rohand", base:32, odd: 1},
{name:"Gozdor", base:32, odd: 1, sort: i => n(i) / td(i, 18)},
{name:"Anor", base:32, odd: 1, sort: i => n(i) / td(i, 10)},
{name:"Dail", base:32, odd: 1, sort: i => n(i) / td(i, 13)},
{name:"Duland", base:32, odd: 1, sort: i => n(i) / td(i, 14)},
{name:"Rohand", base:32, odd: 1, sort: i => n(i) / td(i, 16)},
// rare real-world western
{name:"Norse", base:6, odd: .5},
{name:"Izenlute", base:0, odd: .1},
{name:"Lurian", base:2, odd: .1},
{name:"Getalian", base:3, odd: .1},
{name:"Astelan", base:4, odd: .05},
{name:"Norse", base:6, odd: .5, sort: i => n(i) / td(i, 5) / sf(i)},
{name:"Izenlute", base:0, odd: .1, sort: i => n(i) / td(i, 5)},
{name:"Lurian", base:2, odd: .1, sort: i => n(i) / td(i, 12) / bd(i, [6, 8])},
{name:"Getalian", base:3, odd: .1, sort: i => n(i) / td(i, 15)},
{name:"Astelan", base:4, odd: .05, sort: i => n(i) / td(i, 16)},
// rare real-world exotic
{name:"Yoruba", base:21, odd: .05},
{name:"Ryoko", base:10, odd: .05},
{name:"Toyamo", base:12, odd: .05},
{name:"Guan-Tsu", base:30, odd: .05},
{name:"Ulus-Khan", base:31, odd: .05},
{name:"Turan", base: 16, odd: .05},
{name:"Al'Uma", base: 18, odd: .05},
{name:"Druidas", base: 22, odd: .05},
{name:"Gorodian", base:5, odd: .05}
{name:"Yoruba", base:21, odd: .05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7])},
{name:"Ryoko", base:10, odd: .05, sort: i => n(i) / td(i, 12) / t[i]},
{name:"Toyamo", base:12, odd: .05, sort: i => n(i) / td(i, 15) / t[i]},
{name:"Guan-Tsu", base:30, odd: .05, sort: i => n(i) / td(i, 17)},
{name:"Ulus-Khan", base:31, odd: .05, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i]},
{name:"Turan", base: 16, odd: .05, sort: i => n(i) / td(i, 13)},
{name:"Al'Uma", base: 18, odd: .05, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i]},
{name:"Druidas", base: 22, odd: .05, sort: i => n(i) / td(i, 11) / bd(i, [6, 8]) * t[i]},
{name:"Gorodian", base:5, odd: .05, sort: i => n(i) / td(i, 6) * t[i]}
];
}
if (culturesSet.value === "darkFantasy") {
return [
// common real-world English
{name:"Angshire", base:1, odd: 1},
{name:"Enlandic", base:1, odd: 1},
{name:"Westen", base:1, odd: 1},
{name:"Nortumbic", base:1, odd: 1},
{name:"Mercian", base:1, odd: 1},
{name:"Kentian", base:1, odd: 1},
{name:"Angshire", base:1, odd: 1, sort: i => n(i) / td(i, 10) / sf(i)},
{name:"Enlandic", base:1, odd: 1, sort: i => n(i) / td(i, 12)},
{name:"Westen", base:1, odd: 1, sort: i => n(i) / td(i, 10)},
{name:"Nortumbic", base:1, odd: 1, sort: i => n(i) / td(i, 7)},
{name:"Mercian", base:1, odd: 1, sort: i => n(i) / td(i, 9)},
{name:"Kentian", base:1, odd: 1, sort: i => n(i) / td(i, 12)},
// rare real-world western
{name:"Norse", base:6, odd: .7},
{name:"Schwarzen", base:0, odd: .3},
{name:"Luarian", base:2, odd: .3},
{name:"Hetallian", base:3, odd: .3},
{name:"Astellian", base:4, odd: .3},
{name:"Norse", base:6, odd: .7, sort: i => n(i) / td(i, 5) / sf(i)},
{name:"Schwarzen", base:0, odd: .3, sort: i => n(i) / td(i, 10) / bd(i, [6, 8])},
{name:"Luarian", base:2, odd: .3, sort: i => n(i) / td(i, 12) / bd(i, [6, 8])},
{name:"Hetallian", base:3, odd: .3, sort: i => n(i) / td(i, 15)},
{name:"Astellian", base:4, odd: .3, sort: i => n(i) / td(i, 16)},
// rare real-world exotic
{name:"Kiswaili", base:28, odd: .05},
{name:"Yoruba", base:21, odd: .05},
{name:"Koryo", base:10, odd: .05},
{name:"Hantzu", base:11, odd: .05},
{name:"Yamoto", base:12, odd: .05},
{name:"Guantzu", base:30, odd: .05},
{name:"Ulus", base:31, odd: .05},
{name:"Turan", base: 16, odd: .05},
{name:"Berberan", base: 17, odd: .05},
{name:"Eurabic", base: 18, odd: .05},
{name:"Slovan", base:5, odd: .05},
{name:"Keltan", base: 22, odd: .1},
{name:"Elladan", base:7, odd: .2},
{name:"Romian", base:8, odd: .2},
{name:"Kiswaili", base:28, odd: .05, sort: i => n(i) / td(i, 29) / bd(i, [1, 3, 5, 7])},
{name:"Yoruba", base:21, odd: .05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7])},
{name:"Koryo", base:10, odd: .05, sort: i => n(i) / td(i, 12) / t[i]},
{name:"Hantzu", base:11, odd: .05, sort: i => n(i) / td(i, 13)},
{name:"Yamoto", base:12, odd: .05, sort: i => n(i) / td(i, 15) / t[i]},
{name:"Guantzu", base:30, odd: .05, sort: i => n(i) / td(i, 17)},
{name:"Ulus", base:31, odd: .05, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i]},
{name:"Turan", base: 16, odd: .05, sort: i => n(i) / td(i, 12)},
{name:"Berberan", base: 17, odd: .05, sort: i => n(i) / td(i, 19) / bd(i, [1, 2, 3], 7) * t[i]},
{name:"Eurabic", base: 18, odd: .05, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i]},
{name:"Slovan", base:5, odd: .05, sort: i => n(i) / td(i, 6) * t[i]},
{name:"Keltan", base: 22, odd: .1, sort: i => n(i) / td(i, 11) ** .5 / bd(i, [6, 8])},
{name:"Elladan", base:7, odd: .2, sort: i => n(i) / td(i, 18) / sf(i) * h[i]},
{name:"Romian", base:8, odd: .2, sort: i => n(i) / td(i, 14) / t[i]},
// fantasy races
{name:"Eldar", base: 33, odd: .5}, // Elves
{name:"Trow", base: 34, odd: .8}, // Dark Elves
{name:"Durinn", base: 35, odd: .8}, // Dwarven
{name:"Kobblin", base: 36, odd: .8}, // Goblin
{name:"Uruk", base: 37, odd: .8}, // Orc
{name:"Yotunn", base: 38, odd: .8}, // Giant
{name:"Drake", base: 39, odd: .9}, // Draconic
{name:"Rakhnid", base: 40, odd: .9}, // Arachnid
{name:"Aj'Snaga", base: 41, odd: .9}, // Serpents
{name:"Eldar", base: 33, odd: .5, sort: i => n(i) / bd(i, [6,7,8,9], 10) * t[i]}, // Elves
{name:"Trow", base: 34, odd: .8, sort: i => n(i) / bd(i, [7,8,9,12], 10) * t[i]}, // Dark Elves
{name:"Durinn", base: 35, odd: .8, sort: i => n(i) + h[i]}, // Dwarven
{name:"Kobblin", base: 36, odd: .8, sort: i => t[i] - s[i]}, // Goblin
{name:"Uruk", base: 37, odd: .8, sort: i => h[i] * t[i] / bd(i, [1,2,10,11])}, // Orc
{name:"Yotunn", base: 38, odd: .8, sort: i => td(i, -10)}, // Giant
{name:"Drake", base: 39, odd: .9, sort: i => -s[i]}, // Draconic
{name:"Rakhnid", base: 40, odd: .9, sort: i => t[i] - s[i]}, // Arachnid
{name:"Aj'Snaga", base: 41, odd: .9, sort: i => n(i) / bd(i, [12], 10)}, // Serpents
]
}
@ -313,38 +318,38 @@
// all-world
return [
{name:"Shwazen", base:0, odd: .7},
{name:"Angshire", base:1, odd: 1},
{name:"Luari", base:2, odd: .6},
{name:"Tallian", base:3, odd: .6},
{name:"Astellian", base:4, odd: .6},
{name:"Slovan", base:5, odd: .7},
{name:"Norse", base:6, odd: .7},
{name:"Elladan", base:7, odd: .7},
{name:"Romian", base:8, odd: .7},
{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: .1},
{name:"Vengrian", base: 15, odd: .2},
{name:"Turchian", base: 16, odd: .2},
{name:"Berberan", base: 17, odd: .1},
{name:"Eurabic", base: 18, odd: .2},
{name:"Inuk", base: 19, odd: .05},
{name:"Euskati", base: 20, odd: .05},
{name:"Yoruba", base: 21, odd: .05},
{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: .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:"Ulus", base:31, odd: .1}
{name:"Shwazen", base:0, odd: .7, sort: i => n(i) / td(i, 10) / bd(i, [6, 8])},
{name:"Angshire", base:1, odd: 1, sort: i => n(i) / td(i, 10) / sf(i)},
{name:"Luari", base:2, odd: .6, sort: i => n(i) / td(i, 12) / bd(i, [6, 8])},
{name:"Tallian", base:3, odd: .6, sort: i => n(i) / td(i, 15)},
{name:"Astellian", base:4, odd: .6, sort: i => n(i) / td(i, 16)},
{name:"Slovan", base:5, odd: .7, sort: i => n(i) / td(i, 6) * t[i]},
{name:"Norse", base:6, odd: .7, sort: i => n(i) / td(i, 5)},
{name:"Elladan", base:7, odd: .7, sort: i => n(i) / td(i, 18) * h[i]},
{name:"Romian", base:8, odd: .7, sort: i => n(i) / td(i, 15)},
{name:"Soumi", base:9, odd: .3, sort: i => n(i) / td(i, 5) / bd(i, [9]) * t[i]},
{name:"Koryo", base:10, odd: .1, sort: i => n(i) / td(i, 12) / t[i]},
{name:"Hantzu", base:11, odd: .1, sort: i => n(i) / td(i, 13)},
{name:"Yamoto", base:12, odd: .1, sort: i => n(i) / td(i, 15) / t[i]},
{name:"Portuzian", base:13, odd: .4, sort: i => n(i) / td(i, 17) / sf(i)},
{name:"Nawatli", base:14, odd: .1, sort: i => h[i] / td(i, 18) / bd(i, [7])},
{name:"Vengrian", base: 15, odd: .2, sort: i => n(i) / td(i, 11) / bd(i, [4]) * t[i]},
{name:"Turchian", base: 16, odd: .2, sort: i => n(i) / td(i, 13)},
{name:"Berberan", base: 17, odd: .1, sort: i => n(i) / td(i, 19) / bd(i, [1, 2, 3], 7) * t[i]},
{name:"Eurabic", base: 18, odd: .2, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i]},
{name:"Inuk", base: 19, odd: .05, sort: i => td(i, -1) / bd(i, [10, 11]) / sf(i)},
{name:"Euskati", base: 20, odd: .05, sort: i => n(i) / td(i, 15) * h[i]},
{name:"Yoruba", base: 21, odd: .05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7])},
{name:"Keltan", base: 22, odd: .05, sort: i => n(i) / td(i, 11) / bd(i, [6, 8]) * t[i]},
{name:"Efratic", base: 23, odd: .05, sort: i => n(i) / td(i, 22) * t[i]},
{name:"Tehrani", base: 24, odd: .1, sort: i => n(i) / td(i, 18) * h[i]},
{name:"Maui", base: 25, odd: .05, sort: i => n(i) / td(i, 24) / sf(i) / t[i]},
{name:"Carnatic", base: 26, odd: .05, sort: i => n(i) / td(i, 26)},
{name:"Inqan", base: 27, odd: .05, sort: i => h[i] / td(i, 13)},
{name:"Kiswaili", base: 28, odd: .1, sort: i => n(i) / td(i, 29) / bd(i, [1, 3, 5, 7])},
{name:"Vietic", base: 29, odd: .1, sort: i => n(i) / td(i, 25) / bd(i, [7], 7) / t[i]},
{name:"Guantzu", base:30, odd: .1, sort: i => n(i) / td(i, 17)},
{name:"Ulus", base:31, odd: .1, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i]}
];
}