feat: burg group editor - apply changes

This commit is contained in:
Azgaar 2024-10-09 00:33:22 +02:00
parent b6708bf698
commit b700bf0630
8 changed files with 102 additions and 29 deletions

21
main.js
View file

@ -151,10 +151,7 @@ let notes = [];
let rulers = new Rulers(); let rulers = new Rulers();
let customization = 0; let customization = 0;
let biomesData = Biomes.getDefault(); // global options; in v2.0 to be used for all UI settings
let nameBases = Names.getNameBases(); // cultures-related data
// default options, based on Earth data
let options = { let options = {
pinNotes: false, pinNotes: false,
winds: [225, 45, 225, 315, 135, 315], winds: [225, 45, 225, 315, 135, 315],
@ -163,21 +160,19 @@ let options = {
temperatureSouthPole: -15, temperatureSouthPole: -15,
stateLabelsMode: "auto", stateLabelsMode: "auto",
showBurgPreview: true, showBurgPreview: true,
villageMaxPopulation: 2000,
burgs: { burgs: {
groups: Burgs.getDefaultGroups() groups: Burgs.getDefaultGroups()
} }
}; };
// create groups for each burg type // global style object; in v2.0 to be used for all map styles and render settings
{ let style = {
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order); burgLabels: {},
for (const {name} of sortedGroups) { burgIcons: {}
burgIcons.append("g").attr("id", name); };
burgLabels.append("g").attr("id", name);
}
}
let biomesData = Biomes.getDefault();
let nameBases = Names.getNameBases(); // cultures-related data
let color = d3.scaleSequential(d3.interpolateSpectral); // default color scheme let color = d3.scaleSequential(d3.interpolateSpectral); // default color scheme
const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with default curve interpolation const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with default curve interpolation

View file

@ -189,7 +189,7 @@ window.Burgs = (() => {
.sort((a, b) => a - b); // ascending .sort((a, b) => a - b); // ascending
pack.burgs.forEach(burg => { pack.burgs.forEach(burg => {
if (!burg.i || burg.removed || burg.lock) return; if (!burg.i || burg.removed) return;
defineGroup(burg, populations); defineGroup(burg, populations);
}); });
@ -318,6 +318,12 @@ window.Burgs = (() => {
]; ];
function defineGroup(burg, populations) { function defineGroup(burg, populations) {
if (burg.lock) {
// locked bugrgs: don't change group if it still exists
const group = options.burgs.groups.find(g => g.name === burg.group);
if (group) return;
}
for (const group of options.burgs.groups) { for (const group of options.burgs.groups) {
if (!group.active) continue; if (!group.active) continue;
@ -404,5 +410,5 @@ window.Burgs = (() => {
return burgId; return burgId;
} }
return {generate, getDefaultGroups, specify, getType, add}; return {generate, getDefaultGroups, specify, defineGroup, getType, add};
})(); })();

View file

@ -838,7 +838,6 @@ export function resolveVersionConflicts(mapVersion) {
if (isOlderThan("1.97.0")) { if (isOlderThan("1.97.0")) {
// v1.97.00 changed MFCG link to an arbitrary preview URL // v1.97.00 changed MFCG link to an arbitrary preview URL
options.villageMaxPopulation = 2000;
options.showBurgPreview = options.showMFCGMap; options.showBurgPreview = options.showMFCGMap;
delete options.showMFCGMap; delete options.showMFCGMap;
@ -972,5 +971,7 @@ export function resolveVersionConflicts(mapVersion) {
options.burgs = { options.burgs = {
groups: groups.map(name => ({name, active: true, preview: null})) groups: groups.map(name => ({name, active: true, preview: null}))
}; };
delete options.villageMaxPopulation;
} }
} }

View file

@ -2,8 +2,7 @@
function drawBurgIcons() { function drawBurgIcons() {
TIME && console.time("drawBurgIcons"); TIME && console.time("drawBurgIcons");
createIconGroups();
icons.selectAll("circle, use").remove(); // cleanup
for (const {name} of options.burgs.groups) { for (const {name} of options.burgs.groups) {
const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed); const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed);
@ -49,3 +48,27 @@ function drawBurgIcon(burg) {
.attr("x", burg.x) .attr("x", burg.x)
.attr("y", burg.y); .attr("y", burg.y);
} }
function createIconGroups() {
const defaultStyle = style.burgIcons.towns || Object.values(style.burgIcons)[0];
// save existing styles and remove all groups
document.querySelectorAll("g#burgIcons > g").forEach(group => {
const groupStyle = Object.keys(defaultStyle).reduce((acc, key) => {
acc[key] = group.getAttribute(key);
return acc;
}, {});
style.burgIcons[group.id] = groupStyle;
group.remove();
});
// create groups for each burg group and apply stored or default style
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order);
for (const {name} of sortedGroups) {
const group = burgIcons.append("g").attr("id", name);
const styles = style.burgIcons[name] || defaultStyle;
Object.entries(styles).forEach(([key, value]) => {
group.attr(key, value);
});
}
}

View file

@ -2,8 +2,7 @@
function drawBurgLabels() { function drawBurgLabels() {
TIME && console.time("drawBurgLabels"); TIME && console.time("drawBurgLabels");
createLabelGroups();
burgLabels.selectAll("text").remove(); // cleanup
for (const {name} of options.burgs.groups) { for (const {name} of options.burgs.groups) {
const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed); const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed);
@ -39,3 +38,27 @@ function drawBurgLabel(burg) {
.attr("dy", "-0.4em") .attr("dy", "-0.4em")
.text(burg.name); .text(burg.name);
} }
function createLabelGroups() {
const defaultStyle = style.burgLabels.towns || Object.values(style.burgLabels)[0];
// save existing styles and remove all groups
document.querySelectorAll("g#burgLabels > g").forEach(group => {
const groupStyle = Object.keys(defaultStyle).reduce((acc, key) => {
acc[key] = group.getAttribute(key);
return acc;
}, {});
style.burgLabels[group.id] = groupStyle;
group.remove();
});
// create groups for each burg group and apply stored or default style
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order);
for (const {name} of sortedGroups) {
const group = burgLabels.append("g").attr("id", name);
const styles = style.burgLabels[name] || defaultStyle;
Object.entries(styles).forEach(([key, value]) => {
group.attr(key, value);
});
}
}

View file

@ -211,6 +211,7 @@ function editBurgGroups() {
el.previousElementSibling.value = JSON.stringify(values); el.previousElementSibling.value = JSON.stringify(values);
el.innerHTML = Object.keys(values).length ? "some" : "any"; el.innerHTML = Object.keys(values).length ? "some" : "any";
$(this).dialog("close"); $(this).dialog("close");
}, },
Cancel: function () { Cancel: function () {
@ -305,6 +306,14 @@ function editBurgGroups() {
return group; return group;
}); });
// put burgs to new groups
const validBurgs = pack.burgs.filter(b => b.i && !b.removed);
const populations = validBurgs.map(b => b.population).sort((a, b) => a - b);
validBurgs.forEach(burg => Burgs.defineGroup(burg, populations));
if (layerIsOn("toggleBurgIcons")) drawBurgIcons();
if (layerIsOn("toggleLabels")) drawBurgLabels();
$("#burgGroupsEditor").dialog("close"); $("#burgGroupsEditor").dialog("close");
} }
} }

