From 93efa50b1ef366cf1d9fada8d7ca0cb26e318a23 Mon Sep 17 00:00:00 2001 From: dev7355608 Date: Wed, 16 Aug 2023 00:22:11 +0200 Subject: [PATCH] Add support for metric units --- README.md | 4 +++- lang/de.json | 3 ++- lang/en.json | 3 ++- lang/fr.json | 3 ++- module.json | 6 +++--- scripts/automation.mjs | 23 ++++++++++++++++++++++- scripts/settings.mjs | 41 ++++++++++++++++++++++++++++++++++++++++- 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e4500b1..1ad0590 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,9 @@ A token gains ... - _See Invisibility_ if the actor has an active effect with the name `See Invisibility`[\*](#translations). - _Witch Sight_ if the actor has a feat with the name `Invocation: Witch Sight`[\*](#translations). -By default all tokens have hearing range of 30 feet. The default hearing range can be configured in the settings. +By default all tokens have hearing range of 30 feet. The default hearing range can be configured in the module settings. + +If you use metric units, you need to change the units in the module settings. --- diff --git a/lang/de.json b/lang/de.json index ba1a10b..959c661 100644 --- a/lang/de.json +++ b/lang/de.json @@ -17,5 +17,6 @@ "VISION5E.SeeInvisibility": "Unsichtbares sehen", "VISION5E.WitchSight": "Hexensicht", "VISION5E.Settings.DefaultHearingRangeN": "Standard-Hörweite", - "VISION5E.Settings.DefaultHearingRangeL": "Legt fest, wie weit Spielfiguren standardmäßig hören können. Erfordert Neuladen." + "VISION5E.Settings.DefaultHearingRangeL": "Legt fest, wie weit Spielfiguren standardmäßig hören können. Erfordert Neuladen.", + "VISION5E.Settings.UnitsL": "Legt fest, welche Längeneinheit benutzt wird. Erfordert Neuladen." } diff --git a/lang/en.json b/lang/en.json index abd43f5..fe1cfbc 100644 --- a/lang/en.json +++ b/lang/en.json @@ -17,5 +17,6 @@ "VISION5E.SeeInvisibility": "See Invisibility", "VISION5E.WitchSight": "Witch Sight", "VISION5E.Settings.DefaultHearingRangeN": "Default Hearing Range", - "VISION5E.Settings.DefaultHearingRangeL": "Configure how far tokens can hear by default. Requires the world to be reloaded." + "VISION5E.Settings.DefaultHearingRangeL": "Configure how far tokens can hear by default. Requires the world to be reloaded.", + "VISION5E.Settings.UnitsL": "Configure which unit of length is used. Requires the world to be reloaded." } diff --git a/lang/fr.json b/lang/fr.json index 79143fc..d68053c 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -17,5 +17,6 @@ "VISION5E.SeeInvisibility": "Détection de l'invisibilité", "VISION5E.WitchSight": "Vision sorcière", "VISION5E.Settings.DefaultHearingRangeN": "Distance d'audition par défaut", - "VISION5E.Settings.DefaultHearingRangeL": "Configurez la distance jusqu'où les tokens peuvent entendre par défaut. Un redémarrage du monde est nécessaire." + "VISION5E.Settings.DefaultHearingRangeL": "Configurez la distance jusqu'où les tokens peuvent entendre par défaut. Un redémarrage du monde est nécessaire.", + "VISION5E.Settings.UnitsL": "Configurez l'unité de longueur utilisée. Un redémarrage du monde est nécessaire." } diff --git a/module.json b/module.json index 02890fe..49cad97 100644 --- a/module.json +++ b/module.json @@ -8,7 +8,7 @@ "email": "dev7355608@gmail.com" } ], - "version": "1.9.2", + "version": "1.10.0", "compatibility": { "minimum": "11.299", "verified": "11.307" @@ -57,8 +57,8 @@ }, "url": "https://github.com/dev7355608/vision-5e", "manifest": "https://github.com/dev7355608/vision-5e/releases/latest/download/module.json", - "download": "https://github.com/dev7355608/vision-5e/releases/download/v1.9.2/module.zip", - "changelog": "https://github.com/dev7355608/vision-5e/releases/tag/v1.9.2", + "download": "https://github.com/dev7355608/vision-5e/releases/download/v1.10.0/module.zip", + "changelog": "https://github.com/dev7355608/vision-5e/releases/tag/v1.10.0", "bugs": "https://github.com/dev7355608/vision-5e/issues", "readme": "https://raw.githubusercontent.com/dev7355608/vision-5e/main/README.md", "license": "https://raw.githubusercontent.com/dev7355608/vision-5e/main/LICENSE" diff --git a/scripts/automation.mjs b/scripts/automation.mjs index 926a8d6..28ce954 100644 --- a/scripts/automation.mjs +++ b/scripts/automation.mjs @@ -1,11 +1,30 @@ import settings from "./settings.mjs"; -const RANGE_REGEX = /\b(\d+)\s+(?:feet|ft.?)\b/i; +const RANGE_REGEX = /\b([1-9]\d*)\b/i; const effectMapping = new Map(); const featMapping = new Map(); +function feetToMeters(ft) { + return ft >= 1e15 ? 1e15 : ft * 3 / 10; +} + +function convertRanges(data) { + if (settings.metric) { + + if (typeof data.range === "number") { + data.range = feetToMeters(data.range); + } + + if (typeof data.defaultRange === "number") { + data.defaultRange = feetToMeters(data.defaultRange); + } + } +} + function registerEffect(names, data) { + convertRanges(data); + for (const name of names) { effectMapping.set(name.toLowerCase(), data); } @@ -16,6 +35,8 @@ function getEffect(name) { } function registerFeat(names, data) { + convertRanges(data); + for (const name of names) { featMapping.set(name.toLowerCase(), data); } diff --git a/scripts/settings.mjs b/scripts/settings.mjs index 26a3494..ae99df4 100644 --- a/scripts/settings.mjs +++ b/scripts/settings.mjs @@ -3,6 +3,24 @@ const settings = {}; export default settings; Hooks.once("init", () => { + game.settings.register( + "vision-5e", + "units", + { + name: "DND5E.MovementUnits", + hint: "VISION5E.Settings.UnitsL", + scope: "world", + config: true, + requiresReload: true, + type: String, + choices: { + ft: "DND5E.DistFt", + m: "DND5E.DistM" + }, + default: "ft" + } + ); + game.settings.register( "vision-5e", "defaultHearingRange", @@ -24,6 +42,8 @@ Hooks.once("init", () => { } else { settings.defaultHearingRange = 0; } + + settings.metric = game.settings.get("vision-5e", "units") === "m"; }); Hooks.on("renderSettingsConfig", (app, html) => { @@ -31,14 +51,33 @@ Hooks.on("renderSettingsConfig", (app, html) => { return; } + const units = game.settings.get("vision-5e", "units"); const defaultHearingRange = html[0].querySelector(`input[name="vision-5e.defaultHearingRange"]`); defaultHearingRange.value ||= 0; defaultHearingRange.min = 0; defaultHearingRange.step = 0.01; defaultHearingRange.required = true; + defaultHearingRange.placeholder = "0"; + defaultHearingRange.dataset.units = units; html[0].querySelector(`[data-setting-id="vision-5e.defaultHearingRange"]`).classList.add("slim"); html[0].querySelector(`[data-setting-id="vision-5e.defaultHearingRange"] label`) - .insertAdjacentHTML("beforeend", ` (ft)`); + .insertAdjacentHTML("beforeend", ` (${units})`); + html[0].querySelector(`select[name="vision-5e.units"]`).addEventListener("change", (event) => { + const newUnits = event.target.value; + const oldUnits = defaultHearingRange.dataset.units; + + if (oldUnits !== newUnits) { + defaultHearingRange.dataset.units = newUnits; + + if (newUnits === "m") { + defaultHearingRange.value = (defaultHearingRange.value * 3 / 10).toNearest(defaultHearingRange.step); + } else { + defaultHearingRange.value = (defaultHearingRange.value * 10 / 3).toNearest(defaultHearingRange.step); + } + + html[0].querySelector(`[data-setting-id="vision-5e.defaultHearingRange"] label > span.units`).innerHTML = `(${newUnits})`; + } + }); });