mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
replace old iife by a simpler ones
This commit is contained in:
parent
37e5b803bc
commit
460bb29e49
15 changed files with 2430 additions and 1313 deletions
244
libs/pell.js
244
libs/pell.js
|
|
@ -1,163 +1,157 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Pell = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
"use strict";
|
||||
|
||||
const defaultParagraphSeparatorString = 'defaultParagraphSeparator'
|
||||
const formatBlock = 'formatBlock'
|
||||
const addEventListener = (parent, type, listener) => parent.addEventListener(type, listener)
|
||||
const appendChild = (parent, child) => parent.appendChild(child)
|
||||
const createElement = tag => document.createElement(tag)
|
||||
const queryCommandState = command => document.queryCommandState(command)
|
||||
const queryCommandValue = command => document.queryCommandValue(command)
|
||||
const exec = (command, value = null) => document.execCommand(command, false, value)
|
||||
window.Pell = (function () {
|
||||
const defaultParagraphSeparatorString = "defaultParagraphSeparator";
|
||||
const formatBlock = "formatBlock";
|
||||
const addEventListener = (parent, type, listener) => parent.addEventListener(type, listener);
|
||||
const appendChild = (parent, child) => parent.appendChild(child);
|
||||
const createElement = tag => document.createElement(tag);
|
||||
const queryCommandState = command => document.queryCommandState(command);
|
||||
const queryCommandValue = command => document.queryCommandValue(command);
|
||||
const exec = (command, value = null) => document.execCommand(command, false, value);
|
||||
|
||||
const defaultActions = {
|
||||
bold: {
|
||||
icon: '<b>B</b>',
|
||||
title: 'Bold',
|
||||
state: () => queryCommandState('bold'),
|
||||
result: () => exec('bold')
|
||||
icon: "<b>B</b>",
|
||||
title: "Bold",
|
||||
state: () => queryCommandState("bold"),
|
||||
result: () => exec("bold")
|
||||
},
|
||||
italic: {
|
||||
icon: '<i>I</i>',
|
||||
title: 'Italic',
|
||||
state: () => queryCommandState('italic'),
|
||||
result: () => exec('italic')
|
||||
icon: "<i>I</i>",
|
||||
title: "Italic",
|
||||
state: () => queryCommandState("italic"),
|
||||
result: () => exec("italic")
|
||||
},
|
||||
underline: {
|
||||
icon: '<u>U</u>',
|
||||
title: 'Underline',
|
||||
state: () => queryCommandState('underline'),
|
||||
result: () => exec('underline')
|
||||
icon: "<u>U</u>",
|
||||
title: "Underline",
|
||||
state: () => queryCommandState("underline"),
|
||||
result: () => exec("underline")
|
||||
},
|
||||
strikethrough: {
|
||||
icon: '<strike>S</strike>',
|
||||
title: 'Strike-through',
|
||||
state: () => queryCommandState('strikeThrough'),
|
||||
result: () => exec('strikeThrough')
|
||||
icon: "<strike>S</strike>",
|
||||
title: "Strike-through",
|
||||
state: () => queryCommandState("strikeThrough"),
|
||||
result: () => exec("strikeThrough")
|
||||
},
|
||||
heading1: {
|
||||
icon: '<b>H<sub>1</sub></b>',
|
||||
title: 'Heading 1',
|
||||
result: () => exec(formatBlock, '<h1>')
|
||||
icon: "<b>H<sub>1</sub></b>",
|
||||
title: "Heading 1",
|
||||
result: () => exec(formatBlock, "<h1>")
|
||||
},
|
||||
heading2: {
|
||||
icon: '<b>H<sub>2</sub></b>',
|
||||
title: 'Heading 2',
|
||||
result: () => exec(formatBlock, '<h2>')
|
||||
icon: "<b>H<sub>2</sub></b>",
|
||||
title: "Heading 2",
|
||||
result: () => exec(formatBlock, "<h2>")
|
||||
},
|
||||
paragraph: {
|
||||
icon: '¶',
|
||||
title: 'Paragraph',
|
||||
result: () => exec(formatBlock, '<p>')
|
||||
icon: "¶",
|
||||
title: "Paragraph",
|
||||
result: () => exec(formatBlock, "<p>")
|
||||
},
|
||||
quote: {
|
||||
icon: '“ ”',
|
||||
title: 'Quote',
|
||||
result: () => exec(formatBlock, '<blockquote>')
|
||||
icon: "“ ”",
|
||||
title: "Quote",
|
||||
result: () => exec(formatBlock, "<blockquote>")
|
||||
},
|
||||
olist: {
|
||||
icon: '#',
|
||||
title: 'Ordered List',
|
||||
result: () => exec('insertOrderedList')
|
||||
icon: "#",
|
||||
title: "Ordered List",
|
||||
result: () => exec("insertOrderedList")
|
||||
},
|
||||
ulist: {
|
||||
icon: '•',
|
||||
title: 'Unordered List',
|
||||
result: () => exec('insertUnorderedList')
|
||||
icon: "•",
|
||||
title: "Unordered List",
|
||||
result: () => exec("insertUnorderedList")
|
||||
},
|
||||
code: {
|
||||
icon: '</>',
|
||||
title: 'Code',
|
||||
result: () => exec(formatBlock, '<pre>')
|
||||
icon: "</>",
|
||||
title: "Code",
|
||||
result: () => exec(formatBlock, "<pre>")
|
||||
},
|
||||
line: {
|
||||
icon: '―',
|
||||
title: 'Horizontal Line',
|
||||
result: () => exec('insertHorizontalRule')
|
||||
icon: "―",
|
||||
title: "Horizontal Line",
|
||||
result: () => exec("insertHorizontalRule")
|
||||
},
|
||||
link: {
|
||||
icon: '🔗',
|
||||
title: 'Link',
|
||||
result: () => navigator.clipboard.readText().then(url => exec('createLink', url))
|
||||
icon: "🔗",
|
||||
title: "Link",
|
||||
result: () => navigator.clipboard.readText().then(url => exec("createLink", url))
|
||||
},
|
||||
image: {
|
||||
icon: '📷',
|
||||
title: 'Image',
|
||||
icon: "📷",
|
||||
title: "Image",
|
||||
result: () => {
|
||||
navigator.clipboard.readText().then(url => exec('insertImage', url))
|
||||
exec('enableObjectResizing')
|
||||
navigator.clipboard.readText().then(url => exec("insertImage", url));
|
||||
exec("enableObjectResizing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const defaultClasses = {
|
||||
actionbar: 'pell-actionbar',
|
||||
button: 'pell-button',
|
||||
content: 'pell-content',
|
||||
selected: 'pell-button-selected'
|
||||
}
|
||||
|
||||
actionbar: "pell-actionbar",
|
||||
button: "pell-button",
|
||||
content: "pell-content",
|
||||
selected: "pell-button-selected"
|
||||
};
|
||||
|
||||
const init = settings => {
|
||||
const actions = settings.actions
|
||||
? (
|
||||
settings.actions.map(action => {
|
||||
if (typeof action === 'string') return defaultActions[action]
|
||||
else if (defaultActions[action.name]) return { ...defaultActions[action.name], ...action }
|
||||
return action
|
||||
? settings.actions.map(action => {
|
||||
if (typeof action === "string") return defaultActions[action];
|
||||
else if (defaultActions[action.name]) return {...defaultActions[action.name], ...action};
|
||||
return action;
|
||||
})
|
||||
)
|
||||
: Object.keys(defaultActions).map(action => defaultActions[action])
|
||||
|
||||
const classes = { ...defaultClasses, ...settings.classes }
|
||||
|
||||
const defaultParagraphSeparator = settings[defaultParagraphSeparatorString] || 'div'
|
||||
|
||||
const actionbar = createElement('div')
|
||||
actionbar.className = classes.actionbar
|
||||
appendChild(settings.element, actionbar)
|
||||
|
||||
const content = settings.element.content = createElement('div')
|
||||
content.contentEditable = true
|
||||
content.className = classes.content
|
||||
content.oninput = ({ target: { firstChild } }) => {
|
||||
if (firstChild && firstChild.nodeType === 3) exec(formatBlock, `<${defaultParagraphSeparator}>`)
|
||||
else if (content.innerHTML === '<br>') content.innerHTML = ''
|
||||
settings.onChange(content.innerHTML)
|
||||
}
|
||||
content.onkeydown = event => {
|
||||
if (event.key === 'Enter' && queryCommandValue(formatBlock) === 'blockquote') {
|
||||
setTimeout(() => exec(formatBlock, `<${defaultParagraphSeparator}>`), 0)
|
||||
}
|
||||
}
|
||||
appendChild(settings.element, content)
|
||||
|
||||
actions.forEach(action => {
|
||||
const button = createElement('button')
|
||||
button.className = classes.button
|
||||
button.innerHTML = action.icon
|
||||
button.title = action.title
|
||||
button.setAttribute('type', 'button')
|
||||
button.onclick = () => action.result() && content.focus()
|
||||
|
||||
if (action.state) {
|
||||
const handler = () => button.classList[action.state() ? 'add' : 'remove'](classes.selected)
|
||||
addEventListener(content, 'keyup', handler)
|
||||
addEventListener(content, 'mouseup', handler)
|
||||
addEventListener(button, 'click', handler)
|
||||
}
|
||||
|
||||
appendChild(actionbar, button)
|
||||
})
|
||||
|
||||
if (settings.styleWithCSS) exec('styleWithCSS')
|
||||
exec(defaultParagraphSeparatorString, defaultParagraphSeparator)
|
||||
|
||||
return settings.element
|
||||
}
|
||||
|
||||
return {exec, init}
|
||||
: Object.keys(defaultActions).map(action => defaultActions[action]);
|
||||
|
||||
})));
|
||||
const classes = {...defaultClasses, ...settings.classes};
|
||||
|
||||
const defaultParagraphSeparator = settings[defaultParagraphSeparatorString] || "div";
|
||||
|
||||
const actionbar = createElement("div");
|
||||
actionbar.className = classes.actionbar;
|
||||
appendChild(settings.element, actionbar);
|
||||
|
||||
const content = (settings.element.content = createElement("div"));
|
||||
content.contentEditable = true;
|
||||
content.className = classes.content;
|
||||
content.oninput = ({target: {firstChild}}) => {
|
||||
if (firstChild && firstChild.nodeType === 3) exec(formatBlock, `<${defaultParagraphSeparator}>`);
|
||||
else if (content.innerHTML === "<br>") content.innerHTML = "";
|
||||
settings.onChange(content.innerHTML);
|
||||
};
|
||||
content.onkeydown = event => {
|
||||
if (event.key === "Enter" && queryCommandValue(formatBlock) === "blockquote") {
|
||||
setTimeout(() => exec(formatBlock, `<${defaultParagraphSeparator}>`), 0);
|
||||
}
|
||||
};
|
||||
appendChild(settings.element, content);
|
||||
|
||||
actions.forEach(action => {
|
||||
const button = createElement("button");
|
||||
button.className = classes.button;
|
||||
button.innerHTML = action.icon;
|
||||
button.title = action.title;
|
||||
button.setAttribute("type", "button");
|
||||
button.onclick = () => action.result() && content.focus();
|
||||
|
||||
if (action.state) {
|
||||
const handler = () => button.classList[action.state() ? "add" : "remove"](classes.selected);
|
||||
addEventListener(content, "keyup", handler);
|
||||
addEventListener(content, "mouseup", handler);
|
||||
addEventListener(button, "click", handler);
|
||||
}
|
||||
|
||||
appendChild(actionbar, button);
|
||||
});
|
||||
|
||||
if (settings.styleWithCSS) exec("styleWithCSS");
|
||||
exec(defaultParagraphSeparatorString, defaultParagraphSeparator);
|
||||
|
||||
return settings.element;
|
||||
};
|
||||
|
||||
return {exec, init};
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.BurgsAndStates = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.BurgsAndStates = (function () {
|
||||
const generate = function () {
|
||||
const cells = pack.cells,
|
||||
cultures = pack.cultures,
|
||||
n = cells.i.length;
|
||||
const {cells, cultures} = pack;
|
||||
const n = cells.i.length;
|
||||
|
||||
cells.burg = new Uint16Array(n); // cell burg
|
||||
cells.road = new Uint16Array(n); // cell road power
|
||||
|
|
@ -1224,4 +1221,4 @@
|
|||
};
|
||||
|
||||
return {generate, expandStates, normalizeStates, assignColors, drawBurgs, specifyBurgs, defineBurgFeatures, getType, drawStateLabels, collectStatistics, generateCampaigns, generateDiplomacy, defineStateForms, getFullName, generateProvinces, updateCultures};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,170 +1,364 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.COA = factory());
|
||||
}(this, (function () {'use strict';
|
||||
"use strict";
|
||||
|
||||
window.COA = (function () {
|
||||
const tinctures = {
|
||||
field: { metals: 3, colours: 4, stains: +P(.03), patterns: 1 },
|
||||
division: { metals: 5, colours: 8, stains: +P(.03), patterns: 1 },
|
||||
charge: { metals: 2, colours: 3, stains: +P(.05), patterns: 0 },
|
||||
metals: { argent: 3, or: 2 },
|
||||
colours: { gules: 5, azure: 4, sable: 3, purpure: 3, vert: 2 },
|
||||
stains: { murrey: 1, sanguine: 1, tenné: 1 },
|
||||
field: {metals: 3, colours: 4, stains: +P(0.03), patterns: 1},
|
||||
division: {metals: 5, colours: 8, stains: +P(0.03), patterns: 1},
|
||||
charge: {metals: 2, colours: 3, stains: +P(0.05), patterns: 0},
|
||||
metals: {argent: 3, or: 2},
|
||||
colours: {gules: 5, azure: 4, sable: 3, purpure: 3, vert: 2},
|
||||
stains: {murrey: 1, sanguine: 1, tenné: 1},
|
||||
patterns: {
|
||||
semy: 8, ermine: 6,
|
||||
vair: 4, counterVair: 1, vairInPale: 1, vairEnPointe: 2, vairAncien: 2,
|
||||
potent: 2, counterPotent: 1, potentInPale: 1, potentEnPointe: 1,
|
||||
chequy: 8, lozengy: 5, fusily: 2, pally: 8, barry: 10, gemelles: 1,
|
||||
bendy: 8, bendySinister: 4, palyBendy: 2, barryBendy: 1,
|
||||
pappellony: 2, pappellony2: 3, scaly: 1, plumetty: 1,
|
||||
masoned: 6, fretty: 3, grillage: 1, chainy: 1, maily: 2, honeycombed: 1 }
|
||||
}
|
||||
semy: 8,
|
||||
ermine: 6,
|
||||
vair: 4,
|
||||
counterVair: 1,
|
||||
vairInPale: 1,
|
||||
vairEnPointe: 2,
|
||||
vairAncien: 2,
|
||||
potent: 2,
|
||||
counterPotent: 1,
|
||||
potentInPale: 1,
|
||||
potentEnPointe: 1,
|
||||
chequy: 8,
|
||||
lozengy: 5,
|
||||
fusily: 2,
|
||||
pally: 8,
|
||||
barry: 10,
|
||||
gemelles: 1,
|
||||
bendy: 8,
|
||||
bendySinister: 4,
|
||||
palyBendy: 2,
|
||||
barryBendy: 1,
|
||||
pappellony: 2,
|
||||
pappellony2: 3,
|
||||
scaly: 1,
|
||||
plumetty: 1,
|
||||
masoned: 6,
|
||||
fretty: 3,
|
||||
grillage: 1,
|
||||
chainy: 1,
|
||||
maily: 2,
|
||||
honeycombed: 1
|
||||
}
|
||||
};
|
||||
|
||||
const charges = {
|
||||
// categories selection
|
||||
types: { conventional: 30, crosses: 10, animals: 2, animalHeads: 1, birds: 2, fantastic: 3, plants: 1, agriculture: 1, arms: 3, bodyparts: 1, people: 1, architecture: 1, miscellaneous: 3, inescutcheon: 3 },
|
||||
single: { conventional: 12, crosses: 8, plants: 2, animals: 10, animalHeads: 2, birds: 4, fantastic: 7, agriculture: 1, arms: 6, bodyparts: 1, people: 2, architecture: 1, miscellaneous: 10, inescutcheon: 5 },
|
||||
semy: { conventional: 12, crosses: 3, plants: 1 },
|
||||
types: {conventional: 30, crosses: 10, animals: 2, animalHeads: 1, birds: 2, fantastic: 3, plants: 1, agriculture: 1, arms: 3, bodyparts: 1, people: 1, architecture: 1, miscellaneous: 3, inescutcheon: 3},
|
||||
single: {conventional: 12, crosses: 8, plants: 2, animals: 10, animalHeads: 2, birds: 4, fantastic: 7, agriculture: 1, arms: 6, bodyparts: 1, people: 2, architecture: 1, miscellaneous: 10, inescutcheon: 5},
|
||||
semy: {conventional: 12, crosses: 3, plants: 1},
|
||||
// generic categories
|
||||
conventional: {
|
||||
lozenge: 2, fusil: 4, mascle: 4, rustre: 2, lozengeFaceted: 3, lozengePloye: 1, roundel: 4, roundel2: 3, annulet: 4,
|
||||
mullet: 5, mulletPierced: 1, mulletFaceted: 1, mullet4: 3, mullet6: 4, mullet6Pierced: 1, mullet6Faceted: 1, mullet7: 1, mullet8: 1, mullet10: 1,
|
||||
estoile: 1, compassRose: 1, billet: 5, delf: 0, triangle: 3, trianglePierced: 1, goutte: 4, heart: 4, pique: 2, carreau: 1, trefle: 2,
|
||||
fleurDeLis: 6, sun: 3, sunInSplendour: 1, crescent: 5, fountain: 1
|
||||
lozenge: 2,
|
||||
fusil: 4,
|
||||
mascle: 4,
|
||||
rustre: 2,
|
||||
lozengeFaceted: 3,
|
||||
lozengePloye: 1,
|
||||
roundel: 4,
|
||||
roundel2: 3,
|
||||
annulet: 4,
|
||||
mullet: 5,
|
||||
mulletPierced: 1,
|
||||
mulletFaceted: 1,
|
||||
mullet4: 3,
|
||||
mullet6: 4,
|
||||
mullet6Pierced: 1,
|
||||
mullet6Faceted: 1,
|
||||
mullet7: 1,
|
||||
mullet8: 1,
|
||||
mullet10: 1,
|
||||
estoile: 1,
|
||||
compassRose: 1,
|
||||
billet: 5,
|
||||
delf: 0,
|
||||
triangle: 3,
|
||||
trianglePierced: 1,
|
||||
goutte: 4,
|
||||
heart: 4,
|
||||
pique: 2,
|
||||
carreau: 1,
|
||||
trefle: 2,
|
||||
fleurDeLis: 6,
|
||||
sun: 3,
|
||||
sunInSplendour: 1,
|
||||
crescent: 5,
|
||||
fountain: 1
|
||||
},
|
||||
crosses: {
|
||||
crossHummetty: 15, crossVoided: 1, crossPattee: 2, crossPatteeAlisee: 1, crossFormee: 1, crossFormee2: 2, crossPotent: 2, crossJerusalem:1,
|
||||
crosslet: 1, crossClechy: 3, crossBottony: 1, crossFleury: 3, crossPatonce: 1, crossPommy: 1, crossGamma: 1, crossArrowed: 1, crossFitchy: 1,
|
||||
crossCercelee: 1, crossMoline: 2, crossFourchy: 1, crossAvellane: 1, crossErminee: 1, crossBiparted: 1, crossMaltese: 3, crossTemplar: 2,
|
||||
crossCeltic: 1, crossCeltic2: 1, crossTriquetra: 1, crossCarolingian: 1, crossOccitan: 1, crossSaltire: 3, crossBurgundy: 1,
|
||||
crossLatin: 3, crossPatriarchal: 1, crossOrthodox: 1, crossCalvary: 1, crossDouble: 1, crossTau: 1, crossSantiago: 1, crossAnkh: 1
|
||||
crossHummetty: 15,
|
||||
crossVoided: 1,
|
||||
crossPattee: 2,
|
||||
crossPatteeAlisee: 1,
|
||||
crossFormee: 1,
|
||||
crossFormee2: 2,
|
||||
crossPotent: 2,
|
||||
crossJerusalem: 1,
|
||||
crosslet: 1,
|
||||
crossClechy: 3,
|
||||
crossBottony: 1,
|
||||
crossFleury: 3,
|
||||
crossPatonce: 1,
|
||||
crossPommy: 1,
|
||||
crossGamma: 1,
|
||||
crossArrowed: 1,
|
||||
crossFitchy: 1,
|
||||
crossCercelee: 1,
|
||||
crossMoline: 2,
|
||||
crossFourchy: 1,
|
||||
crossAvellane: 1,
|
||||
crossErminee: 1,
|
||||
crossBiparted: 1,
|
||||
crossMaltese: 3,
|
||||
crossTemplar: 2,
|
||||
crossCeltic: 1,
|
||||
crossCeltic2: 1,
|
||||
crossTriquetra: 1,
|
||||
crossCarolingian: 1,
|
||||
crossOccitan: 1,
|
||||
crossSaltire: 3,
|
||||
crossBurgundy: 1,
|
||||
crossLatin: 3,
|
||||
crossPatriarchal: 1,
|
||||
crossOrthodox: 1,
|
||||
crossCalvary: 1,
|
||||
crossDouble: 1,
|
||||
crossTau: 1,
|
||||
crossSantiago: 1,
|
||||
crossAnkh: 1
|
||||
},
|
||||
animals: {
|
||||
lionRampant: 5, lionPassant: 2, lionPassantGuardant: 1, wolfRampant: 1, wolfPassant: 1, wolfStatant: 1, greyhoundCourant: 1, boarRampant: 1,
|
||||
horseRampant: 2, horseSalient: 1, bearRampant: 2, bearPassant: 1, bullPassant: 1, goat: 1, lamb: 1, elephant: 1, camel: 1
|
||||
lionRampant: 5,
|
||||
lionPassant: 2,
|
||||
lionPassantGuardant: 1,
|
||||
wolfRampant: 1,
|
||||
wolfPassant: 1,
|
||||
wolfStatant: 1,
|
||||
greyhoundCourant: 1,
|
||||
boarRampant: 1,
|
||||
horseRampant: 2,
|
||||
horseSalient: 1,
|
||||
bearRampant: 2,
|
||||
bearPassant: 1,
|
||||
bullPassant: 1,
|
||||
goat: 1,
|
||||
lamb: 1,
|
||||
elephant: 1,
|
||||
camel: 1
|
||||
},
|
||||
animalHeads: { wolfHeadErased: 1, bullHeadCaboshed: 1, deerHeadCaboshed: 1, lionHeadCaboshed: 2 },
|
||||
fantastic: { dragonPassant: 2, dragonRampant: 2, wyvern: 1, wyvernWithWingsDisplayed: 1, griffinPassant: 1, griffinRampant: 1, eagleTwoHeards: 2, unicornRampant: 1, pegasus: 1, serpent: 1 },
|
||||
birds: { eagle: 9, raven: 1, cock: 3, parrot: 1, swan: 2, swanErased: 1, heron: 1, owl: 1 },
|
||||
plants: { tree: 1, oak: 1, cinquefoil: 1, rose: 1 },
|
||||
agriculture: { garb: 1, rake: 1 },
|
||||
arms: { sword: 5, sabre: 1, sabresCrossed: 1, hatchet: 2, axe: 2, lochaberAxe: 1, mallet: 1, bowWithArrow: 2, bow: 1, arrow: 1, arrowsSheaf: 1, helmet: 2 },
|
||||
bodyparts: { hand: 4, head: 1, headWreathed: 1 },
|
||||
people: { cavalier: 3, monk: 1, angel: 2 },
|
||||
architecture: { tower: 1, castle: 1 },
|
||||
animalHeads: {wolfHeadErased: 1, bullHeadCaboshed: 1, deerHeadCaboshed: 1, lionHeadCaboshed: 2},
|
||||
fantastic: {dragonPassant: 2, dragonRampant: 2, wyvern: 1, wyvernWithWingsDisplayed: 1, griffinPassant: 1, griffinRampant: 1, eagleTwoHeards: 2, unicornRampant: 1, pegasus: 1, serpent: 1},
|
||||
birds: {eagle: 9, raven: 1, cock: 3, parrot: 1, swan: 2, swanErased: 1, heron: 1, owl: 1},
|
||||
plants: {tree: 1, oak: 1, cinquefoil: 1, rose: 1},
|
||||
agriculture: {garb: 1, rake: 1},
|
||||
arms: {sword: 5, sabre: 1, sabresCrossed: 1, hatchet: 2, axe: 2, lochaberAxe: 1, mallet: 1, bowWithArrow: 2, bow: 1, arrow: 1, arrowsSheaf: 1, helmet: 2},
|
||||
bodyparts: {hand: 4, head: 1, headWreathed: 1},
|
||||
people: {cavalier: 3, monk: 1, angel: 2},
|
||||
architecture: {tower: 1, castle: 1},
|
||||
miscellaneous: {
|
||||
crown: 3, orb: 1, chalice: 1, key: 1, buckle: 1, bugleHorn: 1, bugleHorn2: 1, bell: 2, pot: 1, bucket: 1, horseshoe: 3,
|
||||
attire: 1, stagsAttires: 1, ramsHorn: 1, cowHorns: 2, wing: 1, wingSword: 1, lute: 1, harp: 1, wheel: 2, crosier: 1, fasces: 1, log: 1
|
||||
crown: 3,
|
||||
orb: 1,
|
||||
chalice: 1,
|
||||
key: 1,
|
||||
buckle: 1,
|
||||
bugleHorn: 1,
|
||||
bugleHorn2: 1,
|
||||
bell: 2,
|
||||
pot: 1,
|
||||
bucket: 1,
|
||||
horseshoe: 3,
|
||||
attire: 1,
|
||||
stagsAttires: 1,
|
||||
ramsHorn: 1,
|
||||
cowHorns: 2,
|
||||
wing: 1,
|
||||
wingSword: 1,
|
||||
lute: 1,
|
||||
harp: 1,
|
||||
wheel: 2,
|
||||
crosier: 1,
|
||||
fasces: 1,
|
||||
log: 1
|
||||
},
|
||||
// selection based on culture type:
|
||||
Naval: { anchor: 3, boat: 1, lymphad: 2, armillarySphere: 1, escallop: 1, dolphin: 1 },
|
||||
Highland: { tower: 1, raven: 1, wolfHeadErased: 1, wolfPassant: 1, goat: 1, axe: 1 },
|
||||
River: { tower: 1, garb: 1, rake: 1, boat: 1, pike: 2, bullHeadCaboshed: 1 },
|
||||
Lake: { cancer: 2, escallop: 1, pike: 2, heron: 1, boat: 1, boat2: 2 },
|
||||
Nomadic: { pot: 1, buckle: 1, wheel: 2, sabre: 2, sabresCrossed: 1, bow: 2, arrow: 1, horseRampant: 1, horseSalient: 1, crescent: 1, camel: 3 },
|
||||
Hunting: { bugleHorn: 2, bugleHorn2: 1, stagsAttires: 2, attire: 2, hatchet: 1, bowWithArrow: 1, arrowsSheaf: 1, deerHeadCaboshed: 1, wolfStatant: 1, oak: 1 },
|
||||
Naval: {anchor: 3, boat: 1, lymphad: 2, armillarySphere: 1, escallop: 1, dolphin: 1},
|
||||
Highland: {tower: 1, raven: 1, wolfHeadErased: 1, wolfPassant: 1, goat: 1, axe: 1},
|
||||
River: {tower: 1, garb: 1, rake: 1, boat: 1, pike: 2, bullHeadCaboshed: 1},
|
||||
Lake: {cancer: 2, escallop: 1, pike: 2, heron: 1, boat: 1, boat2: 2},
|
||||
Nomadic: {pot: 1, buckle: 1, wheel: 2, sabre: 2, sabresCrossed: 1, bow: 2, arrow: 1, horseRampant: 1, horseSalient: 1, crescent: 1, camel: 3},
|
||||
Hunting: {bugleHorn: 2, bugleHorn2: 1, stagsAttires: 2, attire: 2, hatchet: 1, bowWithArrow: 1, arrowsSheaf: 1, deerHeadCaboshed: 1, wolfStatant: 1, oak: 1},
|
||||
// selection based on type
|
||||
City: { key: 3, bell: 2, lute: 1, tower: 1, castle: 1, mallet: 1 },
|
||||
Capital: { crown: 4, orb: 1, lute: 1, castle: 3, tower: 1 },
|
||||
Сathedra: { chalice: 1, orb: 1, crosier: 2, lamb: 1, monk: 2, angel: 3, crossLatin: 2, crossPatriarchal: 1, crossOrthodox: 1, crossCalvary: 1 },
|
||||
City: {key: 3, bell: 2, lute: 1, tower: 1, castle: 1, mallet: 1},
|
||||
Capital: {crown: 4, orb: 1, lute: 1, castle: 3, tower: 1},
|
||||
Сathedra: {chalice: 1, orb: 1, crosier: 2, lamb: 1, monk: 2, angel: 3, crossLatin: 2, crossPatriarchal: 1, crossOrthodox: 1, crossCalvary: 1},
|
||||
// specific cases
|
||||
natural: { fountain: "azure", garb: "or", raven: "sable" }, // charges to mainly use predefined colours
|
||||
sinister: [ // charges that can be sinister
|
||||
"crossGamma", "lionRampant", "lionPassant", "wolfRampant", "wolfPassant", "wolfStatant", "wolfHeadErased", "greyhoundСourant", "boarRampant",
|
||||
"horseRampant", "horseSalient", "bullPassant", "bearRampant", "bearPassant", "goat", "lamb", "elephant", "eagle", "raven", "cock", "parrot",
|
||||
"swan", "swanErased", "heron", "pike", "dragonPassant", "dragonRampant", "wyvern", "wyvernWithWingsDisplayed", "griffinPassant", "griffinRampant",
|
||||
"unicornRampant", "pegasus", "serpent", "hatchet", "lochaberAxe", "hand", "wing", "wingSword", "lute", "harp", "bow", "head", "headWreathed",
|
||||
"knight", "lymphad", "log", "crosier", "dolphin", "sabre", "monk", "owl", "axe", "camel", "fasces", "lionPassantGuardant", "helmet"],
|
||||
reversed: [ // charges that can be reversed
|
||||
"goutte", "mullet", "mullet7", "crescent", "crossTau", "cancer", "sword", "sabresCrossed", "hand",
|
||||
"horseshoe", "bowWithArrow", "arrow", "arrowsSheaf", "rake", "crossTriquetra", "crossLatin", "crossTau"
|
||||
natural: {fountain: "azure", garb: "or", raven: "sable"}, // charges to mainly use predefined colours
|
||||
sinister: [
|
||||
// charges that can be sinister
|
||||
"crossGamma",
|
||||
"lionRampant",
|
||||
"lionPassant",
|
||||
"wolfRampant",
|
||||
"wolfPassant",
|
||||
"wolfStatant",
|
||||
"wolfHeadErased",
|
||||
"greyhoundСourant",
|
||||
"boarRampant",
|
||||
"horseRampant",
|
||||
"horseSalient",
|
||||
"bullPassant",
|
||||
"bearRampant",
|
||||
"bearPassant",
|
||||
"goat",
|
||||
"lamb",
|
||||
"elephant",
|
||||
"eagle",
|
||||
"raven",
|
||||
"cock",
|
||||
"parrot",
|
||||
"swan",
|
||||
"swanErased",
|
||||
"heron",
|
||||
"pike",
|
||||
"dragonPassant",
|
||||
"dragonRampant",
|
||||
"wyvern",
|
||||
"wyvernWithWingsDisplayed",
|
||||
"griffinPassant",
|
||||
"griffinRampant",
|
||||
"unicornRampant",
|
||||
"pegasus",
|
||||
"serpent",
|
||||
"hatchet",
|
||||
"lochaberAxe",
|
||||
"hand",
|
||||
"wing",
|
||||
"wingSword",
|
||||
"lute",
|
||||
"harp",
|
||||
"bow",
|
||||
"head",
|
||||
"headWreathed",
|
||||
"knight",
|
||||
"lymphad",
|
||||
"log",
|
||||
"crosier",
|
||||
"dolphin",
|
||||
"sabre",
|
||||
"monk",
|
||||
"owl",
|
||||
"axe",
|
||||
"camel",
|
||||
"fasces",
|
||||
"lionPassantGuardant",
|
||||
"helmet"
|
||||
],
|
||||
reversed: [
|
||||
// charges that can be reversed
|
||||
"goutte",
|
||||
"mullet",
|
||||
"mullet7",
|
||||
"crescent",
|
||||
"crossTau",
|
||||
"cancer",
|
||||
"sword",
|
||||
"sabresCrossed",
|
||||
"hand",
|
||||
"horseshoe",
|
||||
"bowWithArrow",
|
||||
"arrow",
|
||||
"arrowsSheaf",
|
||||
"rake",
|
||||
"crossTriquetra",
|
||||
"crossLatin",
|
||||
"crossTau"
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const positions = {
|
||||
conventional: { e: 20, abcdefgzi: 3, beh: 3, behdf: 2, acegi: 1, kn: 3, bhdf: 1, jeo: 1, abc: 3, jln: 6, jlh: 3, kmo: 2, jleh: 1, def: 3, abcpqh: 4, ABCDEFGHIJKL: 1 },
|
||||
complex: { e: 40, beh: 1, kn: 1, jeo: 1, abc: 2, jln: 7, jlh: 2, def: 1, abcpqh: 1 },
|
||||
conventional: {e: 20, abcdefgzi: 3, beh: 3, behdf: 2, acegi: 1, kn: 3, bhdf: 1, jeo: 1, abc: 3, jln: 6, jlh: 3, kmo: 2, jleh: 1, def: 3, abcpqh: 4, ABCDEFGHIJKL: 1},
|
||||
complex: {e: 40, beh: 1, kn: 1, jeo: 1, abc: 2, jln: 7, jlh: 2, def: 1, abcpqh: 1},
|
||||
divisions: {
|
||||
perPale: { e: 15, pq: 5, jo: 2, jl: 2, ABCDEFGHIJKL: 1 },
|
||||
perFess: { e: 12, kn: 4, jkl: 2, gizgiz: 1, jlh: 3, kmo: 1, ABCDEFGHIJKL: 1 },
|
||||
perBend: { e: 5, lm: 5, bcfdgh: 1 },
|
||||
perBendSinister: { e: 1, jo: 1 },
|
||||
perCross: { e: 4, jlmo: 1, j: 1, jo: 2, jl: 1 },
|
||||
perChevron: { e: 1, jlh: 1, dfk: 1, dfbh: 2, bdefh: 1 },
|
||||
perChevronReversed: { e: 1, mok: 2, dfh: 2, dfbh: 1, bdefh: 1 },
|
||||
perSaltire: { bhdf: 8, e: 3, abcdefgzi: 1, bh: 1, df: 1, ABCDEFGHIJKL: 1 },
|
||||
perPile: { ee: 3, be: 2, abceh: 1, abcabc: 1, jleh: 1 }
|
||||
perPale: {e: 15, pq: 5, jo: 2, jl: 2, ABCDEFGHIJKL: 1},
|
||||
perFess: {e: 12, kn: 4, jkl: 2, gizgiz: 1, jlh: 3, kmo: 1, ABCDEFGHIJKL: 1},
|
||||
perBend: {e: 5, lm: 5, bcfdgh: 1},
|
||||
perBendSinister: {e: 1, jo: 1},
|
||||
perCross: {e: 4, jlmo: 1, j: 1, jo: 2, jl: 1},
|
||||
perChevron: {e: 1, jlh: 1, dfk: 1, dfbh: 2, bdefh: 1},
|
||||
perChevronReversed: {e: 1, mok: 2, dfh: 2, dfbh: 1, bdefh: 1},
|
||||
perSaltire: {bhdf: 8, e: 3, abcdefgzi: 1, bh: 1, df: 1, ABCDEFGHIJKL: 1},
|
||||
perPile: {ee: 3, be: 2, abceh: 1, abcabc: 1, jleh: 1}
|
||||
},
|
||||
ordinariesOn: {
|
||||
pale: { ee: 12, beh: 10, kn: 3, bb: 1 },
|
||||
fess: { ee: 1, def: 3 },
|
||||
bar: { defdefdef: 1 },
|
||||
fessCotissed: { ee: 1, def: 3 },
|
||||
fessDoubleCotissed: { ee: 1, defdef: 3 },
|
||||
bend: { ee: 2, jo: 1, joe: 1 },
|
||||
bendSinister: { ee: 1, lm: 1, lem: 4 },
|
||||
bendlet: { joejoejoe: 1 },
|
||||
bendletSinister: { lemlemlem: 1 },
|
||||
bordure: { ABCDEFGHIJKL: 1 },
|
||||
chief: { abc: 5, bbb: 1 },
|
||||
quarter: { jjj: 1 },
|
||||
canton: { yyyy: 1 },
|
||||
cross: { eeee: 1, behdfbehdf: 3, behbehbeh: 2 },
|
||||
crossParted: { e: 5, ee: 1 },
|
||||
saltire: { ee: 5, jlemo: 1 },
|
||||
saltireParted: { e: 5, ee: 1 },
|
||||
pall: { ee: 1, jleh: 5, jlhh: 3 },
|
||||
pallReversed: { ee: 1, bemo: 5 },
|
||||
pile: { bbb: 1 },
|
||||
pileInBend: { eeee: 1, eeoo: 1 },
|
||||
pileInBendSinister: { eeee: 1, eemm: 1 }
|
||||
pale: {ee: 12, beh: 10, kn: 3, bb: 1},
|
||||
fess: {ee: 1, def: 3},
|
||||
bar: {defdefdef: 1},
|
||||
fessCotissed: {ee: 1, def: 3},
|
||||
fessDoubleCotissed: {ee: 1, defdef: 3},
|
||||
bend: {ee: 2, jo: 1, joe: 1},
|
||||
bendSinister: {ee: 1, lm: 1, lem: 4},
|
||||
bendlet: {joejoejoe: 1},
|
||||
bendletSinister: {lemlemlem: 1},
|
||||
bordure: {ABCDEFGHIJKL: 1},
|
||||
chief: {abc: 5, bbb: 1},
|
||||
quarter: {jjj: 1},
|
||||
canton: {yyyy: 1},
|
||||
cross: {eeee: 1, behdfbehdf: 3, behbehbeh: 2},
|
||||
crossParted: {e: 5, ee: 1},
|
||||
saltire: {ee: 5, jlemo: 1},
|
||||
saltireParted: {e: 5, ee: 1},
|
||||
pall: {ee: 1, jleh: 5, jlhh: 3},
|
||||
pallReversed: {ee: 1, bemo: 5},
|
||||
pile: {bbb: 1},
|
||||
pileInBend: {eeee: 1, eeoo: 1},
|
||||
pileInBendSinister: {eeee: 1, eemm: 1}
|
||||
},
|
||||
ordinariesOff: {
|
||||
pale: { yyy: 1 },
|
||||
fess: { abc: 3, abcz: 1 },
|
||||
bar: { abc: 2, abcgzi: 1, jlh: 5, bgi: 2, ach: 1 },
|
||||
gemelle: { abc: 1 },
|
||||
bend: { ccg: 2, ccc: 1 },
|
||||
bendSinister: { aai: 2, aaa: 1 },
|
||||
bendlet: { ccg: 2, ccc: 1 },
|
||||
bendletSinister: { aai: 2, aaa: 1 },
|
||||
bordure: { e: 4, jleh:2, kenken: 1, peqpeq: 1 },
|
||||
orle: { e: 4, jleh: 1, kenken: 1, peqpeq: 1 },
|
||||
chief: { emo: 2, emoz: 1, ez: 2 },
|
||||
terrace: { e: 5, def: 1, bdf: 3 },
|
||||
mount: { e: 5, def: 1, bdf: 3 },
|
||||
point: { e: 2, def: 1, bdf: 3, acbdef: 1 },
|
||||
flaunches: { e: 3, kn: 1, beh: 3 },
|
||||
gyron: { bh: 1 },
|
||||
quarter: { e: 1 },
|
||||
canton: { e: 5, beh: 1, def: 1, bdefh: 1, kn: 1 },
|
||||
cross: { acgi: 1 },
|
||||
pall: { BCKFEILGJbdmfo: 1 },
|
||||
pallReversed: { aczac: 1 },
|
||||
chevron: { ach: 3, hhh: 1 },
|
||||
chevronReversed: { bbb: 1 },
|
||||
pile: { acdfgi: 1, acac: 1 },
|
||||
pileInBend: { cg: 1 },
|
||||
pileInBendSinister: { ai: 1 },
|
||||
label: { defgzi: 2, eh: 3, defdefhmo: 1, egiegi: 1, pqn: 5 }
|
||||
pale: {yyy: 1},
|
||||
fess: {abc: 3, abcz: 1},
|
||||
bar: {abc: 2, abcgzi: 1, jlh: 5, bgi: 2, ach: 1},
|
||||
gemelle: {abc: 1},
|
||||
bend: {ccg: 2, ccc: 1},
|
||||
bendSinister: {aai: 2, aaa: 1},
|
||||
bendlet: {ccg: 2, ccc: 1},
|
||||
bendletSinister: {aai: 2, aaa: 1},
|
||||
bordure: {e: 4, jleh: 2, kenken: 1, peqpeq: 1},
|
||||
orle: {e: 4, jleh: 1, kenken: 1, peqpeq: 1},
|
||||
chief: {emo: 2, emoz: 1, ez: 2},
|
||||
terrace: {e: 5, def: 1, bdf: 3},
|
||||
mount: {e: 5, def: 1, bdf: 3},
|
||||
point: {e: 2, def: 1, bdf: 3, acbdef: 1},
|
||||
flaunches: {e: 3, kn: 1, beh: 3},
|
||||
gyron: {bh: 1},
|
||||
quarter: {e: 1},
|
||||
canton: {e: 5, beh: 1, def: 1, bdefh: 1, kn: 1},
|
||||
cross: {acgi: 1},
|
||||
pall: {BCKFEILGJbdmfo: 1},
|
||||
pallReversed: {aczac: 1},
|
||||
chevron: {ach: 3, hhh: 1},
|
||||
chevronReversed: {bbb: 1},
|
||||
pile: {acdfgi: 1, acac: 1},
|
||||
pileInBend: {cg: 1},
|
||||
pileInBendSinister: {ai: 1},
|
||||
label: {defgzi: 2, eh: 3, defdefhmo: 1, egiegi: 1, pqn: 5}
|
||||
},
|
||||
// charges
|
||||
inescutcheon: { e: 4, jln: 1 },
|
||||
mascle: { e: 15, abcdefgzi: 3, beh: 3, bdefh: 4, acegi: 1, kn: 3, joe: 2, abc: 3, jlh: 8, jleh: 1, df: 3, abcpqh: 4, pqe: 3, eknpq: 3 },
|
||||
lionRampant: { e: 10, def: 2, abc: 2, bdefh: 1, kn: 1, jlh: 2, abcpqh: 1 },
|
||||
lionPassant: { e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1 },
|
||||
wolfPassant: { e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1 },
|
||||
greyhoundСourant: { e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1 },
|
||||
griffinRampant: { e: 10, def: 2, abc: 2, bdefh: 1, kn: 1, jlh: 2, abcpqh: 1 },
|
||||
griffinPassant: { e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1 },
|
||||
boarRampant: { e: 12, beh: 1, kn: 1, jln: 2 },
|
||||
eagle: { e: 15, beh: 1, kn: 1, abc: 1, jlh: 2, def: 2, pq: 1 },
|
||||
raven: { e: 15, beh: 1, kn: 1, jeo: 1, abc: 3, jln: 3, def: 1 },
|
||||
wyvern: { e: 10, jln: 1 },
|
||||
garb: { e: 1, def: 3, abc: 2, beh: 1, kn: 1, jln: 3, jleh: 1, abcpqh: 1, joe: 1, lme: 1 },
|
||||
crown: { e: 10, abcdefgzi: 1, beh: 3, behdf: 2, acegi: 1, kn: 1, pq: 2, abc: 1, jln: 4, jleh: 1, def: 2, abcpqh: 3 },
|
||||
hand: { e: 10, jln: 2, kn: 1, jeo: 1, abc: 2, pqe: 1 },
|
||||
inescutcheon: {e: 4, jln: 1},
|
||||
mascle: {e: 15, abcdefgzi: 3, beh: 3, bdefh: 4, acegi: 1, kn: 3, joe: 2, abc: 3, jlh: 8, jleh: 1, df: 3, abcpqh: 4, pqe: 3, eknpq: 3},
|
||||
lionRampant: {e: 10, def: 2, abc: 2, bdefh: 1, kn: 1, jlh: 2, abcpqh: 1},
|
||||
lionPassant: {e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1},
|
||||
wolfPassant: {e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1},
|
||||
greyhoundСourant: {e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1},
|
||||
griffinRampant: {e: 10, def: 2, abc: 2, bdefh: 1, kn: 1, jlh: 2, abcpqh: 1},
|
||||
griffinPassant: {e: 10, def: 1, abc: 1, bdefh: 1, jlh: 1, abcpqh: 1},
|
||||
boarRampant: {e: 12, beh: 1, kn: 1, jln: 2},
|
||||
eagle: {e: 15, beh: 1, kn: 1, abc: 1, jlh: 2, def: 2, pq: 1},
|
||||
raven: {e: 15, beh: 1, kn: 1, jeo: 1, abc: 3, jln: 3, def: 1},
|
||||
wyvern: {e: 10, jln: 1},
|
||||
garb: {e: 1, def: 3, abc: 2, beh: 1, kn: 1, jln: 3, jleh: 1, abcpqh: 1, joe: 1, lme: 1},
|
||||
crown: {e: 10, abcdefgzi: 1, beh: 3, behdf: 2, acegi: 1, kn: 1, pq: 2, abc: 1, jln: 4, jleh: 1, def: 2, abcpqh: 3},
|
||||
hand: {e: 10, jln: 2, kn: 1, jeo: 1, abc: 2, pqe: 1},
|
||||
armillarySphere: {e: 1},
|
||||
tree: {e: 1},
|
||||
lymphad: {e: 1},
|
||||
|
|
@ -175,33 +369,92 @@
|
|||
};
|
||||
|
||||
const lines = {
|
||||
straight: 50, wavy: 8, engrailed: 4, invecked: 3, rayonne: 3, embattled: 1, raguly: 1, urdy: 1, dancetty: 1, indented: 2,
|
||||
dentilly: 1, bevilled: 1, angled: 1, flechy: 1, barby: 1, enclavy: 1, escartely: 1, arched: 2, archedReversed: 1, nowy: 1, nowyReversed: 1,
|
||||
embattledGhibellin: 1, embattledNotched: 1, embattledGrady: 1, dovetailedIndented: 1, dovetailed: 1,
|
||||
potenty: 1, potentyDexter: 1, potentySinister: 1, nebuly: 2, seaWaves: 1, dragonTeeth: 1, firTrees: 1
|
||||
straight: 50,
|
||||
wavy: 8,
|
||||
engrailed: 4,
|
||||
invecked: 3,
|
||||
rayonne: 3,
|
||||
embattled: 1,
|
||||
raguly: 1,
|
||||
urdy: 1,
|
||||
dancetty: 1,
|
||||
indented: 2,
|
||||
dentilly: 1,
|
||||
bevilled: 1,
|
||||
angled: 1,
|
||||
flechy: 1,
|
||||
barby: 1,
|
||||
enclavy: 1,
|
||||
escartely: 1,
|
||||
arched: 2,
|
||||
archedReversed: 1,
|
||||
nowy: 1,
|
||||
nowyReversed: 1,
|
||||
embattledGhibellin: 1,
|
||||
embattledNotched: 1,
|
||||
embattledGrady: 1,
|
||||
dovetailedIndented: 1,
|
||||
dovetailed: 1,
|
||||
potenty: 1,
|
||||
potentyDexter: 1,
|
||||
potentySinister: 1,
|
||||
nebuly: 2,
|
||||
seaWaves: 1,
|
||||
dragonTeeth: 1,
|
||||
firTrees: 1
|
||||
};
|
||||
|
||||
const divisions = {
|
||||
variants: { perPale: 5, perFess: 5, perBend: 2, perBendSinister: 1, perChevron: 1, perChevronReversed: 1, perCross: 5, perPile: 1, perSaltire: 1, gyronny: 1, chevronny: 1 },
|
||||
variants: {perPale: 5, perFess: 5, perBend: 2, perBendSinister: 1, perChevron: 1, perChevronReversed: 1, perCross: 5, perPile: 1, perSaltire: 1, gyronny: 1, chevronny: 1},
|
||||
perPale: lines,
|
||||
perFess: lines,
|
||||
perBend: lines,
|
||||
perBendSinister: lines,
|
||||
perChevron: lines,
|
||||
perChevronReversed: lines,
|
||||
perCross: { straight: 20, wavy: 5, engrailed: 4, invecked: 3, rayonne: 1, embattled: 1, raguly: 1, urdy: 1, indented: 2, dentilly: 1, bevilled: 1, angled: 1, embattledGhibellin: 1, embattledGrady: 1, dovetailedIndented: 1, dovetailed: 1, potenty: 1, potentyDexter: 1, potentySinister: 1, nebuly: 1 },
|
||||
perCross: {straight: 20, wavy: 5, engrailed: 4, invecked: 3, rayonne: 1, embattled: 1, raguly: 1, urdy: 1, indented: 2, dentilly: 1, bevilled: 1, angled: 1, embattledGhibellin: 1, embattledGrady: 1, dovetailedIndented: 1, dovetailed: 1, potenty: 1, potentyDexter: 1, potentySinister: 1, nebuly: 1},
|
||||
perPile: lines
|
||||
};
|
||||
|
||||
const ordinaries = {
|
||||
lined: {
|
||||
pale: 7, fess: 5, bend: 3, bendSinister: 2, chief: 5, bar: 2, gemelle: 1, fessCotissed: 1, fessDoubleCotissed: 1,
|
||||
bendlet: 2, bendletSinister: 1, terrace: 3, cross: 6, crossParted: 1, saltire: 2, saltireParted: 1
|
||||
pale: 7,
|
||||
fess: 5,
|
||||
bend: 3,
|
||||
bendSinister: 2,
|
||||
chief: 5,
|
||||
bar: 2,
|
||||
gemelle: 1,
|
||||
fessCotissed: 1,
|
||||
fessDoubleCotissed: 1,
|
||||
bendlet: 2,
|
||||
bendletSinister: 1,
|
||||
terrace: 3,
|
||||
cross: 6,
|
||||
crossParted: 1,
|
||||
saltire: 2,
|
||||
saltireParted: 1
|
||||
},
|
||||
straight: {
|
||||
bordure: 8, orle: 4, mount: 1, point: 2, flaunches: 1, gore: 1,
|
||||
gyron: 1, quarter: 1, canton: 2, pall: 3, pallReversed: 2, chevron: 4, chevronReversed: 3,
|
||||
pile: 2, pileInBend: 2, pileInBendSinister: 1, piles: 1, pilesInPoint: 2, label: 1
|
||||
bordure: 8,
|
||||
orle: 4,
|
||||
mount: 1,
|
||||
point: 2,
|
||||
flaunches: 1,
|
||||
gore: 1,
|
||||
gyron: 1,
|
||||
quarter: 1,
|
||||
canton: 2,
|
||||
pall: 3,
|
||||
pallReversed: 2,
|
||||
chevron: 4,
|
||||
chevronReversed: 3,
|
||||
pile: 2,
|
||||
pileInBend: 2,
|
||||
pileInBendSinister: 1,
|
||||
piles: 1,
|
||||
pilesInPoint: 2,
|
||||
label: 1
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -215,60 +468,61 @@
|
|||
simple: {round: 12, oval: 6, vesicaPiscis: 1, square: 1, diamond: 2, no: 0},
|
||||
fantasy: {fantasy1: 2, fantasy2: 2, fantasy3: 1, fantasy4: 1, fantasy5: 3},
|
||||
middleEarth: {noldor: 1, gondor: 1, easterling: 1, erebor: 1, ironHills: 1, urukHai: 1, moriaOrc: 1}
|
||||
}
|
||||
};
|
||||
|
||||
const generate = function(parent, kinship, dominion, type) {
|
||||
const generate = function (parent, kinship, dominion, type) {
|
||||
if (!parent || parent === "custom") {
|
||||
parent = null;
|
||||
kinship = 0;
|
||||
dominion = 0;
|
||||
}
|
||||
let usedPattern = null, usedTinctures = [];
|
||||
let usedPattern = null,
|
||||
usedTinctures = [];
|
||||
|
||||
const t1 = P(kinship) ? parent.t1 : getTincture("field");
|
||||
if (t1.includes("-")) usedPattern = t1;
|
||||
const coa = {t1};
|
||||
|
||||
let charge = P(usedPattern ? .5 : .93) ? true : false; // 80% for charge
|
||||
const linedOrdinary = charge && P(.3) || P(.5) ? parent?.ordinaries && P(kinship) ? parent.ordinaries[0].ordinary : rw(ordinaries.lined) : null;
|
||||
const ordinary = !charge && P(.65) || P(.3) ? linedOrdinary ? linedOrdinary : rw(ordinaries.straight) : null; // 36% for ordinary
|
||||
let charge = P(usedPattern ? 0.5 : 0.93) ? true : false; // 80% for charge
|
||||
const linedOrdinary = (charge && P(0.3)) || P(0.5) ? (parent?.ordinaries && P(kinship) ? parent.ordinaries[0].ordinary : rw(ordinaries.lined)) : null;
|
||||
const ordinary = (!charge && P(0.65)) || P(0.3) ? (linedOrdinary ? linedOrdinary : rw(ordinaries.straight)) : null; // 36% for ordinary
|
||||
const rareDivided = ["chief", "terrace", "chevron", "quarter", "flaunches"].includes(ordinary);
|
||||
const divisioned = rareDivided ? P(.03) : charge && ordinary ? P(.03) : charge ? P(.3) : ordinary ? P(.7) : P(.995); // 33% for division
|
||||
const division = divisioned ? parent?.division && P(kinship - .1) ? parent.division.division : rw(divisions.variants) : null;
|
||||
if (charge) charge =
|
||||
parent?.charges && P(kinship - .1) ? parent.charges[0].charge :
|
||||
type && type !== "Generic" && P(.2) ? rw(charges[type]) :
|
||||
selectCharge();
|
||||
const divisioned = rareDivided ? P(0.03) : charge && ordinary ? P(0.03) : charge ? P(0.3) : ordinary ? P(0.7) : P(0.995); // 33% for division
|
||||
const division = divisioned ? (parent?.division && P(kinship - 0.1) ? parent.division.division : rw(divisions.variants)) : null;
|
||||
if (charge) charge = parent?.charges && P(kinship - 0.1) ? parent.charges[0].charge : type && type !== "Generic" && P(0.2) ? rw(charges[type]) : selectCharge();
|
||||
|
||||
if (division) {
|
||||
const t = getTincture("division", usedTinctures, P(.98) ? coa.t1 : null);
|
||||
const t = getTincture("division", usedTinctures, P(0.98) ? coa.t1 : null);
|
||||
coa.division = {division, t};
|
||||
if (divisions[division]) coa.division.line = usedPattern || (ordinary && P(.7)) ? "straight" : rw(divisions[division]);
|
||||
if (divisions[division]) coa.division.line = usedPattern || (ordinary && P(0.7)) ? "straight" : rw(divisions[division]);
|
||||
}
|
||||
|
||||
if (ordinary) {
|
||||
coa.ordinaries = [{ordinary, t: getTincture("charge", usedTinctures, coa.t1)}];
|
||||
if (linedOrdinary) coa.ordinaries[0].line = usedPattern || (division && P(.7)) ? "straight" : rw(lines);
|
||||
if (division && !charge && !usedPattern && P(.5) && ordinary !== "bordure" && ordinary !== "orle") {
|
||||
if (P(.8)) coa.ordinaries[0].divided = "counter"; // 40%
|
||||
else if (P(.6)) coa.ordinaries[0].divided = "field"; // 6%
|
||||
if (linedOrdinary) coa.ordinaries[0].line = usedPattern || (division && P(0.7)) ? "straight" : rw(lines);
|
||||
if (division && !charge && !usedPattern && P(0.5) && ordinary !== "bordure" && ordinary !== "orle") {
|
||||
if (P(0.8)) coa.ordinaries[0].divided = "counter";
|
||||
// 40%
|
||||
else if (P(0.6)) coa.ordinaries[0].divided = "field";
|
||||
// 6%
|
||||
else coa.ordinaries[0].divided = "division"; // 4%
|
||||
}
|
||||
}
|
||||
|
||||
if (charge) {
|
||||
let p = "e", t = "gules";
|
||||
let p = "e",
|
||||
t = "gules";
|
||||
const ordinaryT = coa.ordinaries ? coa.ordinaries[0].t : null;
|
||||
if (positions.ordinariesOn[ordinary] && P(.8)) {
|
||||
if (positions.ordinariesOn[ordinary] && P(0.8)) {
|
||||
// place charge over ordinary (use tincture of field type)
|
||||
p = rw(positions.ordinariesOn[ordinary]);
|
||||
while (charges.natural[charge] === ordinaryT) charge = selectCharge();
|
||||
t = !usedPattern && P(.3) ? coa.t1 : getTincture("charge", [], ordinaryT);
|
||||
} else if (positions.ordinariesOff[ordinary] && P(.95)) {
|
||||
t = !usedPattern && P(0.3) ? coa.t1 : getTincture("charge", [], ordinaryT);
|
||||
} else if (positions.ordinariesOff[ordinary] && P(0.95)) {
|
||||
// place charge out of ordinary (use tincture of ordinary type)
|
||||
p = rw(positions.ordinariesOff[ordinary]);
|
||||
while (charges.natural[charge] === coa.t1) charge = selectCharge();
|
||||
t = !usedPattern && P(.3) ? ordinaryT : getTincture("charge", usedTinctures, coa.t1);
|
||||
t = !usedPattern && P(0.3) ? ordinaryT : getTincture("charge", usedTinctures, coa.t1);
|
||||
} else if (positions.divisions[division]) {
|
||||
// place charge in fields made by division
|
||||
p = rw(positions.divisions[division]);
|
||||
|
|
@ -289,43 +543,41 @@
|
|||
if (charges.natural[charge]) t = charges.natural[charge]; // natural tincture
|
||||
coa.charges = [{charge, t, p}];
|
||||
|
||||
if (p === "ABCDEFGHIKL" && P(.95)) {
|
||||
if (p === "ABCDEFGHIKL" && P(0.95)) {
|
||||
// add central charge if charge is in bordure
|
||||
coa.charges[0].charge = rw(charges.conventional);
|
||||
const charge = selectCharge(charges.single);
|
||||
const t = getTincture("charge", usedTinctures, coa.t1);
|
||||
coa.charges.push({charge, t, p: "e"});
|
||||
} else if (P(.8) && charge === "inescutcheon") {
|
||||
} else if (P(0.8) && charge === "inescutcheon") {
|
||||
// add charge to inescutcheon
|
||||
const charge = selectCharge(charges.types);
|
||||
const t2 = getTincture("charge", [], t);
|
||||
coa.charges.push({charge, t: t2, p, size:.5});
|
||||
coa.charges.push({charge, t: t2, p, size: 0.5});
|
||||
} else if (division && !ordinary) {
|
||||
const allowCounter = !usedPattern && (!coa.line || coa.line === "straight");
|
||||
|
||||
// dimidiation: second charge at division basic positons
|
||||
if (P(.3) && ["perPale", "perFess"].includes(division) && coa.line === "straight") {
|
||||
if (P(0.3) && ["perPale", "perFess"].includes(division) && coa.line === "straight") {
|
||||
coa.charges[0].divided = "field";
|
||||
if (P(.95)) {
|
||||
const p2 = p === "e" || P(.5) ? "e" : rw(positions.divisions[division]);
|
||||
if (P(0.95)) {
|
||||
const p2 = p === "e" || P(0.5) ? "e" : rw(positions.divisions[division]);
|
||||
const charge = selectCharge(charges.single);
|
||||
const t = getTincture("charge", usedTinctures, coa.division.t);
|
||||
coa.charges.push({charge, t, p: p2, divided: "division"});
|
||||
}
|
||||
}
|
||||
else if (allowCounter && P(.4)) coa.charges[0].divided = "counter"; // counterchanged, 40%
|
||||
else if (["perPale", "perFess", "perBend", "perBendSinister"].includes(division) && P(.8)) { // place 2 charges in division standard positions
|
||||
const [p1, p2] = division === "perPale" ? ["p", "q"] :
|
||||
division === "perFess" ? ["k", "n"] :
|
||||
division === "perBend" ? ["l", "m"] :
|
||||
["j", "o"]; // perBendSinister
|
||||
} else if (allowCounter && P(0.4)) coa.charges[0].divided = "counter";
|
||||
// counterchanged, 40%
|
||||
else if (["perPale", "perFess", "perBend", "perBendSinister"].includes(division) && P(0.8)) {
|
||||
// place 2 charges in division standard positions
|
||||
const [p1, p2] = division === "perPale" ? ["p", "q"] : division === "perFess" ? ["k", "n"] : division === "perBend" ? ["l", "m"] : ["j", "o"]; // perBendSinister
|
||||
coa.charges[0].p = p1;
|
||||
|
||||
const charge = selectCharge(charges.single);
|
||||
const t = getTincture("charge", usedTinctures, coa.division.t);
|
||||
coa.charges.push({charge, t, p: p2});
|
||||
}
|
||||
else if (["perCross", "perSaltire"].includes(division) && P(.5)) { // place 4 charges in division standard positions
|
||||
} else if (["perCross", "perSaltire"].includes(division) && P(0.5)) {
|
||||
// place 4 charges in division standard positions
|
||||
const [p1, p2, p3, p4] = division === "perCross" ? ["j", "l", "m", "o"] : ["b", "d", "f", "h"];
|
||||
coa.charges[0].p = p1;
|
||||
|
||||
|
|
@ -338,8 +590,7 @@
|
|||
const c4 = selectCharge(charges.single);
|
||||
const t4 = getTincture("charge", [], coa.t1);
|
||||
coa.charges.push({charge: c2, t: t2, p: p2}, {charge: c3, t: t3, p: p3}, {charge: c4, t: t4, p: p4});
|
||||
}
|
||||
else if (allowCounter && p.length > 1) coa.charges[0].divided = "counter"; // counterchanged, 40%
|
||||
} else if (allowCounter && p.length > 1) coa.charges[0].divided = "counter"; // counterchanged, 40%
|
||||
}
|
||||
|
||||
coa.charges.forEach(c => defineChargeAttributes(c));
|
||||
|
|
@ -351,8 +602,8 @@
|
|||
c.p = [...new Set(c.p)].join("");
|
||||
|
||||
// define orientation
|
||||
if (P(.02) && charges.sinister.includes(c.charge)) c.sinister = 1;
|
||||
if (P(.02) && charges.reversed.includes(c.charge)) c.reversed = 1;
|
||||
if (P(0.02) && charges.sinister.includes(c.charge)) c.sinister = 1;
|
||||
if (P(0.02) && charges.reversed.includes(c.charge)) c.reversed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -380,24 +631,26 @@
|
|||
if (!coa.charges) coa.charges = [];
|
||||
coa.charges.push({charge, t: t2, p: "y", size: 0.5});
|
||||
|
||||
coa.ordinaries ? coa.ordinaries.push(canton) : coa.ordinaries = [canton];
|
||||
coa.ordinaries ? coa.ordinaries.push(canton) : (coa.ordinaries = [canton]);
|
||||
}
|
||||
|
||||
function selectCharge(set) {
|
||||
const type = set ? rw(set) : ordinary || divisioned ? rw(charges.types): rw(charges.single);
|
||||
const type = set ? rw(set) : ordinary || divisioned ? rw(charges.types) : rw(charges.single);
|
||||
return type === "inescutcheon" ? "inescutcheon" : rw(charges[type]);
|
||||
}
|
||||
|
||||
// select tincture: element type (field, division, charge), used field tinctures, field type to follow RoT
|
||||
function getTincture(element, fields = [], RoT) {
|
||||
const base = RoT ? RoT.includes("-") ? RoT.split("-")[1] : RoT : null;
|
||||
const base = RoT ? (RoT.includes("-") ? RoT.split("-")[1] : RoT) : null;
|
||||
|
||||
let type = rw(tinctures[element]); // metals, colours, stains, patterns
|
||||
if (RoT && type !== "patterns") type = getType(base) === "metals" ? "colours" : "metals"; // follow RoT
|
||||
if (type === "metals" && fields.includes("or") && fields.includes("argent")) type = "colours"; // exclude metals overuse
|
||||
let tincture = rw(tinctures[type]);
|
||||
|
||||
while (tincture === base || fields.includes(tincture)) {tincture = rw(tinctures[type]);} // follow RoT
|
||||
while (tincture === base || fields.includes(tincture)) {
|
||||
tincture = rw(tinctures[type]);
|
||||
} // follow RoT
|
||||
|
||||
if (type !== "patterns" && element !== "charge") usedTinctures.push(tincture); // add field tincture
|
||||
|
||||
|
|
@ -425,39 +678,60 @@
|
|||
if (Object.keys(tinctures.stains).includes(tincture)) return "stains";
|
||||
else return "pattern";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function definePattern(pattern, element, size = "") {
|
||||
let t1 = null, t2 = null;
|
||||
if (P(.1)) size = "-small";
|
||||
else if (P(.1)) size = "-smaller";
|
||||
else if (P(.01)) size = "-big";
|
||||
else if (P(.005)) size = "-smallest";
|
||||
let t1 = null,
|
||||
t2 = null;
|
||||
if (P(0.1)) size = "-small";
|
||||
else if (P(0.1)) size = "-smaller";
|
||||
else if (P(0.01)) size = "-big";
|
||||
else if (P(0.005)) size = "-smallest";
|
||||
|
||||
// apply standard tinctures
|
||||
if (P(.5) && ["vair", "vairInPale", "vairEnPointe"].includes(pattern)) {t1 = "azure"; t2 = "argent";}
|
||||
else if (P(.8) && pattern === "ermine") {t1 = "argent"; t2 = "sable";}
|
||||
else if (pattern === "pappellony") {
|
||||
if (P(.2)) {t1 = "gules"; t2 = "or";}
|
||||
else if (P(.2)) {t1 = "argent"; t2 = "sable";}
|
||||
else if (P(.2)) {t1 = "azure"; t2 = "argent";}
|
||||
}
|
||||
else if (pattern === "masoned") {
|
||||
if (P(.3)) {t1 = "gules"; t2 = "argent";}
|
||||
else if (P(.3)) {t1 = "argent"; t2 = "sable";}
|
||||
else if (P(.1)) {t1 = "or"; t2 = "sable";}
|
||||
}
|
||||
else if (pattern === "fretty") {
|
||||
if (t2 === "sable" || P(.35)) {t1 = "argent"; t2 = "gules";}
|
||||
else if (P(.25)) {t1 = "sable"; t2 = "or";}
|
||||
else if (P(.15)) {t1 = "gules"; t2 = "argent";}
|
||||
}
|
||||
else if (pattern === "semy") pattern += "_of_" + selectCharge(charges.semy);
|
||||
|
||||
if (P(0.5) && ["vair", "vairInPale", "vairEnPointe"].includes(pattern)) {
|
||||
t1 = "azure";
|
||||
t2 = "argent";
|
||||
} else if (P(0.8) && pattern === "ermine") {
|
||||
t1 = "argent";
|
||||
t2 = "sable";
|
||||
} else if (pattern === "pappellony") {
|
||||
if (P(0.2)) {
|
||||
t1 = "gules";
|
||||
t2 = "or";
|
||||
} else if (P(0.2)) {
|
||||
t1 = "argent";
|
||||
t2 = "sable";
|
||||
} else if (P(0.2)) {
|
||||
t1 = "azure";
|
||||
t2 = "argent";
|
||||
}
|
||||
} else if (pattern === "masoned") {
|
||||
if (P(0.3)) {
|
||||
t1 = "gules";
|
||||
t2 = "argent";
|
||||
} else if (P(0.3)) {
|
||||
t1 = "argent";
|
||||
t2 = "sable";
|
||||
} else if (P(0.1)) {
|
||||
t1 = "or";
|
||||
t2 = "sable";
|
||||
}
|
||||
} else if (pattern === "fretty") {
|
||||
if (t2 === "sable" || P(0.35)) {
|
||||
t1 = "argent";
|
||||
t2 = "gules";
|
||||
} else if (P(0.25)) {
|
||||
t1 = "sable";
|
||||
t2 = "or";
|
||||
} else if (P(0.15)) {
|
||||
t1 = "gules";
|
||||
t2 = "argent";
|
||||
}
|
||||
} else if (pattern === "semy") pattern += "_of_" + selectCharge(charges.semy);
|
||||
|
||||
if (!t1 || !t2) {
|
||||
const startWithMetal = P(.7);
|
||||
const startWithMetal = P(0.7);
|
||||
t1 = startWithMetal ? rw(tinctures.metals) : rw(tinctures.colours);
|
||||
t2 = startWithMetal ? rw(tinctures.colours) : rw(tinctures.metals);
|
||||
}
|
||||
|
|
@ -474,28 +748,30 @@
|
|||
|
||||
function replaceTincture(t, n) {
|
||||
const type = getType(t);
|
||||
while (!n || n === t) {n = rw(tinctures[type]);}
|
||||
while (!n || n === t) {
|
||||
n = rw(tinctures[type]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
function getSize(p, o = null, d = null) {
|
||||
if (p === "e" && (o === "bordure" || o === "orle")) return 1.1;
|
||||
if (p === "e") return 1.5;
|
||||
if (p === "jln" || p === "jlh") return .7;
|
||||
if (p === "abcpqh" || p === "ez" || p === "be") return .5;
|
||||
if (["a", "b", "c", "d", "f", "g", "h", "i", "bh", "df"].includes(p)) return .5;
|
||||
if (["j", "l", "m", "o", "jlmo"].includes(p) && d === "perCross") return .6;
|
||||
if (p.length > 10) return .18; // >10 (bordure)
|
||||
if (p.length > 7) return .3; // 8, 9, 10
|
||||
if (p.length > 4) return .4; // 5, 6, 7
|
||||
if (p.length > 2) return .5; // 3, 4
|
||||
return .7; // 1, 2
|
||||
if (p === "jln" || p === "jlh") return 0.7;
|
||||
if (p === "abcpqh" || p === "ez" || p === "be") return 0.5;
|
||||
if (["a", "b", "c", "d", "f", "g", "h", "i", "bh", "df"].includes(p)) return 0.5;
|
||||
if (["j", "l", "m", "o", "jlmo"].includes(p) && d === "perCross") return 0.6;
|
||||
if (p.length > 10) return 0.18; // >10 (bordure)
|
||||
if (p.length > 7) return 0.3; // 8, 9, 10
|
||||
if (p.length > 4) return 0.4; // 5, 6, 7
|
||||
if (p.length > 2) return 0.5; // 3, 4
|
||||
return 0.7; // 1, 2
|
||||
}
|
||||
|
||||
return coa;
|
||||
}
|
||||
};
|
||||
|
||||
const getShield = function(culture, state) {
|
||||
const getShield = function (culture, state) {
|
||||
const emblemShape = document.getElementById("emblemShape");
|
||||
const shapeGroup = emblemShape.selectedOptions[0]?.parentNode.label || "Diversiform";
|
||||
if (shapeGroup !== "Diversiform") return emblemShape.value;
|
||||
|
|
@ -504,11 +780,10 @@
|
|||
if (pack.cultures[culture].shield) return pack.cultures[culture].shield;
|
||||
console.error("Shield shape is not defined on culture level", pack.cultures[culture]);
|
||||
return "heater";
|
||||
}
|
||||
};
|
||||
|
||||
const toString = coa => JSON.stringify(coa).replaceAll("#", "%23");
|
||||
const copy = coa => JSON.parse(JSON.stringify(coa));
|
||||
|
||||
return {generate, toString, copy, getShield, shields};
|
||||
|
||||
})));
|
||||
})();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,10 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Cultures = factory());
|
||||
}(this, (function () {'use strict';
|
||||
"use strict";
|
||||
|
||||
window.Cultures = (function () {
|
||||
let cells;
|
||||
|
||||
const generate = function() {
|
||||
TIME && console.time('generateCultures');
|
||||
const generate = function () {
|
||||
TIME && console.time("generateCultures");
|
||||
cells = pack.cells;
|
||||
cells.culture = new Uint16Array(cells.i.length); // cell cultures
|
||||
let count = Math.min(+culturesInput.value, +culturesSet.selectedOptions[0].dataset.max);
|
||||
|
|
@ -17,13 +14,19 @@
|
|||
count = Math.floor(populated.length / 50);
|
||||
if (!count) {
|
||||
WARN && console.warn(`There are no populated cells. Cannot generate cultures`);
|
||||
pack.cultures = [{name:"Wildlands", i:0, base:1, shield:"round"}];
|
||||
pack.cultures = [{name: "Wildlands", i: 0, base: 1, shield: "round"}];
|
||||
alertMessage.innerHTML = `
|
||||
The climate is harsh and people cannot live in this world.<br>
|
||||
No cultures, states and burgs will be created.<br>
|
||||
Please consider changing climate settings in the World Configurator`;
|
||||
$("#alert").dialog({resizable: false, title: "Extreme climate warning",
|
||||
buttons: {Ok: function() {$(this).dialog("close");}}
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
title: "Extreme climate warning",
|
||||
buttons: {
|
||||
Ok: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
|
|
@ -32,22 +35,28 @@
|
|||
There are only ${populated.length} populated cells and it's insufficient livable area.<br>
|
||||
Only ${count} out of ${culturesInput.value} requested cultures will be generated.<br>
|
||||
Please consider changing climate settings in the World Configurator`;
|
||||
$("#alert").dialog({resizable: false, title: "Extreme climate warning",
|
||||
buttons: {Ok: function() {$(this).dialog("close");}}
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
title: "Extreme climate warning",
|
||||
buttons: {
|
||||
Ok: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const cultures = pack.cultures = selectCultures(count);
|
||||
const cultures = (pack.cultures = selectCultures(count));
|
||||
const centers = d3.quadtree();
|
||||
const colors = getColors(count);
|
||||
const emblemShape = document.getElementById("emblemShape").value;
|
||||
|
||||
const codes = [];
|
||||
cultures.forEach(function(c, i) {
|
||||
const cell = c.center = placeCenter(c.sort ? c.sort : (i) => cells.s[i]);
|
||||
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;
|
||||
c.i = i + 1;
|
||||
delete c.odd;
|
||||
delete c.sort;
|
||||
c.color = colors[i];
|
||||
|
|
@ -56,20 +65,24 @@
|
|||
c.origin = 0;
|
||||
c.code = abbreviate(c.name, codes);
|
||||
codes.push(c.code);
|
||||
cells.culture[cell] = i+1;
|
||||
cells.culture[cell] = i + 1;
|
||||
if (emblemShape === "random") c.shield = getRandomShield();
|
||||
});
|
||||
|
||||
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);
|
||||
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 *= 0.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, shield:"round"});
|
||||
cultures.unshift({name: "Wildlands", i: 0, base: 1, origin: null, shield: "round"});
|
||||
|
||||
// make sure all bases exist in nameBases
|
||||
if (!nameBases.length) {
|
||||
|
|
@ -77,7 +90,7 @@
|
|||
nameBases = Names.getNameBases();
|
||||
}
|
||||
|
||||
cultures.forEach(c => c.base = c.base % nameBases.length);
|
||||
cultures.forEach(c => (c.base = c.base % nameBases.length));
|
||||
|
||||
function selectCultures(c) {
|
||||
let def = getDefault(c);
|
||||
|
|
@ -87,11 +100,11 @@
|
|||
const count = Math.min(c, def.length);
|
||||
const cultures = [];
|
||||
|
||||
for (let culture, rnd, i=0; cultures.length < count && i < 200; i++) {
|
||||
for (let culture, rnd, i = 0; cultures.length < count && i < 200; i++) {
|
||||
do {
|
||||
rnd = rand(def.length-1);
|
||||
rnd = rand(def.length - 1);
|
||||
culture = def[rnd];
|
||||
} while (!P(culture.odd))
|
||||
} while (!P(culture.odd));
|
||||
cultures.push(culture);
|
||||
def.splice(rnd, 1);
|
||||
}
|
||||
|
|
@ -100,31 +113,31 @@
|
|||
|
||||
// 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] < 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]]]; // 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 (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(0.1)) || (cells.harbor[i] === 1 && P(0.6)) || (pack.features[cells.f[i]].group === "isle" && P(0.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
|
||||
if (cells.t[i] > 2 && [3,7,8,9,10,12].includes(cells.biome[i])) 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";
|
||||
}
|
||||
|
||||
function defineCultureExpansionism(type) {
|
||||
let base = 1; // Generic
|
||||
if (type === "Lake") base = .8; else
|
||||
if (type === "Naval") base = 1.5; else
|
||||
if (type === "River") base = .9; else
|
||||
if (type === "Nomadic") base = 1.5; else
|
||||
if (type === "Hunting") base = .7; else
|
||||
if (type === "Highland") base = 1.2;
|
||||
return rn((Math.random() * powerInput.value / 2 + 1) * base, 1);
|
||||
if (type === "Lake") base = 0.8;
|
||||
else if (type === "Naval") base = 1.5;
|
||||
else if (type === "River") base = 0.9;
|
||||
else if (type === "Nomadic") base = 1.5;
|
||||
else if (type === "Hunting") base = 0.7;
|
||||
else if (type === "Highland") base = 1.2;
|
||||
return rn(((Math.random() * powerInput.value) / 2 + 1) * base, 1);
|
||||
}
|
||||
|
||||
TIME && console.timeEnd('generateCultures');
|
||||
}
|
||||
TIME && console.timeEnd("generateCultures");
|
||||
};
|
||||
|
||||
const add = function(center) {
|
||||
const add = function (center) {
|
||||
const defaultCultures = getDefault();
|
||||
let culture, base, name;
|
||||
|
||||
|
|
@ -139,7 +152,10 @@
|
|||
name = Names.getCulture(culture, 5, 8, "");
|
||||
base = pack.cultures[culture].base;
|
||||
}
|
||||
const code = abbreviate(name, pack.cultures.map(c => c.code));
|
||||
const code = abbreviate(
|
||||
name,
|
||||
pack.cultures.map(c => c.code)
|
||||
);
|
||||
const i = pack.cultures.length;
|
||||
const color = d3.color(d3.scaleSequential(d3.interpolateRainbow)(Math.random())).hex();
|
||||
|
||||
|
|
@ -148,220 +164,231 @@
|
|||
const emblemShape = document.getElementById("emblemShape").value;
|
||||
if (emblemShape === "random") shield = getRandomShield();
|
||||
|
||||
pack.cultures.push({name, color, base, center, i, expansionism:1, type:"Generic", cells:0, area:0, rural:0, urban:0, origin:0, code, shield});
|
||||
}
|
||||
pack.cultures.push({name, color, base, center, i, expansionism: 1, type: "Generic", cells: 0, area: 0, rural: 0, urban: 0, origin: 0, code, shield});
|
||||
};
|
||||
|
||||
const getDefault = function(count) {
|
||||
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
|
||||
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
|
||||
|
||||
if (culturesSet.value === "european") {
|
||||
return [
|
||||
{name:"Shwazen", base:0, odd:1, sort: i => n(i) / td(i, 10) / bd(i, [6, 8]), shield:"swiss"},
|
||||
{name:"Angshire", base:1, odd:1, sort: i => n(i) / td(i, 10) / sf(i), shield:"wedged"},
|
||||
{name:"Luari", base:2, odd:1, sort: i => n(i) / td(i, 12) / bd(i, [6, 8]), shield:"french"},
|
||||
{name:"Tallian", base:3, odd:1, sort: i => n(i) / td(i, 15), shield:"horsehead"},
|
||||
{name:"Astellian", base:4, odd:1, sort: i => n(i) / td(i, 16), shield:"spanish"},
|
||||
{name:"Slovan", base:5, odd:1, sort: i => n(i) / td(i, 6) * t[i], shield:"polish"},
|
||||
{name:"Norse", base:6, odd:1, sort: i => n(i) / td(i, 5), shield:"heater"},
|
||||
{name:"Elladan", base:7, odd:1, sort: i => n(i) / td(i, 18) * h[i], shield:"boeotian"},
|
||||
{name:"Romian", base:8, odd:.2, sort: i => n(i) / td(i, 15) / t[i], shield:"roman"},
|
||||
{name:"Soumi", base:9, odd:1, sort: i => n(i) / td(i, 5) / bd(i, [9]) * t[i], shield:"pavise"},
|
||||
{name:"Portuzian", base:13, odd:1, sort: i => n(i) / td(i, 17) / sf(i), shield:"renaissance"},
|
||||
{name:"Vengrian", base: 15, odd:1, sort: i => n(i) / td(i, 11) / bd(i, [4]) * t[i], shield:"horsehead2"},
|
||||
{name:"Turchian", base: 16, odd:.05, sort: i => n(i) / td(i, 14), shield:"round"},
|
||||
{name:"Euskati", base: 20, odd:.05, sort: i => n(i) / td(i, 15) * h[i], shield:"oldFrench"},
|
||||
{name:"Keltan", base: 22, odd:.05, sort: i => n(i) / td(i, 11) / bd(i, [6, 8]) * t[i], shield:"oval"}
|
||||
{name: "Shwazen", base: 0, odd: 1, sort: i => n(i) / td(i, 10) / bd(i, [6, 8]), shield: "swiss"},
|
||||
{name: "Angshire", base: 1, odd: 1, sort: i => n(i) / td(i, 10) / sf(i), shield: "wedged"},
|
||||
{name: "Luari", base: 2, odd: 1, sort: i => n(i) / td(i, 12) / bd(i, [6, 8]), shield: "french"},
|
||||
{name: "Tallian", base: 3, odd: 1, sort: i => n(i) / td(i, 15), shield: "horsehead"},
|
||||
{name: "Astellian", base: 4, odd: 1, sort: i => n(i) / td(i, 16), shield: "spanish"},
|
||||
{name: "Slovan", base: 5, odd: 1, sort: i => (n(i) / td(i, 6)) * t[i], shield: "polish"},
|
||||
{name: "Norse", base: 6, odd: 1, sort: i => n(i) / td(i, 5), shield: "heater"},
|
||||
{name: "Elladan", base: 7, odd: 1, sort: i => (n(i) / td(i, 18)) * h[i], shield: "boeotian"},
|
||||
{name: "Romian", base: 8, odd: 0.2, sort: i => n(i) / td(i, 15) / t[i], shield: "roman"},
|
||||
{name: "Soumi", base: 9, odd: 1, sort: i => (n(i) / td(i, 5) / bd(i, [9])) * t[i], shield: "pavise"},
|
||||
{name: "Portuzian", base: 13, odd: 1, sort: i => n(i) / td(i, 17) / sf(i), shield: "renaissance"},
|
||||
{name: "Vengrian", base: 15, odd: 1, sort: i => (n(i) / td(i, 11) / bd(i, [4])) * t[i], shield: "horsehead2"},
|
||||
{name: "Turchian", base: 16, odd: 0.05, sort: i => n(i) / td(i, 14), shield: "round"},
|
||||
{name: "Euskati", base: 20, odd: 0.05, sort: i => (n(i) / td(i, 15)) * h[i], shield: "oldFrench"},
|
||||
{name: "Keltan", base: 22, odd: 0.05, sort: i => (n(i) / td(i, 11) / bd(i, [6, 8])) * t[i], shield: "oval"}
|
||||
];
|
||||
}
|
||||
|
||||
if (culturesSet.value === "oriental") {
|
||||
return [
|
||||
{name:"Koryo", base:10, odd:1, sort: i => n(i) / td(i, 12) / t[i], shield:"round"},
|
||||
{name:"Hantzu", base:11, odd:1, sort: i => n(i) / td(i, 13), shield:"banner"},
|
||||
{name:"Yamoto", base:12, odd:1, sort: i => n(i) / td(i, 15) / t[i], shield:"round"},
|
||||
{name:"Turchian", base: 16, odd:1, sort: i => n(i) / td(i, 12), shield:"round"},
|
||||
{name:"Berberan", base: 17, odd:.2, sort: i => n(i) / td(i, 19) / bd(i, [1, 2, 3], 7) * t[i], shield:"oval"},
|
||||
{name:"Eurabic", base: 18, odd:1, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i], shield:"oval"},
|
||||
{name:"Efratic", base: 23, odd:.1, sort: i => n(i) / td(i, 22) * t[i], shield:"round"},
|
||||
{name:"Tehrani", base: 24, odd:1, sort: i => n(i) / td(i, 18) * h[i], shield:"round"},
|
||||
{name:"Maui", base: 25, odd:.2, sort: i => n(i) / td(i, 24) / sf(i) / t[i], shield:"vesicaPiscis"},
|
||||
{name:"Carnatic", base: 26, odd:.5, sort: i => n(i) / td(i, 26), shield:"round"},
|
||||
{name:"Vietic", base: 29, odd:.8, sort: i => n(i) / td(i, 25) / bd(i, [7], 7) / t[i], shield:"banner"},
|
||||
{name:"Guantzu", base:30, odd:.5, sort: i => n(i) / td(i, 17), shield:"banner"},
|
||||
{name:"Ulus", base:31, odd:1, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i], shield:"banner"}
|
||||
{name: "Koryo", base: 10, odd: 1, sort: i => n(i) / td(i, 12) / t[i], shield: "round"},
|
||||
{name: "Hantzu", base: 11, odd: 1, sort: i => n(i) / td(i, 13), shield: "banner"},
|
||||
{name: "Yamoto", base: 12, odd: 1, sort: i => n(i) / td(i, 15) / t[i], shield: "round"},
|
||||
{name: "Turchian", base: 16, odd: 1, sort: i => n(i) / td(i, 12), shield: "round"},
|
||||
{name: "Berberan", base: 17, odd: 0.2, sort: i => (n(i) / td(i, 19) / bd(i, [1, 2, 3], 7)) * t[i], shield: "oval"},
|
||||
{name: "Eurabic", base: 18, odd: 1, sort: i => (n(i) / td(i, 26) / bd(i, [1, 2], 7)) * t[i], shield: "oval"},
|
||||
{name: "Efratic", base: 23, odd: 0.1, sort: i => (n(i) / td(i, 22)) * t[i], shield: "round"},
|
||||
{name: "Tehrani", base: 24, odd: 1, sort: i => (n(i) / td(i, 18)) * h[i], shield: "round"},
|
||||
{name: "Maui", base: 25, odd: 0.2, sort: i => n(i) / td(i, 24) / sf(i) / t[i], shield: "vesicaPiscis"},
|
||||
{name: "Carnatic", base: 26, odd: 0.5, sort: i => n(i) / td(i, 26), shield: "round"},
|
||||
{name: "Vietic", base: 29, odd: 0.8, sort: i => n(i) / td(i, 25) / bd(i, [7], 7) / t[i], shield: "banner"},
|
||||
{name: "Guantzu", base: 30, odd: 0.5, sort: i => n(i) / td(i, 17), shield: "banner"},
|
||||
{name: "Ulus", base: 31, odd: 1, sort: i => (n(i) / td(i, 5) / bd(i, [2, 4, 10], 7)) * t[i], shield: "banner"}
|
||||
];
|
||||
}
|
||||
|
||||
if (culturesSet.value === "english") {
|
||||
const getName = () => Names.getBase(1, 5, 9, "", 0);
|
||||
return [
|
||||
{name:getName(), base:1, odd:1, shield:"heater"},
|
||||
{name:getName(), base:1, odd:1, shield:"wedged"},
|
||||
{name:getName(), base:1, odd:1, shield:"swiss"},
|
||||
{name:getName(), base:1, odd:1, shield:"oldFrench"},
|
||||
{name:getName(), base:1, odd:1, shield:"swiss"},
|
||||
{name:getName(), base:1, odd:1, shield:"spanish"},
|
||||
{name:getName(), base:1, odd:1, shield:"hessen"},
|
||||
{name:getName(), base:1, odd:1, shield:"fantasy5"},
|
||||
{name:getName(), base:1, odd:1, shield:"fantasy4"},
|
||||
{name:getName(), base:1, odd:1, shield:"fantasy1"}
|
||||
{name: getName(), base: 1, odd: 1, shield: "heater"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "wedged"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "swiss"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "oldFrench"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "swiss"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "spanish"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "hessen"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "fantasy5"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "fantasy4"},
|
||||
{name: getName(), base: 1, odd: 1, shield: "fantasy1"}
|
||||
];
|
||||
}
|
||||
|
||||
if (culturesSet.value === "antique") {
|
||||
return [
|
||||
{name:"Roman", base:8, odd:1, sort: i => n(i) / td(i, 14) / t[i], shield:"roman"}, // Roman
|
||||
{name:"Roman", base:8, odd:1, sort: i => n(i) / td(i, 15) / sf(i), shield:"roman"}, // Roman
|
||||
{name:"Roman", base:8, odd:1, sort: i => n(i) / td(i, 16) / sf(i), shield:"roman"}, // Roman
|
||||
{name:"Roman", base:8, odd:1, sort: i => n(i) / td(i, 17) / t[i], shield:"roman"}, // Roman
|
||||
{name:"Hellenic", base:7, odd:1, sort: i => n(i) / td(i, 18) / sf(i) * h[i], shield:"boeotian"}, // Greek
|
||||
{name:"Hellenic", base:7, odd:1, sort: i => n(i) / td(i, 19) / sf(i) * h[i], shield:"boeotian"}, // Greek
|
||||
{name:"Macedonian", base:7, odd:.5, sort: i => n(i) / td(i, 12) * h[i], shield:"round"}, // Greek
|
||||
{name:"Celtic", base:22, odd:1, sort: i => n(i) / td(i, 11) ** .5 / bd(i, [6, 8]), shield:"round"},
|
||||
{name:"Germanic", base:0, odd:1, sort: i => n(i) / td(i, 10) ** .5 / bd(i, [6, 8]), shield:"round"},
|
||||
{name:"Persian", base:24, odd:.8, sort: i => n(i) / td(i, 18) * h[i], shield:"oval"}, // Iranian
|
||||
{name:"Scythian", base:24, odd:.5, sort: i => n(i) / td(i, 11) ** .5 / bd(i, [4]), shield:"round"}, // Iranian
|
||||
{name:"Cantabrian", base: 20, odd:.5, sort: i => n(i) / td(i, 16) * h[i], shield:"oval"}, // Basque
|
||||
{name:"Estian", base: 9, odd:.2, sort: i => n(i) / td(i, 5) * t[i], shield:"pavise"}, // Finnic
|
||||
{name:"Carthaginian", base: 17, odd:.3, sort: i => n(i) / td(i, 19) / sf(i), shield:"oval"}, // Berber
|
||||
{name:"Mesopotamian", base: 23, odd:.2, sort: i => n(i) / td(i, 22) / bd(i, [1, 2, 3]), shield:"oval"} // Mesopotamian
|
||||
{name: "Roman", base: 8, odd: 1, sort: i => n(i) / td(i, 14) / t[i], shield: "roman"}, // Roman
|
||||
{name: "Roman", base: 8, odd: 1, sort: i => n(i) / td(i, 15) / sf(i), shield: "roman"}, // Roman
|
||||
{name: "Roman", base: 8, odd: 1, sort: i => n(i) / td(i, 16) / sf(i), shield: "roman"}, // Roman
|
||||
{name: "Roman", base: 8, odd: 1, sort: i => n(i) / td(i, 17) / t[i], shield: "roman"}, // Roman
|
||||
{name: "Hellenic", base: 7, odd: 1, sort: i => (n(i) / td(i, 18) / sf(i)) * h[i], shield: "boeotian"}, // Greek
|
||||
{name: "Hellenic", base: 7, odd: 1, sort: i => (n(i) / td(i, 19) / sf(i)) * h[i], shield: "boeotian"}, // Greek
|
||||
{name: "Macedonian", base: 7, odd: 0.5, sort: i => (n(i) / td(i, 12)) * h[i], shield: "round"}, // Greek
|
||||
{name: "Celtic", base: 22, odd: 1, sort: i => n(i) / td(i, 11) ** 0.5 / bd(i, [6, 8]), shield: "round"},
|
||||
{name: "Germanic", base: 0, odd: 1, sort: i => n(i) / td(i, 10) ** 0.5 / bd(i, [6, 8]), shield: "round"},
|
||||
{name: "Persian", base: 24, odd: 0.8, sort: i => (n(i) / td(i, 18)) * h[i], shield: "oval"}, // Iranian
|
||||
{name: "Scythian", base: 24, odd: 0.5, sort: i => n(i) / td(i, 11) ** 0.5 / bd(i, [4]), shield: "round"}, // Iranian
|
||||
{name: "Cantabrian", base: 20, odd: 0.5, sort: i => (n(i) / td(i, 16)) * h[i], shield: "oval"}, // Basque
|
||||
{name: "Estian", base: 9, odd: 0.2, sort: i => (n(i) / td(i, 5)) * t[i], shield: "pavise"}, // Finnic
|
||||
{name: "Carthaginian", base: 17, odd: 0.3, sort: i => n(i) / td(i, 19) / sf(i), shield: "oval"}, // Berber
|
||||
{name: "Mesopotamian", base: 23, odd: 0.2, sort: i => n(i) / td(i, 22) / bd(i, [1, 2, 3]), shield: "oval"} // Mesopotamian
|
||||
];
|
||||
}
|
||||
|
||||
if (culturesSet.value === "highFantasy") {
|
||||
return [
|
||||
// fantasy races
|
||||
{name:"Quenian (Elfish)", base: 33, odd:1, sort: i => n(i) / bd(i, [6,7,8,9], 10) * t[i], shield:"gondor"}, // Elves
|
||||
{name:"Eldar (Elfish)", base: 33, odd:1, sort: i => n(i) / bd(i, [6,7,8,9], 10) * t[i], shield:"noldor"}, // Elves
|
||||
{name:"Trow (Dark Elfish)", base: 34, odd:.9, sort: i => n(i) / bd(i, [7,8,9,12], 10) * t[i], shield:"hessen"}, // Dark Elves
|
||||
{name:"Lothian (Dark Elfish)", base: 34, odd:.3, sort: i => n(i) / bd(i, [7,8,9,12], 10) * t[i], shield:"wedged"}, // Dark Elves
|
||||
{name:"Dunirr (Dwarven)", base: 35, odd:1, sort: i => n(i) + h[i], shield:"ironHills"}, // Dwarfs
|
||||
{name:"Khazadur (Dwarven)", base: 35, odd:1, sort: i => n(i) + h[i], shield:"erebor"}, // Dwarfs
|
||||
{name:"Kobold (Goblin)", base: 36, odd:1, sort: i => t[i] - s[i], shield:"moriaOrc"}, // Goblin
|
||||
{name:"Uruk (Orkish)", base: 37, odd:1, sort: i => h[i] * t[i], shield:"urukHai"}, // Orc
|
||||
{name:"Ugluk (Orkish)", base: 37, odd:.5, sort: i => h[i] * t[i] / bd(i, [1,2,10,11]), shield:"moriaOrc"}, // Orc
|
||||
{name:"Yotunn (Giants)", base: 38, odd:.7, sort: i => td(i, -10), shield:"pavise"}, // Giant
|
||||
{name:"Rake (Drakonic)", base: 39, odd:.7, sort: i => -s[i], shield:"fantasy2"}, // Draconic
|
||||
{name:"Arago (Arachnid)", base: 40, odd:.7, sort: i => t[i] - s[i], shield:"horsehead2"}, // Arachnid
|
||||
{name:"Aj'Snaga (Serpents)", base: 41, odd:.7, sort: i => n(i) / bd(i, [12], 10), shield:"fantasy1"}, // Serpents
|
||||
{name: "Quenian (Elfish)", base: 33, odd: 1, sort: i => (n(i) / bd(i, [6, 7, 8, 9], 10)) * t[i], shield: "gondor"}, // Elves
|
||||
{name: "Eldar (Elfish)", base: 33, odd: 1, sort: i => (n(i) / bd(i, [6, 7, 8, 9], 10)) * t[i], shield: "noldor"}, // Elves
|
||||
{name: "Trow (Dark Elfish)", base: 34, odd: 0.9, sort: i => (n(i) / bd(i, [7, 8, 9, 12], 10)) * t[i], shield: "hessen"}, // Dark Elves
|
||||
{name: "Lothian (Dark Elfish)", base: 34, odd: 0.3, sort: i => (n(i) / bd(i, [7, 8, 9, 12], 10)) * t[i], shield: "wedged"}, // Dark Elves
|
||||
{name: "Dunirr (Dwarven)", base: 35, odd: 1, sort: i => n(i) + h[i], shield: "ironHills"}, // Dwarfs
|
||||
{name: "Khazadur (Dwarven)", base: 35, odd: 1, sort: i => n(i) + h[i], shield: "erebor"}, // Dwarfs
|
||||
{name: "Kobold (Goblin)", base: 36, odd: 1, sort: i => t[i] - s[i], shield: "moriaOrc"}, // Goblin
|
||||
{name: "Uruk (Orkish)", base: 37, odd: 1, sort: i => h[i] * t[i], shield: "urukHai"}, // Orc
|
||||
{name: "Ugluk (Orkish)", base: 37, odd: 0.5, sort: i => (h[i] * t[i]) / bd(i, [1, 2, 10, 11]), shield: "moriaOrc"}, // Orc
|
||||
{name: "Yotunn (Giants)", base: 38, odd: 0.7, sort: i => td(i, -10), shield: "pavise"}, // Giant
|
||||
{name: "Rake (Drakonic)", base: 39, odd: 0.7, sort: i => -s[i], shield: "fantasy2"}, // Draconic
|
||||
{name: "Arago (Arachnid)", base: 40, odd: 0.7, sort: i => t[i] - s[i], shield: "horsehead2"}, // Arachnid
|
||||
{name: "Aj'Snaga (Serpents)", base: 41, odd: 0.7, sort: i => n(i) / bd(i, [12], 10), shield: "fantasy1"}, // Serpents
|
||||
// fantasy human
|
||||
{name:"Anor (Human)", base:32, odd:1, sort: i => n(i) / td(i, 10), shield:"fantasy5"},
|
||||
{name:"Dail (Human)", base:32, odd:1, sort: i => n(i) / td(i, 13), shield:"roman"},
|
||||
{name:"Rohand (Human)", base:16, odd:1, sort: i => n(i) / td(i, 16), shield:"round"},
|
||||
{name:"Dulandir (Human)", base:31, odd:1, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i], shield:"easterling"},
|
||||
{name: "Anor (Human)", base: 32, odd: 1, sort: i => n(i) / td(i, 10), shield: "fantasy5"},
|
||||
{name: "Dail (Human)", base: 32, odd: 1, sort: i => n(i) / td(i, 13), shield: "roman"},
|
||||
{name: "Rohand (Human)", base: 16, odd: 1, sort: i => n(i) / td(i, 16), shield: "round"},
|
||||
{name: "Dulandir (Human)", base: 31, odd: 1, sort: i => (n(i) / td(i, 5) / bd(i, [2, 4, 10], 7)) * t[i], shield: "easterling"}
|
||||
];
|
||||
}
|
||||
|
||||
if (culturesSet.value === "darkFantasy") {
|
||||
return [
|
||||
// common real-world English
|
||||
{name:"Angshire", base:1, odd:1, sort: i => n(i) / td(i, 10) / sf(i), shield:"heater"},
|
||||
{name:"Enlandic", base:1, odd:1, sort: i => n(i) / td(i, 12), shield:"heater"},
|
||||
{name:"Westen", base:1, odd:1, sort: i => n(i) / td(i, 10), shield:"heater"},
|
||||
{name:"Nortumbic", base:1, odd:1, sort: i => n(i) / td(i, 7), shield:"heater"},
|
||||
{name:"Mercian", base:1, odd:1, sort: i => n(i) / td(i, 9), shield:"heater"},
|
||||
{name:"Kentian", base:1, odd:1, sort: i => n(i) / td(i, 12), shield:"heater"},
|
||||
{name: "Angshire", base: 1, odd: 1, sort: i => n(i) / td(i, 10) / sf(i), shield: "heater"},
|
||||
{name: "Enlandic", base: 1, odd: 1, sort: i => n(i) / td(i, 12), shield: "heater"},
|
||||
{name: "Westen", base: 1, odd: 1, sort: i => n(i) / td(i, 10), shield: "heater"},
|
||||
{name: "Nortumbic", base: 1, odd: 1, sort: i => n(i) / td(i, 7), shield: "heater"},
|
||||
{name: "Mercian", base: 1, odd: 1, sort: i => n(i) / td(i, 9), shield: "heater"},
|
||||
{name: "Kentian", base: 1, odd: 1, sort: i => n(i) / td(i, 12), shield: "heater"},
|
||||
// rare real-world western
|
||||
{name:"Norse", base:6, odd:.7, sort: i => n(i) / td(i, 5) / sf(i), shield:"oldFrench"},
|
||||
{name:"Schwarzen", base:0, odd:.3, sort: i => n(i) / td(i, 10) / bd(i, [6, 8]), shield:"gonfalon"},
|
||||
{name:"Luarian", base:2, odd:.3, sort: i => n(i) / td(i, 12) / bd(i, [6, 8]), shield:"oldFrench"},
|
||||
{name:"Hetallian", base:3, odd:.3, sort: i => n(i) / td(i, 15), shield:"oval"},
|
||||
{name:"Astellian", base:4, odd:.3, sort: i => n(i) / td(i, 16), shield:"spanish"},
|
||||
{name: "Norse", base: 6, odd: 0.7, sort: i => n(i) / td(i, 5) / sf(i), shield: "oldFrench"},
|
||||
{name: "Schwarzen", base: 0, odd: 0.3, sort: i => n(i) / td(i, 10) / bd(i, [6, 8]), shield: "gonfalon"},
|
||||
{name: "Luarian", base: 2, odd: 0.3, sort: i => n(i) / td(i, 12) / bd(i, [6, 8]), shield: "oldFrench"},
|
||||
{name: "Hetallian", base: 3, odd: 0.3, sort: i => n(i) / td(i, 15), shield: "oval"},
|
||||
{name: "Astellian", base: 4, odd: 0.3, sort: i => n(i) / td(i, 16), shield: "spanish"},
|
||||
// rare real-world exotic
|
||||
{name:"Kiswaili", base:28, odd:.05, sort: i => n(i) / td(i, 29) / bd(i, [1, 3, 5, 7]), shield:"vesicaPiscis"},
|
||||
{name:"Yoruba", base:21, odd:.05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7]), shield:"vesicaPiscis"},
|
||||
{name:"Koryo", base:10, odd:.05, sort: i => n(i) / td(i, 12) / t[i], shield:"round"},
|
||||
{name:"Hantzu", base:11, odd:.05, sort: i => n(i) / td(i, 13), shield:"banner"},
|
||||
{name:"Yamoto", base:12, odd:.05, sort: i => n(i) / td(i, 15) / t[i], shield:"round"},
|
||||
{name:"Guantzu", base:30, odd:.05, sort: i => n(i) / td(i, 17), shield:"banner"},
|
||||
{name:"Ulus", base:31, odd:.05, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i], shield:"banner"},
|
||||
{name:"Turan", base: 16, odd:.05, sort: i => n(i) / td(i, 12), shield:"round"},
|
||||
{name:"Berberan", base: 17, odd:.05, sort: i => n(i) / td(i, 19) / bd(i, [1, 2, 3], 7) * t[i], shield:"round"},
|
||||
{name:"Eurabic", base: 18, odd:.05, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i], shield:"round"},
|
||||
{name:"Slovan", base:5, odd:.05, sort: i => n(i) / td(i, 6) * t[i], shield:"round"},
|
||||
{name:"Keltan", base: 22, odd:.1, sort: i => n(i) / td(i, 11) ** .5 / bd(i, [6, 8]), shield:"vesicaPiscis"},
|
||||
{name:"Elladan", base:7, odd:.2, sort: i => n(i) / td(i, 18) / sf(i) * h[i], shield:"boeotian"},
|
||||
{name:"Romian", base:8, odd:.2, sort: i => n(i) / td(i, 14) / t[i], shield:"roman"},
|
||||
{name: "Kiswaili", base: 28, odd: 0.05, sort: i => n(i) / td(i, 29) / bd(i, [1, 3, 5, 7]), shield: "vesicaPiscis"},
|
||||
{name: "Yoruba", base: 21, odd: 0.05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7]), shield: "vesicaPiscis"},
|
||||
{name: "Koryo", base: 10, odd: 0.05, sort: i => n(i) / td(i, 12) / t[i], shield: "round"},
|
||||
{name: "Hantzu", base: 11, odd: 0.05, sort: i => n(i) / td(i, 13), shield: "banner"},
|
||||
{name: "Yamoto", base: 12, odd: 0.05, sort: i => n(i) / td(i, 15) / t[i], shield: "round"},
|
||||
{name: "Guantzu", base: 30, odd: 0.05, sort: i => n(i) / td(i, 17), shield: "banner"},
|
||||
{name: "Ulus", base: 31, odd: 0.05, sort: i => (n(i) / td(i, 5) / bd(i, [2, 4, 10], 7)) * t[i], shield: "banner"},
|
||||
{name: "Turan", base: 16, odd: 0.05, sort: i => n(i) / td(i, 12), shield: "round"},
|
||||
{name: "Berberan", base: 17, odd: 0.05, sort: i => (n(i) / td(i, 19) / bd(i, [1, 2, 3], 7)) * t[i], shield: "round"},
|
||||
{name: "Eurabic", base: 18, odd: 0.05, sort: i => (n(i) / td(i, 26) / bd(i, [1, 2], 7)) * t[i], shield: "round"},
|
||||
{name: "Slovan", base: 5, odd: 0.05, sort: i => (n(i) / td(i, 6)) * t[i], shield: "round"},
|
||||
{name: "Keltan", base: 22, odd: 0.1, sort: i => n(i) / td(i, 11) ** 0.5 / bd(i, [6, 8]), shield: "vesicaPiscis"},
|
||||
{name: "Elladan", base: 7, odd: 0.2, sort: i => (n(i) / td(i, 18) / sf(i)) * h[i], shield: "boeotian"},
|
||||
{name: "Romian", base: 8, odd: 0.2, sort: i => n(i) / td(i, 14) / t[i], shield: "roman"},
|
||||
// fantasy races
|
||||
{name:"Eldar", base: 33, odd:.5, sort: i => n(i) / bd(i, [6,7,8,9], 10) * t[i], shield:"fantasy5"}, // Elves
|
||||
{name:"Trow", base: 34, odd:.8, sort: i => n(i) / bd(i, [7,8,9,12], 10) * t[i], shield:"hessen"}, // Dark Elves
|
||||
{name:"Durinn", base: 35, odd:.8, sort: i => n(i) + h[i], shield:"erebor"}, // Dwarven
|
||||
{name:"Kobblin", base: 36, odd:.8, sort: i => t[i] - s[i], shield:"moriaOrc"}, // Goblin
|
||||
{name:"Uruk", base: 37, odd:.8, sort: i => h[i] * t[i] / bd(i, [1,2,10,11]), shield:"urukHai"}, // Orc
|
||||
{name:"Yotunn", base: 38, odd:.8, sort: i => td(i, -10), shield:"pavise"}, // Giant
|
||||
{name:"Drake", base: 39, odd:.9, sort: i => -s[i], shield:"fantasy2"}, // Draconic
|
||||
{name:"Rakhnid", base: 40, odd:.9, sort: i => t[i] - s[i], shield:"horsehead2"}, // Arachnid
|
||||
{name:"Aj'Snaga", base: 41, odd:.9, sort: i => n(i) / bd(i, [12], 10), shield:"fantasy1"}, // Serpents
|
||||
]
|
||||
{name: "Eldar", base: 33, odd: 0.5, sort: i => (n(i) / bd(i, [6, 7, 8, 9], 10)) * t[i], shield: "fantasy5"}, // Elves
|
||||
{name: "Trow", base: 34, odd: 0.8, sort: i => (n(i) / bd(i, [7, 8, 9, 12], 10)) * t[i], shield: "hessen"}, // Dark Elves
|
||||
{name: "Durinn", base: 35, odd: 0.8, sort: i => n(i) + h[i], shield: "erebor"}, // Dwarven
|
||||
{name: "Kobblin", base: 36, odd: 0.8, sort: i => t[i] - s[i], shield: "moriaOrc"}, // Goblin
|
||||
{name: "Uruk", base: 37, odd: 0.8, sort: i => (h[i] * t[i]) / bd(i, [1, 2, 10, 11]), shield: "urukHai"}, // Orc
|
||||
{name: "Yotunn", base: 38, odd: 0.8, sort: i => td(i, -10), shield: "pavise"}, // Giant
|
||||
{name: "Drake", base: 39, odd: 0.9, sort: i => -s[i], shield: "fantasy2"}, // Draconic
|
||||
{name: "Rakhnid", base: 40, odd: 0.9, sort: i => t[i] - s[i], shield: "horsehead2"}, // Arachnid
|
||||
{name: "Aj'Snaga", base: 41, odd: 0.9, sort: i => n(i) / bd(i, [12], 10), shield: "fantasy1"} // Serpents
|
||||
];
|
||||
}
|
||||
|
||||
if (culturesSet.value === "random") {
|
||||
return d3.range(count).map(function() {
|
||||
const rnd = rand(nameBases.length-1);
|
||||
return d3.range(count).map(function () {
|
||||
const rnd = rand(nameBases.length - 1);
|
||||
const name = Names.getBaseShort(rnd);
|
||||
return {name, base:rnd, odd:1, shield:getRandomShield()}
|
||||
return {name, base: rnd, odd: 1, shield: getRandomShield()};
|
||||
});
|
||||
}
|
||||
|
||||
// all-world
|
||||
return [
|
||||
{name:"Shwazen", base:0, odd:.7, sort: i => n(i) / td(i, 10) / bd(i, [6, 8]), shield:"hessen"},
|
||||
{name:"Angshire", base:1, odd:1, sort: i => n(i) / td(i, 10) / sf(i), shield:"heater"},
|
||||
{name:"Luari", base:2, odd:.6, sort: i => n(i) / td(i, 12) / bd(i, [6, 8]), shield:"oldFrench"},
|
||||
{name:"Tallian", base:3, odd:.6, sort: i => n(i) / td(i, 15), shield:"horsehead2"},
|
||||
{name:"Astellian", base:4, odd:.6, sort: i => n(i) / td(i, 16), shield:"spanish"},
|
||||
{name:"Slovan", base:5, odd:.7, sort: i => n(i) / td(i, 6) * t[i], shield:"round"},
|
||||
{name:"Norse", base:6, odd:.7, sort: i => n(i) / td(i, 5), shield:"heater"},
|
||||
{name:"Elladan", base:7, odd:.7, sort: i => n(i) / td(i, 18) * h[i], shield:"boeotian"},
|
||||
{name:"Romian", base:8, odd:.7, sort: i => n(i) / td(i, 15), shield:"roman"},
|
||||
{name:"Soumi", base:9, odd:.3, sort: i => n(i) / td(i, 5) / bd(i, [9]) * t[i], shield:"pavise"},
|
||||
{name:"Koryo", base:10, odd:.1, sort: i => n(i) / td(i, 12) / t[i], shield:"round"},
|
||||
{name:"Hantzu", base:11, odd:.1, sort: i => n(i) / td(i, 13), shield:"banner"},
|
||||
{name:"Yamoto", base:12, odd:.1, sort: i => n(i) / td(i, 15) / t[i], shield:"round"},
|
||||
{name:"Portuzian", base:13, odd:.4, sort: i => n(i) / td(i, 17) / sf(i), shield:"spanish"},
|
||||
{name:"Nawatli", base:14, odd:.1, sort: i => h[i] / td(i, 18) / bd(i, [7]), shield:"square"},
|
||||
{name:"Vengrian", base: 15, odd:.2, sort: i => n(i) / td(i, 11) / bd(i, [4]) * t[i], shield:"wedged"},
|
||||
{name:"Turchian", base: 16, odd:.2, sort: i => n(i) / td(i, 13), shield:"round"},
|
||||
{name:"Berberan", base: 17, odd:.1, sort: i => n(i) / td(i, 19) / bd(i, [1, 2, 3], 7) * t[i], shield:"round"},
|
||||
{name:"Eurabic", base: 18, odd:.2, sort: i => n(i) / td(i, 26) / bd(i, [1, 2], 7) * t[i], shield:"round"},
|
||||
{name:"Inuk", base: 19, odd:.05, sort: i => td(i, -1) / bd(i, [10, 11]) / sf(i), shield:"square"},
|
||||
{name:"Euskati", base: 20, odd:.05, sort: i => n(i) / td(i, 15) * h[i], shield:"spanish"},
|
||||
{name:"Yoruba", base: 21, odd:.05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7]), shield:"vesicaPiscis"},
|
||||
{name:"Keltan", base: 22, odd:.05, sort: i => n(i) / td(i, 11) / bd(i, [6, 8]) * t[i], shield:"vesicaPiscis"},
|
||||
{name:"Efratic", base: 23, odd:.05, sort: i => n(i) / td(i, 22) * t[i], shield:"diamond"},
|
||||
{name:"Tehrani", base: 24, odd:.1, sort: i => n(i) / td(i, 18) * h[i], shield:"round"},
|
||||
{name:"Maui", base: 25, odd:.05, sort: i => n(i) / td(i, 24) / sf(i) / t[i], shield:"round"},
|
||||
{name:"Carnatic", base: 26, odd:.05, sort: i => n(i) / td(i, 26), shield:"round"},
|
||||
{name:"Inqan", base: 27, odd:.05, sort: i => h[i] / td(i, 13), shield:"square"},
|
||||
{name:"Kiswaili", base: 28, odd:.1, sort: i => n(i) / td(i, 29) / bd(i, [1, 3, 5, 7]), shield:"vesicaPiscis"},
|
||||
{name:"Vietic", base: 29, odd:.1, sort: i => n(i) / td(i, 25) / bd(i, [7], 7) / t[i], shield:"banner"},
|
||||
{name:"Guantzu", base:30, odd:.1, sort: i => n(i) / td(i, 17), shield:"banner"},
|
||||
{name:"Ulus", base:31, odd:.1, sort: i => n(i) / td(i, 5) / bd(i, [2, 4, 10], 7) * t[i], shield:"banner"}
|
||||
{name: "Shwazen", base: 0, odd: 0.7, sort: i => n(i) / td(i, 10) / bd(i, [6, 8]), shield: "hessen"},
|
||||
{name: "Angshire", base: 1, odd: 1, sort: i => n(i) / td(i, 10) / sf(i), shield: "heater"},
|
||||
{name: "Luari", base: 2, odd: 0.6, sort: i => n(i) / td(i, 12) / bd(i, [6, 8]), shield: "oldFrench"},
|
||||
{name: "Tallian", base: 3, odd: 0.6, sort: i => n(i) / td(i, 15), shield: "horsehead2"},
|
||||
{name: "Astellian", base: 4, odd: 0.6, sort: i => n(i) / td(i, 16), shield: "spanish"},
|
||||
{name: "Slovan", base: 5, odd: 0.7, sort: i => (n(i) / td(i, 6)) * t[i], shield: "round"},
|
||||
{name: "Norse", base: 6, odd: 0.7, sort: i => n(i) / td(i, 5), shield: "heater"},
|
||||
{name: "Elladan", base: 7, odd: 0.7, sort: i => (n(i) / td(i, 18)) * h[i], shield: "boeotian"},
|
||||
{name: "Romian", base: 8, odd: 0.7, sort: i => n(i) / td(i, 15), shield: "roman"},
|
||||
{name: "Soumi", base: 9, odd: 0.3, sort: i => (n(i) / td(i, 5) / bd(i, [9])) * t[i], shield: "pavise"},
|
||||
{name: "Koryo", base: 10, odd: 0.1, sort: i => n(i) / td(i, 12) / t[i], shield: "round"},
|
||||
{name: "Hantzu", base: 11, odd: 0.1, sort: i => n(i) / td(i, 13), shield: "banner"},
|
||||
{name: "Yamoto", base: 12, odd: 0.1, sort: i => n(i) / td(i, 15) / t[i], shield: "round"},
|
||||
{name: "Portuzian", base: 13, odd: 0.4, sort: i => n(i) / td(i, 17) / sf(i), shield: "spanish"},
|
||||
{name: "Nawatli", base: 14, odd: 0.1, sort: i => h[i] / td(i, 18) / bd(i, [7]), shield: "square"},
|
||||
{name: "Vengrian", base: 15, odd: 0.2, sort: i => (n(i) / td(i, 11) / bd(i, [4])) * t[i], shield: "wedged"},
|
||||
{name: "Turchian", base: 16, odd: 0.2, sort: i => n(i) / td(i, 13), shield: "round"},
|
||||
{name: "Berberan", base: 17, odd: 0.1, sort: i => (n(i) / td(i, 19) / bd(i, [1, 2, 3], 7)) * t[i], shield: "round"},
|
||||
{name: "Eurabic", base: 18, odd: 0.2, sort: i => (n(i) / td(i, 26) / bd(i, [1, 2], 7)) * t[i], shield: "round"},
|
||||
{name: "Inuk", base: 19, odd: 0.05, sort: i => td(i, -1) / bd(i, [10, 11]) / sf(i), shield: "square"},
|
||||
{name: "Euskati", base: 20, odd: 0.05, sort: i => (n(i) / td(i, 15)) * h[i], shield: "spanish"},
|
||||
{name: "Yoruba", base: 21, odd: 0.05, sort: i => n(i) / td(i, 15) / bd(i, [5, 7]), shield: "vesicaPiscis"},
|
||||
{name: "Keltan", base: 22, odd: 0.05, sort: i => (n(i) / td(i, 11) / bd(i, [6, 8])) * t[i], shield: "vesicaPiscis"},
|
||||
{name: "Efratic", base: 23, odd: 0.05, sort: i => (n(i) / td(i, 22)) * t[i], shield: "diamond"},
|
||||
{name: "Tehrani", base: 24, odd: 0.1, sort: i => (n(i) / td(i, 18)) * h[i], shield: "round"},
|
||||
{name: "Maui", base: 25, odd: 0.05, sort: i => n(i) / td(i, 24) / sf(i) / t[i], shield: "round"},
|
||||
{name: "Carnatic", base: 26, odd: 0.05, sort: i => n(i) / td(i, 26), shield: "round"},
|
||||
{name: "Inqan", base: 27, odd: 0.05, sort: i => h[i] / td(i, 13), shield: "square"},
|
||||
{name: "Kiswaili", base: 28, odd: 0.1, sort: i => n(i) / td(i, 29) / bd(i, [1, 3, 5, 7]), shield: "vesicaPiscis"},
|
||||
{name: "Vietic", base: 29, odd: 0.1, sort: i => n(i) / td(i, 25) / bd(i, [7], 7) / t[i], shield: "banner"},
|
||||
{name: "Guantzu", base: 30, odd: 0.1, sort: i => n(i) / td(i, 17), shield: "banner"},
|
||||
{name: "Ulus", base: 31, odd: 0.1, sort: i => (n(i) / td(i, 5) / bd(i, [2, 4, 10], 7)) * t[i], shield: "banner"}
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
// expand cultures across the map (Dijkstra-like algorithm)
|
||||
const expand = function() {
|
||||
TIME && console.time('expandCultures');
|
||||
const expand = function () {
|
||||
TIME && console.time("expandCultures");
|
||||
cells = pack.cells;
|
||||
|
||||
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
|
||||
pack.cultures.forEach(function(c) {
|
||||
pack.cultures.forEach(function (c) {
|
||||
if (!c.i || c.removed) return;
|
||||
queue.queue({e:c.center, p:0, c:c.i});
|
||||
queue.queue({e: c.center, p: 0, c: c.i});
|
||||
});
|
||||
|
||||
const neutral = cells.i.length / 5000 * 3000 * neutralInput.value; // limit cost for culture growth
|
||||
const neutral = (cells.i.length / 5000) * 3000 * neutralInput.value; // limit cost for culture growth
|
||||
const cost = [];
|
||||
while (queue.length) {
|
||||
const next = queue.dequeue(), n = next.e, p = next.p, c = next.c;
|
||||
const next = queue.dequeue(),
|
||||
n = next.e,
|
||||
p = next.p,
|
||||
c = next.c;
|
||||
const type = pack.cultures[c].type;
|
||||
cells.c[n].forEach(function(e) {
|
||||
cells.c[n].forEach(function (e) {
|
||||
const biome = cells.biome[e];
|
||||
const biomeCost = getBiomeCost(c, biome, type);
|
||||
const biomeChangeCost = biome === cells.biome[n] ? 0 : 20; // penalty on biome change
|
||||
|
|
@ -375,13 +402,13 @@
|
|||
if (!cost[e] || totalCost < cost[e]) {
|
||||
if (cells.s[e] > 0) cells.culture[e] = c; // assign culture to populated cell
|
||||
cost[e] = totalCost;
|
||||
queue.queue({e, p:totalCost, c});
|
||||
queue.queue({e, p: totalCost, c});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TIME && console.timeEnd('expandCultures');
|
||||
}
|
||||
TIME && console.timeEnd("expandCultures");
|
||||
};
|
||||
|
||||
function getBiomeCost(c, biome, type) {
|
||||
if (cells.biome[pack.cultures[c].center] === biome) return 10; // tiny penalty for native biome
|
||||
|
|
@ -391,7 +418,8 @@
|
|||
}
|
||||
|
||||
function getHeightCost(i, h, type) {
|
||||
const f = pack.features[cells.f[i]], a = cells.area[i];
|
||||
const f = pack.features[cells.f[i]],
|
||||
a = cells.area[i];
|
||||
if (type === "Lake" && f.type === "lake") return 10; // no lake crossing penalty for Lake cultures
|
||||
if (type === "Naval" && h < 20) return a * 2; // low sea/lake crossing penalty for Naval cultures
|
||||
if (type === "Nomadic" && h < 20) return a * 50; // giant sea/lake crossing penalty for Nomads
|
||||
|
|
@ -407,21 +435,20 @@
|
|||
function getRiverCost(r, i, type) {
|
||||
if (type === "River") return r ? 0 : 100; // penalty for river cultures
|
||||
if (!r) return 0; // no penalty for others if there is no river
|
||||
return Math.min(Math.max(cells.fl[i] / 10, 20), 100) // river penalty from 20 to 100 based on flux
|
||||
return Math.min(Math.max(cells.fl[i] / 10, 20), 100); // river penalty from 20 to 100 based on flux
|
||||
}
|
||||
|
||||
function getTypeCost(t, type) {
|
||||
if (t === 1) return type === "Naval" || type === "Lake" ? 0 : type === "Nomadic" ? 60 : 20; // penalty for coastline
|
||||
if (t === 2) return type === "Naval" || type === "Nomadic" ? 30 : 0; // low penalty for land level 2 for Navals and nomads
|
||||
if (t !== -1) return type === "Naval" || type === "Lake" ? 100 : 0; // penalty for mainland for navals
|
||||
if (t !== -1) return type === "Naval" || type === "Lake" ? 100 : 0; // penalty for mainland for navals
|
||||
return 0;
|
||||
}
|
||||
|
||||
const getRandomShield = function() {
|
||||
const getRandomShield = function () {
|
||||
const type = rw(COA.shields.types);
|
||||
return rw(COA.shields[type]);
|
||||
}
|
||||
};
|
||||
|
||||
return {generate, add, expand, getDefault, getRandomShield};
|
||||
|
||||
})));
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.Lakes = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.Lakes = (function () {
|
||||
const setClimateData = function (h) {
|
||||
const cells = pack.cells;
|
||||
const lakeOutCells = new Uint16Array(cells.i.length);
|
||||
|
|
@ -149,4 +147,4 @@
|
|||
}
|
||||
|
||||
return {setClimateData, cleanupLakeData, prepareLakeData, defineGroup, generateName, getName, getShoreline};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.Military = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.Military = (function () {
|
||||
const generate = function () {
|
||||
TIME && console.time("generateMilitaryForces");
|
||||
const cells = pack.cells,
|
||||
|
|
@ -371,4 +369,4 @@
|
|||
};
|
||||
|
||||
return {generate, getDefaultOptions, getName, generateNote, drawRegiments, drawRegiment, moveRegiment, getTotal, getEmblem};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.Names = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.Names = (function () {
|
||||
let chains = [];
|
||||
|
||||
// calculate Markov chain for a namesbase
|
||||
|
|
@ -294,4 +293,4 @@
|
|||
};
|
||||
|
||||
return {getBase, getCulture, getCultureShort, getBaseShort, getState, updateChain, clearChains, getNameBases, getMapName, calculateChain};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.OceanLayers = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.OceanLayers = (function () {
|
||||
let cells, vertices, pointsN, used;
|
||||
|
||||
const OceanLayers = function OceanLayers() {
|
||||
|
|
@ -91,4 +89,4 @@
|
|||
}
|
||||
|
||||
return OceanLayers;
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.ReliefIcons = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.ReliefIcons = (function () {
|
||||
const ReliefIcons = function () {
|
||||
TIME && console.time("drawRelief");
|
||||
terrain.selectAll("*").remove();
|
||||
|
|
@ -127,4 +125,4 @@
|
|||
}
|
||||
|
||||
return ReliefIcons;
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,19 +1,13 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Religions = factory());
|
||||
}(this, (function () {'use strict';
|
||||
"use strict";
|
||||
|
||||
window.Religions = (function () {
|
||||
// name generation approach and relative chance to be selected
|
||||
const approach = {"Number":1, "Being":3, "Adjective":5, "Color + Animal":5,
|
||||
"Adjective + Animal":5, "Adjective + Being":5, "Adjective + Genitive":1,
|
||||
"Color + Being":3, "Color + Genitive":3, "Being + of + Genitive":2, "Being + of the + Genitive":1,
|
||||
"Animal + of + Genitive":1, "Adjective + Being + of + Genitive":2, "Adjective + Animal + of + Genitive":2};
|
||||
const approach = {Number: 1, Being: 3, Adjective: 5, "Color + Animal": 5, "Adjective + Animal": 5, "Adjective + Being": 5, "Adjective + Genitive": 1, "Color + Being": 3, "Color + Genitive": 3, "Being + of + Genitive": 2, "Being + of the + Genitive": 1, "Animal + of + Genitive": 1, "Adjective + Being + of + Genitive": 2, "Adjective + Animal + of + Genitive": 2};
|
||||
|
||||
// turn weighted array into simple array
|
||||
const approaches = [];
|
||||
for (const a in approach) {
|
||||
for (let j=0; j < approach[a]; j++) {
|
||||
for (let j = 0; j < approach[a]; j++) {
|
||||
approaches.push(a);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +15,7 @@
|
|||
const base = {
|
||||
number: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve"],
|
||||
being: ["God", "Goddess", "Lord", "Lady", "Deity", "Creator", "Maker", "Overlord", "Ruler", "Chief", "Master", "Spirit", "Ancestor", "Father", "Forebear", "Forefather", "Mother", "Brother", "Sister", "Elder", "Numen", "Ancient", "Virgin", "Giver", "Council", "Guardian", "Reaper"],
|
||||
animal: ["Dragon", "Wyvern", "Phoenix", "Unicorn", "Sphinx", "Centaur", "Pegasus", "Kraken", "Basilisk", "Chimera", "Cyclope", "Antelope", "Ape", "Badger", "Bear", "Beaver", "Bison", "Boar", "Buffalo", "Cat", "Cobra", "Crane", "Crocodile", "Crow", "Deer", "Dog", "Eagle", "Elk", "Fox", "Goat", "Goose", "Hare", "Hawk", "Heron", "Horse", "Hyena", "Ibis", "Jackal", "Jaguar", "Lark", "Leopard", "Lion", "Mantis", "Marten", "Moose", "Mule", "Narwhal", "Owl", "Panther", "Rat", "Raven", "Rook", "Scorpion", "Shark", "Sheep", "Snake", "Spider", "Swan", "Tiger", "Turtle", "Viper", "Vulture", "Walrus", "Wolf", "Wolverine", "Worm", "Camel", "Falcon", "Hound", "Ox", "Serpent"],
|
||||
animal: ["Dragon", "Wyvern", "Phoenix", "Unicorn", "Sphinx", "Centaur", "Pegasus", "Kraken", "Basilisk", "Chimera", "Cyclope", "Antelope", "Ape", "Badger", "Bear", "Beaver", "Bison", "Boar", "Buffalo", "Cat", "Cobra", "Crane", "Crocodile", "Crow", "Deer", "Dog", "Eagle", "Elk", "Fox", "Goat", "Goose", "Hare", "Hawk", "Heron", "Horse", "Hyena", "Ibis", "Jackal", "Jaguar", "Lark", "Leopard", "Lion", "Mantis", "Marten", "Moose", "Mule", "Narwhal", "Owl", "Panther", "Rat", "Raven", "Rook", "Scorpion", "Shark", "Sheep", "Snake", "Spider", "Swan", "Tiger", "Turtle", "Viper", "Vulture", "Walrus", "Wolf", "Wolverine", "Worm", "Camel", "Falcon", "Hound", "Ox", "Serpent"],
|
||||
adjective: ["New", "Good", "High", "Old", "Great", "Big", "Young", "Major", "Strong", "Happy", "Last", "Main", "Huge", "Far", "Beautiful", "Wild", "Fair", "Prime", "Crazy", "Ancient", "Proud", "Secret", "Lucky", "Sad", "Silent", "Latter", "Severe", "Fat", "Holy", "Pure", "Aggressive", "Honest", "Giant", "Mad", "Pregnant", "Distant", "Lost", "Broken", "Blind", "Friendly", "Unknown", "Sleeping", "Slumbering", "Loud", "Hungry", "Wise", "Worried", "Sacred", "Magical", "Superior", "Patient", "Dead", "Deadly", "Peaceful", "Grateful", "Frozen", "Evil", "Scary", "Burning", "Divine", "Bloody", "Dying", "Waking", "Brutal", "Unhappy", "Calm", "Cruel", "Favorable", "Blond", "Explicit", "Disturbing", "Devastating", "Brave", "Sunny", "Troubled", "Flying", "Sustainable", "Marine", "Fatal", "Inherent", "Selected", "Naval", "Cheerful", "Almighty", "Benevolent", "Eternal", "Immutable", "Infallible"],
|
||||
genitive: ["Day", "Life", "Death", "Night", "Home", "Fog", "Snow", "Winter", "Summer", "Cold", "Springs", "Gates", "Nature", "Thunder", "Lightning", "War", "Ice", "Frost", "Fire", "Doom", "Fate", "Pain", "Heaven", "Justice", "Light", "Love", "Time", "Victory"],
|
||||
theGenitive: ["World", "Word", "South", "West", "North", "East", "Sun", "Moon", "Peak", "Fall", "Dawn", "Eclipse", "Abyss", "Blood", "Tree", "Earth", "Harvest", "Rainbow", "Sea", "Sky", "Stars", "Storm", "Underworld", "Wild"],
|
||||
|
|
@ -29,64 +23,70 @@
|
|||
};
|
||||
|
||||
const forms = {
|
||||
Folk:{"Shamanism":2, "Animism":2, "Ancestor worship":1, "Polytheism":2},
|
||||
Organized:{"Polytheism":5, "Dualism":1, "Monotheism":4, "Non-theism":1},
|
||||
Cult:{"Cult":1, "Dark Cult":1},
|
||||
Heresy:{"Heresy":1}
|
||||
Folk: {Shamanism: 2, Animism: 2, "Ancestor worship": 1, Polytheism: 2},
|
||||
Organized: {Polytheism: 5, Dualism: 1, Monotheism: 4, "Non-theism": 1},
|
||||
Cult: {Cult: 1, "Dark Cult": 1},
|
||||
Heresy: {Heresy: 1}
|
||||
};
|
||||
|
||||
const methods = {"Random + type":3, "Random + ism":1, "Supreme + ism":5, "Faith of + Supreme":5, "Place + ism":1, "Culture + ism":2, "Place + ian + type":6, "Culture + type":4};
|
||||
const methods = {"Random + type": 3, "Random + ism": 1, "Supreme + ism": 5, "Faith of + Supreme": 5, "Place + ism": 1, "Culture + ism": 2, "Place + ian + type": 6, "Culture + type": 4};
|
||||
|
||||
const types = {
|
||||
"Shamanism":{"Beliefs":3, "Shamanism":2, "Spirits":1},
|
||||
"Animism":{"Spirits":1, "Beliefs":1},
|
||||
"Ancestor worship":{"Beliefs":1, "Forefathers":2, "Ancestors":2},
|
||||
"Polytheism":{"Deities":3, "Faith":1, "Gods":1, "Pantheon":1},
|
||||
Shamanism: {Beliefs: 3, Shamanism: 2, Spirits: 1},
|
||||
Animism: {Spirits: 1, Beliefs: 1},
|
||||
"Ancestor worship": {Beliefs: 1, Forefathers: 2, Ancestors: 2},
|
||||
Polytheism: {Deities: 3, Faith: 1, Gods: 1, Pantheon: 1},
|
||||
|
||||
"Dualism":{"Religion":3, "Faith":1, "Cult":1},
|
||||
"Monotheism":{"Religion":1, "Church":1},
|
||||
"Non-theism":{"Beliefs":3, "Spirits":1},
|
||||
Dualism: {Religion: 3, Faith: 1, Cult: 1},
|
||||
Monotheism: {Religion: 1, Church: 1},
|
||||
"Non-theism": {Beliefs: 3, Spirits: 1},
|
||||
|
||||
"Cult":{"Cult":4, "Sect":4, "Worship":1, "Orden":1, "Coterie":1, "Arcanum":1},
|
||||
"Dark Cult":{"Cult":2, "Sect":2, "Occultism":1, "Idols":1, "Coven":1, "Circle":1, "Blasphemy":1},
|
||||
Cult: {Cult: 4, Sect: 4, Worship: 1, Orden: 1, Coterie: 1, Arcanum: 1},
|
||||
"Dark Cult": {Cult: 2, Sect: 2, Occultism: 1, Idols: 1, Coven: 1, Circle: 1, Blasphemy: 1},
|
||||
|
||||
"Heresy":{"Heresy":3, "Sect":2, "Schism":1, "Dissenters":1, "Circle":1, "Brotherhood":1, "Society":1, "Iconoclasm":1, "Dissent":1, "Apostates":1}
|
||||
Heresy: {Heresy: 3, Sect: 2, Schism: 1, Dissenters: 1, Circle: 1, Brotherhood: 1, Society: 1, Iconoclasm: 1, Dissent: 1, Apostates: 1}
|
||||
};
|
||||
|
||||
const generate = function() {
|
||||
TIME && console.time('generateReligions');
|
||||
const cells = pack.cells, states = pack.states, cultures = pack.cultures;
|
||||
const religions = pack.religions = [];
|
||||
const generate = function () {
|
||||
TIME && console.time("generateReligions");
|
||||
const cells = pack.cells,
|
||||
states = pack.states,
|
||||
cultures = pack.cultures;
|
||||
const religions = (pack.religions = []);
|
||||
cells.religion = new Uint16Array(cells.culture); // cell religion; initially based on culture
|
||||
|
||||
// add folk religions
|
||||
pack.cultures.forEach(c => {
|
||||
if (!c.i) {religions.push({i: 0, name: "No religion"}); return;}
|
||||
if (c.removed) {religions.push({i: c.i, name: "Extinct religion for "+c.name, color:getMixedColor(c.color, .1, 0), removed:true}); return;}
|
||||
if (!c.i) {
|
||||
religions.push({i: 0, name: "No religion"});
|
||||
return;
|
||||
}
|
||||
if (c.removed) {
|
||||
religions.push({i: c.i, name: "Extinct religion for " + c.name, color: getMixedColor(c.color, 0.1, 0), removed: true});
|
||||
return;
|
||||
}
|
||||
const form = rw(forms.Folk);
|
||||
const name = c.name + " " + rw(types[form]);
|
||||
const deity = form === "Animism" ? null : getDeityName(c.i);
|
||||
const color = getMixedColor(c.color, .1, 0); // `url(#hatch${rand(8,13)})`;
|
||||
religions.push({i: c.i, name, color, culture: c.i, type:"Folk", form, deity, center: c.center, origin:0});
|
||||
const color = getMixedColor(c.color, 0.1, 0); // `url(#hatch${rand(8,13)})`;
|
||||
religions.push({i: c.i, name, color, culture: c.i, type: "Folk", form, deity, center: c.center, origin: 0});
|
||||
});
|
||||
|
||||
if (religionsInput.value == 0 || pack.cultures.length < 2) {
|
||||
religions.filter(r => r.i).forEach(r => r.code = abbreviate(r.name));
|
||||
religions.filter(r => r.i).forEach(r => (r.code = abbreviate(r.name)));
|
||||
return;
|
||||
}
|
||||
|
||||
const burgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
const sorted = burgs.length > +religionsInput.value
|
||||
? burgs.sort((a, b) => b.population - a.population).map(b => b.cell)
|
||||
: cells.i.filter(i => cells.s[i] > 2).sort((a, b) => cells.s[b] - cells.s[a]);
|
||||
const sorted = burgs.length > +religionsInput.value ? burgs.sort((a, b) => b.population - a.population).map(b => b.cell) : cells.i.filter(i => cells.s[i] > 2).sort((a, b) => cells.s[b] - cells.s[a]);
|
||||
const religionsTree = d3.quadtree();
|
||||
const spacing = (graphWidth + graphHeight) / 6 / religionsInput.value; // base min distance between towns
|
||||
const cultsCount = Math.floor(rand(10, 40) / 100 * religionsInput.value);
|
||||
const cultsCount = Math.floor((rand(10, 40) / 100) * religionsInput.value);
|
||||
const count = +religionsInput.value - cultsCount + religions.length;
|
||||
|
||||
// generate organized religions
|
||||
for (let i=0; religions.length < count && i < 1000; i++) {
|
||||
let center = sorted[biased(0, sorted.length-1, 5)]; // religion center
|
||||
for (let i = 0; religions.length < count && i < 1000; i++) {
|
||||
let center = sorted[biased(0, sorted.length - 1, 5)]; // religion center
|
||||
const form = rw(forms.Organized);
|
||||
const state = cells.state[center];
|
||||
const culture = cells.culture[center];
|
||||
|
|
@ -96,34 +96,36 @@
|
|||
if (expansion === "state" && !state) expansion = "global";
|
||||
if (expansion === "culture" && !culture) expansion = "global";
|
||||
|
||||
if (expansion === "state" && Math.random() > .5) center = states[state].center;
|
||||
if (expansion === "culture" && Math.random() > .5) center = cultures[culture].center;
|
||||
if (expansion === "state" && Math.random() > 0.5) center = states[state].center;
|
||||
if (expansion === "culture" && Math.random() > 0.5) center = cultures[culture].center;
|
||||
|
||||
if (!cells.burg[center] && cells.c[center].some(c => cells.burg[c])) center = cells.c[center].find(c => cells.burg[c]);
|
||||
const x = cells.p[center][0], y = cells.p[center][1];
|
||||
const x = cells.p[center][0],
|
||||
y = cells.p[center][1];
|
||||
|
||||
const s = spacing * gauss(1, .3, .2, 2, 2); // randomize to make the placement not uniform
|
||||
const s = spacing * gauss(1, 0.3, 0.2, 2, 2); // randomize to make the placement not uniform
|
||||
if (religionsTree.find(x, y, s) !== undefined) continue; // to close to existing religion
|
||||
|
||||
// add "Old" to name of the folk religion on this culture
|
||||
const folk = religions.find(r => r.culture === culture && r.type === "Folk");
|
||||
if (folk && expansion === "culture" && folk.name.slice(0,3) !== "Old") folk.name = "Old " + folk.name;
|
||||
if (folk && expansion === "culture" && folk.name.slice(0, 3) !== "Old") folk.name = "Old " + folk.name;
|
||||
const origin = folk ? folk.i : 0;
|
||||
|
||||
const expansionism = rand(3, 8);
|
||||
const color = getMixedColor(religions[origin].color, .3, 0); // `url(#hatch${rand(0,5)})`;
|
||||
religions.push({i: religions.length, name, color, culture, type:"Organized", form, deity, expansion, expansionism, center, origin});
|
||||
const color = getMixedColor(religions[origin].color, 0.3, 0); // `url(#hatch${rand(0,5)})`;
|
||||
religions.push({i: religions.length, name, color, culture, type: "Organized", form, deity, expansion, expansionism, center, origin});
|
||||
religionsTree.add([x, y]);
|
||||
}
|
||||
|
||||
// generate cults
|
||||
for (let i=0; religions.length < count + cultsCount && i < 1000; i++) {
|
||||
for (let i = 0; religions.length < count + cultsCount && i < 1000; i++) {
|
||||
const form = rw(forms.Cult);
|
||||
let center = sorted[biased(0, sorted.length-1, 1)]; // religion center
|
||||
let center = sorted[biased(0, sorted.length - 1, 1)]; // religion center
|
||||
if (!cells.burg[center] && cells.c[center].some(c => cells.burg[c])) center = cells.c[center].find(c => cells.burg[c]);
|
||||
const x = cells.p[center][0], y = cells.p[center][1];
|
||||
const x = cells.p[center][0],
|
||||
y = cells.p[center][1];
|
||||
|
||||
const s = spacing * gauss(2, .3, 1, 3, 2); // randomize to make the placement not uniform
|
||||
const s = spacing * gauss(2, 0.3, 1, 3, 2); // randomize to make the placement not uniform
|
||||
if (religionsTree.find(x, y, s) !== undefined) continue; // to close to existing religion
|
||||
|
||||
const culture = cells.culture[center];
|
||||
|
|
@ -131,9 +133,9 @@
|
|||
const origin = folk ? folk.i : 0;
|
||||
const deity = getDeityName(culture);
|
||||
const name = getCultName(form, center);
|
||||
const expansionism = gauss(1.1, .5, 0, 5);
|
||||
const color = getMixedColor(cultures[culture].color, .5, 0); // "url(#hatch7)";
|
||||
religions.push({i: religions.length, name, color, culture, type:"Cult", form, deity, expansion:"global", expansionism, center, origin});
|
||||
const expansionism = gauss(1.1, 0.5, 0, 5);
|
||||
const color = getMixedColor(cultures[culture].color, 0.5, 0); // "url(#hatch7)";
|
||||
religions.push({i: religions.length, name, color, culture, type: "Cult", form, deity, expansion: "global", expansionism, center, origin});
|
||||
religionsTree.add([x, y]);
|
||||
//debug.append("circle").attr("cx", x).attr("cy", y).attr("r", 2).attr("fill", "red");
|
||||
}
|
||||
|
|
@ -141,72 +143,90 @@
|
|||
expandReligions();
|
||||
|
||||
// generate heresies
|
||||
religions.filter(r => r.type === "Organized").forEach(r => {
|
||||
if (r.expansionism < 3) return;
|
||||
const count = gauss(0, 1, 0, 3);
|
||||
for (let i=0; i < count; i++) {
|
||||
let center = ra(cells.i.filter(i => cells.religion[i] === r.i && cells.c[i].some(c => cells.religion[c] !== r.i)));
|
||||
if (!center) continue;
|
||||
if (!cells.burg[center] && cells.c[center].some(c => cells.burg[c])) center = cells.c[center].find(c => cells.burg[c]);
|
||||
const x = cells.p[center][0], y = cells.p[center][1];
|
||||
if (religionsTree.find(x, y, spacing / 10) !== undefined) continue; // to close to other
|
||||
religions
|
||||
.filter(r => r.type === "Organized")
|
||||
.forEach(r => {
|
||||
if (r.expansionism < 3) return;
|
||||
const count = gauss(0, 1, 0, 3);
|
||||
for (let i = 0; i < count; i++) {
|
||||
let center = ra(cells.i.filter(i => cells.religion[i] === r.i && cells.c[i].some(c => cells.religion[c] !== r.i)));
|
||||
if (!center) continue;
|
||||
if (!cells.burg[center] && cells.c[center].some(c => cells.burg[c])) center = cells.c[center].find(c => cells.burg[c]);
|
||||
const x = cells.p[center][0],
|
||||
y = cells.p[center][1];
|
||||
if (religionsTree.find(x, y, spacing / 10) !== undefined) continue; // to close to other
|
||||
|
||||
const culture = cells.culture[center];
|
||||
const name = getCultName("Heresy", center);
|
||||
const expansionism = gauss(1.2, .5, 0, 5);
|
||||
const color = getMixedColor(r.color, .4, .2); // "url(#hatch6)";
|
||||
religions.push({i: religions.length, name, color, culture, type:"Heresy", form:r.form, deity: r.deity, expansion:"global", expansionism, center, origin:r.i});
|
||||
religionsTree.add([x, y]);
|
||||
//debug.append("circle").attr("cx", x).attr("cy", y).attr("r", 2).attr("fill", "green");
|
||||
}
|
||||
});
|
||||
const culture = cells.culture[center];
|
||||
const name = getCultName("Heresy", center);
|
||||
const expansionism = gauss(1.2, 0.5, 0, 5);
|
||||
const color = getMixedColor(r.color, 0.4, 0.2); // "url(#hatch6)";
|
||||
religions.push({i: religions.length, name, color, culture, type: "Heresy", form: r.form, deity: r.deity, expansion: "global", expansionism, center, origin: r.i});
|
||||
religionsTree.add([x, y]);
|
||||
//debug.append("circle").attr("cx", x).attr("cy", y).attr("r", 2).attr("fill", "green");
|
||||
}
|
||||
});
|
||||
|
||||
expandHeresies();
|
||||
checkCenters();
|
||||
|
||||
TIME && console.timeEnd('generateReligions');
|
||||
}
|
||||
TIME && console.timeEnd("generateReligions");
|
||||
};
|
||||
|
||||
const add = function(center) {
|
||||
const cells = pack.cells, religions = pack.religions;
|
||||
const add = function (center) {
|
||||
const cells = pack.cells,
|
||||
religions = pack.religions;
|
||||
const r = cells.religion[center];
|
||||
const i = religions.length;
|
||||
const culture = cells.culture[center];
|
||||
const color = getMixedColor(religions[r].color, .3, 0);
|
||||
const color = getMixedColor(religions[r].color, 0.3, 0);
|
||||
|
||||
const type = religions[r].type === "Organized" ? rw({Organized:4, Cult:1, Heresy:2}) : rw({Organized:5, Cult:2});
|
||||
const type = religions[r].type === "Organized" ? rw({Organized: 4, Cult: 1, Heresy: 2}) : rw({Organized: 5, Cult: 2});
|
||||
const form = rw(forms[type]);
|
||||
const deity = type === "Heresy" ? religions[r].deity : form === "Non-theism" ? null : getDeityName(culture);
|
||||
|
||||
let name, expansion;
|
||||
if (type === "Organized") [name, expansion] = getReligionName(form, deity, center)
|
||||
else {name = getCultName(form, center); expansion = "global";}
|
||||
if (type === "Organized") [name, expansion] = getReligionName(form, deity, center);
|
||||
else {
|
||||
name = getCultName(form, center);
|
||||
expansion = "global";
|
||||
}
|
||||
const formName = type === "Heresy" ? religions[r].form : form;
|
||||
const code = abbreviate(name, religions.map(r => r.code));
|
||||
religions.push({i, name, color, culture, type, form:formName, deity, expansion, expansionism:0, center, cells:0, area:0, rural:0, urban:0, origin:r, code});
|
||||
const code = abbreviate(
|
||||
name,
|
||||
religions.map(r => r.code)
|
||||
);
|
||||
religions.push({i, name, color, culture, type, form: formName, deity, expansion, expansionism: 0, center, cells: 0, area: 0, rural: 0, urban: 0, origin: r, code});
|
||||
cells.religion[center] = i;
|
||||
}
|
||||
};
|
||||
|
||||
// growth algorithm to assign cells to religions
|
||||
const expandReligions = function() {
|
||||
const cells = pack.cells, religions = pack.religions;
|
||||
const expandReligions = function () {
|
||||
const cells = pack.cells,
|
||||
religions = pack.religions;
|
||||
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
|
||||
const cost = [];
|
||||
|
||||
religions.filter(r => r.type === "Organized" || r.type === "Cult").forEach(r => {
|
||||
cells.religion[r.center] = r.i;
|
||||
queue.queue({e:r.center, p:0, r:r.i, s: cells.state[r.center], c:r.culture});
|
||||
cost[r.center] = 1;
|
||||
});
|
||||
religions
|
||||
.filter(r => r.type === "Organized" || r.type === "Cult")
|
||||
.forEach(r => {
|
||||
cells.religion[r.center] = r.i;
|
||||
queue.queue({e: r.center, p: 0, r: r.i, s: cells.state[r.center], c: r.culture});
|
||||
cost[r.center] = 1;
|
||||
});
|
||||
|
||||
const neutral = cells.i.length / 5000 * 200 * gauss(1, .3, .2, 2, 2) * neutralInput.value; // limit cost for organized religions growth
|
||||
const neutral = (cells.i.length / 5000) * 200 * gauss(1, 0.3, 0.2, 2, 2) * neutralInput.value; // limit cost for organized religions growth
|
||||
const popCost = d3.max(cells.pop) / 3; // enougth population to spered religion without penalty
|
||||
|
||||
while (queue.length) {
|
||||
const next = queue.dequeue(), n = next.e, p = next.p, r = next.r, c = next.c, s = next.s;
|
||||
const next = queue.dequeue(),
|
||||
n = next.e,
|
||||
p = next.p,
|
||||
r = next.r,
|
||||
c = next.c,
|
||||
s = next.s;
|
||||
const expansion = religions[r].expansion;
|
||||
|
||||
cells.c[n].forEach(function(e) {
|
||||
cells.c[n].forEach(function (e) {
|
||||
if (expansion === "culture" && c !== cells.culture[e]) return;
|
||||
if (expansion === "state" && s !== cells.state[e]) return;
|
||||
|
||||
|
|
@ -215,88 +235,101 @@
|
|||
const biomeCost = cells.road[e] ? 1 : biomesData.cost[cells.biome[e]];
|
||||
const populationCost = Math.max(rn(popCost - cells.pop[e]), 0);
|
||||
const heightCost = Math.max(cells.h[e], 20) - 20;
|
||||
const waterCost = cells.h[e] < 20 ? cells.road[e] ? 50 : 1000 : 0;
|
||||
const waterCost = cells.h[e] < 20 ? (cells.road[e] ? 50 : 1000) : 0;
|
||||
const totalCost = p + (cultureCost + stateCost + biomeCost + populationCost + heightCost + waterCost) / religions[r].expansionism;
|
||||
if (totalCost > neutral) return;
|
||||
|
||||
if (!cost[e] || totalCost < cost[e]) {
|
||||
if (cells.h[e] >= 20 && cells.culture[e]) cells.religion[e] = r; // assign religion to cell
|
||||
cost[e] = totalCost;
|
||||
queue.queue({e, p:totalCost, r, c, s});
|
||||
queue.queue({e, p: totalCost, r, c, s});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// growth algorithm to assign cells to heresies
|
||||
const expandHeresies = function() {
|
||||
const cells = pack.cells, religions = pack.religions;
|
||||
const expandHeresies = function () {
|
||||
const cells = pack.cells,
|
||||
religions = pack.religions;
|
||||
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
|
||||
const cost = [];
|
||||
|
||||
religions.filter(r => r.type === "Heresy").forEach(r => {
|
||||
const b = cells.religion[r.center]; // "base" religion id
|
||||
cells.religion[r.center] = r.i; // heresy id
|
||||
queue.queue({e:r.center, p:0, r:r.i, b});
|
||||
cost[r.center] = 1;
|
||||
});
|
||||
religions
|
||||
.filter(r => r.type === "Heresy")
|
||||
.forEach(r => {
|
||||
const b = cells.religion[r.center]; // "base" religion id
|
||||
cells.religion[r.center] = r.i; // heresy id
|
||||
queue.queue({e: r.center, p: 0, r: r.i, b});
|
||||
cost[r.center] = 1;
|
||||
});
|
||||
|
||||
const neutral = cells.i.length / 5000 * 500 * neutralInput.value; // limit cost for heresies growth
|
||||
const neutral = (cells.i.length / 5000) * 500 * neutralInput.value; // limit cost for heresies growth
|
||||
|
||||
while (queue.length) {
|
||||
const next = queue.dequeue(), n = next.e, p = next.p, r = next.r, b = next.b;
|
||||
const next = queue.dequeue(),
|
||||
n = next.e,
|
||||
p = next.p,
|
||||
r = next.r,
|
||||
b = next.b;
|
||||
|
||||
cells.c[n].forEach(function(e) {
|
||||
cells.c[n].forEach(function (e) {
|
||||
const religionCost = cells.religion[e] === b ? 0 : 2000;
|
||||
const biomeCost = cells.road[e] ? 0 : biomesData.cost[cells.biome[e]];
|
||||
const heightCost = Math.max(cells.h[e], 20) - 20;
|
||||
const waterCost = cells.h[e] < 20 ? cells.road[e] ? 50 : 1000 : 0;
|
||||
const totalCost = p + (religionCost + biomeCost + heightCost + waterCost) / Math.max(religions[r].expansionism, .1);
|
||||
const waterCost = cells.h[e] < 20 ? (cells.road[e] ? 50 : 1000) : 0;
|
||||
const totalCost = p + (religionCost + biomeCost + heightCost + waterCost) / Math.max(religions[r].expansionism, 0.1);
|
||||
|
||||
if (totalCost > neutral) return;
|
||||
|
||||
if (!cost[e] || totalCost < cost[e]) {
|
||||
if (cells.h[e] >= 20 && cells.culture[e]) cells.religion[e] = r; // assign religion to cell
|
||||
cost[e] = totalCost;
|
||||
queue.queue({e, p:totalCost, r});
|
||||
queue.queue({e, p: totalCost, r});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function checkCenters() {
|
||||
const cells = pack.cells, religions = pack.religions;
|
||||
const cells = pack.cells,
|
||||
religions = pack.religions;
|
||||
|
||||
const codes = religions.map(r => r.code);
|
||||
religions.filter(r => r.i).forEach(r => {
|
||||
r.code = abbreviate(r.name, codes);
|
||||
religions
|
||||
.filter(r => r.i)
|
||||
.forEach(r => {
|
||||
r.code = abbreviate(r.name, codes);
|
||||
|
||||
// move religion center if it's not within religion area after expansion
|
||||
if (cells.religion[r.center] === r.i) return; // in area
|
||||
const religCells = cells.i.filter(i => cells.religion[i] === r.i);
|
||||
if (!religCells.length) return; // extinct religion
|
||||
r.center = religCells.sort((a,b) => b.pop - a.pop)[0];
|
||||
});
|
||||
// move religion center if it's not within religion area after expansion
|
||||
if (cells.religion[r.center] === r.i) return; // in area
|
||||
const religCells = cells.i.filter(i => cells.religion[i] === r.i);
|
||||
if (!religCells.length) return; // extinct religion
|
||||
r.center = religCells.sort((a, b) => b.pop - a.pop)[0];
|
||||
});
|
||||
}
|
||||
|
||||
function updateCultures() {
|
||||
TIME && console.time('updateCulturesForReligions');
|
||||
pack.religions = pack.religions.map( (religion, index) => {
|
||||
if(index === 0) {
|
||||
TIME && console.time("updateCulturesForReligions");
|
||||
pack.religions = pack.religions.map((religion, index) => {
|
||||
if (index === 0) {
|
||||
return religion;
|
||||
}
|
||||
return {...religion, culture: pack.cells.culture[religion.center]};
|
||||
});
|
||||
TIME && console.timeEnd('updateCulturesForReligions');
|
||||
TIME && console.timeEnd("updateCulturesForReligions");
|
||||
}
|
||||
|
||||
// get supreme deity name
|
||||
const getDeityName = function(culture) {
|
||||
if (culture === undefined) {ERROR && console.error("Please define a culture"); return;}
|
||||
const getDeityName = function (culture) {
|
||||
if (culture === undefined) {
|
||||
ERROR && console.error("Please define a culture");
|
||||
return;
|
||||
}
|
||||
const meaning = generateMeaning();
|
||||
const cultureName = Names.getCulture(culture, null, null, "", .8);
|
||||
const cultureName = Names.getCulture(culture, null, null, "", 0.8);
|
||||
return cultureName + ", The " + meaning;
|
||||
}
|
||||
};
|
||||
|
||||
function generateMeaning() {
|
||||
const a = ra(approaches); // select generation approach
|
||||
|
|
@ -318,21 +351,29 @@
|
|||
|
||||
function getReligionName(form, deity, center) {
|
||||
const cells = pack.cells;
|
||||
const random = function() {return Names.getCulture(cells.culture[center], null, null, "", 0);}
|
||||
const type = function() {return rw(types[form]);}
|
||||
const supreme = function() {return deity.split(/[ ,]+/)[0];}
|
||||
const place = function(adj) {
|
||||
const random = function () {
|
||||
return Names.getCulture(cells.culture[center], null, null, "", 0);
|
||||
};
|
||||
const type = function () {
|
||||
return rw(types[form]);
|
||||
};
|
||||
const supreme = function () {
|
||||
return deity.split(/[ ,]+/)[0];
|
||||
};
|
||||
const place = function (adj) {
|
||||
const base = cells.burg[center] ? pack.burgs[cells.burg[center]].name : pack.states[cells.state[center]].name;
|
||||
let name = trimVowels(base.split(/[ ,]+/)[0]);
|
||||
return adj ? getAdjective(name) : name;
|
||||
}
|
||||
const culture = function() {return pack.cultures[cells.culture[center]].name;}
|
||||
};
|
||||
const culture = function () {
|
||||
return pack.cultures[cells.culture[center]].name;
|
||||
};
|
||||
|
||||
const m = rw(methods);
|
||||
if (m === "Random + type") return [random() + " " + type(), "global"];
|
||||
if (m === "Random + ism") return [trimVowels(random()) + "ism", "global"];
|
||||
if (m === "Supreme + ism" && deity) return [trimVowels(supreme()) + "ism", "global"];
|
||||
if (m === "Faith of + Supreme" && deity) return [ra(['Faith', 'Way', 'Path', 'Word', 'Witnesses']) + " of " + supreme(), "global"];
|
||||
if (m === "Faith of + Supreme" && deity) return [ra(["Faith", "Way", "Path", "Word", "Witnesses"]) + " of " + supreme(), "global"];
|
||||
if (m === "Place + ism") return [place() + "ism", "state"];
|
||||
if (m === "Culture + ism") return [trimVowels(culture()) + "ism", "culture"];
|
||||
if (m === "Place + ian + type") return [place("adj") + " " + type(), "state"];
|
||||
|
|
@ -342,14 +383,19 @@
|
|||
|
||||
function getCultName(form, center) {
|
||||
const cells = pack.cells;
|
||||
const type = function() {return rw(types[form]);}
|
||||
const random = function() {return trimVowels(Names.getCulture(cells.culture[center], null, null, "", 0).split(/[ ,]+/)[0]);}
|
||||
const burg = function() {return trimVowels(pack.burgs[cells.burg[center]].name.split(/[ ,]+/)[0]);}
|
||||
const type = function () {
|
||||
return rw(types[form]);
|
||||
};
|
||||
const random = function () {
|
||||
return trimVowels(Names.getCulture(cells.culture[center], null, null, "", 0).split(/[ ,]+/)[0]);
|
||||
};
|
||||
const burg = function () {
|
||||
return trimVowels(pack.burgs[cells.burg[center]].name.split(/[ ,]+/)[0]);
|
||||
};
|
||||
if (cells.burg[center]) return burg() + "ian " + type();
|
||||
if (Math.random() > .5) return random() + "ian " + type();
|
||||
if (Math.random() > 0.5) return random() + "ian " + type();
|
||||
return type() + " of the " + generateMeaning();
|
||||
};
|
||||
}
|
||||
|
||||
return {generate, add, getDeityName, expandReligions, updateCultures};
|
||||
|
||||
})));
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.Rivers = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.Rivers = (function () {
|
||||
const generate = function (allowErosion = true) {
|
||||
TIME && console.time("generateRivers");
|
||||
Math.random = aleaPRNG(seed);
|
||||
|
|
@ -442,4 +440,4 @@
|
|||
};
|
||||
|
||||
return {generate, alterHeights, resolveDepressions, addMeandering, getRiverPath, specify, getName, getType, getBasin, getWidth, getOffset, getApproximateLength, getRiverPoints, remove};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.Routes = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
|
||||
window.Routes = (function () {
|
||||
const getRoads = function () {
|
||||
TIME && console.time("generateMainRoads");
|
||||
const cells = pack.cells;
|
||||
const burgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
const capitals = burgs.filter(b => b.capital)
|
||||
.sort((a,b) => a.population - b.population);
|
||||
const capitals = burgs.filter(b => b.capital).sort((a, b) => a.population - b.population);
|
||||
|
||||
if (capitals.length < 2) return []; // not enough capitals to build main roads
|
||||
const paths = []; // array to store path segments
|
||||
|
|
@ -271,4 +266,4 @@
|
|||
}
|
||||
return [from, exit, false];
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.ThreeD = factory());
|
||||
})(this, function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
window.ThreeD = (function () {
|
||||
// set default options
|
||||
const options = {scale: 50, lightness: 0.7, shadow: 0.5, sun: {x: 100, y: 600, z: 1000}, rotateMesh: 0, rotateGlobe: 0.5, skyColor: "#9ecef5", waterColor: "#466eab", extendedWater: 0, labels3d: 0, resolution: 2};
|
||||
|
||||
|
|
@ -581,4 +579,4 @@
|
|||
}
|
||||
|
||||
return {create, redraw, update, stop, options, setScale, setLightness, setSun, setRotation, toggleLabels, toggleSky, setResolution, setColors, saveScreenshot, saveOBJ};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
function editZones() {
|
||||
closeDialogs();
|
||||
if (!layerIsOn("toggleZones")) toggleZones();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue