merge completed... now to fix all the bugs...

This commit is contained in:
howlingsails 2021-12-12 23:02:38 -08:00
commit 87c4d80fbc
3472 changed files with 466748 additions and 6517 deletions

View file

@ -502,6 +502,7 @@ function editStates() {
pack.cells.province.forEach((pr, i) => {
if (pr === p) pack.cells.province[i] = 0;
});
const coaId = 'provinceCOA' + p;
if (document.getElementById(coaId)) document.getElementById(coaId).remove();
emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
@ -568,19 +569,20 @@ function editStates() {
function showStatesChart() {
// build hierarchy tree
const data = pack.states.filter((s) => !s.removed);
const statesData = pack.states.filter((s) => !s.removed);
if (statesData.length < 2) return tip('There are no states to show', false, 'error');
const root = d3
.stratify()
.id((d) => d.i)
.parentId((d) => (d.i ? 0 : null))(data)
.parentId((d) => (d.i ? 0 : null))(statesData)
.sum((d) => d.area)
.sort((a, b) => b.value - a.value);
const width = 150 + 200 * uiSizeOutput.value,
height = 150 + 200 * uiSizeOutput.value;
const size = 150 + 200 * uiSizeOutput.value;
const margin = {top: 0, right: -50, bottom: 0, left: -50};
const w = width - margin.left - margin.right;
const h = height - margin.top - margin.bottom;
const w = size - margin.left - margin.right;
const h = size - margin.top - margin.bottom;
const treeLayout = d3.pack().size([w, h]).padding(3);
// prepare svg
@ -592,12 +594,13 @@ function editStates() {
<option value="burgs">Burgs number</option>
</select>`;
alertMessage.innerHTML += `<div id='statesInfo' class='chartInfo'>&#8205;</div>`;
const svg = d3
.select('#alertMessage')
.insert('svg', '#statesInfo')
.attr('id', 'statesTree')
.attr('width', width)
.attr('height', height)
.attr('width', size)
.attr('height', size)
.style('font-family', 'Almendra SC')
.attr('text-anchor', 'middle')
.attr('dominant-baseline', 'central');
@ -819,9 +822,9 @@ function editStates() {
}
function applyStatesManualAssignent() {
const cells = pack.cells,
affectedStates = [],
affectedProvinces = [];
const {cells} = pack;
const affectedStates = [];
const affectedProvinces = [];
statesBody
.select('#temp')
@ -837,77 +840,143 @@ function editStates() {
if (affectedStates.length) {
refreshStatesEditor();
if (!layerIsOn('toggleStates')) toggleStates();
else drawStates();
layerIsOn('toggleStates') ? drawStates() : toggleStates();
if (adjustLabels.checked) BurgsAndStates.drawStateLabels([...new Set(affectedStates)]);
adjustProvinces([...new Set(affectedProvinces)]);
if (!layerIsOn('toggleBorders')) toggleBorders();
else drawBorders();
layerIsOn('toggleBorders') ? drawBorders() : toggleBorders();
if (layerIsOn('toggleProvinces')) drawProvinces();
}
exitStatesManualAssignment();
}
function adjustProvinces(affectedProvinces) {
const {cells, provinces, states} = pack;
const form = {Zone: 1, Area: 1, Territory: 2, Province: 1};
affectedProvinces.forEach((p) => {
if (!p) return; // do nothing if neutral lands are captured
const old = provinces[p].state;
// remove province from state provinces list
if (states[old]?.provinces?.includes(p)) states[old].provinces.splice(states[old].provinces.indexOf(p), 1);
const {cells, provinces, states, burgs} = pack;
affectedProvinces.forEach((provinceId) => {
// find states owning at least 1 province cell
const provCells = cells.i.filter((i) => cells.province[i] === p);
const provCells = cells.i.filter((i) => cells.state[i] && cells.province[i] === provinceId);
const provStates = [...new Set(provCells.map((i) => cells.state[i]))];
// assign province to its center owner; if center is neutral, remove province
const owner = cells.state[provinces[p].center];
if (owner) {
const name = provinces[p].name;
// province is captured completely => change owner or remove
if (provinceId && provStates.length === 1) return changeProvinceOwner(provinceId, provStates[0], provCells);
// if province is a historical part of another state's province, unite with old province
const part = states[owner].provinces.find((n) => name.includes(provinces[n].name));
if (part) {
provinces[p].removed = true;
provCells.filter((i) => cells.state[i] === owner).forEach((i) => (cells.province[i] = part));
} else {
provinces[p].state = owner;
states[owner].provinces.push(p);
provinces[p].color = getMixedColor(states[owner].color);
}
} else {
provinces[p].removed = true;
provCells.filter((i) => !cells.state[i]).forEach((i) => (cells.province[i] = 0));
}
// create new provinces for non-main part
provStates
.filter((s) => s && s !== owner)
.forEach((s) =>
createProvince(
p,
s,
provCells.filter((i) => cells.state[i] === s)
)
);
// province is captured partially => split province
splitProvince(provinceId, provStates, provCells);
});
function createProvince(initProv, state, provCells) {
const province = provinces.length;
provCells.forEach((i) => (cells.province[i] = province));
function changeProvinceOwner(provinceId, newOwnerId, provinceCells) {
const province = provinces[provinceId];
const prevOwner = states[province.state];
const burgCell = provCells.find((i) => cells.burg[i]);
const center = burgCell ? burgCell : provCells[0];
const burg = burgCell ? cells.burg[burgCell] : 0;
// remove province from old owner list
prevOwner.provinces = prevOwner.provinces.filter((province) => province !== provinceId);
const name = burgCell && P(0.7) ? getAdjective(pack.burgs[burg].name) : getAdjective(states[state].name) + ' ' + provinces[initProv].name.split(' ').slice(-1)[0];
const formName = name.split(' ').length > 1 ? provinces[initProv].formName : rw(form);
const fullName = name + ' ' + formName;
const color = getMixedColor(states[state].color);
provinces.push({i: province, state, center, burg, name, formName, fullName, color});
if (newOwnerId) {
// new owner is a state => change owner
province.state = newOwnerId;
states[newOwnerId].provinces.push(provinceId);
} else {
// new owner is neutral => remove province
provinces[provinceId] = {i: provinceId, removed: true};
provinceCells.forEach((i) => {
cells.province[i] = 0;
});
}
}
function splitProvince(provinceId, provinceStates, provinceCells) {
const province = provinces[provinceId];
const prevOwner = states[province.state];
const provinceCenterOwner = cells.state[province.center];
provinceStates.forEach((stateId) => {
const stateProvinceCells = provinceCells.filter((i) => cells.state[i] === stateId);
if (stateId === provinceCenterOwner) {
// province center is owned by the same state => do nothing for this state
if (stateId === prevOwner.i) return;
// province center is captured by neutrals => remove state
if (!stateId) {
provinces[provinceId] = {i: provinceId, removed: true};
stateProvinceCells.forEach((i) => {
cells.province[i] = 0;
});
return;
}
// reassign province ownership to province center owner
prevOwner.provinces = prevOwner.provinces.filter((province) => province !== provinceId);
province.state = stateId;
province.color = getMixedColor(states[stateId].color);
states[stateId].provinces.push(provinceId);
return;
}
// province cells captured by neutrals => clear province
if (!stateId) {
stateProvinceCells.forEach((i) => {
cells.province[i] = 0;
});
return;
}
// a few province cells owned by state => add to closes province
if (stateProvinceCells.length < 20) {
const closestProvince = findClosestProvince(provinceId, stateId, stateProvinceCells);
if (closestProvince) {
stateProvinceCells.forEach((i) => {
cells.province[i] = closestProvince;
});
return;
}
}
// some province cells owned by state => create new province
createProvince(province, stateId, stateProvinceCells);
});
}
function createProvince(oldProvince, stateId, provinceCells) {
const newProvinceId = provinces.length;
const burgCell = provinceCells.find((i) => cells.burg[i]);
const center = burgCell ? burgCell : provinceCells[0];
const burgId = burgCell ? cells.burg[burgCell] : 0;
const burg = burgId ? burgs[burgId] : null;
const culture = cells.culture[center];
const nameByBurg = burgCell && P(0.5);
const name = nameByBurg ? burg.name : oldProvince.name || Names.getState(Names.getCultureShort(culture), culture);
const formOptions = ['Zone', 'Area', 'Territory', 'Province'];
const formName = burgCell && oldProvince.formName ? oldProvince.formName : ra(formOptions);
const color = getMixedColor(states[stateId].color);
const kinship = nameByBurg ? 0.8 : 0.4;
const type = BurgsAndStates.getType(center, burg?.port);
const coa = COA.generate(burg?.coa || states[stateId].coa, kinship, burg ? null : 0.9, type);
coa.shield = COA.getShield(culture, stateId);
provinces.push({i: newProvinceId, state: stateId, center, burg: burgId, name, formName, fullName: `${name} ${formName}`, color, coa});
provinceCells.forEach((i) => {
cells.province[i] = newProvinceId;
});
states[stateId].provinces.push(newProvinceId);
}
function findClosestProvince(provinceId, stateId, sourceCells) {
const borderCell = sourceCells.find((i) =>
cells.c[i].some((c) => {
return cells.state[c] === stateId && cells.province[c] && cells.province[c] !== provinceId;
})
);
const closesProvince = borderCell && cells.c[borderCell].map((c) => cells.province[c]).find((province) => province && province !== provinceId);
return closesProvince;
}
}
@ -1007,7 +1076,22 @@ function editStates() {
cells.state[center] = newState;
cells.province[center] = 0;
states.push({i: newState, name, diplomacy, provinces: [], color, expansionism: 0.5, capital: burg, type: 'Generic', center, culture, military: [], alert: 1, coa, pole});
states.push({
i: newState,
name,
diplomacy,
provinces: [],
color,
expansionism: 0.5,
capital: burg,
type: 'Generic',
center,
culture,
military: [],
alert: 1,
coa,
pole
});
BurgsAndStates.collectStatistics();
BurgsAndStates.defineStateForms([newState]);
adjustProvinces([cells.province[center]]);
@ -1050,12 +1134,13 @@ function editStates() {
function downloadStatesData() {
const unit = areaUnit.value === 'square' ? distanceUnitInput.value + '2' : areaUnit.value;
let data = 'Id,State,Form,Color,Capital,Culture,Type,Expansionism,Cells,Burgs,Area ' + unit + ',Total Population,Rural Population,Urban Population\n'; // headers
let data = 'Id,State,Full Name,Form,Color,Capital,Culture,Type,Expansionism,Cells,Burgs,Area ' + unit + ',Total Population,Rural Population,Urban Population\n'; // headers
body.querySelectorAll(':scope > div').forEach(function (el) {
const key = parseInt(el.dataset.id);
const statePack = pack.states[key];
data += el.dataset.id + ',';
data += el.dataset.name + ',';
data += (statePack.fullName ? statePack.fullName : '') + ',';
data += el.dataset.form + ',';
data += el.dataset.color + ',';
data += el.dataset.capital + ',';
@ -1066,8 +1151,8 @@ function editStates() {
data += el.dataset.burgs + ',';
data += el.dataset.area + ',';
data += el.dataset.population + ',';
data += `${Math.round(pack.states[key].rural * populationRate)},`;
data += `${Math.round(pack.states[key].urban * populationRate * urbanization)}\n`;
data += `${Math.round(statePack.rural * populationRate)},`;
data += `${Math.round(statePack.urban * populationRate * urbanization)}\n`;
});
const name = getFileName('States') + '.csv';