diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c5bee80..391feee 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -119,7 +119,7 @@ jobs: module.json \ README.md \ LICENSE \ - templates \ + templates/ \ scripts/ \ styles/ \ packs/ \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 55a58ae..040e563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# [12.6.0](https://github.com/ChasarooniZ/pf2e-rpg-numbers/compare/12.5.5...12.6.0) - Our Menu - First Course +- `Settings Menu` + - Redid many settings to be in their own menu + - Added hover over images to preview each setting + - Added option to Import and Export setting +- `Shake on Attack` + - Increased the base strength of this shake to meet recommended parameters +- `API` + - Added import and export settings to api + - `game.pf2eRPGNumbers.settings.export` & `game.pf2eRPGNumbers.settings.import` +- `Damage Numbers` + - Added support for multiply dice for more than `2 * ` + - Removed error when damage roll has no target + # [12.5.5](https://github.com/ChasarooniZ/pf2e-rpg-numbers/compare/12.5.4...12.5.5) - Damage Roll Fix - Fixed bug where damage rolls weren't actually showing diff --git a/assets/feature-vids/check-text.gif b/assets/feature-vids/check-text.gif new file mode 100644 index 0000000..87f1908 Binary files /dev/null and b/assets/feature-vids/check-text.gif differ diff --git a/assets/feature-vids/crit-fire-emblem-awakening.gif b/assets/feature-vids/crit-fire-emblem-awakening.gif new file mode 100644 index 0000000..024b6a6 Binary files /dev/null and b/assets/feature-vids/crit-fire-emblem-awakening.gif differ diff --git a/assets/feature-vids/crit-persona-5.gif b/assets/feature-vids/crit-persona-5.gif new file mode 100644 index 0000000..2e9230a Binary files /dev/null and b/assets/feature-vids/crit-persona-5.gif differ diff --git a/assets/feature-vids/damage-numbers.gif b/assets/feature-vids/damage-numbers.gif new file mode 100644 index 0000000..49d3ed6 Binary files /dev/null and b/assets/feature-vids/damage-numbers.gif differ diff --git a/assets/feature-vids/damage-shake.gif b/assets/feature-vids/damage-shake.gif new file mode 100644 index 0000000..7eb787c Binary files /dev/null and b/assets/feature-vids/damage-shake.gif differ diff --git a/assets/feature-vids/finishing-move.gif b/assets/feature-vids/finishing-move.gif new file mode 100644 index 0000000..ee21e4e Binary files /dev/null and b/assets/feature-vids/finishing-move.gif differ diff --git a/assets/feature-vids/from-soft-elden-ring-death.gif b/assets/feature-vids/from-soft-elden-ring-death.gif new file mode 100644 index 0000000..1bdc752 Binary files /dev/null and b/assets/feature-vids/from-soft-elden-ring-death.gif differ diff --git a/assets/feature-vids/from-soft-elden-ring-noun-verbed.gif b/assets/feature-vids/from-soft-elden-ring-noun-verbed.gif new file mode 100644 index 0000000..9d987a8 Binary files /dev/null and b/assets/feature-vids/from-soft-elden-ring-noun-verbed.gif differ diff --git a/assets/feature-vids/rotate-on-attack.gif b/assets/feature-vids/rotate-on-attack.gif new file mode 100644 index 0000000..f1ff6ce Binary files /dev/null and b/assets/feature-vids/rotate-on-attack.gif differ diff --git a/assets/feature-vids/shake-on-attack.gif b/assets/feature-vids/shake-on-attack.gif new file mode 100644 index 0000000..2364221 Binary files /dev/null and b/assets/feature-vids/shake-on-attack.gif differ diff --git a/assets/feature-vids/shake-on-damaged.gif b/assets/feature-vids/shake-on-damaged.gif new file mode 100644 index 0000000..045d2fc Binary files /dev/null and b/assets/feature-vids/shake-on-damaged.gif differ diff --git a/languages/de.json b/languages/de.json index 39cfadb..ceb5763 100644 --- a/languages/de.json +++ b/languages/de.json @@ -547,6 +547,45 @@ "hint": "Lassen Sie die Konsole Nachrichten für verschiedene Dinge empfangen" } }, + "menu": { + "settings": { + "title": "Konfigurationsmenü PF2e RPG #s", + "buttons": { + "export": "Einstellungen Exportieren", + "import": "Einstellungen Importieren", + "footer": { + "save": "Speichern", + "submit": "Einreichen", + "cancel": "Abbrechen" + } + }, + "notification": { + "save": "Einstellungen erfolgreich gespeichert!", + "submit": "Einstellungen erfolgreich eingereicht!", + "cancel": "Konfigurationsmenü geschlossen ohne zu speichern" + }, + "tabs": { + "home": "Startseite", + "rolls": "Würfe", + "token": "Token", + "critical": "Kritisch", + "text": "Text", + "misc": "Verschiedenes" + } + }, + "import": { + "title": "PF2e RPG Einstellungen Importieren", + "content": "Einstellungen JSON Hochladen", + "buttons": { + "import": "Importieren", + "cancel": "Abbrechen" + }, + "notification": { + "success": "PF2e RPG Einstellungen Importiert!", + "failure": "PF2e RPG Einstellungen Import fehlgeschlagen :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "Kritischer Fehler", diff --git a/languages/en.json b/languages/en.json index 09a0914..6137698 100644 --- a/languages/en.json +++ b/languages/en.json @@ -22,7 +22,7 @@ "headers": { "dmg-numbers": "Damage Numbers", "check-animations": "Checks & Attack Animations", - "screen-shake": "Screen Shake", + "screen-shake": "Shake on Damaged", "token-dmg-shake": { "title": "Token Damage Shake", "scaling": "Token Damage Shake - Scaling" @@ -30,9 +30,7 @@ "shake-on-attack": "Shake on Attack", "rotate-on-attack": "Rotate on Attack", "finishing-move": { - "title": "Finishing Moves", - "pcs": "Finishing Moves: PC Settings", - "npcs": "Finishing Moves: NPC Settings" + "title": "Finishing Moves" }, "plus-one": "Every +1 Matters", "critical": "Critical Hit", @@ -217,7 +215,7 @@ }, "intensity-max": { "name": "Intensity", - "hint": "How hard to shake the screen" + "hint": "How hard to shake the screen in pixels (recommended between 10 and 35)" }, "intensity-type": { "name": "Intensity Scaling", @@ -547,6 +545,45 @@ "hint": "Have the console receive messages for different stuff" } }, + "menu": { + "settings": { + "title": "Pf2e RPG #s Config Menu", + "buttons": { + "export": "Export Settings", + "import": "Import Settings", + "footer": { + "save": "Save", + "submit": "Submit", + "cancel": "Cancel" + } + }, + "notification": { + "save": "Settings saved successfully!", + "submit": "Settings submitted successfully!", + "cancel": "Settings menu closed without saving" + }, + "tabs": { + "home": "Home", + "rolls": "Rolls", + "token": "Token", + "critical": "Critical", + "text": "Text", + "misc": "Misc" + } + }, + "import": { + "title": "PF2e RPG Settings Import", + "content": "Upload Settings JSON", + "buttons": { + "import": "Import", + "cancel": "Cancel" + }, + "notification": { + "success": "Pf2e RPG Settings Imported!", + "failure": "PF2e RPG Settings failed to import :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "Critical Failure", diff --git a/languages/es.json b/languages/es.json index d2d5439..b934afa 100644 --- a/languages/es.json +++ b/languages/es.json @@ -547,6 +547,45 @@ "hint": "Hacer que la consola reciba mensajes para diferentes cosas." } }, + "menu": { + "settings": { + "title": "Menú de Configuración de PF2e RPG #s", + "buttons": { + "export": "Exportar Configuraciones", + "import": "Importar Configuraciones", + "footer": { + "save": "Guardar", + "submit": "Enviar", + "cancel": "Cancelar" + } + }, + "notification": { + "save": "¡Configuraciones guardadas con éxito!", + "submit": "¡Configuraciones enviadas con éxito!", + "cancel": "Menú de configuraciones cerrado sin guardar" + }, + "tabs": { + "home": "Inicio", + "rolls": "Tiradas", + "token": "Ficha", + "critical": "Crítico", + "text": "Texto", + "misc": "Varios" + } + }, + "import": { + "title": "Importación de Configuraciones de PF2e RPG", + "content": "Subir JSON de Configuraciones", + "buttons": { + "import": "Importar", + "cancel": "Cancelar" + }, + "notification": { + "success": "¡Configuraciones de PF2e RPG Importadas!", + "failure": "Falló la importación de Configuraciones de PF2e RPG :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "Fallo crítico", diff --git a/languages/fr.json b/languages/fr.json index 315aa57..62ba666 100644 --- a/languages/fr.json +++ b/languages/fr.json @@ -547,6 +547,45 @@ "hint": "Faire en sorte que la console reçoive des messages pour différentes choses" } }, + "menu": { + "settings": { + "title": "Menu de Configuration PF2e RPG #s", + "buttons": { + "export": "Exporter Paramètres", + "import": "Importer Paramètres", + "footer": { + "save": "Enregistrer", + "submit": "Soumettre", + "cancel": "Annuler" + } + }, + "notification": { + "save": "Paramètres enregistrés avec succès!", + "submit": "Paramètres soumis avec succès!", + "cancel": "Menu de paramètres fermé sans enregistrement" + }, + "tabs": { + "home": "Accueil", + "rolls": "Jets", + "token": "Jeton", + "critical": "Critique", + "text": "Texte", + "misc": "Divers" + } + }, + "import": { + "title": "Importation des Paramètres PF2e RPG", + "content": "Télécharger le JSON des Paramètres", + "buttons": { + "import": "Importer", + "cancel": "Annuler" + }, + "notification": { + "success": "Paramètres PF2e RPG Importés!", + "failure": "Échec de l'importation des Paramètres PF2e RPG :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "Échec critique", diff --git a/languages/ja.json b/languages/ja.json index 92c164f..b4f854e 100644 --- a/languages/ja.json +++ b/languages/ja.json @@ -547,6 +547,45 @@ "hint": "コンソールにさまざまなメッセージを受信させる" } }, + "menu": { + "settings": { + "title": "PF2e RPG #s 設定メニュー", + "buttons": { + "export": "設定のエクスポート", + "import": "設定のインポート", + "footer": { + "save": "保存", + "submit": "送信", + "cancel": "キャンセル" + } + }, + "notification": { + "save": "設定が正常に保存されました!", + "submit": "設定が正常に送信されました!", + "cancel": "設定メニューは保存せずに閉じられました" + }, + "tabs": { + "home": "ホーム", + "rolls": "ロール", + "token": "トークン", + "critical": "クリティカル", + "text": "テキスト", + "misc": "その他" + } + }, + "import": { + "title": "PF2e RPG 設定のインポート", + "content": "設定JSONをアップロード", + "buttons": { + "import": "インポート", + "cancel": "キャンセル" + }, + "notification": { + "success": "PF2e RPG 設定がインポートされました!", + "failure": "PF2e RPG 設定のインポートに失敗しました :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "重大な障害", diff --git a/languages/ko.json b/languages/ko.json index 4fbc5db..b25fd20 100644 --- a/languages/ko.json +++ b/languages/ko.json @@ -547,6 +547,45 @@ "hint": "콘솔이 다양한 내용에 대한 메시지를 받도록 합니다." } }, + "menu": { + "settings": { + "title": "PF2e RPG #s 설정 메뉴", + "buttons": { + "export": "설정 내보내기", + "import": "설정 가져오기", + "footer": { + "save": "저장", + "submit": "제출", + "cancel": "취소" + } + }, + "notification": { + "save": "설정이 성공적으로 저장되었습니다!", + "submit": "설정이 성공적으로 제출되었습니다!", + "cancel": "설정 메뉴가 저장되지 않고 닫혔습니다" + }, + "tabs": { + "home": "홈", + "rolls": "굴림", + "token": "토큰", + "critical": "치명타", + "text": "텍스트", + "misc": "기타" + } + }, + "import": { + "title": "PF2e RPG 설정 가져오기", + "content": "설정 JSON 업로드", + "buttons": { + "import": "가져오기", + "cancel": "취소" + }, + "notification": { + "success": "PF2e RPG 설정이 가져오기되었습니다!", + "failure": "PF2e RPG 설정 가져오기에 실패했습니다 :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "중대한 실패", diff --git a/languages/pl.json b/languages/pl.json index 0090cc4..c4d00b8 100644 --- a/languages/pl.json +++ b/languages/pl.json @@ -547,6 +547,45 @@ "hint": "Niech konsola odbiera komunikaty dla różnych rzeczy" } }, + "menu": { + "settings": { + "title": "Menu Konfiguracji PF2e RPG #s", + "buttons": { + "export": "Eksportuj Ustawienia", + "import": "Importuj Ustawienia", + "footer": { + "save": "Zapisz", + "submit": "Zatwierdź", + "cancel": "Anuluj" + } + }, + "notification": { + "save": "Ustawienia zostały pomyślnie zapisane!", + "submit": "Ustawienia zostały pomyślnie zatwierdzone!", + "cancel": "Menu ustawień zamknięto bez zapisywania" + }, + "tabs": { + "home": "Główna", + "rolls": "Rzuty", + "token": "Żeton", + "critical": "Krytyczny", + "text": "Tekst", + "misc": "Różne" + } + }, + "import": { + "title": "Import Ustawień PF2e RPG", + "content": "Prześlij JSON Ustawień", + "buttons": { + "import": "Importuj", + "cancel": "Anuluj" + }, + "notification": { + "success": "Ustawienia PF2e RPG zaimportowane!", + "failure": "Import Ustawień PF2e RPG nie powiódł się :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "Krytyczna Porażka", diff --git a/languages/ru.json b/languages/ru.json index 684961e..def5dcf 100644 --- a/languages/ru.json +++ b/languages/ru.json @@ -547,6 +547,45 @@ "hint": "Пусть консоль будет получать сообщения о разных вещах" } }, + "menu": { + "settings": { + "title": "Меню Настроек PF2e RPG #s", + "buttons": { + "export": "Экспорт настроек", + "import": "Импорт настроек", + "footer": { + "save": "Сохранить", + "submit": "Отправить", + "cancel": "Отмена" + } + }, + "notification": { + "save": "Настройки успешно сохранены!", + "submit": "Настройки успешно отправлены!", + "cancel": "Меню настроек закрыто без сохранения" + }, + "tabs": { + "home": "Главная", + "rolls": "Броски", + "token": "Токен", + "critical": "Критический", + "text": "Текст", + "misc": "Прочее" + } + }, + "import": { + "title": "Импорт настроек PF2e RPG", + "content": "Загрузить JSON настроек", + "buttons": { + "import": "Импорт", + "cancel": "Отмена" + }, + "notification": { + "success": "Настройки PF2e RPG успешно импортированы!", + "failure": "Ошибка импорта настроек PF2e RPG :(" + } + } + }, "display-text": { "outcomes": { "criticalFailure": "Критический отказ", diff --git a/scripts/helpers/animation/shakeScreenOnAttack.js b/scripts/helpers/animation/shakeScreenOnAttack.js index 01c3a9a..309399b 100644 --- a/scripts/helpers/animation/shakeScreenOnAttack.js +++ b/scripts/helpers/animation/shakeScreenOnAttack.js @@ -1,5 +1,5 @@ export async function shakeOnAttack(token, outcome) { - let strength = 5; + let strength = 10; if (["success", "criticalSuccess"].includes(outcome)) { if (outcome === "criticalSuccess") { strength *= 2; diff --git a/scripts/helpers/api.js b/scripts/helpers/api.js index 94f9a35..a27a0ce 100644 --- a/scripts/helpers/api.js +++ b/scripts/helpers/api.js @@ -5,6 +5,8 @@ import { generateRollScroll } from "./animation/generateRollScroll.js"; import { getDamageList } from "./rollTerms.js"; import { eldenRingDeath, eldenRingNounVerbed } from "./animation/text/fromSoftwareText.js"; import { turnTokenOnAttack } from "./animation/turnTokenOnAttack.js"; +import { exportSettings } from "./forms/exportSettings.js"; +import { importSettings } from "./forms/importSettings.js"; export function createAPI() { game.pf2eRPGNumbers = { @@ -41,6 +43,10 @@ export function createAPI() { nounVerbed: eldenRingNounVerbed, death: eldenRingDeath } + }, + settings: { + export: exportSettings, + import: importSettings } }; } diff --git a/scripts/helpers/forms/exportSettings.js b/scripts/helpers/forms/exportSettings.js new file mode 100644 index 0000000..fcfdb96 --- /dev/null +++ b/scripts/helpers/forms/exportSettings.js @@ -0,0 +1,23 @@ +import { MODULE_ID } from "../misc.js"; + +export function exportSettings() { + const data = { + name: "PF2e RPG Settings Export", + version: game.modules.get(MODULE_ID).version, + // Get all setting keys + settings: Array.from(game.settings.settings.keys()), + }; + data.settings = data.settings.filter((key) => key.startsWith(MODULE_ID)); + + // Map the filtered keys to an array of [key, value] pairs + data.settings = data.settings.map((key) => { + const settingKey = key.replace(`${MODULE_ID}.`, ""); + return [settingKey, game.settings.get(MODULE_ID, settingKey)]; + }); + + saveDataToFile( + JSON.stringify(data), + "json", + `pf2e-rpg-settings-(${new Date().toDateInputString()}).json` + ); +} \ No newline at end of file diff --git a/scripts/helpers/forms/importSettings.js b/scripts/helpers/forms/importSettings.js new file mode 100644 index 0000000..6deb8ac --- /dev/null +++ b/scripts/helpers/forms/importSettings.js @@ -0,0 +1,50 @@ +import { MODULE_ID } from "../misc.js"; + +export function importSettings() { + // Create a dialog to input JSON and upload a file + new Dialog({ + title: game.i18n.localize(`${MODULE_ID}.menu.import.title`), + content: ` +
+
+ + +
+
+ `, + buttons: { + import: { + icon: '', + label: game.i18n.localize(`${MODULE_ID}.menu.import.buttons.import`), + callback: async (html) => { + const fileInput = html.find('[name="file-input"]')[0].files[0]; + if (!fileInput) return; + + // Parse JSON from file + try { + const fileContent = await fileInput.text(); + const jsonObject = JSON.parse(fileContent); + + jsonObject.settings.forEach(([key, value]) => { + game.settings.set(MODULE_ID, key, value); + }); + console.log("Imported PF2e RPG # Data:", jsonObject); + ui.notifications.info( + game.i18n.localize(`${MODULE_ID}.menu.import.notification.success`) + ); + } catch (error) { + console.error("Invalid JSON file for PF2e RPG Numbers:", error); + ui.notifications.error( + game.i18n.localize(`${MODULE_ID}.menu.import.notification.failure`) + ); + } + }, + }, + cancel: { + icon: '', + label: game.i18n.localize(`${MODULE_ID}.menu.import.buttons.cancel`), + }, + }, + default: "import", + }).render(true); +} \ No newline at end of file diff --git a/scripts/helpers/forms/settingsConfigForm.js b/scripts/helpers/forms/settingsConfigForm.js new file mode 100644 index 0000000..df107a2 --- /dev/null +++ b/scripts/helpers/forms/settingsConfigForm.js @@ -0,0 +1,495 @@ +import { getSetting, MODULE_ID, setSetting } from "../misc.js"; + +export class SettingsConfigForm extends FormApplication { + // lots of other things... + constructor(options) { + super(options); + this.options = foundry.utils.mergeObject(this.constructor.defaultOptions, options); + } + + + static get defaultOptions() { + return foundry.utils.mergeObject(super.defaultOptions, { + classes: ['form'], + popOut: true, + template: `modules/pf2e-rpg-numbers/templates/settings/pf2e-rpg-settings-config.hbs`, + id: 'pf2e-rpg-numbers-settings-form', + title: 'Pf2e RPG #s Config Menu', + width: 600, + height: 600, + tabs: [{ navSelector: ".tabs", contentSelector: ".content", initial: "tab1" }] + }); + } + + activateListeners(html) { + super.activateListeners(html); + // Add event listener for the Save button + html.find('#pf2e-rpg-save').on('click', (event) => { + event.preventDefault(); + this._processForm(html, false); // Pass 'false' Fto not submit the form, only save + }); + html.find('#pf2e-rpg-submit').on('click', (event) => { + event.preventDefault(); + this._processForm(html, true); // Pass 'true' to indicate form submission + }); + html.find('#pf2e-rpg-cancel').on('click', (event) => { + event.preventDefault(); + ui.notifications.warn(game.i18n.localize(`${MODULE_ID}.menu.settings.notification.cancel`)); + this.close(); // Close the form without saving + }); + html.find('#pf2e-rpg-import').on('click', (event) => { + game.pf2eRPGNumbers.settings.import(); + this.close(); // Close the form without saving + }); + html.find('#pf2e-rpg-export').on('click', (event) => { + game.pf2eRPGNumbers.settings.export(); + }); + } + + getData() { + //game.settings.get('myModuleName', 'myComplexSettingName') + /*return { + placeholder: true + };*/ + return foundry.utils.mergeObject(super.getData(), { + tabs: [ + { + id: "home", + label: game.i18n.localize(`${MODULE_ID}.menu.settings.tabs.home`), + icon: "fa-dragon", + home: true, + settings: { + enabled: getSetting("enabled") + } + }, + { + id: "rolls", + label: game.i18n.localize(`${MODULE_ID}.menu.settings.tabs.rolls`), + icon: "fa-dice-d20", + rolls: true, + settings: { + 'dmg-numbers': { + enabled: getSetting("dmg-enabled"), + whenTo: getChoicesSetting("dmg-on-apply-or-roll"), + fontSize: getSetting("font-size"), + maxFontScale: getSetting("max-font-scale"), + topOffset: getNumberSetting("top-offset", { + min: -100, + max: 100, + step: 5, + }), + showTotal: getSetting("show-total"), + scaleType: getChoicesSetting("number-scale-type"), + split: getChoicesSetting("damage-split"), + duration: getNumberSetting("duration", { + min: 0, + max: 10, + step: 0.1, + }), + waitTime: getNumberSetting("wait-time-between-numbers", { + min: 0, + max: 1000, + step: 1, + }), + onlyGM: getSetting("show-only-GM"), + scale: getNumberSetting("animation-scale", { + min: 0, + max: 2, + step: 0.05, + }), + jitter: getNumberSetting("jitter", { + min: 0, + max: 1, + step: 0.05, + }), + }, + 'check-animations': { + enabled: getSetting("check-enabled"), + colorScheme: getChoicesSetting("check-color-scheme"), + showOutcome: getChoicesSetting("check-outcome-result"), + fontSize: getSetting("check-font-size"), + duration: getNumberSetting("check-duration", { + min: 0, + max: 10, + step: 0.1, + }), + sfx: { + enabled: getSetting("check-animations.sfx.enabled"), + checkOrAttack: getChoicesSetting("check-animations.sfx.check-or-attack"), + options: getChoicesSetting("check-animations.sfx.options"), + volume: getNumberSetting("check-animations.sfx.volume", { + min: 0, + max: 100, + step: 1, + }), + file: { + criticalSuccess: getSetting("check-animations.sfx.file.criticalSuccess"), + success: getSetting("check-animations.sfx.file.success"), + failure: getSetting("check-animations.sfx.file.failure"), + criticalFailure: getSetting("check-animations.sfx.file.criticalFailure"), + } + }, + }, + } + }, + { + id: "token", + label: game.i18n.localize(`${MODULE_ID}.menu.settings.tabs.token`), + icon: "fa-circle-user", + token: true, + settings: { + tokenShake: { + enabled: getSetting("dmg-shake-directional-enabled"), + distance: getNumberSetting("tok-shake-distance", { + min: 1, + max: 100, + step: 1, + }), + shakes: getNumberSetting("tok-shake-shakes", { + min: 1, + max: 20, + step: 1, + }), + duration: getNumberSetting("tok-shake-duration", { + min: 0, + max: 2000, + step: 10, + }), + scaling: { + type: getChoicesSetting("tok-shake-scaling-type"), + distance: getChoicesSetting("tok-shake-scaling-distance"), + shakes: getChoicesSetting("tok-shake-scaling-shakes"), + duration: getChoicesSetting("tok-shake-scaling-duration"), + } + }, + rotateOnAttack: { + enabled: getSetting("rotate-on-attack"), + duration: getNumberSetting("rotate-on-attack.duration", { + min: 0, + max: 2, + step: 0.1, + }), + scaleOnSize: getSetting("rotate-on-attack.scale-on-size"), + }, + screenShake: { + onDamaged: { + enabled: getSetting("shake-enabled"), + duration: getNumberSetting("shake-duration", { + min: 0, + max: 2000, + step: 10, + }), + maxIntensity: getNumberSetting("shake-intensity-max", { + min: 1, + max: 100, + step: 1, + }), + intensityScaling: getChoicesSetting("shake-intensity-type"), + intensityScalingIncludeTempHP: getSetting("shake-intensity-include-temp-hp"), + shakeGM: getSetting("shake-gm-enabled"), + }, + onAttack: { + enabled: getSetting("shake-on-attack.enabled"), + showFor: getChoicesSetting("shake-on-attack.type"), + } + }, + } + }, + { + id: "critical", + label: game.i18n.localize(`${MODULE_ID}.menu.settings.tabs.critical`), + icon: "fa-explosion", + critical: true, + settings: { + critical: { + enabled: getSetting("critical.enabled"), + style: getChoicesSetting("critical.type"), + checksOrAttacks: getChoicesSetting("critical.show-on"), + pcOrNPC: getChoicesSetting("critical.show-on-token-type"), + defaultImageType: getChoicesSetting("critical.default-img"), + duration: getNumberSetting("critical.duration", + { + min: 0, + max: 10, + step: 0.1, + }), + sound: getSetting("critical.sound"), + volume: getNumberSetting("critical.volume", { + min: 0, + max: 100, + step: 1, + }), + delay: getSetting("critical.delay"), + }, + } + }, + { + id: "text", + label: game.i18n.localize(`${MODULE_ID}.menu.settings.tabs.text`), + icon: "fa-message-captions", + text: true, + settings: { + finishingMove: { + enabled: getSetting("finishing-move.enabled"), + //enabledPlayers: getSetting("finishing-move.enabled-players"), + keepOn: getSetting("finishing-move.keep-on"), + usePlayerColor: getSetting("finishing-move.use-player-color"), + quality: getNumberSetting("finishing-move.quality", { + min: 1, + max: 5, + step: 1, + }), + sound: getSetting("finishing-move.sound-effect"), + volume: getNumberSetting("finishing-move.sound-effect.volume", { + min: 1, + max: 100, + step: 1, + }), + duration: { + word: getNumberSetting("finishing-move.duration.word", { + min: 0, + max: 2000, + step: 25, + }), + end: getNumberSetting("finishing-move.duration.end", { + min: 0, + max: 5000, + step: 25, + }), + }, + }, + fromSoftware: { + eldenRing: { + nounVerbed: { + enabled: getSetting("from-software.noun-verbed.enabled"), + xpThreshold: getSetting("from-software.noun-verbed.xp-threshold"), + fontSize: getNumberSetting("from-software.noun-verbed.font-size", { + min: 1, + max: 150, + step: 1, + }), + sound: getSetting("from-software.noun-verbed.sound-effect"), + volume: getNumberSetting("from-software.noun-verbed.sound-effect.volume", { + min: 1, + max: 100, + step: 1, + }), + duration: getNumberSetting("from-software.noun-verbed.duration", { + min: 0, + max: 12, + step: 0.1, + }), + text: getSetting("from-software.noun-verbed.text"), + }, + death: { + enabled: getSetting("from-software.death.enabled"), + fontSize: getNumberSetting("from-software.death.font-size", { + min: 1, + max: 150, + step: 1, + }), + sound: getSetting("from-software.death.sound-effect"), + volume: getNumberSetting("from-software.death.sound-effect.volume", { + min: 1, + max: 100, + step: 1, + }), + duration: getNumberSetting("from-software.death.duration", { + min: 0, + max: 12, + step: 0.1, + }), + text: getSetting("from-software.death.text"), + } + } + }, + } + }, + // { + // id: "misc", + // label: "Misc", + // icon: "fa-gear", + // misc: true, + // settings: { + // debug: { + // enabled: getSetting("debug-mode"), + // } + // }, + // }, + ] + }) + } + + async _updateObject(event, formData) { + // Expand the flat form data into a nested object structure + + // Debug log for inspecting the expanded form data + //console.log("Expanded Form Data:", { expandedData, formData }); + //game.settings.set('myModuleName', 'myComplexSettingName', data); + } + + async _processForm(html, submit = false) { + // Collect the form data from all inputs in the form + const formData = new FormData(html[0].closest("form")); + const dataObject = {}; + + // Iterate over the form data and convert it to an object + formData.forEach((value, key) => { + // Handle checkboxes separately to store booleans + if (html.find(`[name="${key}"]`).attr("type") === "checkbox") { + dataObject[key] = html.find(`[name="${key}"]`).prop("checked"); + } else { + dataObject[key] = value; + } + }); + + // Log the gathered form data for debugging purposes + console.log("Form Data:", dataObject); + + // Handle saving or submitting + if (submit) { + // If submitting, call _updateObject to store the data + await this.saveSettings(dataObject); + ui.notifications.info(game.i18n.localize(`${MODULE_ID}.menu.settings.notification.submit`)); + this.close(); + } else { + // If saving, call _updateObject to store the data + await this.saveSettings(dataObject); + ui.notifications.info(game.i18n.localize(`${MODULE_ID}.menu.settings.notification.save`)); + } + } + async saveSettings(data) { + const expandedData = expandObject(data); + const settings = expandedData.settings; + + // Home settings + updateIfChanged("enabled", settings.enabled); + + // Rolls: dmg-numbers settings + const dmgNumbers = settings['dmg-numbers']; + updateIfChanged("dmg-enabled", dmgNumbers.enabled); + updateIfChanged("dmg-on-apply-or-roll", dmgNumbers.whenTo); + updateIfChanged("font-size", dmgNumbers.fontSize); + updateIfChanged("max-font-scale", dmgNumbers.maxFontScale); + updateIfChanged("top-offset", dmgNumbers.topOffset); + updateIfChanged("show-total", dmgNumbers.showTotal); + updateIfChanged("number-scale-type", dmgNumbers.scaleType); + updateIfChanged("damage-split", dmgNumbers.split); + updateIfChanged("duration", dmgNumbers.duration); + updateIfChanged("wait-time-between-numbers", dmgNumbers.waitTime); + updateIfChanged("show-only-GM", dmgNumbers.onlyGM); + updateIfChanged("animation-scale", dmgNumbers.scale); + updateIfChanged("jitter", dmgNumbers.jitter); + + // Rolls: check-animations settings + const checkAnimations = settings['check-animations']; + updateIfChanged("check-enabled", checkAnimations.enabled); + updateIfChanged("check-color-scheme", checkAnimations.colorScheme); + updateIfChanged("check-outcome-result", checkAnimations.showOutcome); + updateIfChanged("check-font-size", checkAnimations.fontSize); + updateIfChanged("check-duration", checkAnimations.duration); + updateIfChanged("check-animations.sfx.enabled", checkAnimations.sfx.enabled); + updateIfChanged("check-animations.sfx.check-or-attack", checkAnimations.sfx.checkOrAttack); + updateIfChanged("check-animations.sfx.options", checkAnimations.sfx.options); + updateIfChanged("check-animations.sfx.volume", checkAnimations.sfx.volume); + updateIfChanged("check-animations.sfx.file.criticalSuccess", checkAnimations.sfx.file.criticalSuccess); + updateIfChanged("check-animations.sfx.file.success", checkAnimations.sfx.file.success); + updateIfChanged("check-animations.sfx.file.failure", checkAnimations.sfx.file.failure); + updateIfChanged("check-animations.sfx.file.criticalFailure", checkAnimations.sfx.file.criticalFailure); + + // Token: tokenShake settings + const tokenShake = settings.tokenShake; + updateIfChanged("dmg-shake-directional-enabled", tokenShake.enabled); + updateIfChanged("tok-shake-distance", tokenShake.distance); + updateIfChanged("tok-shake-shakes", tokenShake.shakes); + updateIfChanged("tok-shake-duration", tokenShake.duration); + updateIfChanged("tok-shake-scaling-type", tokenShake.scaling.type); + updateIfChanged("tok-shake-scaling-distance", tokenShake.scaling.distance); + updateIfChanged("tok-shake-scaling-shakes", tokenShake.scaling.shakes); + updateIfChanged("tok-shake-scaling-duration", tokenShake.scaling.duration); + + // Token: rotateOnAttack settings + const rotateOnAttack = settings.rotateOnAttack; + updateIfChanged("rotate-on-attack", rotateOnAttack.enabled); + updateIfChanged("rotate-on-attack.duration", rotateOnAttack.duration); + updateIfChanged("rotate-on-attack.scale-on-size", rotateOnAttack.scaleOnSize); + + // Token: screenShake settings + const screenShake = settings.screenShake; + updateIfChanged("shake-enabled", screenShake.onDamaged.enabled); + updateIfChanged("shake-duration", screenShake.onDamaged.duration); + updateIfChanged("shake-intensity-max", screenShake.onDamaged.maxIntensity); + updateIfChanged("shake-intensity-type", screenShake.onDamaged.intensityScaling); + updateIfChanged("shake-intensity-include-temp-hp", screenShake.onDamaged.intensityScalingIncludeTempHP); + updateIfChanged("shake-gm-enabled", screenShake.onDamaged.shakeGM); + updateIfChanged("shake-on-attack.enabled", screenShake.onAttack.enabled); + updateIfChanged("shake-on-attack.type", screenShake.onAttack.showFor); + + // Critical settings + const critical = settings.critical; + updateIfChanged("critical.enabled", critical.enabled); + updateIfChanged("critical.type", critical.style); + updateIfChanged("critical.show-on", critical.checksOrAttacks); + updateIfChanged("critical.show-on-token-type", critical.pcOrNPC); + updateIfChanged("critical.default-img", critical.defaultImageType); + updateIfChanged("critical.duration", critical.duration); + updateIfChanged("critical.sound", critical.sound); + updateIfChanged("critical.volume", critical.volume); + updateIfChanged("critical.delay", critical.delay); + + // Text: finishingMove settings + const finishingMove = settings.finishingMove; + updateIfChanged("finishing-move.enabled", finishingMove.enabled); + updateIfChanged("finishing-move.keep-on", finishingMove.keepOn); + updateIfChanged("finishing-move.use-player-color", finishingMove.usePlayerColor); + updateIfChanged("finishing-move.quality", finishingMove.quality); + updateIfChanged("finishing-move.sound-effect", finishingMove.sound); + updateIfChanged("finishing-move.sound-effect.volume", finishingMove.volume); + updateIfChanged("finishing-move.duration.word", finishingMove.duration.word); + updateIfChanged("finishing-move.duration.end", finishingMove.duration.end); + + // Text: fromSoftware settings + const fromSoftware = settings.fromSoftware; + const eldenRing = fromSoftware.eldenRing; + updateIfChanged("from-software.noun-verbed.enabled", eldenRing.nounVerbed.enabled); + updateIfChanged("from-software.noun-verbed.xp-threshold", eldenRing.nounVerbed.xpThreshold); + updateIfChanged("from-software.noun-verbed.font-size", eldenRing.nounVerbed.fontSize); + updateIfChanged("from-software.noun-verbed.sound-effect", eldenRing.nounVerbed.sound); + updateIfChanged("from-software.noun-verbed.sound-effect.volume", eldenRing.nounVerbed.volume); + updateIfChanged("from-software.noun-verbed.duration", eldenRing.nounVerbed.duration); + updateIfChanged("from-software.noun-verbed.text", eldenRing.nounVerbed.text); + updateIfChanged("from-software.death.enabled", eldenRing.death.enabled); + updateIfChanged("from-software.death.font-size", eldenRing.death.fontSize); + updateIfChanged("from-software.death.sound-effect", eldenRing.death.sound); + updateIfChanged("from-software.death.sound-effect.volume", eldenRing.death.volume); + updateIfChanged("from-software.death.duration", eldenRing.death.duration); + updateIfChanged("from-software.death.text", eldenRing.death.text); + + // Misc: debug settings + // const debug = settings.debug; + // updateIfChanged("debug-mode", debug.enabled); + } + +} + +function getChoicesSetting(settingPath) { + const choices = game.settings.settings.get(MODULE_ID + "." + settingPath)?.choices; + const value = getSetting(settingPath); + return { choices, value } +} + +function getNumberSetting(settingPath, range) { + const ret = { value: getSetting(settingPath) }; + if (range) ret.range = range; + return ret; +} + +function updateIfChanged(settingID, newValue) { + const currentValue = getSetting(settingID); + if (typeof currentValue == "boolean") { + newValue = !!newValue; + } + if (currentValue !== newValue) { + setSetting(settingID, newValue); + } +} \ No newline at end of file diff --git a/scripts/helpers/misc.js b/scripts/helpers/misc.js index f7c7003..1090446 100644 --- a/scripts/helpers/misc.js +++ b/scripts/helpers/misc.js @@ -9,6 +9,10 @@ export function getSetting(settingID) { return game.settings.get(MODULE_ID, settingID); } +export function setSetting(settingID, value) { + return game.settings.set(MODULE_ID, settingID, value); +} + export function doSomethingOnDamageApply() { return ( getSetting("shake-enabled") || diff --git a/scripts/helpers/rollTerms.js b/scripts/helpers/rollTerms.js index b99e914..6467c24 100644 --- a/scripts/helpers/rollTerms.js +++ b/scripts/helpers/rollTerms.js @@ -86,7 +86,8 @@ function processArithmeticExpression(term, result, flavor) { if (term.operator === "*") { // This works on the assumption of times 2 const [first, second] = operands; - return result.concat(first, first); + // add a way to figure out which is number + return result.concat(...Array(second).fill(first)); } return result; } diff --git a/scripts/module.js b/scripts/module.js index 4a0e829..c65f7ed 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -13,7 +13,6 @@ import { //FinisherDialog, getSetting, handleDiceSoNice, - localize, MODULE_ID } from "./helpers/misc.js"; import { getDamageList } from "./helpers/rollTerms.js"; @@ -273,7 +272,8 @@ export function getTargetList(msg) { } // No pf2e target damage module - return [msg?.target?.token?.id ?? msg.token.id]; + const tok = msg?.target?.token?.id ?? msg?.token?.id; + return tok ? [tok] : []; } export function createUpdateMessage() { @@ -281,4 +281,4 @@ export function createUpdateMessage() { content: chatContent, whisper: ChatMessage.getWhisperRecipients("GM"), }); -} +} \ No newline at end of file diff --git a/scripts/settings.js b/scripts/settings.js index 164d788..972bbee 100644 --- a/scripts/settings.js +++ b/scripts/settings.js @@ -1,6 +1,16 @@ import { localize, MODULE_ID, registerSetting } from "./helpers/misc.js"; +import { SettingsConfigForm } from "./helpers/forms/settingsConfigForm.js"; Hooks.on("init", () => { + loadTemplates([ + `modules/pf2e-rpg-numbers/templates/settings/pf2e-rpg-settings-config.hbs`, + 'modules/pf2e-rpg-numbers/templates/settings/tabs/home.hbs', + 'modules/pf2e-rpg-numbers/templates/settings/tabs/critical.hbs', + 'modules/pf2e-rpg-numbers/templates/settings/tabs/misc.hbs', + 'modules/pf2e-rpg-numbers/templates/settings/tabs/rolls.hbs', + 'modules/pf2e-rpg-numbers/templates/settings/tabs/text.hbs', + 'modules/pf2e-rpg-numbers/templates/settings/tabs/token.hbs' + ]) Hooks.on("renderSettingsConfig", renderSettingsConfig); //TODO finalize this // game.settings.registerMenu(mod, 'settingsMenu', { @@ -10,11 +20,19 @@ Hooks.on("init", () => { // type: SettingsForm, // restricted: false // }); + game.settings.registerMenu(MODULE_ID, "pf2eRPGSettingsMenu", { + name: "PF2e RPG Settings", + label: "PF2e RPG Settings", // The text label used in the button + hint: "Settings for the PF2e RPG settings", + icon: "fas fa-dragon", // A Font Awesome icon used in the submenu button + type: SettingsConfigForm, // A FormApplication subclass + restricted: true // Restrict this submenu to gamemaster only? + }); registerSetting("", "enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -22,7 +40,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "dmg-enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -30,7 +48,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "dmg-on-apply-or-roll", { desc: "on-apply-or-roll", scope: "world", - config: true, + config: false, default: "roll", type: String, choices: ["apply", "roll"], @@ -39,7 +57,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "font-size", { desc: "font-size", scope: "world", - config: true, + config: false, default: 20, type: Number, }); @@ -47,7 +65,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "max-font-scale", { desc: "max-font-scale", scope: "world", - config: true, + config: false, default: 3, type: Number, }); @@ -55,7 +73,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "top-offset", { desc: "top-offset", scope: "world", - config: true, + config: false, default: -25, range: { min: -100, @@ -68,7 +86,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "show-total", { desc: "show-total", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -76,7 +94,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "number-scale-type", { desc: "number-scale-type", scope: "world", - config: true, + config: false, default: "percentMaxHealth", type: String, choices: ["percentRemainingHealth", "percentMaxHealth", "none"], @@ -85,7 +103,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "damage-split", { desc: "damage-split", scope: "world", - config: true, + config: false, default: "by-damage-type", type: String, choices: ["none", "by-damage-type", "all"], @@ -94,7 +112,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "duration", { desc: "duration", scope: "world", - config: true, + config: false, default: 2, range: { min: 0, @@ -106,7 +124,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "wait-time-between-numbers", { desc: "wait-time-between-numbers", scope: "world", - config: true, + config: false, default: 100, range: { min: 0, @@ -119,7 +137,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "show-only-GM", { desc: "show-only-GM", scope: "world", - config: true, + config: false, default: false, type: Boolean, }); @@ -127,7 +145,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "animation-scale", { desc: "animation-scale", scope: "world", - config: true, + config: false, default: 1, range: { min: 0, @@ -140,7 +158,7 @@ Hooks.on("init", () => { registerSetting("dmg-numbers", "jitter", { desc: "jitter", scope: "world", - config: true, + config: false, default: 0, range: { min: 0, @@ -154,7 +172,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -162,7 +180,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-color-scheme", { desc: "color-scheme", scope: "world", - config: true, + config: false, default: "default", type: String, choices: ["default", "dark"], @@ -171,7 +189,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-outcome-result", { desc: "outcome-result", scope: "world", - config: true, + config: false, default: "outcome-except-combat-crits", type: String, choices: ["numbers", "outcome-except-combat-crits", "outcome"], @@ -180,7 +198,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-font-size", { desc: "font-size", scope: "world", - config: true, + config: false, default: 30, type: Number, }); @@ -188,7 +206,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-duration", { desc: "duration", scope: "world", - config: true, + config: false, default: 2, range: { min: 0, @@ -202,7 +220,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.enabled", { desc: "sfx.enabled", scope: "world", - config: true, + config: false, default: false, type: Boolean, }); @@ -210,7 +228,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.check-or-attack", { desc: "sfx.check-or-attack", scope: "world", - config: true, + config: false, default: !game?.modules?.get("pf2e-jb2a-macros")?.active ? "both" : "checks", type: String, choices: ["both", "attacks", "checks"], @@ -219,7 +237,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.options", { desc: "sfx.options", scope: "world", - config: true, + config: false, default: "all", type: String, choices: ["none", "all", "success-or-fail", "crits-only"], @@ -228,7 +246,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.volume", { desc: "sfx.volume", scope: "world", - config: true, + config: false, default: 50, range: { min: 0, @@ -241,7 +259,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.file.criticalSuccess", { desc: "sfx.file.criticalSuccess", scope: "world", - config: true, + config: false, default: "modules/pf2e-rpg-numbers/resources/sounds/checks/success_1.mp3", type: String, filePicker: "audio", @@ -250,7 +268,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.file.success", { desc: "sfx.file.success", scope: "world", - config: true, + config: false, default: "modules/pf2e-rpg-numbers/resources/sounds/checks/correct-answer-tone.ogg", type: String, filePicker: "audio", @@ -259,7 +277,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.file.failure", { desc: "sfx.file.failure", scope: "world", - config: true, + config: false, default: "modules/pf2e-rpg-numbers/resources/sounds/checks/Jpn_L_drum1.mp3", type: String, filePicker: "audio", @@ -268,7 +286,7 @@ Hooks.on("init", () => { registerSetting("check-animations", "check-animations.sfx.file.criticalFailure", { desc: "sfx.file.criticalFailure", scope: "world", - config: true, + config: false, default: "modules/pf2e-rpg-numbers/resources/sounds/checks/negative-answer-lose.ogg", type: String, filePicker: "audio", @@ -278,7 +296,7 @@ Hooks.on("init", () => { registerSetting("screen-shake", "shake-enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: false, type: Boolean, }); @@ -286,7 +304,7 @@ Hooks.on("init", () => { registerSetting("screen-shake", "shake-duration", { desc: "duration", scope: "world", - config: true, + config: false, default: 250, range: { min: 0, @@ -299,7 +317,7 @@ Hooks.on("init", () => { registerSetting("screen-shake", "shake-intensity-max", { desc: "intensity-max", scope: "world", - config: true, + config: false, default: 35, range: { min: 1, @@ -312,7 +330,7 @@ Hooks.on("init", () => { registerSetting("screen-shake", "shake-intensity-type", { desc: "intensity-type", scope: "world", - config: true, + config: false, default: "%-current-hp", type: String, choices: ["max", "%-current-hp", "%-max-hp"], @@ -321,7 +339,7 @@ Hooks.on("init", () => { registerSetting("screen-shake", "shake-intensity-include-temp-hp", { desc: "intensity-include-temp-hp", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -329,7 +347,7 @@ Hooks.on("init", () => { registerSetting("screen-shake", "shake-gm-enabled", { desc: "gm-enabled", scope: "world", - config: true, + config: false, default: false, type: Boolean, }); @@ -338,7 +356,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "dmg-shake-directional-enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -346,7 +364,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-distance", { desc: "distance", scope: "world", - config: true, + config: false, default: 20, range: { min: 1, @@ -359,7 +377,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-shakes", { desc: "shakes", scope: "world", - config: true, + config: false, default: 7, range: { min: 1, @@ -372,7 +390,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-duration", { desc: "duration", scope: "world", - config: true, + config: false, default: 500, range: { min: 0, @@ -385,7 +403,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-scaling-type", { desc: "scaling.type", scope: "world", - config: true, + config: false, default: "no", type: String, choices: ["no", "%-current-hp", "%-max-hp"], @@ -394,7 +412,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-scaling-distance", { desc: "scaling.distance", scope: "world", - config: true, + config: false, default: "no", type: String, choices: ["no", "max", "mid"], @@ -403,7 +421,7 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-scaling-shakes", { desc: "scaling.shakes", scope: "world", - config: true, + config: false, default: "no", type: String, choices: ["no", "max", "mid"], @@ -412,16 +430,17 @@ Hooks.on("init", () => { registerSetting("token-dmg-shake", "tok-shake-scaling-duration", { desc: "scaling.duration", scope: "world", - config: true, + config: false, default: "no", type: String, choices: ["no", "max", "mid"], }); + //Shake Screen on attack registerSetting("shake-on-attack", "shake-on-attack.enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -429,16 +448,17 @@ Hooks.on("init", () => { registerSetting("shake-on-attack", "shake-on-attack.type", { desc: "type", scope: "world", - config: true, + config: false, default: false, type: String, choices: ["both", "gm", "players"], }); + //Rotate on Attack registerSetting("rotate-on-attack", "rotate-on-attack", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, requiresReload: true, @@ -447,7 +467,7 @@ Hooks.on("init", () => { registerSetting("rotate-on-attack", "rotate-on-attack.duration", { desc: "duration", scope: "world", - config: true, + config: false, default: 0.5, range: { min: 0, @@ -460,7 +480,7 @@ Hooks.on("init", () => { registerSetting("rotate-on-attack", "rotate-on-attack.scale-on-size", { desc: "scale-on-size", scope: "world", - config: true, + config: false, default: false, type: Boolean, }); @@ -469,11 +489,12 @@ Hooks.on("init", () => { registerSetting("critical", "critical.enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); + //TODO keep in normal settings registerSetting("critical", "critical.player-enabled", { desc: "player-enabled", scope: "client", @@ -488,7 +509,7 @@ Hooks.on("init", () => { registerSetting("critical", "critical.type", { desc: "type", scope: "world", - config: true, + config: false, default: "persona", type: String, choices: ["persona", "fire-emblem"], @@ -497,7 +518,7 @@ Hooks.on("init", () => { registerSetting("critical", "critical.show-on", { desc: "show-on", scope: "world", - config: true, + config: false, default: "attacks", type: String, choices: ["attacks", "checks", "both"], @@ -506,7 +527,7 @@ Hooks.on("init", () => { registerSetting("critical", "critical.show-on-token-type", { desc: "show-on-token-type", scope: "world", - config: true, + config: false, default: "pc+npc", type: String, choices: ["pc", "npc", "pc+npc"], @@ -515,7 +536,7 @@ Hooks.on("init", () => { registerSetting("critical", "critical.default-img", { desc: "default-img", scope: "world", - config: true, + config: false, default: "pc-tok-npc-tok", type: String, choices: ["pc-tok-npc-tok", "pc-act-npc-act", "pc-tok-npc-act", "pc-act-npc-tok"], @@ -524,15 +545,20 @@ Hooks.on("init", () => { registerSetting("critical", "critical.duration", { desc: "duration", scope: "world", - config: true, + config: false, default: 1.5, + range: { + min: 0, + max: 10, + step: 0.1, + }, type: Number, }); registerSetting("critical", "critical.sound", { desc: "sound", scope: "world", - config: true, + config: false, default: "modules/pf2e-rpg-numbers/resources/sounds/swoosh-universfield.mp3", type: String, filePicker: "audio", @@ -541,10 +567,10 @@ Hooks.on("init", () => { registerSetting("critical", "critical.volume", { desc: "volume", scope: "world", - config: true, + config: false, default: 50, range: { - min: 1, + min: 0, max: 100, step: 1, }, @@ -554,7 +580,7 @@ Hooks.on("init", () => { registerSetting("critical", "critical.delay", { desc: "delay", scope: "world", - config: true, + config: false, default: 0, type: Number, }); @@ -563,7 +589,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.enabled", { desc: "enabled", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -571,7 +597,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.enabled-players", { desc: "enabled-players", scope: "world", - config: true, + config: false, default: false, type: Boolean, requiresReload: true, @@ -580,7 +606,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.keep-on", { desc: "keep-on", scope: "world", - config: true, + config: false, default: false, type: Boolean, }); @@ -588,7 +614,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.use-player-color", { desc: "use-player-color", scope: "world", - config: true, + config: false, default: true, type: Boolean, }); @@ -596,7 +622,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.quality", { desc: "quality", scope: "world", - config: true, + config: false, default: 2, range: { min: 1, @@ -609,7 +635,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.sound-effect", { desc: "sound-effect", scope: "world", - config: true, + config: false, type: String, default: "modules/pf2e-rpg-numbers/resources/sounds/Deep_Impact_(Speedenza).ogg", filePicker: "audio", @@ -618,10 +644,10 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.sound-effect.volume", { desc: "sound-effect.volume", scope: "world", - config: true, + config: false, default: 40, range: { - min: 1, + min: 0, max: 100, step: 1, }, @@ -631,7 +657,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.duration.word", { desc: "duration.word", scope: "world", - config: true, + config: false, default: 200, range: { min: 0, @@ -644,7 +670,7 @@ Hooks.on("init", () => { registerSetting("finishing-move", "finishing-move.duration.end", { desc: "duration.end", scope: "world", - config: true, + config: false, default: 1000, range: { min: 0, @@ -661,7 +687,8 @@ Hooks.on("init", () => { registerSetting(`from-software.${option}`, `from-software.${option}.enabled`, { desc: "enabled", scope: "world", - config: true, + + config: false, default: false, type: Boolean, }); @@ -669,7 +696,8 @@ Hooks.on("init", () => { registerSetting(`from-software.noun-verbed`, `from-software.noun-verbed.xp-threshold`, { desc: "xp-threshold", scope: "world", - config: true, + + config: false, default: 120, type: Number, }); @@ -677,7 +705,8 @@ Hooks.on("init", () => { registerSetting(`from-software.${option}`, `from-software.${option}.font-size`, { desc: "font-size", scope: "world", - config: true, + + config: false, default: 52, range: { min: 1, @@ -690,7 +719,8 @@ Hooks.on("init", () => { registerSetting(`from-software.${option}`, `from-software.${option}.sound-effect`, { desc: "sound-effect", scope: "world", - config: true, + + config: false, type: String, default: option === 'death' ? "modules/pf2e-rpg-numbers/resources/sounds/eldenRingDeath.ogg" : "modules/pf2e-rpg-numbers/resources/sounds/eldenRingVictoryReverb.ogg", filePicker: "audio", @@ -699,10 +729,11 @@ Hooks.on("init", () => { registerSetting(`from-software.${option}`, `from-software.${option}.sound-effect.volume`, { desc: "sound-effect.volume", scope: "world", - config: true, + + config: false, default: 40, range: { - min: 1, + min: 0, max: 100, step: 1, }, @@ -712,7 +743,8 @@ Hooks.on("init", () => { registerSetting(`from-software.${option}`, `from-software.${option}.duration`, { desc: "duration", scope: "world", - config: true, + + config: false, default: 6.5, range: { min: 0, @@ -724,7 +756,8 @@ Hooks.on("init", () => { registerSetting(`from-software.${option}`, `from-software.${option}.text`, { desc: "text", scope: "world", - config: true, + + config: false, default: option === 'death' ? 'You Died' : 'Enemy Felled', type: String, }); @@ -772,6 +805,7 @@ Hooks.on("init", () => { }); }); + /** * Credit to PF2e Token Action HUD for the code on this to reference, helped a tooon * @param {} _ diff --git a/scripts/settingsForm.js b/scripts/settingsForm.js deleted file mode 100644 index d616c93..0000000 --- a/scripts/settingsForm.js +++ /dev/null @@ -1,100 +0,0 @@ -//TODO use cod egenrated for module -import { Settings } from './settings.js'; - -/** - * A form for inputting Custom CSS settings. - * - * @export - * @class SettingsForm - * @extends {FormApplication} - */ -export class SettingsForm extends FormApplication { - /** - * Default Options for this FormApplication - * - * @readonly - * @static - * @memberof SettingsForm - */ - static get defaultOptions() { - return mergeObject(super.defaultOptions, { - id: "customcss-settings-form", - title: game.i18n.localize("CCSS.settings.settingsMenu.title"), - template: "./modules/custom-css/templates/settings.html", - classes: ["sheet"], - width: 500, - height: game.user.isGM ? 900 : 500, - closeOnSubmit: false, - submitOnClose: true, - resizable: true - }); - } - - codeEditors = []; - - /** - * Construct an object of data to be passed to this froms HTML template. - * - * @return {object} The data being supplied to the template. - * @memberof SettingsForm - */ - getData() { - return { - isGM: game.user.isGM, - stylesheet: Settings.getWorldStylesheet(), - userStylesheet: Settings.getUserStylesheet() - }; - } - - /** - * Handles retrieving data from the form. - * - * @override Save the code editor instance before retrieving data to ensure the data is synchronised. - * - * @param {array} args - All arguments passed to this method, which will be forwarded to super - * @return {object} The form data - * @memberof SettingsForm - */ - _getSubmitData(...args) { - this.codeEditors.forEach(editor => editor.save()); - return super._getSubmitData(...args); - } - - /** - * Executes on form submission. - * - * @param {Event} event - the form submission event - * @param {object} data - the form data - * @memberof SettingsForm - */ - async _updateObject(event, data) { - await Settings.updateStylesheets(data["stylesheet"], data["userStylesheet"]); - } - - /** - * Activates all event listeners related to this form. - * - * @override Activates the CodeMirror code editor. - * - * @param {JQuery} html - The html content of the form. - * @memberof SettingsForm - */ - activateListeners(html) { - super.activateListeners(html); - - const options = { - mode: "css", - ...CodeMirror.userSettings, - lineNumbers: true, - inputStyle: "contenteditable", - autofocus: true, - spellcheck: true, - extraKeys: { "Ctrl-Space": "autocomplete" } - } - - if (game.user.isGM) - this.codeEditors.push(CodeMirror.fromTextArea(html.find(".stylesheet")[0], options)); - - this.codeEditors.push(CodeMirror.fromTextArea(html.find(".userStylesheet")[0], options)); - } -} \ No newline at end of file diff --git a/templates/settings/pf2e-rpg-settings-config.hbs b/templates/settings/pf2e-rpg-settings-config.hbs new file mode 100644 index 0000000..5ed6ee4 --- /dev/null +++ b/templates/settings/pf2e-rpg-settings-config.hbs @@ -0,0 +1,79 @@ +
+ + +
+ {{#each tabs as |tab|}} +
+ {{#if tab.home}} + {{> 'modules/pf2e-rpg-numbers/templates/settings/tabs/home.hbs' this}} + {{/if}} + {{#if tab.rolls}} + {{> 'modules/pf2e-rpg-numbers/templates/settings/tabs/rolls.hbs' this}} + {{/if}} + {{#if tab.token}} + {{> 'modules/pf2e-rpg-numbers/templates/settings/tabs/token.hbs' this}} + {{/if}} + {{#if tab.critical}} + {{> 'modules/pf2e-rpg-numbers/templates/settings/tabs/critical.hbs' this}} + {{/if}} + {{#if tab.text}} + {{> 'modules/pf2e-rpg-numbers/templates/settings/tabs/text.hbs' this}} + {{/if}} + {{#if tab.misc}} + {{> 'modules/pf2e-rpg-numbers/templates/settings/tabs/misc.hbs' this}} + {{/if}} +
+ {{/each}} +
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/templates/settings/tabs/critical.hbs b/templates/settings/tabs/critical.hbs new file mode 100644 index 0000000..ea1f8f5 --- /dev/null +++ b/templates/settings/tabs/critical.hbs @@ -0,0 +1,127 @@ +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.critical"}} +

+{{! Enabled }} +
+ + +
+{{! Style }} +
+ + +
+{{! Checks or Attacks }} +
+ + +
+{{! PC or NPC }} +
+ + +
+{{! Default Image Type }} +
+ + +
+{{! Duration }} +
+ + {{numberInput + settings.critical.duration.value + name="settings.critical.duration" + step=settings.critical.duration.range.step + min=settings.critical.duration.range.min + max=settings.critical.duration.range.max + }} +
+{{! Sound Effect }} +
+ + + {{filePicker target="settings.critical.sound" type="audio"}} +
+{{! Volume }} +
+ + {{numberInput settings.critical.volume.value name="settings.critical.volume" step=1 min=0 max=100}} +
+{{! Delay }} +
+ + {{numberInput settings.critical.delay name="settings.critical.delay"}} +
+{{!-- {{filePicker type="image" target="flags.moduleid.flagname"}} --}} \ No newline at end of file diff --git a/templates/settings/tabs/home.hbs b/templates/settings/tabs/home.hbs new file mode 100644 index 0000000..0432729 --- /dev/null +++ b/templates/settings/tabs/home.hbs @@ -0,0 +1,17 @@ + + {{! Enabled }} +
+ + +
+ + +
\ No newline at end of file diff --git a/templates/settings/tabs/misc.hbs b/templates/settings/tabs/misc.hbs new file mode 100644 index 0000000..c70ea41 --- /dev/null +++ b/templates/settings/tabs/misc.hbs @@ -0,0 +1,12 @@ +{{! Debug }} +
+ + +
\ No newline at end of file diff --git a/templates/settings/tabs/rolls.hbs b/templates/settings/tabs/rolls.hbs new file mode 100644 index 0000000..a6824f7 --- /dev/null +++ b/templates/settings/tabs/rolls.hbs @@ -0,0 +1,403 @@ + + {{! Damage Numbers }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.dmg-numbers"}} +

+ {{! Enabled }} +
+ + +
+ {{! When To Show }} +
+ + +
+ {{! Font Size }} +
+ + {{numberInput settings.dmg-numbers.fontSize name="settings.dmg-numbers.fontSize" step=1}} +
+ {{! Max Font Scale }} +
+ + {{numberInput settings.dmg-numbers.maxFontScale name="settings.dmg-numbers.maxFontScale" step=0.1}} +
+ {{! Top Offset }} +
+ + {{numberInput + settings.dmg-numbers.topOffset.value + name="settings.dmg-numbers.topOffset" + step=settings.dmg-numbers.topOffset.range.step + min=settings.dmg-numbers.topOffset.range.min + max=settings.dmg-numbers.topOffset.range.max + }} +
+ {{! Show Total }} +
+ + +
+ {{! Scale Type }} +
+ + +
+ {{! Damage Split Type }} +
+ + +
+ {{! Duration }} +
+ + {{numberInput + settings.dmg-numbers.duration.value + name="settings.dmg-numbers.duration" + step=settings.dmg-numbers.duration.range.step + min=settings.dmg-numbers.duration.range.min + max=settings.dmg-numbers.duration.range.max + }} +
+ {{! Wait Time }} +
+ + {{numberInput + settings.dmg-numbers.waitTime.value + name="settings.dmg-numbers.waitTime" + step=settings.dmg-numbers.waitTime.range.step + min=settings.dmg-numbers.waitTime.range.min + max=settings.dmg-numbers.waitTime.range.max + }} +
+ {{! Only GM }} +
+ + +
+ {{! Scale }} +
+ + {{numberInput + settings.dmg-numbers.scale.value + name="settings.dmg-numbers.scale" + step=settings.dmg-numbers.scale.range.step + min=settings.dmg-numbers.scale.range.min + max=settings.dmg-numbers.scale.range.max + }} +
+ {{! Jitter }} +
+ + {{numberInput + settings.dmg-numbers.jitter.value + name="settings.dmg-numbers.jitter" + step=settings.dmg-numbers.jitter.range.step + min=settings.dmg-numbers.jitter.range.min + max=settings.dmg-numbers.jitter.range.max + }} +
+
+ + {{! Check Numbers }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.check-animations"}} +

+ {{! Enabled }} +
+ + +
+ {{! Color Scheme }} +
+ + +
+ {{! Show Outcome Result }} +
+ + +
+ {{! Font Size }} +
+ + {{numberInput settings.check-animations.fontSize name="settings.check-animations.fontSize" step=1}} +
+ {{! Duration }} +
+ + {{numberInput + settings.dmg-numbers.duration.value + name="settings.dmg-numbers.duration" + step=settings.dmg-numbers.duration.range.step + min=settings.dmg-numbers.duration.range.min + max=settings.dmg-numbers.duration.range.max + }} +
+

+ Check SFX +

+ {{! SFX Enabled }} +
+ + +
+ {{! SFX Check or Attack }} +
+ + +
+ {{! SFX Options }} +
+ + +
+ {{! SFX Volume }} +
+ + {{numberInput + settings.check-animations.sfx.volume.value + name="settings.check-animations.sfx.volume" + step=settings.check-animations.sfx.volume.range.step + min=settings.check-animations.sfx.volume.range.min + max=settings.check-animations.sfx.volume.range.max + }} +
+ {{! Sound Effect - Critical Success }} +
+ + + {{filePicker target="settings.check-animations.sfx.file.criticalSuccess" type="audio"}} +
+ {{! Sound Effect - Success }} +
+ + + {{filePicker target="settings.check-animations.sfx.file.success" type="audio"}} +
+ {{! Sound Effect - Failure }} +
+ + + {{filePicker target="settings.check-animations.sfx.file.failure" type="audio"}} +
+ {{! Sound Effect - Critical Failure }} +
+ + + {{filePicker target="settings.check-animations.sfx.file.criticalFailure" type="audio"}} +
+
\ No newline at end of file diff --git a/templates/settings/tabs/text.hbs b/templates/settings/tabs/text.hbs new file mode 100644 index 0000000..a959580 --- /dev/null +++ b/templates/settings/tabs/text.hbs @@ -0,0 +1,350 @@ + +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.finishing-move.title"}} +

+ {{! Enabled }} +
+ + +
+ {{! Keep On }} +
+ + +
+ {{! Use Player Color }} +
+ + +
+ {{! Quality }} +
+ + {{numberInput + settings.finishingMove.quality.value + name="settings.finishingMove.quality" + step=settings.finishingMove.quality.range.step + min=settings.finishingMove.quality.range.min + max=settings.finishingMove.quality.range.max + }} +
+ {{! Sound Effect }} +
+ + + {{filePicker target="settings.finishingMove.sound" type="audio"}} +
+ {{! Volume }} +
+ + {{numberInput + settings.finishingMove.volume.value + name="settings.finishingMove.volume" + step=settings.finishingMove.volume.range.step + min=settings.finishingMove.volume.range.min + max=settings.finishingMove.volume.range.max + }} +
+ {{! Duration Word }} +
+ + {{numberInput + settings.finishingMove.duration.word.value + name="settings.finishingMove.duration.word" + step=settings.finishingMove.duration.word.range.step + min=settings.finishingMove.duration.word.range.min + max=settings.finishingMove.duration.word.range.max + }} +
+ {{! Duration End }} +
+ + {{numberInput + settings.finishingMove.duration.end.value + name="settings.finishingMove.duration.end" + step=settings.finishingMove.duration.end.range.step + min=settings.finishingMove.duration.end.range.min + max=settings.finishingMove.duration.end.range.max + }} +
+
+ +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.fromSoftware.elden-ring.title"}} + - + {{localize "pf2e-rpg-numbers.module-settings.headers.fromSoftware.elden-ring.noun-verbed"}} +

+ {{! Enabled }} +
+ + +
+ {{! XP Threshold }} +
+ + {{numberInput + settings.fromSoftware.eldenRing.nounVerbed.xpThreshold + name="settings.fromSoftware.eldenRing.nounVerbed.xpThreshold" + step=5 + min=0 + max=999 + }} +
+ {{! Font Size }} +
+ + {{numberInput + settings.fromSoftware.eldenRing.nounVerbed.fontSize.value + name="settings.fromSoftware.eldenRing.nounVerbed.fontSize" + step=settings.fromSoftware.eldenRing.nounVerbed.fontSize.range.step + min=settings.fromSoftware.eldenRing.nounVerbed.fontSize.range.min + max=settings.fromSoftware.eldenRing.nounVerbed.fontSize.range.max + }} +
+ {{! Sound Effect }} +
+ + + {{filePicker target="settings.fromSoftware.eldenRing.nounVerbed.sound" type="audio"}} +
+ {{! Volume }} +
+ + {{numberInput + settings.fromSoftware.eldenRing.nounVerbed.volume.value + name="settings.fromSoftware.eldenRing.nounVerbed.volume" + step=settings.fromSoftware.eldenRing.nounVerbed.volume.range.step + min=settings.fromSoftware.eldenRing.nounVerbed.volume.range.min + max=settings.fromSoftware.eldenRing.nounVerbed.volume.range.max + }} +
+ {{! Duration}} +
+ + {{numberInput + settings.fromSoftware.eldenRing.nounVerbed.duration.value + name="settings.fromSoftware.eldenRing.nounVerbed.duration" + step=settings.fromSoftware.eldenRing.nounVerbed.duration.range.step + min=settings.fromSoftware.eldenRing.nounVerbed.duration.range.min + max=settings.fromSoftware.eldenRing.nounVerbed.duration.range.max + }} +
+ {{! Text }} +
+ + +
+
+ +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.fromSoftware.elden-ring.title"}} + - + {{localize "pf2e-rpg-numbers.module-settings.headers.fromSoftware.elden-ring.death"}} +

+ {{! Enabled }} +
+ + +
+ {{! Font Size }} +
+ + {{numberInput + settings.fromSoftware.eldenRing.death.fontSize.value + name="settings.fromSoftware.eldenRing.death.fontSize" + step=settings.fromSoftware.eldenRing.death.fontSize.range.step + min=settings.fromSoftware.eldenRing.death.fontSize.range.min + max=settings.fromSoftware.eldenRing.death.fontSize.range.max + }} +
+ {{! Sound Effect }} +
+ + + {{filePicker target="settings.fromSoftware.eldenRing.death.sound" type="audio"}} +
+ {{! Volume }} +
+ + {{numberInput + settings.fromSoftware.eldenRing.death.volume.value + name="settings.fromSoftware.eldenRing.death.volume" + step=settings.fromSoftware.eldenRing.death.volume.range.step + min=settings.fromSoftware.eldenRing.death.volume.range.min + max=settings.fromSoftware.eldenRing.death.volume.range.max + }} +
+ {{! Duration}} +
+ + {{numberInput + settings.fromSoftware.eldenRing.death.duration.value + name="settings.fromSoftware.eldenRing.death.duration" + step=settings.fromSoftware.eldenRing.death.duration.range.step + min=settings.fromSoftware.eldenRing.death.duration.range.min + max=settings.fromSoftware.eldenRing.death.duration.range.max + }} +
+ {{! Text }} +
+ + +
+
\ No newline at end of file diff --git a/templates/settings/tabs/token.hbs b/templates/settings/tabs/token.hbs new file mode 100644 index 0000000..47ddf21 --- /dev/null +++ b/templates/settings/tabs/token.hbs @@ -0,0 +1,328 @@ + + {{! Token Shake }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.token-dmg-shake.title"}} +

+ {{! Enabled }} +
+ + +
+ {{! Distance }} +
+ + {{numberInput + settings.tokenShake.distance.value + name="settings.tokenShake.distance" + step=settings.tokenShake.distance.range.step + min=settings.tokenShake.distance.range.min + max=settings.tokenShake.distance.range.max + }} +
+ {{! Shakes }} +
+ + {{numberInput + settings.tokenShake.shakes.value + name="settings.tokenShake.shakes" + step=settings.tokenShake.shakes.range.step + min=settings.tokenShake.shakes.range.min + max=settings.tokenShake.shakes.range.max + }} +
+ {{! Duration }} +
+ + {{numberInput + settings.tokenShake.duration.value + name="settings.tokenShake.duration" + step=settings.tokenShake.duration.range.step + min=settings.tokenShake.duration.range.min + max=settings.tokenShake.duration.range.max + }} +
+ {{! Scaling }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.token-dmg-shake.scaling"}} +

+ {{! Scaling Type }} +
+ + +
+ {{! Scaling Distance }} +
+ + +
+ {{! Scaling Shakes }} +
+ + +
+ {{! Scaling Duration }} +
+ + +
+
+ + {{! Rotate on Attack }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.rotate-on-attack"}} +

+ {{! Enabled }} +
+ + +
+ {{! Duration }} +
+ + {{numberInput + settings.rotateOnAttack.duration.value + name="settings.rotateOnAttack.duration" + step=settings.rotateOnAttack.duration.range.step + min=settings.rotateOnAttack.duration.range.min + max=settings.rotateOnAttack.duration.range.max + }} +
+ {{! Scale on Size }} +
+ + +
+
+ + {{! Shake on Damaged }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.screen-shake"}} +

+ {{! Enabled }} +
+ + +
+ {{! Duration }} +
+ + {{numberInput + settings.screenShake.onDamaged.duration.value + name="settings.screenShake.onDamaged.duration" + step=settings.screenShake.onDamaged.duration.range.step + min=settings.screenShake.onDamaged.duration.range.min + max=settings.screenShake.onDamaged.duration.range.max + }} +
+ {{! Max Intensity }} +
+ + {{numberInput + settings.screenShake.onDamaged.maxIntensity.value + name="settings.screenShake.onDamaged.maxIntensity" + step=settings.screenShake.onDamaged.maxIntensity.range.step + min=settings.screenShake.onDamaged.maxIntensity.range.min + max=settings.screenShake.onDamaged.maxIntensity.range.max + }} +
+ {{! Intensity Scaling }} +
+ + +
+ {{! Intensity Scaling Includes Temp HP }} +
+ + +
+ {{! Shake for GM }} +
+ + +
+
+ + {{! Shake on Attack }} +

+ {{localize "pf2e-rpg-numbers.module-settings.headers.shake-on-attack"}} +

+ {{! Enabled }} +
+ + +
+ {{! Show For }} +
+ + +
+
\ No newline at end of file