From 1a1d8927d5dd2d1473bc78ba147313bdefdf6ce8 Mon Sep 17 00:00:00 2001 From: DC23 Date: Sat, 23 Nov 2024 15:09:00 +1100 Subject: [PATCH 01/17] Adding registerSettings function, file and call from translation services ready event hook #75 --- module/basicfantasyrpg.mjs | 14 ++++++++++++++ module/settings/settings.mjs | 2 ++ 2 files changed, 16 insertions(+) create mode 100644 module/settings/settings.mjs diff --git a/module/basicfantasyrpg.mjs b/module/basicfantasyrpg.mjs index 017f2ef..d606a94 100644 --- a/module/basicfantasyrpg.mjs +++ b/module/basicfantasyrpg.mjs @@ -7,6 +7,7 @@ import { BasicFantasyRPGItemSheet } from './sheets/item-sheet.mjs'; // Import helper/utility classes and constants. import { preloadHandlebarsTemplates } from './helpers/templates.mjs'; import { BASICFANTASYRPG } from './helpers/config.mjs'; +import { registerSettings } from './settings/settings.mjs'; /* -------------------------------------------- */ /* Init Hook */ @@ -110,6 +111,19 @@ Handlebars.registerPartial('iconRanged', ` Date: Sat, 23 Nov 2024 16:07:07 +1100 Subject: [PATCH 03/17] Added localised settings for saving throw names #69 --- lang/en.json | 5 ++- lang/fr.json | 7 +++- module/settings/settings.mjs | 75 +++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/lang/en.json b/lang/en.json index 1bdd39a..e1ffd4e 100644 --- a/lang/en.json +++ b/lang/en.json @@ -159,6 +159,9 @@ "BASICFANTASYRPG.EffectToggle": "Toggle Effect", "BASICFANTASYRPG.EffectEdit": "Edit Effect", "BASICFANTASYRPG.EffectDelete": "Delete Effect", + "BASICFANTASYRPG.AutoRollTokenHP.name": "Automatically Roll Token HP", - "BASICFANTASYRPG.AutoRollTokenHP.hint": "Based on HD value. If this setting is turned off, HP will be set to TODO WORK OUT WHAT" + "BASICFANTASYRPG.AutoRollTokenHP.hint": "Based on HD value. If this setting is turned off, HP will be set to TODO WORK OUT WHAT", + + "BASICFANTASYRPG.SaveName.hint": "Custom name for this saving throw. The same name is used for all players." } \ No newline at end of file diff --git a/lang/fr.json b/lang/fr.json index 2be7934..c98ed24 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -158,5 +158,10 @@ "BASICFANTASYRPG.EffectCreate": "Créer un Effet", "BASICFANTASYRPG.EffectToggle": "Effet On/Off", "BASICFANTASYRPG.EffectEdit": "Modifier l'Effet", - "BASICFANTASYRPG.EffectDelete": "Supprimer l'Effet" + "BASICFANTASYRPG.EffectDelete": "Supprimer l'Effet", + + "BASICFANTASYRPG.AutoRollTokenHP.name": "Automatically Roll Token HP", + "BASICFANTASYRPG.AutoRollTokenHP.hint": "Based on HD value. If this setting is turned off, HP will be set to TODO WORK OUT WHAT", + + "BASICFANTASYRPG.SaveName.hint": "Custom name for this saving throw. The same name is used for all players." } diff --git a/module/settings/settings.mjs b/module/settings/settings.mjs index fe7e876..1d67835 100644 --- a/module/settings/settings.mjs +++ b/module/settings/settings.mjs @@ -2,7 +2,12 @@ * pseudo-enum to make setting ID references less error prone */ export const SETTINGS = { - AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP' + AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', + SAVE_DEATH_NAME: 'saveDeathName', + SAVE_WANDS_NAME: 'saveWandsName', + SAVE_PARALYSIS_NAME: 'saveParalysisName', + SAVE_BREATH_NAME: 'saveBreathName', + SAVE_SPELLS_NAME: 'saveSpellsName', } // Use this internally for now. Refactoring the whole system is too big a job! @@ -21,6 +26,72 @@ export function registerSettings () { type: Boolean, default: true, requiresReload: false, - restricted: true, // GM-only setting + restricted: true // GM-only setting }) + + /** + * Saving throw customisation. + * If we get too many settings, these could be broken out into a submenu. + * It's more coding work, but keeps things together for the users. + */ + // Death Ray or Poison + game.settings.register(SYSTEM_ID, SETTINGS.SAVE_DEATH_NAME, { + name: 'BASICFANTASYRPG.SaveDeath', + hint: 'BASICFANTASYRPG.SaveName.hint', + scope: 'world', + config: true, + type: String, + default: game.i18n.localize('BASICFANTASYRPG.SaveDeath'), + requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered + restricted: true // GM-only setting + }) + + // "BASICFANTASYRPG.SaveWands": "Magic Wands", + game.settings.register(SYSTEM_ID, SETTINGS.SAVE_WANDS_NAME, { + name: 'BASICFANTASYRPG.SaveWands', + hint: 'BASICFANTASYRPG.SaveName.hint', + scope: 'world', + config: true, + type: String, + default: game.i18n.localize('BASICFANTASYRPG.SaveWands'), + requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered + restricted: true // GM-only setting + }) + + // "BASICFANTASYRPG.SaveParalysis": "Paralysis or Petrify", + game.settings.register(SYSTEM_ID, SETTINGS.SAVE_PARALYSIS_NAME, { + name: 'BASICFANTASYRPG.SaveParalysis', + hint: 'BASICFANTASYRPG.SaveName.hint', + scope: 'world', + config: true, + type: String, + default: game.i18n.localize('BASICFANTASYRPG.SaveParalysis'), + requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered + restricted: true // GM-only setting + }) + + // "BASICFANTASYRPG.SaveBreath": "Dragon Breath", + game.settings.register(SYSTEM_ID, SETTINGS.SAVE_BREATH_NAME, { + name: 'BASICFANTASYRPG.SaveBreath', + hint: 'BASICFANTASYRPG.SaveName.hint', + scope: 'world', + config: true, + type: String, + default: game.i18n.localize('BASICFANTASYRPG.SaveBreath'), + requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered + restricted: true // GM-only setting + }) + + // "BASICFANTASYRPG.SaveSpells": "Rods, Staves, and Spells", + game.settings.register(SYSTEM_ID, SETTINGS.SAVE_SPELLS_NAME, { + name: 'BASICFANTASYRPG.SaveSpells', + hint: 'BASICFANTASYRPG.SaveName.hint', + scope: 'world', + config: true, + type: String, + default: game.i18n.localize('BASICFANTASYRPG.SaveSpells'), + requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered + restricted: true // GM-only setting + }) + } From 37f051dcd782a6fd32af557af9dd05596d44853e Mon Sep 17 00:00:00 2001 From: DC23 Date: Sat, 23 Nov 2024 21:09:25 +1100 Subject: [PATCH 04/17] Disabling auto-roll token HP setting. It's the wrong interpretation of the feature. #18 --- module/settings/settings.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/module/settings/settings.mjs b/module/settings/settings.mjs index 1d67835..96ef7b9 100644 --- a/module/settings/settings.mjs +++ b/module/settings/settings.mjs @@ -2,7 +2,7 @@ * pseudo-enum to make setting ID references less error prone */ export const SETTINGS = { - AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', +// AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', SAVE_DEATH_NAME: 'saveDeathName', SAVE_WANDS_NAME: 'saveWandsName', SAVE_PARALYSIS_NAME: 'saveParalysisName', @@ -18,6 +18,9 @@ export function registerSettings () { * If we have any settings submenus, they'd be defined in separate files and called from here. */ + /* + Disabled for now based on https://discord.com/channels/735808783493890058/1307906023444582430/1309772596103086081 + Will delete later once confirmed that it's the wrong direction. game.settings.register(SYSTEM_ID, SETTINGS.AUTO_ROLL_TOKEN_HP, { name: 'BASICFANTASYRPG.AutoRollTokenHP.name', hint: 'BASICFANTASYRPG.AutoRollTokenHP.hint', @@ -28,6 +31,7 @@ export function registerSettings () { requiresReload: false, restricted: true // GM-only setting }) +*/ /** * Saving throw customisation. From c6f32f45109f743c8013ed5a0d9f8e58fecb9c67 Mon Sep 17 00:00:00 2001 From: DC23 Date: Tue, 26 Nov 2024 19:45:02 +1100 Subject: [PATCH 05/17] Updated system settings plumbing with the correct v12 method to hide settings from players. Fixes #75 --- module/settings/settings.mjs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/module/settings/settings.mjs b/module/settings/settings.mjs index 96ef7b9..e63a148 100644 --- a/module/settings/settings.mjs +++ b/module/settings/settings.mjs @@ -13,6 +13,31 @@ export const SETTINGS = { // Use this internally for now. Refactoring the whole system is too big a job! const SYSTEM_ID = 'basicfantasyrpg' +/** + * Array of setting IDs for the settings that should be hidden from + * non-GM users. We iterate the array in the renderSettingsConfig + * hook and remove those settings from the DOM when required. + * This workaround is necessary because in Foundry v12, a restricted + * flag to show a setting to GM users is only supported for a setting + * menu, not a setting itself. + */ +const GM_ONLY_SETTINGS = [ + SETTINGS.SAVE_DEATH_NAME, + SETTINGS.SAVE_WANDS_NAME, + SETTINGS.SAVE_PARALYSIS_NAME, + SETTINGS.SAVE_BREATH_NAME, + SETTINGS.SAVE_SPELLS_NAME, +] + +Hooks.on('renderSettingsConfig', (app, [html], context) => { + if (game.user.isGM) return + + GM_ONLY_SETTINGS.forEach(id => { + html.querySelector(`.form-group[data-setting-id="${SYSTEM_ID}.${id}"]`)?.remove() + }) +}) + + export function registerSettings () { /** * If we have any settings submenus, they'd be defined in separate files and called from here. @@ -29,7 +54,6 @@ export function registerSettings () { type: Boolean, default: true, requiresReload: false, - restricted: true // GM-only setting }) */ @@ -47,7 +71,6 @@ export function registerSettings () { type: String, default: game.i18n.localize('BASICFANTASYRPG.SaveDeath'), requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - restricted: true // GM-only setting }) // "BASICFANTASYRPG.SaveWands": "Magic Wands", @@ -59,7 +82,6 @@ export function registerSettings () { type: String, default: game.i18n.localize('BASICFANTASYRPG.SaveWands'), requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - restricted: true // GM-only setting }) // "BASICFANTASYRPG.SaveParalysis": "Paralysis or Petrify", @@ -71,7 +93,6 @@ export function registerSettings () { type: String, default: game.i18n.localize('BASICFANTASYRPG.SaveParalysis'), requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - restricted: true // GM-only setting }) // "BASICFANTASYRPG.SaveBreath": "Dragon Breath", @@ -83,7 +104,6 @@ export function registerSettings () { type: String, default: game.i18n.localize('BASICFANTASYRPG.SaveBreath'), requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - restricted: true // GM-only setting }) // "BASICFANTASYRPG.SaveSpells": "Rods, Staves, and Spells", @@ -95,7 +115,6 @@ export function registerSettings () { type: String, default: game.i18n.localize('BASICFANTASYRPG.SaveSpells'), requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - restricted: true // GM-only setting }) } From 1c41b18a952804efeac9476fa58b6b002fc88734 Mon Sep 17 00:00:00 2001 From: DC23 Date: Tue, 26 Nov 2024 20:31:51 +1100 Subject: [PATCH 06/17] implementing setting names --- module/settings/settings.mjs | 16 ++++++++++------ module/sheets/actor-sheet.mjs | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/module/settings/settings.mjs b/module/settings/settings.mjs index e63a148..c65ce51 100644 --- a/module/settings/settings.mjs +++ b/module/settings/settings.mjs @@ -1,17 +1,21 @@ +import { BASICFANTASYRPG } from "../helpers/config.mjs" + /** * pseudo-enum to make setting ID references less error prone */ export const SETTINGS = { // AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', - SAVE_DEATH_NAME: 'saveDeathName', - SAVE_WANDS_NAME: 'saveWandsName', - SAVE_PARALYSIS_NAME: 'saveParalysisName', - SAVE_BREATH_NAME: 'saveBreathName', - SAVE_SPELLS_NAME: 'saveSpellsName', + // use the saves keys as the setting ID to make retrieval easy. + // So long as the system.key is unique, it's fine. + SAVE_DEATH_NAME: 'death', + SAVE_WANDS_NAME: 'wands', + SAVE_PARALYSIS_NAME: 'paralysis', + SAVE_BREATH_NAME: 'breath', + SAVE_SPELLS_NAME: 'spells', } // Use this internally for now. Refactoring the whole system is too big a job! -const SYSTEM_ID = 'basicfantasyrpg' +export const SYSTEM_ID = 'basicfantasyrpg' /** * Array of setting IDs for the settings that should be hidden from diff --git a/module/sheets/actor-sheet.mjs b/module/sheets/actor-sheet.mjs index fe40633..29bd223 100644 --- a/module/sheets/actor-sheet.mjs +++ b/module/sheets/actor-sheet.mjs @@ -1,5 +1,6 @@ import {successChatMessage} from '../helpers/chat.mjs'; import {onManageActiveEffect, prepareActiveEffectCategories} from '../helpers/effects.mjs'; +import { SYSTEM_ID } from '../settings/settings.mjs'; /** * Extend the basic ActorSheet with some very simple modifications @@ -85,7 +86,7 @@ export class BasicFantasyRPGActorSheet extends ActorSheet { _prepareActorData(context) { // Handle saves. for (let [k, v] of Object.entries(context.data.saves)) { - v.label = game.i18n.localize(CONFIG.BASICFANTASYRPG.saves[k]) ?? k; + v.label = game.settings.get(SYSTEM_ID, k) ?? k } } From 9096a70df6a1c741f6895ea430b4bc8371c385eb Mon Sep 17 00:00:00 2001 From: DC23 Date: Tue, 26 Nov 2024 23:01:09 +1100 Subject: [PATCH 07/17] work in progress on moving saves customisation into a settings menu so I can have validation and better control #69 --- lang/en.json | 7 +- module/helpers/settings.mjs | 17 ++++ module/settings/saves-settings.mjs | 92 ++++++++++++++++++++++ module/settings/settings.mjs | 109 +++++--------------------- templates/settings/saves-settings.hbs | 25 ++++++ 5 files changed, 158 insertions(+), 92 deletions(-) create mode 100644 module/helpers/settings.mjs create mode 100644 module/settings/saves-settings.mjs create mode 100644 templates/settings/saves-settings.hbs diff --git a/lang/en.json b/lang/en.json index e1ffd4e..7b31965 100644 --- a/lang/en.json +++ b/lang/en.json @@ -160,8 +160,9 @@ "BASICFANTASYRPG.EffectEdit": "Edit Effect", "BASICFANTASYRPG.EffectDelete": "Delete Effect", - "BASICFANTASYRPG.AutoRollTokenHP.name": "Automatically Roll Token HP", - "BASICFANTASYRPG.AutoRollTokenHP.hint": "Based on HD value. If this setting is turned off, HP will be set to TODO WORK OUT WHAT", - + "BASICFANTASYRPG.Settings.SavesMenu.name": "Edit Saving Throw Names", + "BASICFANTASYRPG.Settings.SavesMenu.label": "Saving Throw Settings", + "BASICFANTASYRPG.Settings.SavesMenu.hint": "", "BASICFANTASYRPG.SaveName.hint": "Custom name for this saving throw. The same name is used for all players." + } \ No newline at end of file diff --git a/module/helpers/settings.mjs b/module/helpers/settings.mjs new file mode 100644 index 0000000..04d944b --- /dev/null +++ b/module/helpers/settings.mjs @@ -0,0 +1,17 @@ +// not the greatest approach, but +export function objectsShallowEqual (obj1, obj2) { + const entries1 = Object.entries(obj1) + const entries2 = Object.entries(obj2) + + if (entries1.length !== entries2.length) { + return false + } + + for (let [key, value] of entries1) { + if (obj2[key] !== value) { + return false + } + } + + return true +} diff --git a/module/settings/saves-settings.mjs b/module/settings/saves-settings.mjs new file mode 100644 index 0000000..560662c --- /dev/null +++ b/module/settings/saves-settings.mjs @@ -0,0 +1,92 @@ +// import { Helpers } from './helpers.mjs' +import { objectsShallowEqual } from '../helpers/settings.mjs' +import { SYSTEM_ID, SETTINGS } from './settings.mjs' + +// Helper array of IDs we'll use in a few places +const saves = ['death', 'wands', 'paralysis', 'breath', 'spells'] + +export function registerSavesSettings () { + // The settings menu + game.settings.registerMenu(SYSTEM_ID, SETTINGS.SAVES_MENU, { + name: 'BASICFANTASYRPG.Settings.SavesMenu.name', + label: 'BASICFANTASYRPG.Settings.SavesMenu.label', + hint: 'BASICFANTASYRPG.Settings.SavesMenu.hint', + icon: 'fas fa-cog', + type: SavesSettings, + restricted: true // GM-only + }) + + // the settings object + game.settings.register(SYSTEM_ID, SETTINGS.SAVES_SETTINGS, { + scope: 'world', + config: false, + type: Object, + default: SavesSettings.defaultSaves + }) +} + +class SavesSettings extends FormApplication { + static #defaultSaves = null + static get defaultSaves () { + if (!SavesSettings.#defaultSaves) { + SavesSettings.#defaultSaves = {} + saves.forEach(s => { + SavesSettings.#defaultSaves[s] = game.i18n.localize( + `BASICFANTASYRPG.Save${s.capitalize()}` + ) + }) + } + return SavesSettings.#defaultSaves + } + + static get defaultOptions () { + return foundry.utils.mergeObject(super.defaultOptions, { + popOut: true, + width: 400, + template: `systems/${SYSTEM_ID}/templates/settings/saves-settings.hbs`, + id: SETTINGS.SAVES_MENU, + title: 'BASICFANTASYRPG.Settings.SavesMenu.name' + }) + } + + getData () { + const initialValues = game.settings.get(SYSTEM_ID, SETTINGS.SAVES_SETTINGS) + // repack the current saves names into id, label and values for the form + const data = {} + saves.forEach((v, i) => { + data[i] = { + id: v, + label: SavesSettings.defaultSaves[v], + value: initialValues[v] + } + }) + return data + } + + _updateObject (event, formData) { + const data = foundry.utils.expandObject(formData) + const current = game.settings.get(SYSTEM_ID, SETTINGS.SAVES_SETTINGS) + + if (!objectsShallowEqual(data, current)) { + game.settings.set(SYSTEM_ID, SETTINGS.SAVES_SETTINGS, data) + SettingsConfig.reloadConfirm({ world: true }) + } + } + + activateListeners (html) { + super.activateListeners(html) + html.on('click', '[data-action=reset]', this._handleResetButtonClicked) + } + + async _handleResetButtonClicked (event) { + console.log('BFRPG | Reset save names to default values') + saves.forEach(id => { + const element = $(event.delegateTarget).find(`[name=${id}]`) + if (element && element.length > 0) { + element[0].value = game.i18n.localize( + `BASICFANTASYRPG.Save${id.capitalize()}` + ) + } + }) + } +} diff --git a/module/settings/settings.mjs b/module/settings/settings.mjs index c65ce51..583e06b 100644 --- a/module/settings/settings.mjs +++ b/module/settings/settings.mjs @@ -1,17 +1,21 @@ -import { BASICFANTASYRPG } from "../helpers/config.mjs" +import { BASICFANTASYRPG } from '../helpers/config.mjs' +import { registerSavesSettings } from './saves-settings.mjs' /** * pseudo-enum to make setting ID references less error prone */ export const SETTINGS = { -// AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', - // use the saves keys as the setting ID to make retrieval easy. + // AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', + // use the saves keys as the setting ID to make retrieval easy. // So long as the system.key is unique, it's fine. SAVE_DEATH_NAME: 'death', SAVE_WANDS_NAME: 'wands', SAVE_PARALYSIS_NAME: 'paralysis', SAVE_BREATH_NAME: 'breath', SAVE_SPELLS_NAME: 'spells', + + SAVES_MENU: 'savesMenu', + SAVES_SETTINGS: 'savesSettings' } // Use this internally for now. Refactoring the whole system is too big a job! @@ -22,103 +26,30 @@ export const SYSTEM_ID = 'basicfantasyrpg' * non-GM users. We iterate the array in the renderSettingsConfig * hook and remove those settings from the DOM when required. * This workaround is necessary because in Foundry v12, a restricted - * flag to show a setting to GM users is only supported for a setting + * flag to show a setting to GM users is only supported for a setting * menu, not a setting itself. */ const GM_ONLY_SETTINGS = [ - SETTINGS.SAVE_DEATH_NAME, - SETTINGS.SAVE_WANDS_NAME, - SETTINGS.SAVE_PARALYSIS_NAME, - SETTINGS.SAVE_BREATH_NAME, - SETTINGS.SAVE_SPELLS_NAME, +// SETTINGS.SAVE_DEATH_NAME, +// SETTINGS.SAVE_WANDS_NAME, +// SETTINGS.SAVE_PARALYSIS_NAME, +// SETTINGS.SAVE_BREATH_NAME, +// SETTINGS.SAVE_SPELLS_NAME ] Hooks.on('renderSettingsConfig', (app, [html], context) => { - if (game.user.isGM) return + if (game.user.isGM) return - GM_ONLY_SETTINGS.forEach(id => { - html.querySelector(`.form-group[data-setting-id="${SYSTEM_ID}.${id}"]`)?.remove() - }) + GM_ONLY_SETTINGS.forEach(id => { + html + .querySelector(`.form-group[data-setting-id="${SYSTEM_ID}.${id}"]`) + ?.remove() + }) }) - export function registerSettings () { /** * If we have any settings submenus, they'd be defined in separate files and called from here. */ - - /* - Disabled for now based on https://discord.com/channels/735808783493890058/1307906023444582430/1309772596103086081 - Will delete later once confirmed that it's the wrong direction. - game.settings.register(SYSTEM_ID, SETTINGS.AUTO_ROLL_TOKEN_HP, { - name: 'BASICFANTASYRPG.AutoRollTokenHP.name', - hint: 'BASICFANTASYRPG.AutoRollTokenHP.hint', - scope: 'world', - config: true, - type: Boolean, - default: true, - requiresReload: false, - }) -*/ - - /** - * Saving throw customisation. - * If we get too many settings, these could be broken out into a submenu. - * It's more coding work, but keeps things together for the users. - */ - // Death Ray or Poison - game.settings.register(SYSTEM_ID, SETTINGS.SAVE_DEATH_NAME, { - name: 'BASICFANTASYRPG.SaveDeath', - hint: 'BASICFANTASYRPG.SaveName.hint', - scope: 'world', - config: true, - type: String, - default: game.i18n.localize('BASICFANTASYRPG.SaveDeath'), - requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - }) - - // "BASICFANTASYRPG.SaveWands": "Magic Wands", - game.settings.register(SYSTEM_ID, SETTINGS.SAVE_WANDS_NAME, { - name: 'BASICFANTASYRPG.SaveWands', - hint: 'BASICFANTASYRPG.SaveName.hint', - scope: 'world', - config: true, - type: String, - default: game.i18n.localize('BASICFANTASYRPG.SaveWands'), - requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - }) - - // "BASICFANTASYRPG.SaveParalysis": "Paralysis or Petrify", - game.settings.register(SYSTEM_ID, SETTINGS.SAVE_PARALYSIS_NAME, { - name: 'BASICFANTASYRPG.SaveParalysis', - hint: 'BASICFANTASYRPG.SaveName.hint', - scope: 'world', - config: true, - type: String, - default: game.i18n.localize('BASICFANTASYRPG.SaveParalysis'), - requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - }) - - // "BASICFANTASYRPG.SaveBreath": "Dragon Breath", - game.settings.register(SYSTEM_ID, SETTINGS.SAVE_BREATH_NAME, { - name: 'BASICFANTASYRPG.SaveBreath', - hint: 'BASICFANTASYRPG.SaveName.hint', - scope: 'world', - config: true, - type: String, - default: game.i18n.localize('BASICFANTASYRPG.SaveBreath'), - requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - }) - - // "BASICFANTASYRPG.SaveSpells": "Rods, Staves, and Spells", - game.settings.register(SYSTEM_ID, SETTINGS.SAVE_SPELLS_NAME, { - name: 'BASICFANTASYRPG.SaveSpells', - hint: 'BASICFANTASYRPG.SaveName.hint', - scope: 'world', - config: true, - type: String, - default: game.i18n.localize('BASICFANTASYRPG.SaveSpells'), - requiresReload: true, // I assume this will need a reload to ensure everything is re-rendered - }) - + registerSavesSettings() } diff --git a/templates/settings/saves-settings.hbs b/templates/settings/saves-settings.hbs new file mode 100644 index 0000000..8eaede9 --- /dev/null +++ b/templates/settings/saves-settings.hbs @@ -0,0 +1,25 @@ +{{#*inline "savePartial"}} +
+ + +
+{{/inline}} + +{{log this}} +
+
+ {{localize "BASICFANTASYRPG.Settings.SavesMenu.name"}}: + {{#each this}} + {{> savePartial}} + {{/each}} +
+ +
+ + +
+
\ No newline at end of file From 5e6301e6190fd2fc65e589ad6f99ed059542df36 Mon Sep 17 00:00:00 2001 From: DC23 Date: Tue, 26 Nov 2024 23:15:18 +1100 Subject: [PATCH 08/17] Fully working saves menu #69 --- lang/en.json | 2 +- module/settings/saves-settings.mjs | 2 ++ module/sheets/actor-sheet.mjs | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lang/en.json b/lang/en.json index 7b31965..652c7ce 100644 --- a/lang/en.json +++ b/lang/en.json @@ -160,7 +160,7 @@ "BASICFANTASYRPG.EffectEdit": "Edit Effect", "BASICFANTASYRPG.EffectDelete": "Delete Effect", - "BASICFANTASYRPG.Settings.SavesMenu.name": "Edit Saving Throw Names", + "BASICFANTASYRPG.Settings.SavesMenu.name": "Configure Saving Throw Names", "BASICFANTASYRPG.Settings.SavesMenu.label": "Saving Throw Settings", "BASICFANTASYRPG.Settings.SavesMenu.hint": "", "BASICFANTASYRPG.SaveName.hint": "Custom name for this saving throw. The same name is used for all players." diff --git a/module/settings/saves-settings.mjs b/module/settings/saves-settings.mjs index 560662c..8ec8d91 100644 --- a/module/settings/saves-settings.mjs +++ b/module/settings/saves-settings.mjs @@ -67,6 +67,8 @@ class SavesSettings extends FormApplication { const data = foundry.utils.expandObject(formData) const current = game.settings.get(SYSTEM_ID, SETTINGS.SAVES_SETTINGS) + // todo: trim whitespace from each string & escape html + if (!objectsShallowEqual(data, current)) { game.settings.set(SYSTEM_ID, SETTINGS.SAVES_SETTINGS, data) SettingsConfig.reloadConfirm({ world: true }) diff --git a/module/sheets/actor-sheet.mjs b/module/sheets/actor-sheet.mjs index 29bd223..901fa6d 100644 --- a/module/sheets/actor-sheet.mjs +++ b/module/sheets/actor-sheet.mjs @@ -1,6 +1,6 @@ import {successChatMessage} from '../helpers/chat.mjs'; import {onManageActiveEffect, prepareActiveEffectCategories} from '../helpers/effects.mjs'; -import { SYSTEM_ID } from '../settings/settings.mjs'; +import { SYSTEM_ID, SETTINGS } from '../settings/settings.mjs'; /** * Extend the basic ActorSheet with some very simple modifications @@ -85,8 +85,9 @@ export class BasicFantasyRPGActorSheet extends ActorSheet { */ _prepareActorData(context) { // Handle saves. + const savesNames = game.settings.get(SYSTEM_ID, SETTINGS.SAVES_SETTINGS) for (let [k, v] of Object.entries(context.data.saves)) { - v.label = game.settings.get(SYSTEM_ID, k) ?? k + v.label = savesNames[k] ?? k } } From 206733783b1355c1308a7b3f5fc96004f03301a1 Mon Sep 17 00:00:00 2001 From: DC23 Date: Tue, 26 Nov 2024 23:35:32 +1100 Subject: [PATCH 09/17] Removed saves settings menu logging statement and added CSS styles for settings forms. fixes #69 --- styles/basicfantasyrpg.css | 10 ++++++++++ templates/settings/saves-settings.hbs | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/styles/basicfantasyrpg.css b/styles/basicfantasyrpg.css index 1cfff7a..bbd645a 100644 --- a/styles/basicfantasyrpg.css +++ b/styles/basicfantasyrpg.css @@ -371,6 +371,16 @@ width: 0; } +.form-row { + margin: 5px; +} + +.button-container { + display: flex; + gap: 10px; + margin-top: 5px; +} + /* Styles limited to basicfantasyrpg sheets */ .basicfantasyrpg.sheet.actor { diff --git a/templates/settings/saves-settings.hbs b/templates/settings/saves-settings.hbs index 8eaede9..36aca2a 100644 --- a/templates/settings/saves-settings.hbs +++ b/templates/settings/saves-settings.hbs @@ -5,7 +5,6 @@ {{/inline}} -{{log this}}
{{localize "BASICFANTASYRPG.Settings.SavesMenu.name"}}: From 9bb24a6ed722468805b3fe3ff15ef494331ceca1 Mon Sep 17 00:00:00 2001 From: DC23 Date: Wed, 27 Nov 2024 13:28:49 +1100 Subject: [PATCH 10/17] Adding prettier config. I'll try to only reformat new files that I add --- .prettierrc | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6bb2084 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "useTabs": false, + "printWidth": 100 +} \ No newline at end of file From 103581bc097d2eea8f9fbbb55ed89a32ed155f75 Mon Sep 17 00:00:00 2001 From: DC23 Date: Wed, 27 Nov 2024 14:00:24 +1100 Subject: [PATCH 11/17] Added whitespace trim to save name settings. Formatted saves-settings with new prettier config #69 --- module/settings/saves-settings.mjs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/module/settings/saves-settings.mjs b/module/settings/saves-settings.mjs index 8ec8d91..a2d3aeb 100644 --- a/module/settings/saves-settings.mjs +++ b/module/settings/saves-settings.mjs @@ -1,4 +1,3 @@ -// import { Helpers } from './helpers.mjs' import { objectsShallowEqual } from '../helpers/settings.mjs' import { SYSTEM_ID, SETTINGS } from './settings.mjs' @@ -13,7 +12,7 @@ export function registerSavesSettings () { hint: 'BASICFANTASYRPG.Settings.SavesMenu.hint', icon: 'fas fa-cog', type: SavesSettings, - restricted: true // GM-only + restricted: true, // GM-only }) // the settings object @@ -21,7 +20,7 @@ export function registerSavesSettings () { scope: 'world', config: false, type: Object, - default: SavesSettings.defaultSaves + default: SavesSettings.defaultSaves, }) } @@ -31,9 +30,7 @@ class SavesSettings extends FormApplication { if (!SavesSettings.#defaultSaves) { SavesSettings.#defaultSaves = {} saves.forEach(s => { - SavesSettings.#defaultSaves[s] = game.i18n.localize( - `BASICFANTASYRPG.Save${s.capitalize()}` - ) + SavesSettings.#defaultSaves[s] = game.i18n.localize(`BASICFANTASYRPG.Save${s.capitalize()}`) }) } return SavesSettings.#defaultSaves @@ -45,7 +42,7 @@ class SavesSettings extends FormApplication { width: 400, template: `systems/${SYSTEM_ID}/templates/settings/saves-settings.hbs`, id: SETTINGS.SAVES_MENU, - title: 'BASICFANTASYRPG.Settings.SavesMenu.name' + title: 'BASICFANTASYRPG.Settings.SavesMenu.name', }) } @@ -57,7 +54,7 @@ class SavesSettings extends FormApplication { data[i] = { id: v, label: SavesSettings.defaultSaves[v], - value: initialValues[v] + value: initialValues[v], } }) return data @@ -67,7 +64,10 @@ class SavesSettings extends FormApplication { const data = foundry.utils.expandObject(formData) const current = game.settings.get(SYSTEM_ID, SETTINGS.SAVES_SETTINGS) - // todo: trim whitespace from each string & escape html + // todo: escape html + for (let [k, v] of Object.entries(data)) { + data[k] = v.trim() + } if (!objectsShallowEqual(data, current)) { game.settings.set(SYSTEM_ID, SETTINGS.SAVES_SETTINGS, data) @@ -85,9 +85,7 @@ class SavesSettings extends FormApplication { saves.forEach(id => { const element = $(event.delegateTarget).find(`[name=${id}]`) if (element && element.length > 0) { - element[0].value = game.i18n.localize( - `BASICFANTASYRPG.Save${id.capitalize()}` - ) + element[0].value = game.i18n.localize(`BASICFANTASYRPG.Save${id.capitalize()}`) } }) } From 343027abcc686c9c7c18af35020ab6e297d90e4e Mon Sep 17 00:00:00 2001 From: DC23 Date: Wed, 27 Nov 2024 16:20:45 +1100 Subject: [PATCH 12/17] cleaned up stale code left over from the first saves setting implementation #69 --- module/settings/settings.mjs | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/module/settings/settings.mjs b/module/settings/settings.mjs index 583e06b..5789584 100644 --- a/module/settings/settings.mjs +++ b/module/settings/settings.mjs @@ -5,20 +5,11 @@ import { registerSavesSettings } from './saves-settings.mjs' * pseudo-enum to make setting ID references less error prone */ export const SETTINGS = { - // AUTO_ROLL_TOKEN_HP: 'autoRollTokenHP', - // use the saves keys as the setting ID to make retrieval easy. - // So long as the system.key is unique, it's fine. - SAVE_DEATH_NAME: 'death', - SAVE_WANDS_NAME: 'wands', - SAVE_PARALYSIS_NAME: 'paralysis', - SAVE_BREATH_NAME: 'breath', - SAVE_SPELLS_NAME: 'spells', - SAVES_MENU: 'savesMenu', - SAVES_SETTINGS: 'savesSettings' + SAVES_SETTINGS: 'savesSettings', } -// Use this internally for now. Refactoring the whole system is too big a job! +// Use this just for settings for now. Refactoring the whole system is too big a job! export const SYSTEM_ID = 'basicfantasyrpg' /** @@ -29,27 +20,23 @@ export const SYSTEM_ID = 'basicfantasyrpg' * flag to show a setting to GM users is only supported for a setting * menu, not a setting itself. */ -const GM_ONLY_SETTINGS = [ -// SETTINGS.SAVE_DEATH_NAME, -// SETTINGS.SAVE_WANDS_NAME, -// SETTINGS.SAVE_PARALYSIS_NAME, -// SETTINGS.SAVE_BREATH_NAME, -// SETTINGS.SAVE_SPELLS_NAME -] +const GM_ONLY_SETTINGS = [] Hooks.on('renderSettingsConfig', (app, [html], context) => { if (game.user.isGM) return GM_ONLY_SETTINGS.forEach(id => { - html - .querySelector(`.form-group[data-setting-id="${SYSTEM_ID}.${id}"]`) - ?.remove() + html.querySelector(`.form-group[data-setting-id="${SYSTEM_ID}.${id}"]`)?.remove() }) }) export function registerSettings () { /** - * If we have any settings submenus, they'd be defined in separate files and called from here. + * register settings menus + */ + registerSavesSettings() + + /** + * register top-level settings */ - registerSavesSettings() } From fc5809646665fd07e65fa149c7972aee27a5df31 Mon Sep 17 00:00:00 2001 From: DC23 Date: Wed, 27 Nov 2024 16:36:44 +1100 Subject: [PATCH 13/17] making saves-settings.hbs template more generic. fixed required attribute bug for when it is passed into the template as false (it was correct for values of true). #69 --- module/settings/saves-settings.mjs | 3 ++- ...s-settings.hbs => string-array-settings.hbs} | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) rename templates/settings/{saves-settings.hbs => string-array-settings.hbs} (66%) diff --git a/module/settings/saves-settings.mjs b/module/settings/saves-settings.mjs index a2d3aeb..bb71974 100644 --- a/module/settings/saves-settings.mjs +++ b/module/settings/saves-settings.mjs @@ -40,7 +40,7 @@ class SavesSettings extends FormApplication { return foundry.utils.mergeObject(super.defaultOptions, { popOut: true, width: 400, - template: `systems/${SYSTEM_ID}/templates/settings/saves-settings.hbs`, + template: `systems/${SYSTEM_ID}/templates/settings/string-array-settings.hbs`, id: SETTINGS.SAVES_MENU, title: 'BASICFANTASYRPG.Settings.SavesMenu.name', }) @@ -55,6 +55,7 @@ class SavesSettings extends FormApplication { id: v, label: SavesSettings.defaultSaves[v], value: initialValues[v], + required: true, } }) return data diff --git a/templates/settings/saves-settings.hbs b/templates/settings/string-array-settings.hbs similarity index 66% rename from templates/settings/saves-settings.hbs rename to templates/settings/string-array-settings.hbs index 36aca2a..dbc87ff 100644 --- a/templates/settings/saves-settings.hbs +++ b/templates/settings/string-array-settings.hbs @@ -1,17 +1,18 @@ -{{#*inline "savePartial"}} +{{!-- fa + --}} + +{{#*inline "stringFieldPartial"}}
- +
{{/inline}} +{{log this}} -
- {{localize "BASICFANTASYRPG.Settings.SavesMenu.name"}}: - {{#each this}} - {{> savePartial}} - {{/each}} -
+ {{#each this}} + {{> stringFieldPartial}} + {{/each}}