From ab529a823c79a6dfe038e732c7342c34f2577f2f Mon Sep 17 00:00:00 2001 From: kruschen Date: Sun, 25 Aug 2024 21:16:34 +0000 Subject: [PATCH 01/27] fix options year missing --- src/main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 290f6cd6..57973304 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,7 +20,8 @@ options = { pinNotes: false, showMFCGMap: true, winds: [225, 45, 225, 315, 135, 315], - stateLabelsMode: "auto" + stateLabelsMode: "auto", + year: 0, }; checkForUpdates(); From 1dc735421669e0ac01ce611c39ba30f1ce8e3bab Mon Sep 17 00:00:00 2001 From: kruschen Date: Sun, 25 Aug 2024 21:17:00 +0000 Subject: [PATCH 02/27] fix dublicated value --- src/scripts/generation/pack/burgsAndStates/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scripts/generation/pack/burgsAndStates/config.ts b/src/scripts/generation/pack/burgsAndStates/config.ts index 6c660f39..2e860ef8 100644 --- a/src/scripts/generation/pack/burgsAndStates/config.ts +++ b/src/scripts/generation/pack/burgsAndStates/config.ts @@ -77,7 +77,6 @@ export const culturalTheocracyFormsMap: {[key: number]: {[key in TMonarchyForms] [NB.Roman]: Catholic, [NB.Portuguese]: Catholic, [NB.Ruthenian]: Orthodox, - [NB.Ruthenian]: Orthodox, [NB.Turkish]: Islamic, [NB.Nigerian]: Islamic, [NB.Berber]: Islamic, From 743e9bbbb160debdbbdb7e60484df49f88c87553 Mon Sep 17 00:00:00 2001 From: kruschen Date: Sun, 25 Aug 2024 21:17:52 +0000 Subject: [PATCH 03/27] update toggle to check for NoElements instead of i --- src/layers/toggles.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/layers/toggles.ts b/src/layers/toggles.ts index 27ab35fc..40e107e8 100644 --- a/src/layers/toggles.ts +++ b/src/layers/toggles.ts @@ -9,6 +9,7 @@ import {calculateFriendlyGridSize, editStyle, shiftCompass} from "modules/ui/sty import {getInputNumber, getInputValue} from "utils/nodeUtils"; import {renderLayer} from "./renderers"; import {layerIsOn, turnLayerButtonOff, turnLayerButtonOn} from "./utils"; +import { isCulture, isReligion } from "utils/typeUtils"; const layerTogglesMap = { toggleBiomes, @@ -187,7 +188,7 @@ function toggleIce(event?: MouseEvent) { } function toggleCultures(event?: MouseEvent) { - const cultures = pack.cultures.filter(({i, removed}) => i && !removed); + const cultures = pack.cultures.filter((culture) => isCulture(culture) && !culture.removed); const empty = !cults.selectAll("path").size(); if (empty && cultures.length) { turnLayerButtonOn("toggleCultures"); @@ -204,7 +205,7 @@ function toggleCultures(event?: MouseEvent) { } function toggleReligions(event?: MouseEvent) { - const religions = pack.religions.filter(({i, removed}) => i && !removed); + const religions = pack.religions.filter((religion) => isReligion(religion) && !religion.removed); if (!relig.selectAll("path").size() && religions.length) { turnLayerButtonOn("toggleReligions"); renderLayer("religions"); From 3b6f8349ef521d38ab932ea160ec919f5fd5f923 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 00:34:19 +0000 Subject: [PATCH 04/27] utils import is now condensed into "/utils" --- src/dialogs/dialogs/ice-editor.ts | 19 +++++++------------ src/utils/index.ts | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 src/utils/index.ts diff --git a/src/dialogs/dialogs/ice-editor.ts b/src/dialogs/dialogs/ice-editor.ts index db24c291..8f98b770 100644 --- a/src/dialogs/dialogs/ice-editor.ts +++ b/src/dialogs/dialogs/ice-editor.ts @@ -1,19 +1,14 @@ import * as d3 from "d3"; -import {closeDialogs} from "dialogs/utils"; -import {layerIsOn, toggleLayer} from "layers"; -import {clearMainTip, tip} from "scripts/tooltips"; -import {findGridCell, getGridPolygon} from "utils/graphUtils"; -import {getInputNumber} from "utils/nodeUtils"; -import {rn} from "utils/numberUtils"; -import {rand} from "utils/probabilityUtils"; -import {byId} from "utils/shorthands"; -import {parseTransform} from "utils/stringUtils"; +import { closeDialogs } from "dialogs/utils"; +import { layerIsOn, toggleLayer } from "layers"; +import { clearMainTip, tip } from "scripts/tooltips"; +import { byId, findGridCell, getGridPolygon, getInputNumber, parseTransform, rand, rn } from "utils"; // @ts-expect-error js module -import {editStyle} from "modules/style"; -import {setDefaultEventHandlers} from "scripts/events"; +import { editStyle } from "modules/style"; +import { setDefaultEventHandlers } from "scripts/events"; // @ts-expect-error js module -import {unselect} from "modules/ui/editors"; +import { unselect } from "modules/ui/editors"; let isLoaded = false; diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..9a0f2088 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,18 @@ +export * from "./arrayUtils"; +export * from "./colorUtils"; +export * from "./coordinateUtils"; +export * from "./debugUtils"; +export * from "./errorUtils"; +export * from "./functionUtils"; +export * from "./graphUtils"; +export * from "./keyboardUtils"; +export * from "./languageUtils"; +export * from "./lineUtils"; +export * from "./linkUtils"; +export * from "./nodeUtils"; +export * from "./numberUtils"; +export * from "./probabilityUtils"; +export * from "./shorthands"; +export * from "./stringUtils"; +export * from "./typeUtils"; +export * from "./unitUtils"; \ No newline at end of file From f90652b68c3d333e3aae1345b8f259d95cfad537 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 00:34:38 +0000 Subject: [PATCH 05/27] jquery type imports --- src/main.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.ts b/src/main.ts index 57973304..b9f8452c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,8 @@ // https://github.com/Azgaar/Fantasy-Map-Generator import "./components"; +import "jquery"; +import "jqueryui"; // @ts-expect-error js-module import {defineSvg} from "./modules/define-svg"; // @ts-expect-error js-module From 195a4676adb124d9b18e043cc358db160368d107 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 19:23:30 +0000 Subject: [PATCH 06/27] Burg Type now filtered properly in generations.ts --- src/scripts/generation/generation.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/scripts/generation/generation.ts b/src/scripts/generation/generation.ts index 25b0f581..fa9978e6 100644 --- a/src/scripts/generation/generation.ts +++ b/src/scripts/generation/generation.ts @@ -26,6 +26,7 @@ import {createGrid} from "./grid/grid"; import {createPack} from "./pack/pack"; import {getInputValue, setInputValue} from "utils/nodeUtils"; import {calculateMapCoordinates} from "modules/coordinates"; +import { isBurg } from "utils/typeUtils"; const {Zoom, ThreeD} = window; @@ -195,6 +196,7 @@ function focusOn() { if (burgParam) { const burg = isNaN(+burgParam) ? pack.burgs.find(burg => burg.name === burgParam) : pack.burgs[+burgParam]; if (!burg) return; + if (!isBurg(burg)) return; const {x, y} = burg; Zoom.to(x, y, scale, 1600); @@ -209,8 +211,8 @@ function focusOn() { // find burg for MFCG and focus on it function findBurgForMFCG(params: URLSearchParams) { - const {cells, burgs} = pack; - + const {cells, burgs: burgsT} = pack; + const burgs = burgsT.filter(isBurg); if (pack.burgs.length < 2) { ERROR && console.error("Cannot select a burg for MFCG"); return; @@ -247,13 +249,13 @@ function findBurgForMFCG(params: URLSearchParams) { if (param === "name") b.name = value; else if (param === "size") b.population = +value; else if (param === "seed") b.MFCG = +value; - else if (param === "shantytown") b.shanty = +value; + else if (param === "shantytown") b.shanty = +value > 0 ? 1 : 0; } const nameParam = params.get("name"); if (nameParam && nameParam !== "null") b.name = nameParam; - const label = burgLabels.select("[data-id='" + burgId + "']"); + const label = burgLabels.select("[data-id='" + burgId + "']"); if (label.size()) { label .text(b.name) From 7519ed097e974a0096c29bea43b906eee0d6433d Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 20:57:02 +0000 Subject: [PATCH 07/27] renderer type files for current js files --- src/layers/renderers/drawCoordinates.d.ts | 5 +++++ src/layers/renderers/drawEmblems.d.ts | 5 +++++ src/layers/renderers/drawGrid.d.ts | 5 +++++ src/layers/renderers/drawHeightmap.d.ts | 5 +++++ src/layers/renderers/drawIce.d.ts | 5 +++++ src/layers/renderers/drawMarkers.d.ts | 5 +++++ src/layers/renderers/drawPerciption.d.ts | 5 +++++ src/layers/renderers/drawPopulation.d.ts | 5 +++++ src/layers/renderers/drawTemperature.d.ts | 5 +++++ src/layers/renderers/index.ts | 24 ++++++++++++----------- 10 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 src/layers/renderers/drawCoordinates.d.ts create mode 100644 src/layers/renderers/drawEmblems.d.ts create mode 100644 src/layers/renderers/drawGrid.d.ts create mode 100644 src/layers/renderers/drawHeightmap.d.ts create mode 100644 src/layers/renderers/drawIce.d.ts create mode 100644 src/layers/renderers/drawMarkers.d.ts create mode 100644 src/layers/renderers/drawPerciption.d.ts create mode 100644 src/layers/renderers/drawPopulation.d.ts create mode 100644 src/layers/renderers/drawTemperature.d.ts diff --git a/src/layers/renderers/drawCoordinates.d.ts b/src/layers/renderers/drawCoordinates.d.ts new file mode 100644 index 00000000..9c8a0ccc --- /dev/null +++ b/src/layers/renderers/drawCoordinates.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawCoordinates.d.ts +declare module 'drawCoordinates.js' { + export function drawCoordinates(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawEmblems.d.ts b/src/layers/renderers/drawEmblems.d.ts new file mode 100644 index 00000000..b11d4259 --- /dev/null +++ b/src/layers/renderers/drawEmblems.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawEmblems.d.ts +declare module 'drawEmblems.js' { + export function drawEmblems(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawGrid.d.ts b/src/layers/renderers/drawGrid.d.ts new file mode 100644 index 00000000..6a933128 --- /dev/null +++ b/src/layers/renderers/drawGrid.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawGrid.d.ts +declare module 'drawGrid.js' { + export function drawGrid(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawHeightmap.d.ts b/src/layers/renderers/drawHeightmap.d.ts new file mode 100644 index 00000000..ee8676e1 --- /dev/null +++ b/src/layers/renderers/drawHeightmap.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawHeightmap.d.ts +declare module 'drawHeightmap.js' { + export function drawHeightmap(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawIce.d.ts b/src/layers/renderers/drawIce.d.ts new file mode 100644 index 00000000..cc12fef5 --- /dev/null +++ b/src/layers/renderers/drawIce.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawIce.d.ts +declare module 'drawIce.js' { + export function drawIce(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawMarkers.d.ts b/src/layers/renderers/drawMarkers.d.ts new file mode 100644 index 00000000..74033677 --- /dev/null +++ b/src/layers/renderers/drawMarkers.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawMarkers.d.ts +declare module 'drawMarkers.js' { + export function drawMarkers(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawPerciption.d.ts b/src/layers/renderers/drawPerciption.d.ts new file mode 100644 index 00000000..46fab332 --- /dev/null +++ b/src/layers/renderers/drawPerciption.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawPrecipitation.d.ts +declare module 'drawPrecipitation.js' { + export function drawPrecipitation(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawPopulation.d.ts b/src/layers/renderers/drawPopulation.d.ts new file mode 100644 index 00000000..e65e6ddb --- /dev/null +++ b/src/layers/renderers/drawPopulation.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawPopulation.d.ts +declare module 'drawPopulation.js' { + export function drawPopulation(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/drawTemperature.d.ts b/src/layers/renderers/drawTemperature.d.ts new file mode 100644 index 00000000..cee84975 --- /dev/null +++ b/src/layers/renderers/drawTemperature.d.ts @@ -0,0 +1,5 @@ +// src/layers/renderers/drawTemperature.d.ts +declare module 'drawTemperature.js' { + export function drawTemperature(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/layers/renderers/index.ts b/src/layers/renderers/index.ts index ce5ba093..6d42d021 100644 --- a/src/layers/renderers/index.ts +++ b/src/layers/renderers/index.ts @@ -3,23 +3,23 @@ import {drawBiomes} from "./drawBiomes"; import {drawBorders} from "./drawBorders"; import {drawBurgs} from "./drawBurgs"; import {drawCells} from "./drawCells"; -import {drawCoordinates} from "./drawCoordinates"; +import {drawCoordinates} from "drawCoordinates.js"; //MARKER: drawCoordinates.js import {drawCultures} from "./drawCultures"; -import {drawEmblems} from "./drawEmblems"; +import {drawEmblems} from "drawEmblems.js"; //MARKER: drawEmblems.js import {drawFeatures} from "./drawFeatures"; -import {drawGrid} from "./drawGrid"; -import {drawHeightmap} from "./drawHeightmap"; -import {drawIce} from "./drawIce"; +import {drawGrid} from "drawGrid.js"; //MARKER: drawGrid.js +import {drawHeightmap} from "drawHeightmap.js"; +import {drawIce} from "drawIce.js"; //MARKER: drawIce.js import {drawLabels} from "./drawLabels"; -import {drawMarkers} from "./drawMarkers"; -import {drawPopulation} from "./drawPopulation"; -import {drawPrecipitation} from "./drawPrecipitation"; +import {drawMarkers} from "drawMarkers.js"; //MARKER: drawMarkers.js +import {drawPopulation} from "drawPopulation.js"; //MARKER: drawPopulation.js +import {drawPrecipitation} from "drawPrecipitation.js"; //MARKER: drawPrecipitation.js import {drawProvinces} from "./drawProvinces"; import {drawReligions} from "./drawReligions"; import {drawRivers} from "./drawRivers"; import {drawRoutes} from "./drawRoutes"; import {drawStates} from "./drawStates"; -import {drawTemperature} from "./drawTemperature"; +import {drawTemperature} from "drawTemperature.js"; //MARKER: drawTemperature.js // Note: missed renderers are in toggle functions const layerRenderersMap = { @@ -46,9 +46,11 @@ const layerRenderersMap = { temperature: drawTemperature }; -export function renderLayer(layerName: keyof typeof layerRenderersMap, ...args: any[]) { +// export function renderLayer(layerName: keyof typeof layerRenderersMap, ...args: any[]) { +export function renderLayer(layerName: keyof typeof layerRenderersMap) { const renderer = layerRenderersMap[layerName]; TIME && console.time(renderer.name); - renderer(...args); + // renderer(...args); MARKER: for now we are not passing any arguments + renderer(); TIME && console.timeEnd(renderer.name); } From c3dd1d9e6f2557d7cf12d82cecd4020dac1b7aef Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 21:00:05 +0000 Subject: [PATCH 08/27] burg check added to unitUtils population conversion --- src/utils/unitUtils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/unitUtils.ts b/src/utils/unitUtils.ts index 0f6d5aca..0b46c082 100644 --- a/src/utils/unitUtils.ts +++ b/src/utils/unitUtils.ts @@ -1,6 +1,7 @@ import {rn} from "./numberUtils"; import {findCell, findGridCell} from "./graphUtils"; import {getInputNumber, getInputValue} from "./nodeUtils"; +import { isBurg } from "./typeUtils"; // *** // SI @@ -136,7 +137,8 @@ export function getBurgPopulationPoints(burgPopulationValue: number) { export function getCellPopulation(cellId: number) { const rural = getRuralPopulation(pack.cells.pop[cellId]); const burgId = pack.cells.burg[cellId]; - const urban = burgId ? getBurgPopulation(pack.burgs[burgId].population) : 0; + const burg = pack.burgs[burgId]; + const urban = isBurg(burg) ? getBurgPopulation(burg.population) : 0; return [rural, urban]; } From cdb8d29e62320fec777dc0f3ec3a9807dbcffe25 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 21:02:59 +0000 Subject: [PATCH 09/27] onhover resolved most types, few are temporary hacks marked with MARKER --- src/modules/ui/cell-info.d.ts | 5 +++++ src/scripts/events/onhover.ts | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 src/modules/ui/cell-info.d.ts diff --git a/src/modules/ui/cell-info.d.ts b/src/modules/ui/cell-info.d.ts new file mode 100644 index 00000000..ec677eea --- /dev/null +++ b/src/modules/ui/cell-info.d.ts @@ -0,0 +1,5 @@ +// src/modules/ui/cell-info.d.ts +declare module 'modules/ui/cell-info.js' { + export function updateCellInfo(coords: [number, number], cellId: number, gridCell: any): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/scripts/events/onhover.ts b/src/scripts/events/onhover.ts index 90da1d71..310cc628 100644 --- a/src/scripts/events/onhover.ts +++ b/src/scripts/events/onhover.ts @@ -1,7 +1,7 @@ import * as d3 from "d3"; import {layerIsOn} from "layers"; -import {updateCellInfo} from "modules/ui/cell-info"; +import {updateCellInfo} from "modules/ui/cell-info.js"; import {debounce} from "utils/functionUtils"; import {findCell, findGridCell, isLand} from "utils/graphUtils"; import {byId} from "utils/shorthands"; @@ -16,7 +16,7 @@ import { } from "utils/unitUtils"; import {showMainTip, tip} from "scripts/tooltips"; import {defineEmblemData} from "./utils"; -import {isState} from "utils/typeUtils"; +import {isBurg, isProvince, isReligion, isState} from "utils/typeUtils"; export const onMouseMove = debounce(handleMouseMove, 100); @@ -107,7 +107,7 @@ const onHoverEventsMap: OnHoverEventMap = { const emblemData = defineEmblemData(element); if (emblemData) { const {type, el} = emblemData; - const name = ("fullName" in el && el.fullName) || el.name; + const name = el !== 0 && (("fullname" in el && el.fullname) || el.name); //MARKER: el nutral check tip(`${name} ${type} emblem. Click to edit`); } }, @@ -127,7 +127,10 @@ const onHoverEventsMap: OnHoverEventMap = { burg: ({path}) => { const burgId = +(path.at(-10)?.dataset.id || 0); - const {population, name} = pack.burgs[burgId]; + const burg = pack.burgs[burgId]; + let population = 0; + const name = burg.name; + isBurg(burg) && (population = burg.population); tip(`${name}. Population: ${si(getBurgPopulation(population))}. Click to edit`); highlightDialogLine("burgOverview", burgId, 5000); @@ -153,7 +156,8 @@ const onHoverEventsMap: OnHoverEventMap = { lake: ({element, subgroup}) => { const lakeId = +(element.dataset.f || 0); - const name = pack.features[lakeId]?.name; + const lake = pack.features[lakeId]; + const name = lake ? (lake as IPackFeatureLake).name : ""; //MARKER: as IPackFeatureLake const fullName = subgroup === "freshwater" ? name : name + " " + subgroup; tip(`${fullName} lake. Click to edit`); }, @@ -187,7 +191,8 @@ const onHoverEventsMap: OnHoverEventMap = { religionsLayer: ({packCellId}) => { const religionId = pack.cells.religion[packCellId]; - const {type, name} = pack.religions[religionId] || {}; + const religion = pack.religions[religionId]; + const {type, name} = isReligion(religion) ? religion : {}; //MARKER: religion check const typeTip = type === "Cult" || type == "Heresy" ? type : type + " religion"; tip(`${typeTip}: ${name}`); @@ -200,7 +205,8 @@ const onHoverEventsMap: OnHoverEventMap = { const stateName = isState(state) ? state.fullName : state.name; const provinceId = pack.cells.province[packCellId]; - const provinceName = provinceId ? `${pack.provinces[provinceId].fullName}, ` : ""; + const province = pack.provinces[provinceId]; + const provinceName = isProvince(province) ? `${province.fullName}, ` : ""; tip(provinceName + stateName); highlightDialogLine("statesEditor", stateId); From 509fc8ca0b3d9c5e019b83161576370c5ccbab48 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 21:03:33 +0000 Subject: [PATCH 10/27] province type enforced on province generation --- .../generation/pack/provinces/generateCoreProvinces.ts | 4 ++-- .../generation/pack/provinces/generateWildProvinces.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scripts/generation/pack/provinces/generateCoreProvinces.ts b/src/scripts/generation/pack/provinces/generateCoreProvinces.ts index 84c804f9..09141663 100644 --- a/src/scripts/generation/pack/provinces/generateCoreProvinces.ts +++ b/src/scripts/generation/pack/provinces/generateCoreProvinces.ts @@ -35,8 +35,8 @@ export function generateCoreProvinces(states: TStates, burgs: TBurgs, cultures: const fullName = name + " " + formName; const color = brighter(getMixedColor(state.color, 0.2), 0.3); const coa = generateEmblem(nameByBurg, burgEmblem, type, cultures, cultureId, state); - - provinces.push({i: provinces.length + 1, name, formName, center, burg, state: state.i, fullName, color, coa}); + const province : IProvince = {i: provinces.length + 1, name, formName, center, burg, state: state.i, fullName, color, coa,pole: state.pole}; + provinces.push(province); } }); diff --git a/src/scripts/generation/pack/provinces/generateWildProvinces.ts b/src/scripts/generation/pack/provinces/generateWildProvinces.ts index f9f64c5e..4a049d0a 100644 --- a/src/scripts/generation/pack/provinces/generateWildProvinces.ts +++ b/src/scripts/generation/pack/provinces/generateWildProvinces.ts @@ -54,8 +54,8 @@ export function generateWildProvinces({ const coa = generateEmblem(formName, state, burg, cultureId); const color = brighter(getMixedColor(state.color, 0.2), 0.3); - - wildProvinces.push({i: provinceId, name, formName, center, burg: burgId, state: state.i, fullName, color, coa}); + const province : IProvince = {i: provinceId, name, formName, center, burg: burgId, state: state.i, fullName, color, coa, pole: state.pole}; + wildProvinces.push(province); // re-check noProvinceCellsInState = noProvinceCells.filter(i => cells.state[i] === state.i && !provinceIds[i]); From 09591a180b88e588eb7ce616b14fb39e57d00cd9 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 21:05:25 +0000 Subject: [PATCH 11/27] fix for ice-editor types data will be seperated later --- src/dialogs/dialogs/ice-editor.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dialogs/dialogs/ice-editor.ts b/src/dialogs/dialogs/ice-editor.ts index 8f98b770..f944560f 100644 --- a/src/dialogs/dialogs/ice-editor.ts +++ b/src/dialogs/dialogs/ice-editor.ts @@ -16,7 +16,7 @@ export function open() { closeDialogs(".stable"); if (!layerIsOn("toggleIce")) toggleLayer("toggleIce"); - elSelected = d3.select(d3.event.target); + const elSelected = d3.select(d3.event.target); const type = elSelected.attr("type") ? "Glacier" : "Iceberg"; if (byId("iceRandomize")) byId("iceRandomize")!.style.display = type === "Glacier" ? "none" : "inline-block"; @@ -26,7 +26,7 @@ export function open() { $iceSize.style.display = type === "Glacier" ? "none" : "inline-block"; if (type === "Iceberg") $iceSize.value = elSelected.attr("size"); } - ice.selectAll("*").classed("draggable", true).call(d3.drag().on("drag", dragElement)); + ice.selectAll("*").classed("draggable", true).on("drag", dragElement); $("#iceEditor").dialog({ title: "Edit " + type, @@ -53,7 +53,7 @@ export function open() { const cn = grid.points[i]; const poly = getGridPolygon(i).map(p => [p[0] - cn[0], p[1] - cn[1]]); const points = poly.map(p => [rn(c[0] + p[0] * s, 2), rn(c[1] + p[1] * s, 2)]); - elSelected.attr("points", points); + elSelected.attr("points", points.flat().toString()); } function changeSize(this: HTMLInputElement) { @@ -69,13 +69,13 @@ export function open() { const poly = pairs.map(p => [(p[0] - c[0]) / s, (p[1] - c[1]) / s]); const size = +this.value; const points = poly.map(p => [rn(c[0] + p[0] * size, 2), rn(c[1] + p[1] * size, 2)]); - elSelected.attr("points", points).attr("size", size); + elSelected.attr("points", points.toString()).attr("size", size); } function toggleAdd() { byId("iceNew")?.classList.toggle("pressed"); if (byId("iceNew")?.classList.contains("pressed")) { - viewbox.style("cursor", "crosshair").on("click", addIcebergOnClick); + viewbox.style("cursor", "crosshair").on("click",() => addIcebergOnClick); tip("Click on map to create an iceberg. Hold Shift to add multiple", true); } else { clearMainTip(); @@ -90,8 +90,8 @@ export function open() { const s = getInputNumber("iceSize"); const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) / s) | 0, (p[1] + (c[1] - p[1]) / s) | 0]); - const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", s); - iceberg.call(d3.drag().on("drag", dragElement)); + const iceberg = ice.append("polygon").attr("points", points.flat().toString()).attr("cell", i).attr("size", s); + iceberg.on("drag", dragElement); if (d3.event.shiftKey === false) toggleAdd(); } @@ -114,7 +114,7 @@ export function open() { }); } - function dragElement(this: Element) { + function dragElement(this: SVGPolygonElement) { const tr = parseTransform(this.getAttribute("transform")); const dx = +tr[0] - d3.event.x; const dy = +tr[1] - d3.event.y; @@ -126,7 +126,7 @@ export function open() { } function closeEditor() { - ice.selectAll("*").classed("draggable", false).call(d3.drag().on("drag", null)); + ice.selectAll("*").classed("draggable", false).on("drag", null); clearMainTip(); byId("iceNew")?.classList.remove("pressed"); unselect(); From 7300d2eedd4a971bca4f5c7f8d9c027e6368ffb1 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 21:20:18 +0000 Subject: [PATCH 12/27] fix import in scripts/events for modules/legend --- src/modules/legend.d.ts | 6 ++++++ src/scripts/events/index.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 src/modules/legend.d.ts diff --git a/src/modules/legend.d.ts b/src/modules/legend.d.ts new file mode 100644 index 00000000..1aa67a45 --- /dev/null +++ b/src/modules/legend.d.ts @@ -0,0 +1,6 @@ +// src/modules/legend.d.ts +declare module 'modules/legend.js' { + export function clearLegend(): void; + export function dragLegendBox(): void; + // Add other exports as needed + } \ No newline at end of file diff --git a/src/scripts/events/index.ts b/src/scripts/events/index.ts index 977cfb3f..22c60a0c 100644 --- a/src/scripts/events/index.ts +++ b/src/scripts/events/index.ts @@ -4,7 +4,7 @@ import {openDialog} from "dialogs"; import {tip} from "scripts/tooltips"; import {handleMapClick} from "./onclick"; import {onMouseMove} from "./onhover"; -import {clearLegend, dragLegendBox} from "modules/legend"; +import {clearLegend, dragLegendBox} from "modules/legend.js"; //MARKER: modules/legend.js export function setDefaultEventHandlers() { window.Zoom.setZoomBehavior(); From 0e02e48a34ed4119daeec12d683a48cccafe4ee7 Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 22:35:05 +0000 Subject: [PATCH 13/27] allow js imports temporarily --- src/layers/renderers/drawCoordinates.d.ts | 5 ----- src/layers/renderers/drawEmblems.d.ts | 5 ----- src/layers/renderers/drawGrid.d.ts | 5 ----- src/layers/renderers/drawHeightmap.d.ts | 5 ----- src/layers/renderers/drawIce.d.ts | 5 ----- src/layers/renderers/drawMarkers.d.ts | 5 ----- src/layers/renderers/drawPerciption.d.ts | 5 ----- src/layers/renderers/drawPopulation.d.ts | 5 ----- src/layers/renderers/drawTemperature.d.ts | 5 ----- src/layers/renderers/index.ts | 18 +++++++++--------- tsconfig.json | 3 ++- 11 files changed, 11 insertions(+), 55 deletions(-) delete mode 100644 src/layers/renderers/drawCoordinates.d.ts delete mode 100644 src/layers/renderers/drawEmblems.d.ts delete mode 100644 src/layers/renderers/drawGrid.d.ts delete mode 100644 src/layers/renderers/drawHeightmap.d.ts delete mode 100644 src/layers/renderers/drawIce.d.ts delete mode 100644 src/layers/renderers/drawMarkers.d.ts delete mode 100644 src/layers/renderers/drawPerciption.d.ts delete mode 100644 src/layers/renderers/drawPopulation.d.ts delete mode 100644 src/layers/renderers/drawTemperature.d.ts diff --git a/src/layers/renderers/drawCoordinates.d.ts b/src/layers/renderers/drawCoordinates.d.ts deleted file mode 100644 index 9c8a0ccc..00000000 --- a/src/layers/renderers/drawCoordinates.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawCoordinates.d.ts -declare module 'drawCoordinates.js' { - export function drawCoordinates(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawEmblems.d.ts b/src/layers/renderers/drawEmblems.d.ts deleted file mode 100644 index b11d4259..00000000 --- a/src/layers/renderers/drawEmblems.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawEmblems.d.ts -declare module 'drawEmblems.js' { - export function drawEmblems(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawGrid.d.ts b/src/layers/renderers/drawGrid.d.ts deleted file mode 100644 index 6a933128..00000000 --- a/src/layers/renderers/drawGrid.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawGrid.d.ts -declare module 'drawGrid.js' { - export function drawGrid(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawHeightmap.d.ts b/src/layers/renderers/drawHeightmap.d.ts deleted file mode 100644 index ee8676e1..00000000 --- a/src/layers/renderers/drawHeightmap.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawHeightmap.d.ts -declare module 'drawHeightmap.js' { - export function drawHeightmap(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawIce.d.ts b/src/layers/renderers/drawIce.d.ts deleted file mode 100644 index cc12fef5..00000000 --- a/src/layers/renderers/drawIce.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawIce.d.ts -declare module 'drawIce.js' { - export function drawIce(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawMarkers.d.ts b/src/layers/renderers/drawMarkers.d.ts deleted file mode 100644 index 74033677..00000000 --- a/src/layers/renderers/drawMarkers.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawMarkers.d.ts -declare module 'drawMarkers.js' { - export function drawMarkers(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawPerciption.d.ts b/src/layers/renderers/drawPerciption.d.ts deleted file mode 100644 index 46fab332..00000000 --- a/src/layers/renderers/drawPerciption.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawPrecipitation.d.ts -declare module 'drawPrecipitation.js' { - export function drawPrecipitation(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawPopulation.d.ts b/src/layers/renderers/drawPopulation.d.ts deleted file mode 100644 index e65e6ddb..00000000 --- a/src/layers/renderers/drawPopulation.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawPopulation.d.ts -declare module 'drawPopulation.js' { - export function drawPopulation(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/drawTemperature.d.ts b/src/layers/renderers/drawTemperature.d.ts deleted file mode 100644 index cee84975..00000000 --- a/src/layers/renderers/drawTemperature.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/layers/renderers/drawTemperature.d.ts -declare module 'drawTemperature.js' { - export function drawTemperature(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/src/layers/renderers/index.ts b/src/layers/renderers/index.ts index 6d42d021..cdeac727 100644 --- a/src/layers/renderers/index.ts +++ b/src/layers/renderers/index.ts @@ -3,23 +3,23 @@ import {drawBiomes} from "./drawBiomes"; import {drawBorders} from "./drawBorders"; import {drawBurgs} from "./drawBurgs"; import {drawCells} from "./drawCells"; -import {drawCoordinates} from "drawCoordinates.js"; //MARKER: drawCoordinates.js +import {drawCoordinates} from "./drawCoordinates.js"; //MARKER: drawCoordinates.js import {drawCultures} from "./drawCultures"; -import {drawEmblems} from "drawEmblems.js"; //MARKER: drawEmblems.js +import {drawEmblems} from "./drawEmblems.js"; //MARKER: drawEmblems.js import {drawFeatures} from "./drawFeatures"; -import {drawGrid} from "drawGrid.js"; //MARKER: drawGrid.js -import {drawHeightmap} from "drawHeightmap.js"; -import {drawIce} from "drawIce.js"; //MARKER: drawIce.js +import {drawGrid} from "./drawGrid.js"; //MARKER: drawGrid.js +import {drawHeightmap} from "./drawHeightmap.js"; +import {drawIce} from "./drawIce.js"; //MARKER: drawIce.js import {drawLabels} from "./drawLabels"; -import {drawMarkers} from "drawMarkers.js"; //MARKER: drawMarkers.js -import {drawPopulation} from "drawPopulation.js"; //MARKER: drawPopulation.js -import {drawPrecipitation} from "drawPrecipitation.js"; //MARKER: drawPrecipitation.js +import {drawMarkers} from "./drawMarkers.js"; //MARKER: drawMarkers.js +import {drawPopulation} from "./drawPopulation.js"; //MARKER: drawPopulation.js +import {drawPrecipitation} from "./drawPrecipitation.js"; //MARKER: drawPrecipitation.js import {drawProvinces} from "./drawProvinces"; import {drawReligions} from "./drawReligions"; import {drawRivers} from "./drawRivers"; import {drawRoutes} from "./drawRoutes"; import {drawStates} from "./drawStates"; -import {drawTemperature} from "drawTemperature.js"; //MARKER: drawTemperature.js +import {drawTemperature} from "./drawTemperature.js"; //MARKER: drawTemperature.js // Note: missed renderers are in toggle functions const layerRenderersMap = { diff --git a/tsconfig.json b/tsconfig.json index 3f25b627..e5ef3dcc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,8 @@ "noImplicitReturns": true, "skipLibCheck": true, "types": ["vitest/globals"], - "baseUrl": "src" + "baseUrl": "src", + "allowJs": true, }, "include": ["src"] } From 185740b5fa88ace2e405cabafaa1ddf87b3e4f9a Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 26 Aug 2024 22:35:55 +0000 Subject: [PATCH 14/27] Revert "jquery type imports" This reverts commit f90652b68c3d333e3aae1345b8f259d95cfad537. --- src/main.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index b9f8452c..57973304 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,8 +2,6 @@ // https://github.com/Azgaar/Fantasy-Map-Generator import "./components"; -import "jquery"; -import "jqueryui"; // @ts-expect-error js-module import {defineSvg} from "./modules/define-svg"; // @ts-expect-error js-module From 7ceeaa071fef77083e5f7d9136431b8ebb06b703 Mon Sep 17 00:00:00 2001 From: kruschen Date: Tue, 27 Aug 2024 16:32:19 +0000 Subject: [PATCH 15/27] js files temporarly ignored for import, deleted leftover mapping --- src/layers/renderers/index.ts | 9 +++++++++ src/modules/legend.d.ts | 6 ------ tsconfig.json | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 src/modules/legend.d.ts diff --git a/src/layers/renderers/index.ts b/src/layers/renderers/index.ts index cdeac727..3a109cc4 100644 --- a/src/layers/renderers/index.ts +++ b/src/layers/renderers/index.ts @@ -3,22 +3,31 @@ import {drawBiomes} from "./drawBiomes"; import {drawBorders} from "./drawBorders"; import {drawBurgs} from "./drawBurgs"; import {drawCells} from "./drawCells"; +// @ts-expect-error js-module import {drawCoordinates} from "./drawCoordinates.js"; //MARKER: drawCoordinates.js import {drawCultures} from "./drawCultures"; +// @ts-expect-error js-module import {drawEmblems} from "./drawEmblems.js"; //MARKER: drawEmblems.js import {drawFeatures} from "./drawFeatures"; +// @ts-expect-error js-module import {drawGrid} from "./drawGrid.js"; //MARKER: drawGrid.js +// @ts-expect-error js-module import {drawHeightmap} from "./drawHeightmap.js"; +// @ts-expect-error js-module import {drawIce} from "./drawIce.js"; //MARKER: drawIce.js import {drawLabels} from "./drawLabels"; +// @ts-expect-error js-module import {drawMarkers} from "./drawMarkers.js"; //MARKER: drawMarkers.js +// @ts-expect-error js-module import {drawPopulation} from "./drawPopulation.js"; //MARKER: drawPopulation.js +// @ts-expect-error js-module import {drawPrecipitation} from "./drawPrecipitation.js"; //MARKER: drawPrecipitation.js import {drawProvinces} from "./drawProvinces"; import {drawReligions} from "./drawReligions"; import {drawRivers} from "./drawRivers"; import {drawRoutes} from "./drawRoutes"; import {drawStates} from "./drawStates"; +// @ts-expect-error js-module import {drawTemperature} from "./drawTemperature.js"; //MARKER: drawTemperature.js // Note: missed renderers are in toggle functions diff --git a/src/modules/legend.d.ts b/src/modules/legend.d.ts deleted file mode 100644 index 1aa67a45..00000000 --- a/src/modules/legend.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// src/modules/legend.d.ts -declare module 'modules/legend.js' { - export function clearLegend(): void; - export function dragLegendBox(): void; - // Add other exports as needed - } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index e5ef3dcc..aed3e220 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,9 +15,9 @@ "noUnusedParameters": true, "noImplicitReturns": true, "skipLibCheck": true, - "types": ["vitest/globals"], + "types": ["vitest/globals","jquery","jqueryui"], "baseUrl": "src", - "allowJs": true, + "allowJs": false, }, "include": ["src"] } From e4c837870c01467ef51dc927e79f4f7f26a50d4d Mon Sep 17 00:00:00 2001 From: kruschen Date: Tue, 27 Aug 2024 16:32:50 +0000 Subject: [PATCH 16/27] import js temporarily silenced --- src/scripts/events/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripts/events/index.ts b/src/scripts/events/index.ts index 22c60a0c..7e8e3619 100644 --- a/src/scripts/events/index.ts +++ b/src/scripts/events/index.ts @@ -4,6 +4,7 @@ import {openDialog} from "dialogs"; import {tip} from "scripts/tooltips"; import {handleMapClick} from "./onclick"; import {onMouseMove} from "./onhover"; +// @ts-expect-error js-module import {clearLegend, dragLegendBox} from "modules/legend.js"; //MARKER: modules/legend.js export function setDefaultEventHandlers() { From 19117a7ac5fe012a6e77dd16ed87fd664c729b4e Mon Sep 17 00:00:00 2001 From: kruschen Date: Tue, 27 Aug 2024 16:46:38 +0000 Subject: [PATCH 17/27] religion in onhover to have a well definde default --- src/scripts/events/onhover.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/events/onhover.ts b/src/scripts/events/onhover.ts index 310cc628..1d5d6f05 100644 --- a/src/scripts/events/onhover.ts +++ b/src/scripts/events/onhover.ts @@ -192,7 +192,7 @@ const onHoverEventsMap: OnHoverEventMap = { religionsLayer: ({packCellId}) => { const religionId = pack.cells.religion[packCellId]; const religion = pack.religions[religionId]; - const {type, name} = isReligion(religion) ? religion : {}; //MARKER: religion check + const {type, name} = isReligion(religion) ? religion : {type: "None", name: "None"}; //MARKER: religion check const typeTip = type === "Cult" || type == "Heresy" ? type : type + " religion"; tip(`${typeTip}: ${name}`); From 324d92613d99356b4553cae7e1938a6f8b32aa90 Mon Sep 17 00:00:00 2001 From: kruschen Date: Tue, 27 Aug 2024 16:47:22 +0000 Subject: [PATCH 18/27] render function does not need argument pack atm --- src/layers/toggles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layers/toggles.ts b/src/layers/toggles.ts index 40e107e8..ed88cbbe 100644 --- a/src/layers/toggles.ts +++ b/src/layers/toggles.ts @@ -364,7 +364,7 @@ function toggleTexture(event?: MouseEvent) { function toggleRivers(event?: MouseEvent) { if (!layerIsOn("toggleRivers")) { turnLayerButtonOn("toggleRivers"); - renderLayer("rivers", pack); + renderLayer("rivers"); if (isCtrlPressed(event)) editStyle("rivers"); } else { if (isCtrlPressed(event)) return editStyle("rivers"); From 70e77714b9d191bdf03bbebd9f17984bb0111857 Mon Sep 17 00:00:00 2001 From: kruschen Date: Wed, 28 Aug 2024 22:33:16 +0000 Subject: [PATCH 19/27] partial options typing --- src/modules/coa-renderer.js | 2 +- src/modules/ui/{options.js => options.ts} | 367 +++++++++++++--------- src/scripts/options/lock.ts | 2 +- 3 files changed, 223 insertions(+), 148 deletions(-) rename src/modules/ui/{options.js => options.ts} (75%) diff --git a/src/modules/coa-renderer.js b/src/modules/coa-renderer.js index 8c7e370b..10ed9a47 100644 --- a/src/modules/coa-renderer.js +++ b/src/modules/coa-renderer.js @@ -1,6 +1,6 @@ import {ERROR} from "config/logging"; -window.COArenderer = (function () { +export const COArenderer = (function () { const colors = { argent: "#fafafa", or: "#ffe066", diff --git a/src/modules/ui/options.js b/src/modules/ui/options.ts similarity index 75% rename from src/modules/ui/options.js rename to src/modules/ui/options.ts index 466e0aa1..2c823f87 100644 --- a/src/modules/ui/options.js +++ b/src/modules/ui/options.ts @@ -2,7 +2,7 @@ import * as d3 from "d3"; import {heightmapTemplates} from "config/heightmap-templates"; import {precreatedHeightmaps} from "config/precreated-heightmaps"; -import {lock, locked} from "scripts/options/lock"; +import {lock, locked, unlock} from "scripts/options/lock"; import {clearMainTip, tip} from "scripts/tooltips"; import {last} from "utils/arrayUtils"; import {applyDropdownOption} from "utils/nodeUtils"; @@ -10,15 +10,84 @@ import {minmax, rn} from "utils/numberUtils"; import {gauss, P, rand, rw} from "utils/probabilityUtils"; import {byId, stored} from "utils/shorthands"; import {regenerateMap} from "scripts/generation/generation"; -import {fitScaleBar} from "modules/measurers"; +// @ts-expect-error js file +import {fitScaleBar} from "modules/measurers.js"; import {openDialog} from "dialogs"; import {closeDialogs} from "dialogs/utils"; +// @ts-expect-error js file import {quickSave, saveToDropbox, dowloadMap} from "modules/io/save.js"; +// @ts-expect-error js file +import {fitLegendBox} from "modules/legend.js"; +// @ts-expect-error js file +import {COArenderer} from "modules/coa-renderer.js"; +import { isBurg, isCulture, isProvince, isState } from "utils/typeUtils.js"; $("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"}); $("#exitCustomization").draggable({handle: "div"}); $("#mapLayers").disableSelection(); +// Window Objects +const Zoom = window.Zoom; +const COA = window.COA; + +// DIV elements +const tooltip = byId("tooltip")! as HTMLDivElement; + +// Options pane elements +const optionsTrigger = byId("optionsTrigger")! as HTMLButtonElement; +const regenerate = byId("regenerate")! as HTMLButtonElement; +const optionsDiv = byId("options")! as HTMLDivElement; +const collapsible = byId("collapsible")! as HTMLDivElement; +const layersContent = byId("layersContent")! as HTMLDivElement; +const styleContent = byId("styleContent")! as HTMLDivElement; +const customizationMenu = byId("customizationMenu")! as HTMLDivElement; +const toolsContent = byId("toolsContent")! as HTMLDivElement; +const aboutContent = byId("aboutContent")! as HTMLDivElement; +const optionsContent = byId("optionsContent")! as HTMLDivElement; +const alertMessage = byId("alertMessage")! as HTMLDivElement; +const dialogDiv = byId("dialogs")! as HTMLDivElement; + +// Number inputs +const themeColorInput = byId("themeColorInput")! as HTMLInputElement; +const themeHueInput = byId("themeHueInput")! as HTMLInputElement; + +const transparencyInput = byId("transparencyInput")! as HTMLInputElement; +const transparencyOutput = byId("transparencyOutput")! as HTMLInputElement; + +const mapWidthInput = byId("mapWidthInput")! as HTMLInputElement; +const mapHeightInput = byId("mapHeightInput")! as HTMLInputElement; + +const zoomExtentMin = byId("zoomExtentMin")! as HTMLInputElement; +const zoomExtentMax = byId("zoomExtentMax")! as HTMLInputElement; + +const optionsSeed = byId("optionsSeed")! as HTMLInputElement; +const pointsInput = byId("pointsInput")! as HTMLInputElement; + +const culturesInput = byId("culturesInput")! as HTMLInputElement; +const regionsOutput = byId("regionsOutput")! as HTMLInputElement; + +const uiSizeInput = byId("uiSizeInput")! as HTMLInputElement; +const uiSizeOutput = byId("uiSizeOutput")! as HTMLInputElement; + +const distanceUnitInput = byId("distanceUnitInput")! as HTMLSelectElement; +const heightUnitInput = byId("heightUnitInput")! as HTMLSelectElement; + +// Text inputs +const mapName = byId("mapName")! as HTMLInputElement; +const templateInput = byId("templateInput")! as HTMLSelectElement +const culturesSet = byId("culturesSet")! as HTMLSelectElement; +const culturesOutput = byId("culturesOutput")! as HTMLInputElement; + +const stylePreset = byId("stylePreset")! as HTMLSelectElement; + +const shapeRendering = byId("shapeRendering")! as HTMLSelectElement; +const stateLabelsModeInput = byId("stateLabelsModeInput")! as HTMLSelectElement; + +// Outputs +const manorsOutput = byId("manorsOutput")! as HTMLOutputElement; +const pointsOutputFormatted = byId("pointsOutputFormatted")! as HTMLOutputElement; + + // remove glow if tip is aknowledged if (stored("disable_click_arrow_tooltip")) { clearMainTip(); @@ -26,37 +95,37 @@ if (stored("disable_click_arrow_tooltip")) { } // Show options pane on trigger click -function showOptions(event) { +function showOptions(event: MouseEvent) { if (!stored("disable_click_arrow_tooltip")) { clearMainTip(); - localStorage.setItem("disable_click_arrow_tooltip", true); + localStorage.setItem("disable_click_arrow_tooltip", "true"); optionsTrigger.classList.remove("glow"); } regenerate.style.display = "none"; - byId("options").style.display = "block"; + optionsDiv.style.display = "block"; optionsTrigger.style.display = "none"; if (event) event.stopPropagation(); } // Hide options pane on trigger click -export function hideOptions(event) { - byId("options").style.display = "none"; +export function hideOptions(event: Event) { + optionsDiv.style.display = "none"; optionsTrigger.style.display = "block"; if (event) event.stopPropagation(); } // To toggle options on hotkey press -export function toggleOptions(event) { - if (byId("options").style.display === "none") showOptions(event); +export function toggleOptions(event: MouseEvent) { + if (optionsDiv.style.display === "none") showOptions(event); else hideOptions(event); } // Toggle "New Map!" pane on hover optionsTrigger.on("mouseenter", function () { if (optionsTrigger.classList.contains("glow")) return; - if (byId("options").style.display === "none") regenerate.style.display = "block"; + if (optionsDiv.style.display === "none") regenerate.style.display = "block"; }); collapsible.on("mouseleave", function () { @@ -64,21 +133,19 @@ collapsible.on("mouseleave", function () { }); // Activate options tab on click -document - .getElementById("options") - .querySelector("div.tab") - .on("click", function (event) { +optionsDiv + .querySelector("div.tab")! + .on("click", function (event: any ) { // MARKER: any if (event.target.tagName !== "BUTTON") return; const id = event.target.id; - const active = byId("options").querySelector(".tab > button.active"); + const active = optionsDiv.querySelector(".tab > button.active"); if (active && id === active.id) return; // already active tab is clicked if (active) active.classList.remove("active"); - byId(id).classList.add("active"); - document - .getElementById("options") - .querySelectorAll(".tabcontent") - .forEach(e => (e.style.display = "none")); + byId(id)!.classList.add("active"); + optionsDiv + .querySelectorAll(".tabcontent") + .forEach((e: HTMLElement) => {e.style.display = "none"}); if (id === "layersTab") layersContent.style.display = "block"; else if (id === "styleTab") styleContent.style.display = "block"; @@ -90,9 +157,10 @@ document // show popup with a list of Patreon supportes (updated manually) async function showSupporters() { + // @ts-expect-error js file const {supporters} = await import("../dynamic/supporters.js"); alertMessage.innerHTML = - "
    " + supporters.map(n => `
  • ${n}
  • `).join("") + "
"; + "
    " + (supporters as String[]).map(n => `
  • ${n}
  • `).join("") + "
"; // MARKER: as conversion $("#alert").dialog({ resizable: false, title: "Patreon Supporters", @@ -102,16 +170,16 @@ async function showSupporters() { } // on any option or dialog change -byId("options").on("change", storeValueIfRequired); -byId("dialogs").on("change", storeValueIfRequired); -byId("options").on("input", updateOutputToFollowInput); -byId("dialogs").on("input", updateOutputToFollowInput); +optionsDiv.on("change", storeValueIfRequired); +dialogDiv.on("change", storeValueIfRequired); +optionsDiv.on("input", updateOutputToFollowInput); +dialogDiv.on("input", updateOutputToFollowInput); -function storeValueIfRequired(ev) { +function storeValueIfRequired(ev: any) { // MARKER: any if (ev.target.dataset.stored) lock(ev.target.dataset.stored); } -function updateOutputToFollowInput(ev) { +function updateOutputToFollowInput(ev: any) { // MARKER: any const id = ev.target.id; const value = ev.target.value; @@ -120,17 +188,17 @@ function updateOutputToFollowInput(ev) { // generic case if (id.slice(-5) === "Input") { - const output = byId(id.slice(0, -5) + "Output"); + const output = byId(id.slice(0, -5) + "Output") as HTMLOutputElement; // MARKER: as conversion if (output) output.value = value; } else if (id.slice(-6) === "Output") { - const input = byId(id.slice(0, -6) + "Input"); + const input = byId(id.slice(0, -6) + "Input") as HTMLInputElement; // MARKER: as conversion if (input) input.value = value; } } // Option listeners -const optionsContent = byId("optionsContent"); -optionsContent.on("input", function (event) { + +optionsContent.on("input", function (event: any) { // MARKER: any const id = event.target.id; const value = event.target.value; if (id === "mapWidthInput" || id === "mapHeightInput") mapSizeInputChange(); @@ -144,12 +212,12 @@ optionsContent.on("input", function (event) { else if (id === "transparencyInput") changeDialogsTheme(themeColorInput.value, value); }); -optionsContent.on("change", function (event) { +optionsContent.on("change", function (event: any) { // MARKER: any const id = event.target.id; const value = event.target.value; if (id === "zoomExtentMin" || id === "zoomExtentMax") changeZoomExtent(value); - else if (id === "optionsSeed") generateMapWithSeed("seed change"); + else if (id === "optionsSeed") generateMapWithSeed(); else if (id === "uiSizeInput" || id === "uiSizeOutput") changeUIsize(value); else if (id === "shapeRendering") setRendering(value); else if (id === "yearInput") changeYear(); @@ -157,7 +225,7 @@ optionsContent.on("change", function (event) { else if (id === "stateLabelsModeInput") options.stateLabelsMode = value; }); -optionsContent.on("click", function (event) { +optionsContent.on("click", function (event:any) { // MARKER: any const id = event.target.id; if (id === "toggleFullscreen") toggleFullscreen(); else if (id === "optionsMapHistory") showSeedHistoryDialog(); @@ -184,8 +252,8 @@ export function addResizeListener() { if (stored("mapWidth") && stored("mapHeight")) return; const {innerWidth, innerHeight} = window; - byId("mapWidthInput").value = innerWidth; - byId("mapHeightInput").value = innerHeight; + mapWidthInput.value = innerWidth.toString(); // MARKER: toString + mapHeightInput.value = innerHeight.toString(); // MARKER: toString changeMapSize(); }); @@ -193,14 +261,14 @@ export function addResizeListener() { // change svg size on manual size change or window resize, do not change graph size function changeMapSize() { - svgWidth = Math.min(+mapWidthInput.value, window.innerWidth); - svgHeight = Math.min(+mapHeightInput.value, window.innerHeight); + svgWidth = Math.min(Number(mapWidthInput.value), window.innerWidth); + svgHeight = Math.min(Number(mapHeightInput.value), window.innerHeight); svg.attr("width", svgWidth).attr("height", svgHeight); - const maxWidth = Math.max(+mapWidthInput.value, graphWidth); - const maxHeight = Math.max(+mapHeightInput.value, graphHeight); + const maxWidth = Math.max(Number(mapWidthInput.value), graphWidth); + const maxHeight = Math.max(Number(mapHeightInput.value), graphHeight); - Zoom.translateExtent([0, 0, maxWidth, maxHeight]); + Zoom.translateExtent([[0, 0], [maxWidth, maxHeight]]); landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight); oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight); @@ -210,15 +278,15 @@ function changeMapSize() { texture.select("image").attr("width", maxWidth).attr("height", maxHeight); fitScaleBar(); - if (window.fitLegendBox) fitLegendBox(); + fitLegendBox(); } // just apply canvas size that was already set export function applyMapSize() { - const zoomMin = +zoomExtentMin.value; - const zoomMax = +zoomExtentMax.value; - graphWidth = +mapWidthInput.value; - graphHeight = +mapHeightInput.value; + const zoomMin = Number(zoomExtentMin.value); + const zoomMax = Number(zoomExtentMax.value); + graphWidth = Number(mapWidthInput.value); + graphHeight = Number(mapHeightInput.value); svgWidth = Math.min(graphWidth, window.innerWidth); svgHeight = Math.min(graphHeight, window.innerHeight); svg.attr("width", svgWidth).attr("height", svgHeight); @@ -231,19 +299,19 @@ export function applyMapSize() { } function toggleFullscreen() { - if (mapWidthInput.value != window.innerWidth || mapHeightInput.value != window.innerHeight) { - mapWidthInput.value = window.innerWidth; - mapHeightInput.value = window.innerHeight; + if (Number(mapWidthInput.value) != Number(window.innerWidth) || Number(mapHeightInput.value) != Number(window.innerHeight)) { + mapWidthInput.value = window.innerWidth.toString(); + mapHeightInput.value = window.innerHeight.toString(); localStorage.removeItem("mapHeight"); localStorage.removeItem("mapWidth"); } else { - mapWidthInput.value = graphWidth; - mapHeightInput.value = graphHeight; + mapWidthInput.value = graphWidth.toString(); + mapHeightInput.value = graphHeight.toString(); } changeMapSize(); } -function toggleTranslateExtent(el) { +function toggleTranslateExtent(el: any) { // MARKER: any const on = !Number(el.dataset.on); const extent = on ? [-graphWidth / 2, -graphHeight / 2, graphWidth * 1.5, graphHeight * 1.5] @@ -259,13 +327,13 @@ const voiceInterval = setInterval(function () { if (voices.length) clearInterval(voiceInterval); else return; - const select = byId("speakerVoice"); + const select = byId("speakerVoice")! as HTMLSelectElement; voices.forEach((voice, i) => { - select.options.add(new Option(voice.name, i, false)); + select.options.add(new Option(voice.name, i.toString(), false)); }); - if (stored("speakerVoice")) select.value = stored("speakerVoice"); + if (stored("speakerVoice")) select.value = stored("speakerVoice")!; // MARKER: ! // se voice to store - else select.value = voices.findIndex(voice => voice.lang === "en-US"); // or to first found English-US + else select.value = voices.findIndex(voice => voice.lang === "en-US").toString(); // or to first found English-US }, 1000); function testSpeaker() { @@ -273,7 +341,7 @@ function testSpeaker() { const speaker = new SpeechSynthesisUtterance(text); const voices = speechSynthesis.getVoices(); if (voices.length) { - const voiceId = +byId("speakerVoice").value; + const voiceId = Number((byId("speakerVoice") as HTMLInputElement).value); // MARKER: as conversion speaker.voice = voices[voiceId]; } speechSynthesis.speak(speaker); @@ -302,12 +370,12 @@ function showSeedHistoryDialog() { } // generate map with historical seed -function restoreSeed(id) { +function restoreSeed(id: number) { const {seed, width, height, template} = mapHistory[id]; - byId("optionsSeed").value = seed; - byId("mapWidthInput").value = width; - byId("mapHeightInput").value = height; - byId("templateInput").value = template; + optionsSeed.value = seed; + mapWidthInput.value = width.toString(); + mapHeightInput.value = height.toString(); + templateInput.value = template; if (locked("template")) unlock("template"); @@ -315,8 +383,8 @@ function restoreSeed(id) { } function restoreDefaultZoomExtent() { - zoomExtentMin.value = 1; - zoomExtentMax.value = 20; + zoomExtentMin.value = "1"; + zoomExtentMax.value = "20"; Zoom.scaleExtent([1, 20]); Zoom.scaleTo(svg, 1); } @@ -335,52 +403,52 @@ function copyMapURL() { .catch(err => tip("Could not copy URL: " + err, false, "error", 5000)); } -const cellsDensityMap = { - 1: 1000, - 2: 2000, - 3: 5000, - 4: 10000, - 5: 20000, - 6: 30000, - 7: 40000, - 8: 50000, - 9: 60000, - 10: 70000, - 11: 80000, - 12: 90000, - 13: 100000 -}; +const cellsDensityMap = [ + 1000, + 2000, + 5000, + 10000, + 20000, + 30000, + 40000, + 50000, + 60000, + 70000, + 80000, + 90000, + 100000 +]; -function changeCellsDensity(value) { +function changeCellsDensity(value: number) { const cells = cellsDensityMap[value] || 1000; - pointsInput.dataset.cells = cells; + pointsInput.dataset.cells = cells.toString(); pointsOutputFormatted.value = getCellsDensityValue(cells); pointsOutputFormatted.style.color = getCellsDensityColor(cells); } -function getCellsDensityValue(cells) { +function getCellsDensityValue(cells: number) { return cells / 1000 + "K"; } -function getCellsDensityColor(cells) { +function getCellsDensityColor(cells: number) { return cells > 50000 ? "#b12117" : cells !== 10000 ? "#dfdf12" : "#053305"; } function changeCultureSet() { - const max = culturesSet.selectedOptions[0].dataset.max; + const max = culturesSet.selectedOptions[0].dataset.max!; culturesInput.max = culturesOutput.max = max; - if (+culturesOutput.value > +max) culturesInput.value = culturesOutput.value = max; + if (Number(culturesOutput.value) > Number(max)) culturesInput.value = culturesOutput.value = max; } -function changeEmblemShape(emblemShape) { - const image = byId("emblemShapeImage"); - const shapePath = window.COArenderer && COArenderer.shieldPaths[emblemShape]; +function changeEmblemShape(emblemShape: string) { + const image = byId("emblemShapeImage")! as SVGPathElement; + const shapePath = COArenderer && COArenderer.shieldPaths[emblemShape]; shapePath ? image.setAttribute("d", shapePath) : image.removeAttribute("d"); const specificShape = ["culture", "state", "random"].includes(emblemShape) ? null : emblemShape; - if (emblemShape === "random") pack.cultures.filter(c => !c.removed).forEach(c => (c.shield = COA.getRandomShield())); + if (emblemShape === "random") pack.cultures.filter(c => isCulture(c) && !c.removed).forEach(c => (c.shield = COA.getRandomShield())); - const rerenderCOA = (id, coa) => { + const rerenderCOA = (id: string, coa: ICoa | string) => { const coaEl = byId(id); if (!coaEl) return; // not rendered coaEl.remove(); @@ -388,7 +456,7 @@ function changeEmblemShape(emblemShape) { }; pack.states.forEach(state => { - if (!state.i || state.removed || !state.coa || state.coa === "custom") return; + if (!isState(state) || state.removed || !state.coa || state.coa === "custom") return; const newShield = specificShape || COA.getPackShield(state.culture, null); if (newShield === state.coa.shield) return; @@ -397,7 +465,7 @@ function changeEmblemShape(emblemShape) { }); pack.provinces.forEach(province => { - if (!province.i || province.removed || !province.coa || province.coa === "custom") return; + if (!isProvince(province) || province.removed || !province.coa || province.coa === "custom") return; const culture = pack.cells.culture[province.center]; const newShield = specificShape || COA.getPackShield(culture, province.state); if (newShield === province.coa.shield) return; @@ -406,7 +474,7 @@ function changeEmblemShape(emblemShape) { }); pack.burgs.forEach(burg => { - if (!burg.i || burg.removed || !burg.coa || burg.coa === "custom") return; + if (!isBurg(burg) || burg.removed || !burg.coa || burg.coa === "custom") return; const newShield = specificShape || COA.getPackShield(burg.culture, burg.state); if (newShield === burg.coa.shield) return; burg.coa.shield = newShield; @@ -414,28 +482,32 @@ function changeEmblemShape(emblemShape) { }); } -function changeStatesNumber(value) { - regionsOutput.style.color = +value ? null : "#b12117"; - burgLabels.select("#capitals").attr("data-size", Math.max(rn(6 - value / 20), 3)); - labels.select("#countries").attr("data-size", Math.max(rn(18 - value / 6), 4)); +function changeStatesNumber(value: string) { + if (Number(value)) { + regionsOutput.style.removeProperty("color"); + } else { + regionsOutput.style.color = "#b12117"; + } + burgLabels.select("#capitals").attr("data-size", Math.max(rn(6 - Number(value) / 20), 3)); + labels.select("#countries").attr("data-size", Math.max(rn(18 - Number(value) / 6), 4)); } -function changeUIsize(value) { - if (isNaN(+value) || +value < 0.5) return; +function changeUIsize(value: string) { + if (isNaN(Number(value)) || Number(value) < 0.5) return; const max = getUImaxSize(); - if (+value > max) value = max; + if (Number(value) > max) value = max.toString(); uiSizeInput.value = uiSizeOutput.value = value; - document.getElementsByTagName("body")[0].style.fontSize = rn(value * 10, 2) + "px"; - byId("options").style.width = value * 300 + "px"; + document.getElementsByTagName("body")[0].style.fontSize = rn(Number(value) * 10, 2) + "px"; + optionsDiv.style.width = Number(value) * 300 + "px"; } function getUImaxSize() { return rn(Math.min(window.innerHeight / 465, window.innerWidth / 302), 1); } -function changeTooltipSize(value) { +function changeTooltipSize(value: string) { tooltip.style.fontSize = `calc(${value}px + 0.5vw)`; } @@ -445,23 +517,23 @@ function restoreDefaultThemeColor() { changeDialogsTheme(THEME_COLOR, transparencyInput.value); } -function changeThemeHue(hue) { +function changeThemeHue(hue: string) { const {s, l} = d3.hsl(themeColorInput.value); - const newColor = d3.hsl(+hue, s, l).hex(); + const newColor = d3.hsl(+hue, s, l).formatHex(); changeDialogsTheme(newColor, transparencyInput.value); } // change color and transparency for modal windows -function changeDialogsTheme(themeColor, transparency) { +function changeDialogsTheme(themeColor: string, transparency: string) { transparencyInput.value = transparencyOutput.value = transparency; - const alpha = (100 - +transparency) / 100; + const alpha = (100 - Number(transparency)) / 100; const alphaReduced = Math.min(alpha + 0.3, 1); const {h, s, l} = d3.hsl(themeColor || THEME_COLOR); themeColorInput.value = themeColor || THEME_COLOR; - themeHueInput.value = h; + themeHueInput.value = h.toString(); - const getRGBA = (hue, saturation, lightness, alpha) => { + const getRGBA = (hue: number, saturation: number, lightness: number, alpha: number) => { const color = d3.hsl(hue, saturation, lightness, alpha); return color.toString(); }; @@ -480,81 +552,84 @@ function changeDialogsTheme(themeColor, transparency) { const sx = document.documentElement.style; theme.forEach(({name, h, s, l, alpha}) => { - sx.setProperty(name, getRGBA(h, s, l, alpha)); + sx.setProperty(name, getRGBA(h, s, l, alpha!)); // MARKER: ! }); } -function changeZoomExtent(value) { - const zoomExtentMin = byId("zoomExtentMin"); - const zoomExtentMax = byId("zoomExtentMax"); +function changeZoomExtent(value: string) { + const zoomExtentMin = byId("zoomExtentMin")! as HTMLInputElement; + const zoomExtentMax = byId("zoomExtentMax")! as HTMLInputElement; - if (+zoomExtentMin.value > +zoomExtentMax.value) { + if (Number(zoomExtentMin.value) > Number(zoomExtentMax.value)) { [zoomExtentMin.value, zoomExtentMax.value] = [zoomExtentMax.value, zoomExtentMin.value]; } - const min = Math.max(+zoomExtentMin.value, 0.01); - const max = Math.min(+zoomExtentMax.value, 200); - zoomExtentMin.value = min; - zoomExtentMax.value = max; - zoom.scaleExtent([min, max]); - const scale = minmax(+value, 0.01, 200); + const min = Math.max(Number(zoomExtentMin.value, 0.01); + const max = Math.min(Number(zoomExtentMax.value, 200); + zoomExtentMin.value = min.toString(); + zoomExtentMax.value = max.toString(); + const scale = minmax(Number(value), 0.01, 200); + Zoom.scaleExtent([min, max]); Zoom.scaleTo(svg, scale); } // restore options stored in localStorage export function applyStoredOptions() { if (!stored("mapWidth") || !stored("mapHeight")) { - mapWidthInput.value = window.innerWidth; - mapHeightInput.value = window.innerHeight; + mapWidthInput.value = window.innerWidth.toString(); + mapHeightInput.value = window.innerHeight.toString(); } const heightmapId = stored("template"); if (heightmapId) { const name = heightmapTemplates[heightmapId]?.name || precreatedHeightmaps[heightmapId]?.name || heightmapId; - applyDropdownOption(byId("templateInput"), heightmapId, name); + applyDropdownOption(templateInput, heightmapId, name); } - - if (stored("distanceUnit")) applyDropdownOption(byId("distanceUnitInput"), stored("distanceUnit")); - if (stored("heightUnit")) applyDropdownOption(byId("heightUnit"), stored("heightUnit")); + + if (stored("distanceUnit")) applyDropdownOption(distanceUnitInput, stored("distanceUnit")!); // MARKER: ! + if (stored("heightUnit")) applyDropdownOption(heightUnitInput, stored("heightUnit")!); // MARKER: ! for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); + const key = localStorage.key(i)!; // MARKER: ! if (key === "speakerVoice") continue; - const input = byId(key + "Input") || byId(key); - const output = byId(key + "Output"); + const input = (byId(key + "Input")! || byId(key)!) as HTMLInputElement; // MARKER: ! + const output = (byId(key + "Output")!) as HTMLInputElement; // MARKER: ! const value = stored(key); - if (input) input.value = value; - if (output) output.value = value; + if (input) input.value = value!; // MARKER: ! + if (output) output.value = value!; // MARKER: ! lock(key); // add saved style presets to options - if (key.slice(0, 5) === "style") applyDropdownOption(byId("stylePreset"), key, key.slice(5)); + if (key.slice(0, 5) === "style") applyDropdownOption(stylePreset, key, key.slice(5)); } if (stored("winds")) options.winds = localStorage - .getItem("winds") + .getItem("winds")! .split(",") - .map(w => +w); - if (stored("military")) options.military = JSON.parse(stored("military")); + .map(w => Number(w)); + if (stored("military") options.military = JSON.parse(stored("military")!); // MARKER: ! - if (stored("tooltipSize")) changeTooltipSize(stored("tooltipSize")); - if (stored("regions")) changeStatesNumber(stored("regions")); + if (stored("tooltipSize")) changeTooltipSize(stored("tooltipSize")!); + if (stored("regions")) changeStatesNumber(stored("regions")!); - uiSizeInput.max = uiSizeOutput.max = getUImaxSize(); - if (stored("uiSize")) changeUIsize(stored("uiSize")); - else changeUIsize(minmax(rn(mapWidthInput.value / 1280, 1), 1, 2.5)); + uiSizeInput.max = uiSizeOutput.max = getUImaxSize().toString(); + if (stored("uiSize")) { + changeUIsize(stored("uiSize")!) + } else { + changeUIsize(minmax(rn(Number(mapWidthInput.value) / 1280, 1), 1, 2.5).toString()); + } // search params overwrite stored and default options const params = new URL(window.location.href).searchParams; - const width = +params.get("width"); - const height = +params.get("height"); - if (width) mapWidthInput.value = width; - if (height) mapHeightInput.value = height; + const width = Number(params.get("width")); + const height = Number(params.get("height")); + if (width) mapWidthInput.value = width.toString(); + if (height) mapHeightInput.value = height.toString(); - const transparency = stored("transparency") || 5; - const themeColor = stored("themeColor"); + const transparency = stored("transparency") || "5"; + const themeColor = stored("themeColor") || THEME_COLOR; changeDialogsTheme(themeColor, transparency); setRendering(shapeRendering.value); diff --git a/src/scripts/options/lock.ts b/src/scripts/options/lock.ts index ece16f6a..bf477296 100644 --- a/src/scripts/options/lock.ts +++ b/src/scripts/options/lock.ts @@ -41,7 +41,7 @@ export function lock(id: string) { } // unlock option -function unlock(id: string) { +export function unlock(id: string) { localStorage.removeItem(id); const $lock = document.getElementById("lock_" + id); if ($lock) { From f75327772f21c1fcf335c4e7029dd3465eca72c8 Mon Sep 17 00:00:00 2001 From: kruschen Date: Wed, 28 Aug 2024 23:08:35 +0000 Subject: [PATCH 20/27] options available through button again --- src/main.ts | 1 - src/modules/ui/options.ts | 10 +++++----- src/scripts/listeners.ts | 9 +++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main.ts b/src/main.ts index 57973304..58dfed02 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,7 +8,6 @@ import {defineSvg} from "./modules/define-svg"; import {clearLegend} from "./modules/legend"; // @ts-expect-error js-module import {Rulers} from "./modules/measurers"; -// @ts-expect-error js-module import {applyStoredOptions} from "./modules/ui/options"; import {addGlobalListeners} from "./scripts/listeners"; import {checkForUpdates} from "./scripts/updater"; diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index 2c823f87..9d592711 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -95,7 +95,7 @@ if (stored("disable_click_arrow_tooltip")) { } // Show options pane on trigger click -function showOptions(event: MouseEvent) { +export function showOptions(event: MouseEvent) { if (!stored("disable_click_arrow_tooltip")) { clearMainTip(); localStorage.setItem("disable_click_arrow_tooltip", "true"); @@ -563,8 +563,8 @@ function changeZoomExtent(value: string) { if (Number(zoomExtentMin.value) > Number(zoomExtentMax.value)) { [zoomExtentMin.value, zoomExtentMax.value] = [zoomExtentMax.value, zoomExtentMin.value]; } - const min = Math.max(Number(zoomExtentMin.value, 0.01); - const max = Math.min(Number(zoomExtentMax.value, 200); + const min = Math.max(Number(zoomExtentMin.value), 0.01); + const max = Math.min(Number(zoomExtentMax.value), 200); zoomExtentMin.value = min.toString(); zoomExtentMax.value = max.toString(); const scale = minmax(Number(value), 0.01, 200); @@ -609,7 +609,7 @@ export function applyStoredOptions() { .getItem("winds")! .split(",") .map(w => Number(w)); - if (stored("military") options.military = JSON.parse(stored("military")!); // MARKER: ! + if (stored("military")) options.military = JSON.parse(stored("military")!); // MARKER: ! if (stored("tooltipSize")) changeTooltipSize(stored("tooltipSize")!); if (stored("regions")) changeStatesNumber(stored("regions")!); @@ -633,7 +633,7 @@ export function applyStoredOptions() { changeDialogsTheme(themeColor, transparency); setRendering(shapeRendering.value); - options.stateLabelsMode = stateLabelsModeInput.value; + options.stateLabelsMode = stateLabelsModeInput.value as "auto" | "short" | "full"; // MARKER: as conversion } // randomize options if randomization is allowed (not locked or options='default') diff --git a/src/scripts/listeners.ts b/src/scripts/listeners.ts index c28b09f3..99ca4223 100644 --- a/src/scripts/listeners.ts +++ b/src/scripts/listeners.ts @@ -3,8 +3,7 @@ import {addOnLoadListener} from "./loading"; import {assignLockBehavior} from "./options/lock"; import {addTooptipListers} from "./tooltips"; import {assignSpeakerBehavior} from "./speaker"; -// @ts-ignore -import {addResizeListener} from "modules/ui/options"; +import {addResizeListener, hideOptions, showOptions} from "modules/ui/options"; // @ts-ignore import {addDragToUpload} from "modules/io/load"; import {addHotkeyListeners} from "scripts/hotkeys"; @@ -25,6 +24,7 @@ export function addGlobalListeners() { assignSpeakerBehavior(); addDragToUpload(); addFindAll(); + addOptionsListeners(); } function registerServiceWorker() { @@ -54,3 +54,8 @@ function addInstallationPrompt() { function addBeforeunloadListener() { window.onbeforeunload = () => "Are you sure you want to navigate away?"; } + +function addOptionsListeners() { + document.querySelector("#optionsTrigger")!.on("click", (evt) => showOptions(evt as MouseEvent)); + document.querySelector("#optionsHide")!.on("click", (evt) => hideOptions(evt as MouseEvent)); +} \ No newline at end of file From 2dd6935135132f0aec9246747eb6ee6ea0299c4d Mon Sep 17 00:00:00 2001 From: kruschen Date: Thu, 29 Aug 2024 01:19:03 +0200 Subject: [PATCH 21/27] Delete src/modules/ui/cell-info.d.ts delete cell-info.d.ts in favor of temporary js import --- src/modules/ui/cell-info.d.ts | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/modules/ui/cell-info.d.ts diff --git a/src/modules/ui/cell-info.d.ts b/src/modules/ui/cell-info.d.ts deleted file mode 100644 index ec677eea..00000000 --- a/src/modules/ui/cell-info.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// src/modules/ui/cell-info.d.ts -declare module 'modules/ui/cell-info.js' { - export function updateCellInfo(coords: [number, number], cellId: number, gridCell: any): void; - // Add other exports as needed - } \ No newline at end of file From 50fe5ae2e76f002bf05044ba4167e50cd82e671e Mon Sep 17 00:00:00 2001 From: kruschen Date: Sun, 1 Sep 2024 22:12:56 +0200 Subject: [PATCH 22/27] refactor: Update byId function for typed object returns (#1) * updated byId with typing and optional null check * apply new byId --- src/modules/ui/options.ts | 80 ++++++++++++++++++++------------------- src/utils/nodeUtils.ts | 40 +++++++++++++++++++- 2 files changed, 79 insertions(+), 41 deletions(-) diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index 9d592711..d0a6535f 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -5,10 +5,10 @@ import {precreatedHeightmaps} from "config/precreated-heightmaps"; import {lock, locked, unlock} from "scripts/options/lock"; import {clearMainTip, tip} from "scripts/tooltips"; import {last} from "utils/arrayUtils"; -import {applyDropdownOption} from "utils/nodeUtils"; +import {applyDropdownOption, byId } from "utils/nodeUtils"; import {minmax, rn} from "utils/numberUtils"; import {gauss, P, rand, rw} from "utils/probabilityUtils"; -import {byId, stored} from "utils/shorthands"; +import {stored} from "utils/shorthands"; import {regenerateMap} from "scripts/generation/generation"; // @ts-expect-error js file import {fitScaleBar} from "modules/measurers.js"; @@ -34,58 +34,60 @@ const COA = window.COA; const tooltip = byId("tooltip")! as HTMLDivElement; // Options pane elements -const optionsTrigger = byId("optionsTrigger")! as HTMLButtonElement; -const regenerate = byId("regenerate")! as HTMLButtonElement; -const optionsDiv = byId("options")! as HTMLDivElement; -const collapsible = byId("collapsible")! as HTMLDivElement; -const layersContent = byId("layersContent")! as HTMLDivElement; -const styleContent = byId("styleContent")! as HTMLDivElement; -const customizationMenu = byId("customizationMenu")! as HTMLDivElement; -const toolsContent = byId("toolsContent")! as HTMLDivElement; -const aboutContent = byId("aboutContent")! as HTMLDivElement; -const optionsContent = byId("optionsContent")! as HTMLDivElement; -const alertMessage = byId("alertMessage")! as HTMLDivElement; -const dialogDiv = byId("dialogs")! as HTMLDivElement; +const optionsTrigger = byId<'button'>("optionsTriggerr"); +const regenerate = byId<'button'>("regenerate"); +const optionsDiv = byId<'div'>("optionsContainer"); +const collapsible = byId<'div'>("collapsible"); +const layersContent = byId<'div'>("layersContent"); +const styleContent = byId<'div'>("styleContent"); +const customizationMenu = byId<'div'>("customizationMenu"); +const toolsContent = byId<'div'>("toolsContent"); +const aboutContent = byId<'div'>("aboutContent"); +const optionsContent = byId<'div'>("optionsContent"); +const alertMessage = byId<'div'>("alertMessage"); +const dialogDiv = byId<'div'>("dialogs"); // Number inputs -const themeColorInput = byId("themeColorInput")! as HTMLInputElement; -const themeHueInput = byId("themeHueInput")! as HTMLInputElement; +const themeColorInput = byId<'input'>("themeColorInput"); +const themeHueInput = byId<'input'>("themeHueInput"); -const transparencyInput = byId("transparencyInput")! as HTMLInputElement; -const transparencyOutput = byId("transparencyOutput")! as HTMLInputElement; +const transparencyInput = byId<'input'>("transparencyInput"); +const transparencyOutput = byId<'input'>("transparencyOutput"); -const mapWidthInput = byId("mapWidthInput")! as HTMLInputElement; -const mapHeightInput = byId("mapHeightInput")! as HTMLInputElement; +const mapWidthInput = byId<'input'>("mapWidthInput"); +const mapHeightInput = byId<'input'>("mapHeightInput"); -const zoomExtentMin = byId("zoomExtentMin")! as HTMLInputElement; -const zoomExtentMax = byId("zoomExtentMax")! as HTMLInputElement; +const zoomExtentMin = byId<'input'>("zoomExtentMin"); +const zoomExtentMax = byId<'input'>("zoomExtentMax"); -const optionsSeed = byId("optionsSeed")! as HTMLInputElement; -const pointsInput = byId("pointsInput")! as HTMLInputElement; +const optionsSeed = byId<'input'>("optionsSeed"); +const pointsInput = byId<'input'>("pointsInput"); -const culturesInput = byId("culturesInput")! as HTMLInputElement; -const regionsOutput = byId("regionsOutput")! as HTMLInputElement; +const culturesInput = byId<'input'>("culturesInput"); +const regionsOutput = byId<'input'>("regionsOutput"); -const uiSizeInput = byId("uiSizeInput")! as HTMLInputElement; -const uiSizeOutput = byId("uiSizeOutput")! as HTMLInputElement; +const uiSizeInput = byId<'input'>("uiSizeInput"); +const uiSizeOutput = byId<'input'>("uiSizeOutput"); -const distanceUnitInput = byId("distanceUnitInput")! as HTMLSelectElement; -const heightUnitInput = byId("heightUnitInput")! as HTMLSelectElement; +const distanceUnitInput = byId<'select'>("distanceUnitInput"); +const heightUnitInput = byId<'select'>("heightUnitInput"); + +const regionsInput = byId<'input'>("regionsInput"); // Text inputs -const mapName = byId("mapName")! as HTMLInputElement; -const templateInput = byId("templateInput")! as HTMLSelectElement -const culturesSet = byId("culturesSet")! as HTMLSelectElement; -const culturesOutput = byId("culturesOutput")! as HTMLInputElement; +const mapName = byId<"input">("mapName"); +const templateInput = byId<'select'>("templateInput") +const culturesSet = byId<'select'>("culturesSet"); +const culturesOutput = byId<'input'>("culturesOutput"); -const stylePreset = byId("stylePreset")! as HTMLSelectElement; +const stylePreset = byId<'select'>("stylePreset"); -const shapeRendering = byId("shapeRendering")! as HTMLSelectElement; -const stateLabelsModeInput = byId("stateLabelsModeInput")! as HTMLSelectElement; +const shapeRendering = byId<'select'>("shapeRendering"); +const stateLabelsModeInput = byId<'select'>("stateLabelsModeInput"); // Outputs -const manorsOutput = byId("manorsOutput")! as HTMLOutputElement; -const pointsOutputFormatted = byId("pointsOutputFormatted")! as HTMLOutputElement; +const manorsOutput = byId<'output'>("manorsOutput"); +const pointsOutputFormatted = byId<'output'>("pointsOutputFormatted"); // remove glow if tip is aknowledged diff --git a/src/utils/nodeUtils.ts b/src/utils/nodeUtils.ts index 1538bba5..b3744a5f 100644 --- a/src/utils/nodeUtils.ts +++ b/src/utils/nodeUtils.ts @@ -1,4 +1,40 @@ -import {byId} from "./shorthands"; +export type ElementMap = { + a: HTMLAnchorElement; + button: HTMLButtonElement; + div: HTMLDivElement; + img: HTMLImageElement; + input: HTMLInputElement; + output: HTMLOutputElement; + select: HTMLSelectElement; + // add more types as needed +}; + +type ElementMapKeys = keyof ElementMap; + +interface ByIdOptions { + throwOnNull?: boolean; + // add more options as needed +} + +// function definition with overloads to account for different options +export function byId(id: string, options?: ByIdOptions & {throwOnNull: true}): ElementMap[K]; +export function byId(id: string, options: ByIdOptions & {throwOnNull: boolean}): ElementMap[K]|null; +/** + * Retrieves an element from the DOM by its ID. + * @template K - The key of the element in the ElementMap. + * @param {string} id - The ID of the element to retrieve. + * @param {ByIdOptions} [options] - The options for retrieving the element. + * @param {boolean} [options.throwOnNull=true] - Whether to throw an error if the element is not found. + * @returns {ElementMap[K] | null} The retrieved element or null if not found. + * @throws {Error} If the element is not found and options.throwOnNull is true. + */ +export function byId(id: string, options: ByIdOptions = {throwOnNull: true}) { + const element = document.getElementById(id); + if (!element && options.throwOnNull) { + throw new Error(`Element ${id} not found`); + } + return element as ElementMap[K] | null; +} // get next unused id export function getNextId(core: string, index = 1) { @@ -42,4 +78,4 @@ export function applyDropdownOption($select: HTMLSelectElement, value: string, n const isExisting = Array.from($select.options).some(o => o.value === value); if (!isExisting) $select.options.add(new Option(name, value)); $select.value = value; -} +} \ No newline at end of file From 0216c0456f104392e6fbe29e9e21674d0d04c3ff Mon Sep 17 00:00:00 2001 From: kruschen Date: Sun, 1 Sep 2024 20:58:48 +0000 Subject: [PATCH 23/27] moved listener for option back to option file --- src/modules/ui/options.ts | 143 +++++++++++++++++++++++--------------- src/scripts/listeners.ts | 8 +-- 2 files changed, 88 insertions(+), 63 deletions(-) diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index d0a6535f..c88b438e 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -26,12 +26,16 @@ $("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode $("#exitCustomization").draggable({handle: "div"}); $("#mapLayers").disableSelection(); +// add listeners to options pane +byId<'button'>("#optionsTrigger").on("click", showOptions); +byId<'button'>("#optionsHide").on("click", hideOptions); + // Window Objects const Zoom = window.Zoom; const COA = window.COA; // DIV elements -const tooltip = byId("tooltip")! as HTMLDivElement; +const tooltip = byId<'div'>("tooltip"); // Options pane elements const optionsTrigger = byId<'button'>("optionsTriggerr"); @@ -69,11 +73,33 @@ const regionsOutput = byId<'input'>("regionsOutput"); const uiSizeInput = byId<'input'>("uiSizeInput"); const uiSizeOutput = byId<'input'>("uiSizeOutput"); -const distanceUnitInput = byId<'select'>("distanceUnitInput"); -const heightUnitInput = byId<'select'>("heightUnitInput"); - const regionsInput = byId<'input'>("regionsInput"); +const provincesInput = byId<'input'>("provincesInput"); +const provincesOutput = byId<'input'>("provincesOutput"); + +const manorsInput = byId<'input'>("manorsInput"); + +const religionsInput = byId<'input'>("religionsInput"); + +const powerInput = byId<'input'>("powerInput"); +const powerOutput = byId<'input'>("powerOutput"); + +const neutralInput = byId<'input'>("neutralInput"); +const neutralOutput = byId<'input'>("neutralOutput"); + +const precInput = byId<'input'>("precInput"); +const precOutput = byId<'input'>("precOutput"); + +const temperatureEquatorInput = byId<'input'>("temperatureEquatorInput"); +const temperatureEquatorOutput = byId<'input'>("temperatureEquatorOutput"); + +const temperaturePoleInput = byId<'input'>("temperaturePoleInput"); +const temperaturePoleOutput = byId<'input'>("temperaturePoleOutput"); + +const distanceScaleInput = byId<'input'>("distanceScaleInput"); +const distanceScaleOutput = byId<'input'>("distanceScaleOutput"); + // Text inputs const mapName = byId<"input">("mapName"); const templateInput = byId<'select'>("templateInput") @@ -85,9 +111,15 @@ const stylePreset = byId<'select'>("stylePreset"); const shapeRendering = byId<'select'>("shapeRendering"); const stateLabelsModeInput = byId<'select'>("stateLabelsModeInput"); +const distanceUnitInput = byId<'select'>("distanceUnitInput"); +const heightUnitInput = byId<'select'>("heightUnitInput"); +const heightUnit = byId<'select'>("heightUnit"); +const temperatureScale = byId<'select'>("temperatureScale"); + // Outputs const manorsOutput = byId<'output'>("manorsOutput"); const pointsOutputFormatted = byId<'output'>("pointsOutputFormatted"); +const religionsOutput = byId<'output'>("religionsOutput"); // remove glow if tip is aknowledged @@ -97,7 +129,7 @@ if (stored("disable_click_arrow_tooltip")) { } // Show options pane on trigger click -export function showOptions(event: MouseEvent) { +export function showOptions(event: Event) { if (!stored("disable_click_arrow_tooltip")) { clearMainTip(); localStorage.setItem("disable_click_arrow_tooltip", "true"); @@ -210,7 +242,7 @@ optionsContent.on("input", function (event: any) { // MARKER: any else if (id === "emblemShape") changeEmblemShape(value); else if (id === "tooltipSizeInput" || id === "tooltipSizeOutput") changeTooltipSize(value); else if (id === "themeHueInput") changeThemeHue(value); - else if (id === "themeColorInput") changeDialogsTheme(themeColorInput.value, transparencyInput.value); + else if (id === "themeColorInput") changeDialogsTheme(themeColorInput.value, transparencyInput.valueAsNumber); else if (id === "transparencyInput") changeDialogsTheme(themeColorInput.value, value); }); @@ -263,12 +295,12 @@ export function addResizeListener() { // change svg size on manual size change or window resize, do not change graph size function changeMapSize() { - svgWidth = Math.min(Number(mapWidthInput.value), window.innerWidth); - svgHeight = Math.min(Number(mapHeightInput.value), window.innerHeight); + svgWidth = Math.min(mapWidthInput.valueAsNumber, window.innerWidth); + svgHeight = Math.min(mapHeightInput.valueAsNumber, window.innerHeight); svg.attr("width", svgWidth).attr("height", svgHeight); - const maxWidth = Math.max(Number(mapWidthInput.value), graphWidth); - const maxHeight = Math.max(Number(mapHeightInput.value), graphHeight); + const maxWidth = Math.max(mapWidthInput.valueAsNumber, graphWidth); + const maxHeight = Math.max(mapHeightInput.valueAsNumber, graphHeight); Zoom.translateExtent([[0, 0], [maxWidth, maxHeight]]); @@ -494,15 +526,15 @@ function changeStatesNumber(value: string) { labels.select("#countries").attr("data-size", Math.max(rn(18 - Number(value) / 6), 4)); } -function changeUIsize(value: string) { - if (isNaN(Number(value)) || Number(value) < 0.5) return; +function changeUIsize(value: number) { + if (isNaN(value) || value < 0.5) return; const max = getUImaxSize(); - if (Number(value) > max) value = max.toString(); + if (value > max) value = max; - uiSizeInput.value = uiSizeOutput.value = value; - document.getElementsByTagName("body")[0].style.fontSize = rn(Number(value) * 10, 2) + "px"; - optionsDiv.style.width = Number(value) * 300 + "px"; + uiSizeInput.valueAsNumber = uiSizeOutput.valueAsNumber = value; + document.getElementsByTagName("body")[0].style.fontSize = rn(value * 10, 2) + "px"; + optionsDiv.style.width = value * 300 + "px"; } function getUImaxSize() { @@ -516,24 +548,24 @@ function changeTooltipSize(value: string) { const THEME_COLOR = "#997787"; function restoreDefaultThemeColor() { localStorage.removeItem("themeColor"); - changeDialogsTheme(THEME_COLOR, transparencyInput.value); + changeDialogsTheme(THEME_COLOR, transparencyInput.valueAsNumber); } -function changeThemeHue(hue: string) { +function changeThemeHue(hue: number) { const {s, l} = d3.hsl(themeColorInput.value); - const newColor = d3.hsl(+hue, s, l).formatHex(); - changeDialogsTheme(newColor, transparencyInput.value); + const newColor = d3.hsl(hue, s, l).formatHex(); + changeDialogsTheme(newColor, transparencyInput.valueAsNumber); } // change color and transparency for modal windows -function changeDialogsTheme(themeColor: string, transparency: string) { - transparencyInput.value = transparencyOutput.value = transparency; - const alpha = (100 - Number(transparency)) / 100; +function changeDialogsTheme(themeColor: string, transparency: number) { + transparencyInput.valueAsNumber = transparencyOutput.valueAsNumber = transparency; + const alpha = (100 - transparency) / 100; const alphaReduced = Math.min(alpha + 0.3, 1); const {h, s, l} = d3.hsl(themeColor || THEME_COLOR); themeColorInput.value = themeColor || THEME_COLOR; - themeHueInput.value = h.toString(); + themeHueInput.valueAsNumber = h; const getRGBA = (hue: number, saturation: number, lightness: number, alpha: number) => { const color = d3.hsl(hue, saturation, lightness, alpha); @@ -558,18 +590,18 @@ function changeDialogsTheme(themeColor: string, transparency: string) { }); } -function changeZoomExtent(value: string) { - const zoomExtentMin = byId("zoomExtentMin")! as HTMLInputElement; - const zoomExtentMax = byId("zoomExtentMax")! as HTMLInputElement; +function changeZoomExtent(value: number) { + const zoomExtentMin = byId<'input'>("zoomExtentMin"); + const zoomExtentMax = byId<'input'>("zoomExtentMax"); - if (Number(zoomExtentMin.value) > Number(zoomExtentMax.value)) { + if (zoomExtentMin.valueAsNumber > zoomExtentMax.valueAsNumber) { [zoomExtentMin.value, zoomExtentMax.value] = [zoomExtentMax.value, zoomExtentMin.value]; } - const min = Math.max(Number(zoomExtentMin.value), 0.01); - const max = Math.min(Number(zoomExtentMax.value), 200); - zoomExtentMin.value = min.toString(); - zoomExtentMax.value = max.toString(); - const scale = minmax(Number(value), 0.01, 200); + const min = Math.max(zoomExtentMin.valueAsNumber, 0.01); + const max = Math.min(zoomExtentMax.valueAsNumber, 200); + zoomExtentMin.valueAsNumber = min; + zoomExtentMax.valueAsNumber = max; + const scale = minmax(value, 0.01, 200); Zoom.scaleExtent([min, max]); Zoom.scaleTo(svg, scale); } @@ -577,8 +609,8 @@ function changeZoomExtent(value: string) { // restore options stored in localStorage export function applyStoredOptions() { if (!stored("mapWidth") || !stored("mapHeight")) { - mapWidthInput.value = window.innerWidth.toString(); - mapHeightInput.value = window.innerHeight.toString(); + mapWidthInput.valueAsNumber = window.innerWidth; + mapHeightInput.valueAsNumber = window.innerHeight; } const heightmapId = stored("template"); @@ -594,8 +626,8 @@ export function applyStoredOptions() { const key = localStorage.key(i)!; // MARKER: ! if (key === "speakerVoice") continue; - const input = (byId(key + "Input")! || byId(key)!) as HTMLInputElement; // MARKER: ! - const output = (byId(key + "Output")!) as HTMLInputElement; // MARKER: ! + const input = byId<'input'>(key + "Input", {throwOnNull: false}) || byId<'input'>(key)!; // MARKER: ! + const output = byId<'input'>(key + "Output")!; // MARKER: ! const value = stored(key); if (input) input.value = value!; // MARKER: ! @@ -618,9 +650,9 @@ export function applyStoredOptions() { uiSizeInput.max = uiSizeOutput.max = getUImaxSize().toString(); if (stored("uiSize")) { - changeUIsize(stored("uiSize")!) + changeUIsize(Number(stored("uiSize")!)) } else { - changeUIsize(minmax(rn(Number(mapWidthInput.value) / 1280, 1), 1, 2.5).toString()); + changeUIsize(minmax(rn(mapWidthInput.valueAsNumber / 1280, 1), 1, 2.5)); } // search params overwrite stored and default options @@ -630,7 +662,7 @@ export function applyStoredOptions() { if (width) mapWidthInput.value = width.toString(); if (height) mapHeightInput.value = height.toString(); - const transparency = stored("transparency") || "5"; + const transparency = Number(stored("transparency")) || 5; const themeColor = stored("themeColor") || THEME_COLOR; changeDialogsTheme(themeColor, transparency); @@ -644,30 +676,29 @@ export function randomizeOptions() { // 'Options' settings if (randomize || !locked("template")) randomizeHeightmapTemplate(); - if (randomize || !locked("regions")) regionsInput.value = regionsOutput.value = gauss(18, 5, 2, 30); - if (randomize || !locked("provinces")) provincesInput.value = provincesOutput.value = gauss(5, 15, 3, 100); + if (randomize || !locked("regions")) regionsInput.valueAsNumber = regionsOutput.valueAsNumber = gauss(18, 5, 2, 30); + if (randomize || !locked("provinces")) provincesInput.valueAsNumber = provincesOutput.valueAsNumber = gauss(5, 15, 3, 100); if (randomize || !locked("manors")) { - manorsInput.value = 1000; + manorsInput.valueAsNumber = 1000; manorsOutput.value = "auto"; } - if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(6, 3, 2, 10); - if (randomize || !locked("power")) powerInput.value = powerOutput.value = gauss(4, 2, 0, 10, 2); - if (randomize || !locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1); - if (randomize || !locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30); + if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(6, 3, 2, 10).toString(); + if (randomize || !locked("power")) powerInput.valueAsNumber = powerOutput.valueAsNumber = gauss(4, 2, 0, 10, 2); + if (randomize || !locked("neutral")) neutralInput.valueAsNumber = neutralOutput.valueAsNumber = rn(1 + Math.random(), 1); + if (randomize || !locked("cultures")) culturesInput.valueAsNumber = culturesOutput.valueAsNumber = gauss(12, 3, 5, 30); if (randomize || !locked("culturesSet")) randomizeCultureSet(); // 'Configure World' settings - if (randomize || !locked("prec")) precInput.value = precOutput.value = gauss(100, 40, 5, 500); - const tMax = 30, - tMin = -30; // temperature extremes + if (randomize || !locked("prec")) precInput.valueAsNumber = precOutput.valueAsNumber = gauss(100, 40, 5, 500); + const tMax = 30, tMin = -30; // temperature extremes if (randomize || !locked("temperatureEquator")) - temperatureEquatorOutput.value = temperatureEquatorInput.value = rand(tMax - 10, tMax); + temperatureEquatorOutput.valueAsNumber = temperatureEquatorInput.valueAsNumber = rand(tMax - 10, tMax); if (randomize || !locked("temperaturePole")) - temperaturePoleOutput.value = temperaturePoleInput.value = rand(tMin, tMin + 30); + temperaturePoleOutput.valueAsNumber = temperaturePoleInput.valueAsNumber = rand(tMin, tMin + 30); // 'Units Editor' settings const US = navigator.language === "en-US"; - if (randomize || !locked("distanceScale")) distanceScaleOutput.value = distanceScaleInput.value = gauss(3, 1, 1, 5); + if (randomize || !locked("distanceScale")) distanceScaleOutput.valueAsNumber = distanceScaleInput.valueAsNumber = gauss(3, 1, 1, 5); if (!stored("distanceUnit")) distanceUnitInput.value = US ? "mi" : "km"; if (!stored("heightUnit")) heightUnit.value = US ? "ft" : "m"; if (!stored("temperatureScale")) temperatureScale.value = US ? "°F" : "°C"; @@ -678,13 +709,13 @@ export function randomizeOptions() { // select heightmap template pseudo-randomly function randomizeHeightmapTemplate() { - const templates = {}; + const templates: Dict = {}; for (const key in heightmapTemplates) { templates[key] = heightmapTemplates[key].probability || 0; } const template = rw(templates); const name = heightmapTemplates[template].name; - applyDropdownOption(byId("templateInput"), template, name); + applyDropdownOption(templateInput, template, name); } // select culture set pseudo-randomly @@ -703,7 +734,7 @@ function randomizeCultureSet() { changeCultureSet(); } -function setRendering(value) { +function setRendering(value: string) { viewbox?.attr("shape-rendering", value); } diff --git a/src/scripts/listeners.ts b/src/scripts/listeners.ts index 99ca4223..e1b47d23 100644 --- a/src/scripts/listeners.ts +++ b/src/scripts/listeners.ts @@ -3,7 +3,7 @@ import {addOnLoadListener} from "./loading"; import {assignLockBehavior} from "./options/lock"; import {addTooptipListers} from "./tooltips"; import {assignSpeakerBehavior} from "./speaker"; -import {addResizeListener, hideOptions, showOptions} from "modules/ui/options"; +import {addResizeListener} from "modules/ui/options"; // @ts-ignore import {addDragToUpload} from "modules/io/load"; import {addHotkeyListeners} from "scripts/hotkeys"; @@ -24,7 +24,6 @@ export function addGlobalListeners() { assignSpeakerBehavior(); addDragToUpload(); addFindAll(); - addOptionsListeners(); } function registerServiceWorker() { @@ -53,9 +52,4 @@ function addInstallationPrompt() { function addBeforeunloadListener() { window.onbeforeunload = () => "Are you sure you want to navigate away?"; -} - -function addOptionsListeners() { - document.querySelector("#optionsTrigger")!.on("click", (evt) => showOptions(evt as MouseEvent)); - document.querySelector("#optionsHide")!.on("click", (evt) => hideOptions(evt as MouseEvent)); } \ No newline at end of file From b66f4c6ca8226905bdb809e9a47bdaa8fff8185d Mon Sep 17 00:00:00 2001 From: kruschen Date: Sun, 1 Sep 2024 22:29:35 +0000 Subject: [PATCH 24/27] update options file 80% --- src/modules/io/cloudTypes.ts | 6 + src/modules/ui/options.ts | 177 ++++++++++++++++----------- src/scripts/generation/generation.ts | 3 +- src/types/overrides.d.ts | 1 + src/utils/nodeUtils.ts | 1 + 5 files changed, 114 insertions(+), 74 deletions(-) create mode 100644 src/modules/io/cloudTypes.ts diff --git a/src/modules/io/cloudTypes.ts b/src/modules/io/cloudTypes.ts new file mode 100644 index 00000000..f5c9a37c --- /dev/null +++ b/src/modules/io/cloudTypes.ts @@ -0,0 +1,6 @@ +export type DropboxFile = { + name: string, + updated: any, // MARKER: Type unclear + size: number, + path: string + }; \ No newline at end of file diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index c88b438e..a002666a 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -9,7 +9,7 @@ import {applyDropdownOption, byId } from "utils/nodeUtils"; import {minmax, rn} from "utils/numberUtils"; import {gauss, P, rand, rw} from "utils/probabilityUtils"; import {stored} from "utils/shorthands"; -import {regenerateMap} from "scripts/generation/generation"; +import {IGenerationOptions, regenerateMap} from "scripts/generation/generation"; // @ts-expect-error js file import {fitScaleBar} from "modules/measurers.js"; import {openDialog} from "dialogs"; @@ -21,24 +21,27 @@ import {fitLegendBox} from "modules/legend.js"; // @ts-expect-error js file import {COArenderer} from "modules/coa-renderer.js"; import { isBurg, isCulture, isProvince, isState } from "utils/typeUtils.js"; +import { DropboxFile } from "modules/io/cloudTypes.js"; $("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"}); $("#exitCustomization").draggable({handle: "div"}); $("#mapLayers").disableSelection(); // add listeners to options pane -byId<'button'>("#optionsTrigger").on("click", showOptions); -byId<'button'>("#optionsHide").on("click", hideOptions); +byId<'button'>("optionsTrigger").on("click", showOptions); +byId<'button'>("optionsHide").on("click", hideOptions); // Window Objects const Zoom = window.Zoom; const COA = window.COA; +const Cloud = window.Cloud; +const ThreeD = window.ThreeD; // DIV elements const tooltip = byId<'div'>("tooltip"); // Options pane elements -const optionsTrigger = byId<'button'>("optionsTriggerr"); +const optionsTrigger = byId<'button'>("optionsTrigger"); const regenerate = byId<'button'>("regenerate"); const optionsDiv = byId<'div'>("optionsContainer"); const collapsible = byId<'div'>("collapsible"); @@ -100,6 +103,9 @@ const temperaturePoleOutput = byId<'input'>("temperaturePoleOutput"); const distanceScaleInput = byId<'input'>("distanceScaleInput"); const distanceScaleOutput = byId<'input'>("distanceScaleOutput"); +const yearInput = byId<'input'>("yearInput"); +const eraInput = byId<'input'>("eraInput"); + // Text inputs const mapName = byId<"input">("mapName"); const templateInput = byId<'select'>("templateInput") @@ -112,7 +118,7 @@ const shapeRendering = byId<'select'>("shapeRendering"); const stateLabelsModeInput = byId<'select'>("stateLabelsModeInput"); const distanceUnitInput = byId<'select'>("distanceUnitInput"); -const heightUnitInput = byId<'select'>("heightUnitInput"); +// const heightUnitInput = byId<'select'>("heightUnitInput"); const heightUnit = byId<'select'>("heightUnit"); const temperatureScale = byId<'select'>("temperatureScale"); @@ -121,6 +127,27 @@ const manorsOutput = byId<'output'>("manorsOutput"); const pointsOutputFormatted = byId<'output'>("pointsOutputFormatted"); const religionsOutput = byId<'output'>("religionsOutput"); +// 3D options +const options3dMesh = byId<'div'>("options3dMesh"); +const options3dGlobe = byId<'div'>("options3dGlobe"); +const options3dOBJSave = byId<'button'>("options3dOBJSave"); +const options3dScaleRange = byId<'input'>("options3dScaleRange"); +const options3dScaleNumber = byId<'input'>("options3dScaleNumber"); +const options3dLightnessRange = byId<'input'>("options3dLightnessRange"); +const options3dLightnessNumber = byId<'input'>("options3dLightnessNumber"); +const options3dSunX = byId<'input'>("options3dSunX"); +const options3dSunY = byId<'input'>("options3dSunY"); +const options3dSunZ = byId<'input'>("options3dSunZ"); +const options3dMeshRotationRange = byId<'input'>("options3dMeshRotationRange"); +const options3dMeshRotationNumber = byId<'input'>("options3dMeshRotationNumber"); +const options3dGlobeRotationRange = byId<'input'>("options3dGlobeRotationRange"); +const options3dGlobeRotationNumber = byId<'input'>("options3dGlobeRotationNumber"); +const options3dMeshLabels3d = byId<'input'>("options3dMeshLabels3d"); +const options3dMeshSkyMode = byId<'input'>("options3dMeshSkyMode"); +const options3dColorSection = byId<'div'>("options3dColorSection"); +const options3dMeshSky = byId<'input'>("options3dMeshSky"); +const options3dMeshWater = byId<'input'>("options3dMeshWater"); +const options3dGlobeResolution = byId<'select'>("options3dGlobeResolution"); // remove glow if tip is aknowledged if (stored("disable_click_arrow_tooltip")) { @@ -620,14 +647,14 @@ export function applyStoredOptions() { } if (stored("distanceUnit")) applyDropdownOption(distanceUnitInput, stored("distanceUnit")!); // MARKER: ! - if (stored("heightUnit")) applyDropdownOption(heightUnitInput, stored("heightUnit")!); // MARKER: ! + if (stored("heightUnit")) applyDropdownOption(heightUnit, stored("heightUnit")!); // MARKER: ! for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i)!; // MARKER: ! if (key === "speakerVoice") continue; - const input = byId<'input'>(key + "Input", {throwOnNull: false}) || byId<'input'>(key)!; // MARKER: ! - const output = byId<'input'>(key + "Output")!; // MARKER: ! + const input = byId<'input'>(key + "Input", {throwOnNull: false}) || byId<'input'>(key, {throwOnNull: false}); // MARKER: ! + const output = byId<'input'>(key + "Output", {throwOnNull: false}); // MARKER: ! const value = stored(key); if (input) input.value = value!; // MARKER: ! @@ -740,10 +767,10 @@ function setRendering(value: string) { // generate current year and era name function generateEra() { - if (!stored("year")) yearInput.value = rand(100, 2000); // current year + if (!stored("year")) yearInput.valueAsNumber = rand(100, 2000); // current year if (!stored("era")) eraInput.value = Names.getBaseShort(P(0.7) ? 1 : rand(nameBases.length)) + " Era"; - options.year = +yearInput.value; - options.era = eraInput.value; + options.year = yearInput.valueAsNumber; + options.era = eraInput.valueAsNumber; options.eraShort = options.era .split(" ") .map(w => w[0].toUpperCase()) @@ -760,18 +787,18 @@ function regenerateEra() { } function changeYear() { - if (!yearInput.value) return; - if (isNaN(+yearInput.value)) { + if (!yearInput.valueAsNumber) return; + if (isNaN(yearInput.valueAsNumber)) { tip("Current year should be a number", false, "error"); return; } - options.year = +yearInput.value; + options.year = yearInput.valueAsNumber; } function changeEra() { - if (!eraInput.value) return; + if (!eraInput.valueAsNumber) return; lock("era"); - options.era = eraInput.value; + options.era = eraInput.valueAsNumber; } // remove all saved data from LocalStorage and reload the page @@ -781,8 +808,8 @@ function restoreDefaultOptions() { } // Sticked menu Options listeners -byId("sticked").on("click", function (event) { - const id = event.target.id; +byId("sticked").on("click", function (event: any) { + const id = event.target.id; // MARKER: any if (id === "newMapButton") regeneratePrompt(); else if (id === "saveButton") showSavePane(); else if (id === "exportButton") showExportPane(); @@ -790,9 +817,9 @@ byId("sticked").on("click", function (event) { else if (id === "zoomReset") Zoom.reset(1000); }); -byId("regenerate").on("click", regeneratePrompt); +byId("regenerate").on("click", () => regeneratePrompt); -export function regeneratePrompt(options) { +export function regeneratePrompt(options? : IGenerationOptions) { if (customization) return tip("New map cannot be generated when edit mode is active, please exit the mode and retry", false, "error"); const workingTime = (Date.now() - last(mapHistory).created) / 60000; // minutes @@ -837,13 +864,13 @@ byId("saveToDropbox").on("click", saveToDropbox); byId("quickSave").on("click", quickSave); function copyLinkToClickboard() { - const shrableLink = byId("sharableLink"); - const link = shrableLink.getAttribute("href"); + const shrableLink = byId<'a'>("sharableLink"); + const link = shrableLink.href; navigator.clipboard.writeText(link).then(() => tip("Link is copied to the clipboard", true, "success", 8000)); } function showExportPane() { - byId("showLabels").checked = !hideLabels.checked; + byId<'input'>("showLabels").checked = !byId<'input'>("hideLabels").checked; $("#exportMapData").dialog({ title: "Export map data", @@ -893,13 +920,16 @@ async function showLoadPane() { // already connected to Dropbox: list saved maps if (Cloud.providers.dropbox.api) { - byId("dropboxConnectButton").style.display = "none"; - byId("loadFromDropboxSelect").style.display = "block"; - const loadFromDropboxButtons = byId("loadFromDropboxButtons"); - const fileSelect = byId("loadFromDropboxSelect"); + const dropboxConnectButton = byId<'button'>("dropboxConnectButton"); + const loadFromDropboxSelect = byId<'select'>("loadFromDropboxSelect"); + const loadFromDropboxButtons = byId<'button'>("loadFromDropboxButtons"); + const fileSelect = byId<'select'>("loadFromDropboxSelect"); + + dropboxConnectButton.style.display = "none"; + loadFromDropboxSelect.style.display = "block"; fileSelect.innerHTML = /* html */ ``; - const files = await Cloud.providers.dropbox.list(); + const files: DropboxFile[] = await Cloud.providers.dropbox.list(); if (!files) { loadFromDropboxButtons.style.display = "none"; @@ -952,7 +982,7 @@ function loadURL() { width: "27em", buttons: { Load: function () { - const value = mapURL.value; + const value = byId<'input'>("mapURL").value; if (!pattern.test(value)) { tip("Please provide a valid URL", false, "error"); return; @@ -968,7 +998,7 @@ function loadURL() { } // load map -byId("mapToLoad").on("change", function () { +byId<'input'>("mapToLoad").on("change", function () { const fileToLoad = this.files[0]; this.value = ""; closeDialogs(); @@ -980,7 +1010,7 @@ function openSaveTiles() { updateTilesOptions(); const status = byId("tileStatus"); status.innerHTML = ""; - let loading = null; + let loading: NodeJS.Timer; const inputs = byId("saveTilesScreen").querySelectorAll("input"); inputs.forEach(input => input.on("input", updateTilesOptions)); @@ -1020,9 +1050,9 @@ function updateTilesOptions() { } const tileSize = byId("tileSize"); - const tilesX = +byId("tileColsOutput").value; - const tilesY = +byId("tileRowsOutput").value; - const scale = +byId("tileScaleOutput").value; + const tilesX = byId<'input'>("tileColsOutput").valueAsNumber; + const tilesY = byId<'input'>("tileRowsOutput").valueAsNumber; + const scale = byId<'input'>("tileScaleOutput").valueAsNumber; // calculate size const sizeX = graphWidth * scale * tilesX; @@ -1052,30 +1082,30 @@ function updateTilesOptions() { } // View mode -viewMode.on("click", changeViewMode); -export function changeViewMode(event) { +byId<'div'>("viewMode").on("click", changeViewMode); +export function changeViewMode(event: any) { // MARKER: any const button = event.target; if (button.tagName !== "BUTTON") return; const pressed = button.classList.contains("pressed"); enterStandardView(); if (!pressed && button.id !== "viewStandard") { - viewStandard.classList.remove("pressed"); + byId("viewStandard").classList.remove("pressed"); button.classList.add("pressed"); enter3dView(button.id); } } function enterStandardView() { - viewMode.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed")); - heightmap3DView.classList.remove("pressed"); - viewStandard.classList.add("pressed"); + byId<'div'>("viewMode").querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed")); + byId("heightmap3DView").classList.remove("pressed"); + byId("viewStandard").classList.add("pressed"); if (!byId("canvas3d")) return; ThreeD.stop(); byId("canvas3d").remove(); - if (options3dUpdate.offsetParent) $("#options3d").dialog("close"); - if (preview3d.offsetParent) $("#preview3d").dialog("close"); + if (byId("options3dUpdate").offsetParent) $("#options3d").dialog("close"); + if (byId("preview3d").offsetParent) $("#preview3d").dialog("close"); } async function enter3dView(type) { @@ -1084,7 +1114,7 @@ async function enter3dView(type) { canvas.dataset.type = type; if (type === "heightmap3DView") { - canvas.width = parseFloat(preview3d.style.width) || graphWidth / 3; + canvas.width = parseFloat(byId("preview3d").style.width) || graphWidth / 3; canvas.height = canvas.width / (graphWidth / graphHeight); canvas.style.display = "block"; } else { @@ -1101,8 +1131,8 @@ async function enter3dView(type) { canvas.onmouseenter = () => { const help = "Left mouse to change angle, middle mouse / mousewheel to zoom, right mouse to pan. O to toggle options"; - +canvas.dataset.hovered > 2 ? tip("") : tip(help); - canvas.dataset.hovered = (+canvas.dataset.hovered | 0) + 1; + Number(canvas.dataset.hovered) > 2 ? tip("") : tip(help); + canvas.dataset.hovered = String((+canvas.dataset.hovered! | 0) + 1); }; if (type === "heightmap3DView") { @@ -1114,13 +1144,14 @@ async function enter3dView(type) { resizeStop: resize3d, close: enterStandardView }); - } else document.body.insertBefore(canvas, optionsContainer); + } else document.body.insertBefore(canvas, optionsDiv); toggle3dOptions(); } function resize3d() { - const canvas = byId("canvas3d"); + const canvas = byId<'canvas'>("canvas3d"); + const preview3d = byId<'div'>("preview3d"); canvas.width = parseFloat(preview3d.style.width); canvas.height = parseFloat(preview3d.style.height) - 2; ThreeD.redraw(); @@ -1129,6 +1160,7 @@ function resize3d() { let isLoaded = false; export function toggle3dOptions() { + const options3dUpdate = byId("options3dUpdate"); if (options3dUpdate.offsetParent) { $("#options3d").dialog("close"); return; @@ -1145,27 +1177,27 @@ export function toggle3dOptions() { if (isLoaded) return; isLoaded = true; - byId("options3dUpdate").on("click", ThreeD.update); + options3dUpdate.on("click", ThreeD.update); byId("options3dConfigureWorld").on("click", () => openDialog("worldConfigurator")); byId("options3dSave").on("click", ThreeD.saveScreenshot); - byId("options3dOBJSave").on("click", ThreeD.saveOBJ); + options3dOBJSave.on("click", ThreeD.saveOBJ); - byId("options3dScaleRange").on("input", changeHeightScale); - byId("options3dScaleNumber").on("change", changeHeightScale); - byId("options3dLightnessRange").on("input", changeLightness); - byId("options3dLightnessNumber").on("change", changeLightness); - byId("options3dSunX").on("change", changeSunPosition); - byId("options3dSunY").on("change", changeSunPosition); - byId("options3dSunZ").on("change", changeSunPosition); - byId("options3dMeshRotationRange").on("input", changeRotation); - byId("options3dMeshRotationNumber").on("change", changeRotation); - byId("options3dGlobeRotationRange").on("input", changeRotation); - byId("options3dGlobeRotationNumber").on("change", changeRotation); - byId("options3dMeshLabels3d").on("change", toggleLabels3d); - byId("options3dMeshSkyMode").on("change", toggleSkyMode); - byId("options3dMeshSky").on("input", changeColors); - byId("options3dMeshWater").on("input", changeColors); - byId("options3dGlobeResolution").on("change", changeResolution); + options3dScaleRange.on("input", changeHeightScale); + options3dScaleNumber.on("change", changeHeightScale); + options3dLightnessRange.on("input", changeLightness); + options3dLightnessNumber.on("change", changeLightness); + options3dSunX.on("change", changeSunPosition); + options3dSunY.on("change", changeSunPosition); + options3dSunZ.on("change", changeSunPosition); + options3dMeshRotationRange.on("input", changeRotation); + options3dMeshRotationNumber.on("change", changeRotation); + options3dGlobeRotationRange.on("input", changeRotation); + options3dGlobeRotationNumber.on("change", changeRotation); + options3dMeshLabels3d.on("change", toggleLabels3d); + options3dMeshSkyMode.on("change", toggleSkyMode); + options3dMeshSky.on("input", changeColors); + options3dMeshWater.on("input", changeColors); + options3dGlobeResolution.on("change", changeResolution); function updateValues() { const globe = byId("canvas3d").dataset.type === "viewGlobe"; @@ -1173,7 +1205,7 @@ export function toggle3dOptions() { options3dGlobe.style.display = globe ? "block" : "none"; options3dOBJSave.style.display = globe ? "none" : "inline-block"; options3dScaleRange.value = options3dScaleNumber.value = ThreeD.options.scale; - options3dLightnessRange.value = options3dLightnessNumber.value = ThreeD.options.lightness * 100; + options3dLightnessRange.valueAsNumber = options3dLightnessNumber.valueAsNumber = ThreeD.options.lightness * 100; options3dSunX.value = ThreeD.options.sun.x; options3dSunY.value = ThreeD.options.sun.y; options3dSunZ.value = ThreeD.options.sun.z; @@ -1198,16 +1230,17 @@ export function toggle3dOptions() { } function changeSunPosition() { - const x = +options3dSunX.value; - const y = +options3dSunY.value; - const z = +options3dSunZ.value; + const x = options3dSunX.valueAsNumber; + const y = options3dSunY.valueAsNumber; + const z = options3dSunZ.valueAsNumber; ThreeD.setSun(x, y, z); } function changeRotation() { - (this.nextElementSibling || this.previousElementSibling).value = this.value; - const speed = +this.value; - ThreeD.setRotation(speed); + console.log(this, "\n", this.value); + // (this.nextElementSibling || this.previousElementSibling).value = this.value; + // const speed = +this.value; + // ThreeD.setRotation(speed); } function toggleLabels3d() { diff --git a/src/scripts/generation/generation.ts b/src/scripts/generation/generation.ts index fa9978e6..fb5472cd 100644 --- a/src/scripts/generation/generation.ts +++ b/src/scripts/generation/generation.ts @@ -8,7 +8,6 @@ import {initLayers, renderLayer, restoreLayers} from "layers"; import {drawScaleBar, Rulers} from "modules/measurers"; // @ts-expect-error js module import {unfog} from "modules/ui/editors"; -// @ts-expect-error js module import {applyMapSize, randomizeOptions} from "modules/ui/options"; // @ts-expect-error js module import {applyStyleOnLoad} from "modules/ui/stylePresets"; @@ -30,7 +29,7 @@ import { isBurg } from "utils/typeUtils"; const {Zoom, ThreeD} = window; -interface IGenerationOptions { +export interface IGenerationOptions { seed: string; graph: IGrid; } diff --git a/src/types/overrides.d.ts b/src/types/overrides.d.ts index 713029bc..0c049c2c 100644 --- a/src/types/overrides.d.ts +++ b/src/types/overrides.d.ts @@ -29,6 +29,7 @@ interface Window { Markers: any; COA: any; Routes: any; + Cloud: any; } interface Node { diff --git a/src/utils/nodeUtils.ts b/src/utils/nodeUtils.ts index b3744a5f..3a07fe64 100644 --- a/src/utils/nodeUtils.ts +++ b/src/utils/nodeUtils.ts @@ -6,6 +6,7 @@ export type ElementMap = { input: HTMLInputElement; output: HTMLOutputElement; select: HTMLSelectElement; + canvas: HTMLCanvasElement; // add more types as needed }; From 4f4066333afbe6d47475c9836f1ba16dc59a03ae Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 2 Sep 2024 19:42:03 +0000 Subject: [PATCH 25/27] options 90% --- src/modules/ui/options.ts | 56 ++++++++++++++++++----------------- src/types/globals.d.ts | 5 +++- src/types/pack/burgs.d.ts | 2 +- src/types/pack/provinces.d.ts | 2 +- src/types/pack/states.d.ts | 2 +- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index a002666a..09d4fde0 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -32,10 +32,7 @@ byId<'button'>("optionsTrigger").on("click", showOptions); byId<'button'>("optionsHide").on("click", hideOptions); // Window Objects -const Zoom = window.Zoom; -const COA = window.COA; -const Cloud = window.Cloud; -const ThreeD = window.ThreeD; +const {Zoom, COA, Cloud, ThreeD, Names} = window; // DIV elements const tooltip = byId<'div'>("tooltip"); @@ -535,7 +532,7 @@ function changeEmblemShape(emblemShape: string) { }); pack.burgs.forEach(burg => { - if (!isBurg(burg) || burg.removed || !burg.coa || burg.coa === "custom") return; + if (!isBurg(burg) || burg.removed || !burg.coa || ( burg.coa === "custom")) return; const newShield = specificShape || COA.getPackShield(burg.culture, burg.state); if (newShield === burg.coa.shield) return; burg.coa.shield = newShield; @@ -770,7 +767,7 @@ function generateEra() { if (!stored("year")) yearInput.valueAsNumber = rand(100, 2000); // current year if (!stored("era")) eraInput.value = Names.getBaseShort(P(0.7) ? 1 : rand(nameBases.length)) + " Era"; options.year = yearInput.valueAsNumber; - options.era = eraInput.valueAsNumber; + options.era = eraInput.value; options.eraShort = options.era .split(" ") .map(w => w[0].toUpperCase()) @@ -798,7 +795,7 @@ function changeYear() { function changeEra() { if (!eraInput.valueAsNumber) return; lock("era"); - options.era = eraInput.valueAsNumber; + options.era = eraInput.value; } // remove all saved data from LocalStorage and reload the page @@ -998,9 +995,11 @@ function loadURL() { } // load map -byId<'input'>("mapToLoad").on("change", function () { - const fileToLoad = this.files[0]; - this.value = ""; +byId<'input'>("mapToLoad").on("change", () => function (element: HTMLInputElement) { + const fileList = element.files; + if (!fileList || !fileList.length) return; + const fileToLoad = fileList[0]; + element.value = ""; closeDialogs(); uploadMap(fileToLoad); }); @@ -1013,7 +1012,7 @@ function openSaveTiles() { let loading: NodeJS.Timer; const inputs = byId("saveTilesScreen").querySelectorAll("input"); - inputs.forEach(input => input.on("input", updateTilesOptions)); + inputs.forEach(input => input.on("input", updateTilesOptionsValues)); $("#saveTilesScreen").dialog({ resizable: false, @@ -1035,20 +1034,24 @@ function openSaveTiles() { } }, close: () => { - inputs.forEach(input => input.removeEventListener("input", updateTilesOptions)); + inputs.forEach(input => input.removeEventListener("input", updateTilesOptionsValues)); debug.selectAll("*").remove(); clearInterval(loading); } }); } -function updateTilesOptions() { - if (this?.tagName === "INPUT") { +function updateTilesOptionsValues(this: HTMLInputElement) { + if (this.tagName === "INPUT") { const {nextElementSibling: next, previousElementSibling: prev} = this; - if (next?.tagName === "INPUT") next.value = this.value; - if (prev?.tagName === "INPUT") prev.value = this.value; + if (next?.tagName === "INPUT") (next as HTMLInputElement).value = this.value; + if (prev?.tagName === "INPUT") (prev as HTMLInputElement).value = this.value; } + updateTilesOptions(); + } + +function updateTilesOptions() { const tileSize = byId("tileSize"); const tilesX = byId<'input'>("tileColsOutput").valueAsNumber; const tilesY = byId<'input'>("tileRowsOutput").valueAsNumber; @@ -1176,7 +1179,7 @@ export function toggle3dOptions() { if (isLoaded) return; isLoaded = true; - +// MARKER: Move to separate file ThreeD.ts options3dUpdate.on("click", ThreeD.update); byId("options3dConfigureWorld").on("click", () => openDialog("worldConfigurator")); byId("options3dSave").on("click", ThreeD.saveScreenshot); @@ -1219,14 +1222,14 @@ export function toggle3dOptions() { options3dGlobeResolution.value = ThreeD.options.resolution; } - function changeHeightScale() { + function changeHeightScale(this: HTMLInputElement) { options3dScaleRange.value = options3dScaleNumber.value = this.value; - ThreeD.setScale(+this.value); + ThreeD.setScale(this.valueAsNumber); } - function changeLightness() { + function changeLightness(this: HTMLInputElement) { options3dLightnessRange.value = options3dLightnessNumber.value = this.value; - ThreeD.setLightness(this.value / 100); + ThreeD.setLightness(this.valueAsNumber / 100); } function changeSunPosition() { @@ -1236,11 +1239,10 @@ export function toggle3dOptions() { ThreeD.setSun(x, y, z); } - function changeRotation() { - console.log(this, "\n", this.value); - // (this.nextElementSibling || this.previousElementSibling).value = this.value; - // const speed = +this.value; - // ThreeD.setRotation(speed); + function changeRotation(this: HTMLInputElement) { + ((this.nextElementSibling || this.previousElementSibling)! as HTMLInputElement).value = this.value; + const speed = +this.value; + ThreeD.setRotation(speed); } function toggleLabels3d() { @@ -1257,7 +1259,7 @@ export function toggle3dOptions() { ThreeD.setColors(options3dMeshSky.value, options3dMeshWater.value); } - function changeResolution() { + function changeResolution(this: HTMLSelectElement) { ThreeD.setResolution(this.value); } } diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index c65e7859..e8f94b76 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -23,9 +23,12 @@ declare let options: IOptions; interface IOptions { pinNotes: boolean; showMFCGMap: boolean; - winds: [number, number, number, number, number, number]; + winds: number[]; stateLabelsMode: "auto" | "short" | "full"; year: number; + era: string; + eraShort: string; + military: any; //MARKER any } declare let populationRate: number; diff --git a/src/types/pack/burgs.d.ts b/src/types/pack/burgs.d.ts index 36755f59..43eb58a1 100644 --- a/src/types/pack/burgs.d.ts +++ b/src/types/pack/burgs.d.ts @@ -9,7 +9,7 @@ interface IBurg { y: number; population: number; type: TCultureType; - coa: ICoa | "string"; + coa: ICoa | "custom"; capital: Logical; // 1 - capital, 0 - burg port: number; // port feature id, 0 - not a port citadel: Logical; diff --git a/src/types/pack/provinces.d.ts b/src/types/pack/provinces.d.ts index 39f7ec8e..681bede6 100644 --- a/src/types/pack/provinces.d.ts +++ b/src/types/pack/provinces.d.ts @@ -8,7 +8,7 @@ interface IProvince { state: number; center: number; pole: TPoint; - coa: ICoa | string; + coa: ICoa | "custom"; removed?: boolean; } diff --git a/src/types/pack/states.d.ts b/src/types/pack/states.d.ts index 79dd27cd..a106099a 100644 --- a/src/types/pack/states.d.ts +++ b/src/types/pack/states.d.ts @@ -11,7 +11,7 @@ interface IState { formName: string; fullName: string; pole: TPoint; - coa: ICoa | string; + coa: ICoa | "custom"; area: number; cells: number; burgs: number; From 6c983419e7530971984f807b656fbf755572512f Mon Sep 17 00:00:00 2001 From: kruschen Date: Mon, 2 Sep 2024 19:43:17 +0000 Subject: [PATCH 26/27] move selects for 3d to 3d code --- src/modules/ui/options.ts | 43 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index 09d4fde0..e5391706 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -124,27 +124,6 @@ const manorsOutput = byId<'output'>("manorsOutput"); const pointsOutputFormatted = byId<'output'>("pointsOutputFormatted"); const religionsOutput = byId<'output'>("religionsOutput"); -// 3D options -const options3dMesh = byId<'div'>("options3dMesh"); -const options3dGlobe = byId<'div'>("options3dGlobe"); -const options3dOBJSave = byId<'button'>("options3dOBJSave"); -const options3dScaleRange = byId<'input'>("options3dScaleRange"); -const options3dScaleNumber = byId<'input'>("options3dScaleNumber"); -const options3dLightnessRange = byId<'input'>("options3dLightnessRange"); -const options3dLightnessNumber = byId<'input'>("options3dLightnessNumber"); -const options3dSunX = byId<'input'>("options3dSunX"); -const options3dSunY = byId<'input'>("options3dSunY"); -const options3dSunZ = byId<'input'>("options3dSunZ"); -const options3dMeshRotationRange = byId<'input'>("options3dMeshRotationRange"); -const options3dMeshRotationNumber = byId<'input'>("options3dMeshRotationNumber"); -const options3dGlobeRotationRange = byId<'input'>("options3dGlobeRotationRange"); -const options3dGlobeRotationNumber = byId<'input'>("options3dGlobeRotationNumber"); -const options3dMeshLabels3d = byId<'input'>("options3dMeshLabels3d"); -const options3dMeshSkyMode = byId<'input'>("options3dMeshSkyMode"); -const options3dColorSection = byId<'div'>("options3dColorSection"); -const options3dMeshSky = byId<'input'>("options3dMeshSky"); -const options3dMeshWater = byId<'input'>("options3dMeshWater"); -const options3dGlobeResolution = byId<'select'>("options3dGlobeResolution"); // remove glow if tip is aknowledged if (stored("disable_click_arrow_tooltip")) { @@ -1180,6 +1159,28 @@ export function toggle3dOptions() { if (isLoaded) return; isLoaded = true; // MARKER: Move to separate file ThreeD.ts +// 3D options +const options3dMesh = byId<'div'>("options3dMesh"); +const options3dGlobe = byId<'div'>("options3dGlobe"); +const options3dOBJSave = byId<'button'>("options3dOBJSave"); +const options3dScaleRange = byId<'input'>("options3dScaleRange"); +const options3dScaleNumber = byId<'input'>("options3dScaleNumber"); +const options3dLightnessRange = byId<'input'>("options3dLightnessRange"); +const options3dLightnessNumber = byId<'input'>("options3dLightnessNumber"); +const options3dSunX = byId<'input'>("options3dSunX"); +const options3dSunY = byId<'input'>("options3dSunY"); +const options3dSunZ = byId<'input'>("options3dSunZ"); +const options3dMeshRotationRange = byId<'input'>("options3dMeshRotationRange"); +const options3dMeshRotationNumber = byId<'input'>("options3dMeshRotationNumber"); +const options3dGlobeRotationRange = byId<'input'>("options3dGlobeRotationRange"); +const options3dGlobeRotationNumber = byId<'input'>("options3dGlobeRotationNumber"); +const options3dMeshLabels3d = byId<'input'>("options3dMeshLabels3d"); +const options3dMeshSkyMode = byId<'input'>("options3dMeshSkyMode"); +const options3dColorSection = byId<'div'>("options3dColorSection"); +const options3dMeshSky = byId<'input'>("options3dMeshSky"); +const options3dMeshWater = byId<'input'>("options3dMeshWater"); +const options3dGlobeResolution = byId<'select'>("options3dGlobeResolution"); + options3dUpdate.on("click", ThreeD.update); byId("options3dConfigureWorld").on("click", () => openDialog("worldConfigurator")); byId("options3dSave").on("click", ThreeD.saveScreenshot); From 1644b0594f0b56cb74656ec67f74e244987d2c14 Mon Sep 17 00:00:00 2001 From: kruschen Date: Tue, 3 Sep 2024 20:37:32 +0000 Subject: [PATCH 27/27] clean up byId function --- src/modules/ui/options.ts | 2 +- src/utils/nodeUtils.ts | 22 +++------------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/modules/ui/options.ts b/src/modules/ui/options.ts index e5391706..5bd21b92 100644 --- a/src/modules/ui/options.ts +++ b/src/modules/ui/options.ts @@ -1083,7 +1083,7 @@ function enterStandardView() { byId("heightmap3DView").classList.remove("pressed"); byId("viewStandard").classList.add("pressed"); - if (!byId("canvas3d")) return; + if (!byId("canvas3d",{throwOnNull:false})) return; ThreeD.stop(); byId("canvas3d").remove(); if (byId("options3dUpdate").offsetParent) $("#options3d").dialog("close"); diff --git a/src/utils/nodeUtils.ts b/src/utils/nodeUtils.ts index 3a07fe64..8d7e88b3 100644 --- a/src/utils/nodeUtils.ts +++ b/src/utils/nodeUtils.ts @@ -10,26 +10,10 @@ export type ElementMap = { // add more types as needed }; -type ElementMapKeys = keyof ElementMap; - -interface ByIdOptions { - throwOnNull?: boolean; - // add more options as needed -} - // function definition with overloads to account for different options -export function byId(id: string, options?: ByIdOptions & {throwOnNull: true}): ElementMap[K]; -export function byId(id: string, options: ByIdOptions & {throwOnNull: boolean}): ElementMap[K]|null; -/** - * Retrieves an element from the DOM by its ID. - * @template K - The key of the element in the ElementMap. - * @param {string} id - The ID of the element to retrieve. - * @param {ByIdOptions} [options] - The options for retrieving the element. - * @param {boolean} [options.throwOnNull=true] - Whether to throw an error if the element is not found. - * @returns {ElementMap[K] | null} The retrieved element or null if not found. - * @throws {Error} If the element is not found and options.throwOnNull is true. - */ -export function byId(id: string, options: ByIdOptions = {throwOnNull: true}) { +export function byId(id: string): ElementMap[K]; +export function byId(id: string, options?: {throwOnNull: false}): ElementMap[K] | null; +export function byId(id: string, options = {throwOnNull: true}) { const element = document.getElementById(id); if (!element && options.throwOnNull) { throw new Error(`Element ${id} not found`);