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

@ -1,15 +1,15 @@
// module to control the Tools options (click to edit, to re-geenerate, tp add)
'use strict';
// module to control the Tools options (click to edit, to re-geenerate, tp add)
toolsContent.addEventListener('click', function (event) {
if (customization) {
tip('Please exit the customization mode first', false, 'warning');
return;
}
if (event.target.tagName !== 'BUTTON') return;
if (!['BUTTON', 'I'].includes(event.target.tagName)) return;
const button = event.target.id;
// Click to open Editor buttons
// click on open Editor buttons
if (button === 'editHeightmapButton') editHeightmap();
else if (button === 'editBiomesButton') editBiomes();
else if (button === 'editStatesButton') editStates();
@ -17,7 +17,6 @@ toolsContent.addEventListener('click', function (event) {
else if (button === 'editDiplomacyButton') editDiplomacy();
else if (button === 'editCulturesButton') editCultures();
else if (button === 'editReligions') editReligions();
else if (button === 'editResources') editResources();
else if (button === 'editEmblemButton') openEmblemEditor();
else if (button === 'editNamesBaseButton') editNamesbase();
else if (button === 'editUnitsButton') editUnits();
@ -26,9 +25,10 @@ toolsContent.addEventListener('click', function (event) {
else if (button === 'overviewBurgsButton') overviewBurgs();
else if (button === 'overviewRiversButton') overviewRivers();
else if (button === 'overviewMilitaryButton') overviewMilitary();
else if (button === 'overviewMarkersButton') overviewMarkers();
else if (button === 'overviewCellsButton') viewCellDetails();
// Click to Regenerate buttons
// click on Regenerate buttons
if (event.target.parentNode.id === 'regenerateFeature') {
if (sessionStorage.getItem('regenerateFeatureDontAsk')) {
processFeatureRegeneration(event, button);
@ -61,7 +61,10 @@ toolsContent.addEventListener('click', function (event) {
});
}
// Click to Add buttons
// click on Configure regenerate buttons
if (button === 'configRegenerateMarkers') configMarkersGeneration();
// click on Add buttons
if (button === 'addLabel') toggleAddLabel();
else if (button === 'addBurgTool') toggleAddBurg();
else if (button === 'addRiver') toggleAddRiver();
@ -84,13 +87,12 @@ function processFeatureRegeneration(event, button) {
else if (button === 'regenerateStates') regenerateStates();
else if (button === 'regenerateProvinces') regenerateProvinces();
else if (button === 'regenerateBurgs') regenerateBurgs();
else if (button === 'regenerateResources') regenerateResources();
else if (button === 'regenerateEmblems') regenerateEmblems();
else if (button === 'regenerateReligions') regenerateReligions();
else if (button === 'regenerateCultures') regenerateCultures();
else if (button === 'regenerateMilitary') regenerateMilitary();
else if (button === 'regenerateIce') regenerateIce();
else if (button === 'regenerateMarkers') regenerateMarkers(event);
else if (button === 'regenerateMarkers') regenerateMarkers();
else if (button === 'regenerateZones') regenerateZones(event);
}
@ -119,6 +121,7 @@ function regenerateRivers() {
Lakes.defineGroup();
Rivers.specify();
if (!layerIsOn('toggleRivers')) toggleRivers();
else drawRivers();
}
function recalculatePopulation() {
@ -137,21 +140,11 @@ function recalculatePopulation() {
function regenerateStates() {
const localSeed = Math.floor(Math.random() * 1e9); // new random seed
Math.random = aleaPRNG(localSeed);
const burgs = pack.burgs.filter((b) => b.i && !b.removed);
if (!burgs.length) {
tip('No burgs to generate states. Please create burgs first', false, 'error');
return;
}
if (burgs.length < +regionsInput.value) {
tip(`Not enough burgs to generate ${regionsInput.value} states. Will generate only ${burgs.length} states`, false, 'warn');
}
// burg local ids sorted by a bit randomized population:
const sorted = burgs
.map((b, i) => [i, b.population * Math.random()])
.sort((a, b) => b[1] - a[1])
.map((b) => b[0]);
const capitalsTree = d3.quadtree();
const statesCount = +regionsInput.value;
const burgs = pack.burgs.filter((b) => b.i && !b.removed);
if (!burgs.length) return tip('There are no any burgs to generate states. Please create burgs first', false, 'error');
if (burgs.length < statesCount) tip(`Not enough burgs to generate ${statesCount} states. Will generate only ${burgs.length} states`, false, 'warn');
// turn all old capitals into towns
burgs
@ -168,8 +161,7 @@ function regenerateStates() {
unfog();
// if desired states number is 0
if (regionsInput.value == 0) {
if (!statesCount) {
tip(`Cannot generate zero states. Please check the <i>States Number</i> option`, false, 'warn');
pack.states = pack.states.slice(0, 1); // remove all except of neutrals
pack.states[0].diplomacy = []; // clear diplomacy
@ -185,26 +177,34 @@ function regenerateStates() {
return;
}
const neutral = pack.states[0].name;
const count = Math.min(+regionsInput.value, burgs.length);
// burg local ids sorted by a bit randomized population:
const sortedBurgs = burgs
.map((b, i) => [b, b.population * Math.random()])
.sort((a, b) => b[1] - a[1])
.map((b) => b[0]);
const capitalsTree = d3.quadtree();
const neutral = pack.states[0].name; // neutrals name
const count = Math.min(statesCount, burgs.length) + 1; // +1 for neutral
let spacing = (graphWidth + graphHeight) / 2 / count; // min distance between capitals
pack.states = d3.range(count).map((i) => {
if (!i) return {i, name: neutral};
let capital = null,
x = 0,
y = 0;
for (const i of sorted) {
capital = burgs[i];
(x = capital.x), (y = capital.y);
if (capitalsTree.find(x, y, spacing) === undefined) break;
let capital = null;
for (const burg of sortedBurgs) {
const {x, y} = burg;
if (capitalsTree.find(x, y, spacing) === undefined) {
burg.capital = 1;
capital = burg;
capitalsTree.add([x, y]);
moveBurgToGroup(burg.i, 'cities');
break;
}
spacing = Math.max(spacing - 1, 1);
}
capitalsTree.add([x, y]);
capital.capital = 1;
moveBurgToGroup(capital.i, 'cities');
const culture = capital.culture;
const basename = capital.name.length < 9 && capital.cell % 5 === 0 ? capital.name : Names.getCulture(culture, 3, 6, '', 0);
const name = Names.getState(basename, culture);
@ -337,13 +337,6 @@ function regenerateBurgs() {
if (document.getElementById('statesEditorRefresh').offsetParent) statesEditorRefresh.click();
}
function regenerateResources() {
Resources.generate();
goods.selectAll('*').remove();
if (layerIsOn('toggleResources')) drawResources();
refreshAllEditors();
}
function regenerateEmblems() {
// remove old emblems
document.querySelectorAll('[id^=stateCOA]').forEach((el) => el.remove());
@ -424,23 +417,11 @@ function regenerateIce() {
drawIce();
}
function regenerateMarkers(event) {
if (isCtrlClick(event)) prompt('Please provide markers number multiplier', {default: 1, step: 0.01, min: 0, max: 100}, (v) => addNumberOfMarkers(v));
else addNumberOfMarkers(gauss(1, 0.5, 0.3, 5, 2));
function addNumberOfMarkers(number) {
// remove existing markers and assigned notes
markers
.selectAll('use')
.each(function () {
const index = notes.findIndex((n) => n.id === this.id);
if (index != -1) notes.splice(index, 1);
})
.remove();
addMarkers(number);
if (!layerIsOn('toggleMarkers')) toggleMarkers();
}
function regenerateMarkers() {
Markers.regenerate();
turnButtonOn('toggleMarkers');
drawMarkers();
if (document.getElementById('markersOverviewRefresh').offsetParent) markersOverviewRefresh.click();
}
function regenerateZones(event) {
@ -485,7 +466,10 @@ function addLabelOnClick() {
const name = Names.getCulture(culture);
const id = getNextId('label');
let group = labels.select('#addedLabels');
// use most recently selected label group
let selected = labelGroupSelect.value;
const symbol = selected ? '#' + selected : '#addedLabels';
let group = labels.select(symbol);
if (!group.size())
group = labels
.append('g')
@ -495,7 +479,6 @@ function addLabelOnClick() {
.attr('stroke', '#3a3a3a')
.attr('stroke-width', 0)
.attr('font-family', 'Almendra SC')
.attr('data-font', 'Almendra+SC')
.attr('font-size', 18)
.attr('data-size', 18)
.attr('filter', null);
@ -697,7 +680,7 @@ function addRouteOnClick() {
}
function toggleAddMarker() {
const pressed = document.getElementById('addMarker').classList.contains('pressed');
const pressed = document.getElementById('addMarker')?.classList.contains('pressed');
if (pressed) {
unpressClickToAddButton();
return;
@ -705,45 +688,115 @@ function toggleAddMarker() {
addFeature.querySelectorAll('button.pressed').forEach((b) => b.classList.remove('pressed'));
addMarker.classList.add('pressed');
closeDialogs('.stable');
markersAddFromOverview.classList.add('pressed');
viewbox.style('cursor', 'crosshair').on('click', addMarkerOnClick);
tip('Click on map to add a marker. Hold Shift to add multiple', true);
if (!layerIsOn('toggleMarkers')) toggleMarkers();
}
function addMarkerOnClick() {
const {markers} = pack;
const point = d3.mouse(this);
const x = rn(point[0], 2),
y = rn(point[1], 2);
const id = getNextId('markerElement');
const x = rn(point[0], 2);
const y = rn(point[1], 2);
const i = last(markers).i + 1;
const selected = markerSelectGroup.value;
const valid =
selected &&
d3
.select('#defs-markers')
.select('#' + selected)
.size();
const symbol = valid ? '#' + selected : '#marker0';
const added = markers.select("[data-id='" + symbol + "']").size();
let desired = valid && added ? markers.select("[data-id='" + symbol + "']").attr('data-size') : 1;
if (isNaN(desired)) desired = 1;
const size = desired * 5 + 25 / scale;
const isMarkerSelected = elSelected?.node()?.parentElement?.id === 'markers';
const selectedMarker = isMarkerSelected ? markers.find((marker) => marker.i === +elSelected.attr('id').slice(6)) : null;
const baseMarker = selectedMarker || {icon: '❓'};
const marker = {...baseMarker, i, x, y};
markers
.append('use')
.attr('id', id)
.attr('xlink:href', symbol)
.attr('data-id', symbol)
.attr('data-x', x)
.attr('data-y', y)
.attr('x', x - size / 2)
.attr('y', y - size)
.attr('data-size', desired)
.attr('width', size)
.attr('height', size);
markers.push(marker);
const markersElement = document.getElementById('markers');
const rescale = +markersElement.getAttribute('rescale');
markersElement.insertAdjacentHTML('beforeend', drawMarker(marker, rescale));
if (d3.event.shiftKey === false) unpressClickToAddButton();
if (d3.event.shiftKey === false) {
document.getElementById('markerAdd').classList.remove('pressed');
document.getElementById('markersAddFromOverview').classList.remove('pressed');
unpressClickToAddButton();
}
}
function configMarkersGeneration() {
drawConfigTable();
function drawConfigTable() {
const {markers} = pack;
const config = Markers.getConfig();
const headers = `<thead style='font-weight:bold'><tr>
<td data-tip="Marker type name">Type</td>
<td data-tip="Marker icon">Icon</td>
<td data-tip="Marker number multiplier">Multiplier</td>
<td data-tip="Number of markers of that type on the current map">Number</td>
</tr></thead>`;
const lines = config.map(({type, icon, multiplier}, index) => {
const inputId = `markerIconInput${index}`;
return `<tr>
<td><input value="${type}" /></td>
<td>
<input id="${inputId}" style="width: 5em" value="${icon}" />
<i class="icon-edit pointer" style="position: absolute; margin:.4em 0 0 -1.4em; font-size:.85em"></i>
</td>
<td><input type="number" min="0" max="100" step="0.1" value="${multiplier}" /></td>
<td style="text-align:center">${markers.filter((marker) => marker.type === type).length}</td>
</tr>`;
});
const table = `<table class="table">${headers}<tbody>${lines.join('')}</tbody></table>`;
alertMessage.innerHTML = table;
alertMessage.querySelectorAll('i').forEach((selectIconButton) => {
selectIconButton.addEventListener('click', function () {
const input = this.previousElementSibling;
selectIcon(input.value, (icon) => (input.value = icon));
});
});
}
const applyChanges = () => {
const rows = alertMessage.querySelectorAll('tbody > tr');
const rowsData = Array.from(rows).map((row) => {
const inputs = row.querySelectorAll('input');
return {
type: inputs[0].value,
icon: inputs[1].value,
multiplier: parseFloat(inputs[2].value)
};
});
const config = Markers.getConfig();
const newConfig = config.map((markerType, index) => {
const {type, icon, multiplier} = rowsData[index];
return {...markerType, type, icon, multiplier};
});
Markers.setConfig(newConfig);
};
$('#alert').dialog({
resizable: false,
title: 'Markers generation settings',
position: {my: 'left top', at: 'left+10 top+10', of: 'svg', collision: 'fit'},
buttons: {
Regenerate: () => {
applyChanges();
regenerateMarkers();
drawConfigTable();
},
Close: function () {
$(this).dialog('close');
}
},
open: function () {
const buttons = $(this).dialog('widget').find('.ui-dialog-buttonset > button');
buttons[0].addEventListener('mousemove', () => tip('Apply changes and regenerate markers'));
buttons[1].addEventListener('mousemove', () => tip('Close the window'));
},
close: function () {
$(this).dialog('destroy');
}
});
}
function viewCellDetails() {