View file

@ -240,13 +240,10 @@ function togglePort(burg) {
.attr("height", size); .attr("height", size);
} }
// TODO: rework this function to use the new data structure
function getBurgLink(burg) { function getBurgLink(burg) {
if (burg.link) return burg.link; if (burg.link) return burg.link;
if (burg.citadel || burg.walls || burg.temple || burg.shanty) return createMfcgLink(burg);
const population = burg.population * populationRate * urbanization;
if (population >= options.villageMaxPopulation || burg.citadel || burg.walls || burg.temple || burg.shanty)
return createMfcgLink(burg);
return createVillageGeneratorLink(burg); return createVillageGeneratorLink(burg);
} }

View file

@ -71,13 +71,22 @@ async function fetchSystemPreset(preset) {
} }
} }
function applyStyle(style) { function applyStyle(styleJSON) {
for (const selector in style) { for (const selector in styleJSON) {
if (selector.startsWith("#burgLabels")) {
const group = selector.replace("#burgLabels > g#", "");
style.burgLabels[group] = styleJSON[selector];
}
if (selector.startsWith("#burgIcons")) {
const group = selector.replace("#burgIcons > g#", "");
style.burgIcons[group] = styleJSON[selector];
}
const el = document.querySelector(selector); const el = document.querySelector(selector);
if (!el) continue; if (!el) continue;
for (const attribute in style[selector]) { for (const attribute in styleJSON[selector]) {
const value = style[selector][attribute]; const value = styleJSON[selector][attribute];
if (value === "null" || value === null) { if (value === "null" || value === null) {
el.removeAttribute(attribute); el.removeAttribute(attribute);
@ -342,8 +351,18 @@ function addStylePreset() {
"stroke-dasharray", "stroke-dasharray",
"stroke-linecap" "stroke-linecap"
]; ];
const burgLabelsAttributes = [
"opacity",
"fill",
"text-shadow",
"letter-spacing",
"data-size",
"font-size",
"font-family"
];
options.burgs.groups.forEach(({name}) => { options.burgs.groups.forEach(({name}) => {
attributes[`#burgIcons > g.${name}`] = burgIconsAttributes; attributes[`#burgIcons > g.${name}`] = burgIconsAttributes;
attributes[`#burgLabels > g#${name}`] = burgLabelsAttributes;
}); });
for (const selector in attributes) { for (const selector in attributes) {