diff --git a/daggerheart.mjs b/daggerheart.mjs index 96b407d3..6ef550ce 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -106,7 +106,7 @@ Hooks.once('init', () => { Hooks.on('ready', () => { ui.resources = new CONFIG.ui.resources(); - if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.DisplayFear) !== 'hide') + if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).displayFear !== 'hide') ui.resources.render({ force: true }); document.body.classList.toggle( 'theme-colorful', diff --git a/lang/en.json b/lang/en.json index 71dbd08a..1417e905 100755 --- a/lang/en.json +++ b/lang/en.json @@ -24,10 +24,7 @@ "Automation": { "Name": "Automation Settings", "Label": "Configure Automation", - "Hint": "Various settings automating resource management and more", - "HopeLabel": "Hope", - "FearLabel": "Fear", - "ActionPointsLabel": "Action Points" + "Hint": "Various settings automating resource management and more" }, "Homebrew": { "Name": "Homebrew Settings", @@ -38,13 +35,7 @@ "Range": { "Name": "Range Settings", "Label": "Configure Range Handling", - "Hint": "System ruler setup for displaying ranges in Daggerheart", - "EnabledLabel": "Enabled", - "MeleeLabel": "Melee", - "VeryCloseLabel": "Very Close", - "CloseLabel": "Close", - "FarLabel": "Far", - "VeryFarLabel": "Very Far" + "Hint": "System ruler setup for displaying ranges in Daggerheart" }, "Appearance": { "title": "Appearance Settings", @@ -69,18 +60,36 @@ "actionTokens": "Action Tokens" } }, - "Automation": { - "Hope": { - "Name": "Hope", - "Hint": "Automatically increase a character's hope on a hope duality roll result." + "Appearance": { + "FIELDS": { + "displayFear": { "label": "Fear Display" } }, + "FearDisplay": { + "Token": "Tokens", + "Bar": "Bar", + "Hide": "Hide" + } + }, + "Automation": { "Fear": { "Name": "Fear", "Hint": "Automatically increase the GM's fear pool on a fear duality roll result." }, - "ActionPoints": { - "Name": "Action Points", - "Hint": "Automatically give and take Action Points as combatants take their turns." + "FIELDS": { + "hope": { + "label": "Hope", + "hint": "Automatically increase a character's hope on a hope duality roll result." + }, + "actionPoints": { + "label": "Action Points", + "hint": "Automatically give and take Action Points as combatants take their turns." + } + } + }, + "Homebrew": { + "FIELDS": { + "maxFear": { "label": "Max Fear" }, + "traitArray": { "label": "Initial Trait Modifiers" } } }, "Resources": { @@ -113,6 +122,10 @@ "hint": "Give each player action tokens to use in combat" }, "FIELDS": { + "actionTokens": { + "enabled": { "label": "Enabled" }, + "tokens": { "label": "Tokens" } + }, "useCoins": { "label": "Use Coins", "hint": "test" @@ -163,7 +176,9 @@ "OK": "OK", "Cancel": "Cancel", "Or": "Or", + "Enabled": "Enabled", "Description": "Description", + "Modifier": "Modifier", "Features": "Features", "proficiency": "Proficiency", "unarmored": "Unarmored", diff --git a/module/applications/resources.mjs b/module/applications/resources.mjs index bbd47fc5..4560ee91 100644 --- a/module/applications/resources.mjs +++ b/module/applications/resources.mjs @@ -32,7 +32,7 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) position: { width: 222, height: 222 - // top: "200px", + // top: "200px",s // left: "120px" } }; @@ -50,7 +50,7 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) } get maxFear() { - return game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.MaxFear); + return game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).maxFear; } /* -------------------------------------------- */ @@ -59,7 +59,7 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) /** @override */ async _prepareContext(_options) { - const display = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.DisplayFear), + const display = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).displayFear, current = this.currentFear, max = this.maxFear, percent = (current / max) * 100, diff --git a/module/applications/settings.mjs b/module/applications/settings.mjs index 8f5b3446..cb1aa1bd 100644 --- a/module/applications/settings.mjs +++ b/module/applications/settings.mjs @@ -1,178 +1,121 @@ -import { DualityRollColor } from '../config/settingsConfig.mjs'; import { defaultLevelTiers, DhLevelTiers } from '../data/levelTier.mjs'; -import DhAppearance from '../data/settings/Appearance.mjs'; -import DHAppearanceSettings from './settings/appearanceSettings.mjs'; -import DhVariantRules from '../data/settings/VariantRules.mjs'; -import DHVariantRuleSettings from './settings/variantRuleSettings.mjs'; - -class DhpAutomationSettings extends FormApplication { - constructor(object = {}, options = {}) { - super(object, options); - } - - static get defaultOptions() { - const defaults = super.defaultOptions; - const overrides = { - height: 'auto', - width: 400, - id: 'daggerheart-automation-settings', - template: 'systems/daggerheart/templates/views/automation-settings.hbs', - closeOnSubmit: true, - submitOnChange: false, - classes: ['daggerheart', 'views', 'settings'] - }; - - const mergedOptions = foundry.utils.mergeObject(defaults, overrides); - - return mergedOptions; - } - - async getData() { - const context = super.getData(); - context.settings = SYSTEM.SETTINGS.gameSettings.Automation; - context.hope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope); - context.actionPoints = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.ActionPoints); - - return context; - } - - activateListeners(html) { - super.activateListeners(html); - } - - async _updateObject(_, formData) { - const data = foundry.utils.expandObject(formData); - const updateSettingsKeys = Object.keys(data); - for (var i = 0; i < updateSettingsKeys.length; i++) { - await game.settings.set(SYSTEM.id, updateSettingsKeys[i], data[updateSettingsKeys[i]]); - } - } -} - -class DhpHomebrewSettings extends FormApplication { - constructor(object = {}, options = {}) { - super(object, options); - } - - static get defaultOptions() { - const defaults = super.defaultOptions; - const overrides = { - height: 'auto', - width: 400, - id: 'daggerheart-homebrew-settings', - template: 'systems/daggerheart/templates/views/homebrew-settings.hbs', - closeOnSubmit: true, - submitOnChange: false, - classes: ['daggerheart', 'views', 'settings'] - }; - - const mergedOptions = foundry.utils.mergeObject(defaults, overrides); - - return mergedOptions; - } - - async getData() { - const context = super.getData(); - context.settings = SYSTEM.SETTINGS.gameSettings.General; - context.abilityArray = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.AbilityArray); - - return context; - } - - activateListeners(html) { - super.activateListeners(html); - } - - async _updateObject(_, formData) { - const data = foundry.utils.expandObject(formData); - const updateSettingsKeys = Object.keys(data); - for (var i = 0; i < updateSettingsKeys.length; i++) { - await game.settings.set(SYSTEM.id, updateSettingsKeys[i], data[updateSettingsKeys[i]]); - } - } -} - -class DhpRangeSettings extends FormApplication { - constructor(object = {}, options = {}) { - super(object, options); - - this.range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.RangeMeasurement); - } - - static get defaultOptions() { - const defaults = super.defaultOptions; - const overrides = { - height: 'auto', - width: 400, - id: 'daggerheart-range-settings', - template: 'systems/daggerheart/templates/views/range-settings.hbs', - closeOnSubmit: false, - submitOnChange: true, - classes: ['daggerheart', 'views', 'settings'] - }; - - const mergedOptions = foundry.utils.mergeObject(defaults, overrides); - - return mergedOptions; - } - - async getData() { - const context = super.getData(); - context.settings = SYSTEM.SETTINGS.gameSettings.General; - context.range = this.range; - context.disabled = - context.range.enabled && - [ - context.range.melee, - context.range.veryClose, - context.range.close, - context.range.far, - context.range.veryFar - ].some(x => x === null || x === false); - - return context; - } - - activateListeners(html) { - super.activateListeners(html); - - html.find('.range-reset').click(this.reset.bind(this)); - html.find('.save').click(this.save.bind(this)); - html.find('.close').click(this.close.bind(this)); - } - - async _updateObject(_, formData) { - const data = foundry.utils.expandObject(formData, { disabled: true }); - this.range = foundry.utils.mergeObject(this.range, data); - this.render(true); - } - - reset() { - this.range = { - enabled: false, - melee: 5, - veryClose: 15, - close: 30, - far: 60, - veryFar: 120 - }; - this.render(true); - } - - async save() { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.RangeMeasurement, this.range); - this.close(); - } -} +import { + DhAppearance, + DhAutomation, + DhHomebrew, + DhRangeMeasurement, + DhVariantRules +} from '../data/settings/_module.mjs'; +import { + DhAppearanceSettings, + DhAutomationSettings, + DhHomebrewSettings, + DhRangeMeasurementSettings, + DhVariantRuleSettings +} from './settings/_module.mjs'; export const registerDHSettings = () => { - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.AbilityArray, { - name: game.i18n.localize('DAGGERHEART.Settings.General.AbilityArray.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.General.AbilityArray.Hint'), + registerMenuSettings(); + registerMenus(); + registerNonConfigSettings(); +}; + +const registerMenuSettings = () => { + game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules, { scope: 'world', config: false, - type: String, - default: '[2,1,1,0,0,-1]' + type: DhVariantRules + }); + + game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation, { + scope: 'world', + config: false, + type: DhAutomation + }); + + game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew, { + scope: 'world', + config: false, + type: DhHomebrew, + onChange: value => { + if (value.maxFear) { + if (ui.resources) ui.resources.render({ force: true }); + } + } + }); + + game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, { + scope: 'client', + config: false, + type: DhAppearance, + onChange: value => { + if (value.displayFear) { + if (ui.resources) { + if (value.displayFear === 'hide') ui.resources.close({ allowed: true }); + else ui.resources.render({ force: true }); + } + } + } + }); + + game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement, { + scope: 'client', + config: false, + type: DhRangeMeasurement + }); +}; + +const registerMenus = () => { + game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, { + name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'), + label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'), + hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Hint'), + icon: SYSTEM.SETTINGS.menu.Automation.Icon, + type: DhAutomationSettings, + restricted: true + }); + game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Homebrew.Name, { + name: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Name'), + label: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Label'), + hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Hint'), + icon: SYSTEM.SETTINGS.menu.Homebrew.Icon, + type: DhHomebrewSettings, + restricted: true + }); + game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Range.Name, { + name: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Name'), + label: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Label'), + hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Hint'), + icon: SYSTEM.SETTINGS.menu.Range.Icon, + type: DhRangeMeasurementSettings, + restricted: true + }); + + game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, { + name: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.title'), + label: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.label'), + hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.hint'), + icon: 'fa-solid fa-palette', + type: DhAppearanceSettings, + restricted: false + }); + + game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.VariantRules.Name, { + name: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.title'), + label: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.label'), + hint: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.hint'), + icon: SYSTEM.SETTINGS.menu.VariantRules.Icon, + type: DhVariantRuleSettings, + restricted: false + }); +}; + +const registerNonConfigSettings = () => { + game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers, { + scope: 'world', + config: false, + type: DhLevelTiers, + default: defaultLevelTiers }); game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, { @@ -187,144 +130,4 @@ export const registerDHSettings = () => { ui.combat.render({ force: true }); } }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.MaxFear, { - name: game.i18n.localize('DAGGERHEART.Settings.Resources.MaxFear.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.Resources.MaxFear.Hint'), - scope: 'world', - config: true, - type: Number, - default: 12, - onChange: () => { - if (ui.resources) ui.resources.render({ force: true }); - } - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.DisplayFear, { - name: game.i18n.localize('DAGGERHEART.Settings.Resources.DisplayFear.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.Resources.DisplayFear.Hint'), - scope: 'client', - config: true, - type: String, - choices: { - token: 'Tokens', - bar: 'Bar', - hide: 'Hide' - }, - default: 'token', - onChange: value => { - if (ui.resources) { - if (value === 'hide') ui.resources.close({ allowed: true }); - else ui.resources.render({ force: true }); - } - } - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope, { - name: game.i18n.localize('DAGGERHEART.Settings.Automation.Hope.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.Automation.Hope.Hint'), - scope: 'world', - config: false, - type: Boolean, - default: false - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.ActionPoints, { - name: game.i18n.localize('DAGGERHEART.Settings.Automation.ActionPoints.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.Automation.ActionPoints.Hint'), - scope: 'world', - config: false, - type: Boolean, - default: true - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.RangeMeasurement, { - name: game.i18n.localize('DAGGERHEART.Settings.General.RangeMeasurement.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.General.RangeMeasurement.Hint'), - scope: 'world', - config: false, - type: Object, - default: { - enabled: true, - melee: 5, - veryClose: 15, - close: 30, - far: 60, - veryFar: 120 - } - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules, { - scope: 'world', - config: false, - type: DhVariantRules, - default: DhVariantRules.defaultSchema - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, { - scope: 'client', - config: false, - type: DhAppearance, - default: DhAppearance.defaultSchema - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.DualityRollColor, { - name: game.i18n.localize('DAGGERHEART.Settings.DualityRollColor.Name'), - hint: game.i18n.localize('DAGGERHEART.Settings.DualityRollColor.Hint'), - scope: 'world', - config: false, - type: Number, - choices: Object.values(DualityRollColor), - default: DualityRollColor.colorful.value - }); - - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers, { - scope: 'world', - config: false, - type: DhLevelTiers, - default: defaultLevelTiers - }); - - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, { - name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'), - label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'), - hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Hint'), - icon: SYSTEM.SETTINGS.menu.Automation.Icon, - type: DhpAutomationSettings, - restricted: true - }); - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Homebrew.Name, { - name: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Name'), - label: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Label'), - hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Hint'), - icon: SYSTEM.SETTINGS.menu.Homebrew.Icon, - type: DhpHomebrewSettings, - restricted: true - }); - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Range.Name, { - name: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Name'), - label: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Label'), - hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Hint'), - icon: SYSTEM.SETTINGS.menu.Range.Icon, - type: DhpRangeSettings, - restricted: true - }); - - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, { - name: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.title'), - label: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.label'), - hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.hint'), - icon: 'fa-solid fa-palette', - type: DHAppearanceSettings, - restricted: false - }); - - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.VariantRules.Name, { - name: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.title'), - label: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.label'), - hint: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.hint'), - icon: SYSTEM.SETTINGS.menu.VariantRules.Icon, - type: DHVariantRuleSettings, - restricted: false - }); }; diff --git a/module/applications/settings/_module.mjs b/module/applications/settings/_module.mjs new file mode 100644 index 00000000..b5b5748d --- /dev/null +++ b/module/applications/settings/_module.mjs @@ -0,0 +1,13 @@ +import DhAppearanceSettings from './appearanceSettings.mjs'; +import DhAutomationSettings from './automationSettings.mjs'; +import DhHomebrewSettings from './homebrewSettings.mjs'; +import DhRangeMeasurementSettings from './rangeMeasurementSettings.mjs'; +import DhVariantRuleSettings from './variantRuleSettings.mjs'; + +export { + DhAppearanceSettings, + DhAutomationSettings, + DhHomebrewSettings, + DhRangeMeasurementSettings, + DhVariantRuleSettings +}; diff --git a/module/applications/settings/appearanceSettings.mjs b/module/applications/settings/appearanceSettings.mjs index 5797836b..c11efd0f 100644 --- a/module/applications/settings/appearanceSettings.mjs +++ b/module/applications/settings/appearanceSettings.mjs @@ -54,20 +54,11 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App static async save() { await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, this.settings.toObject()); - /* const reload = await foundry.applications.api.DialogV2.confirm({ - id: 'reload-world-confirm', - modal: true, - rejectClose: false, - window: { title: 'SETTINGS.ReloadPromptTitle' }, - position: { width: 400 }, - content: `

${game.i18n.localize('SETTINGS.ReloadPromptBody')}

` - }); - - if (reload) { - await game.socket.emit('reload'); - foundry.utils.debouncedReload(); - } */ - document.body.classList.toggle('theme-colorful', game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme === DualityRollColor.colorful.value); + document.body.classList.toggle( + 'theme-colorful', + game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme === + DualityRollColor.colorful.value + ); this.close(); } diff --git a/module/applications/settings/automationSettings.mjs b/module/applications/settings/automationSettings.mjs new file mode 100644 index 00000000..6de21efd --- /dev/null +++ b/module/applications/settings/automationSettings.mjs @@ -0,0 +1,59 @@ +import { DhAutomation } from '../../data/settings/_module.mjs'; + +const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; + +export default class DhAutomationSettings extends HandlebarsApplicationMixin(ApplicationV2) { + constructor() { + super({}); + + this.settings = new DhAutomation( + game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).toObject() + ); + } + + get title() { + return game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'); + } + + static DEFAULT_OPTIONS = { + tag: 'form', + id: 'daggerheart-automation-settings', + classes: ['daggerheart', 'setting', 'dh-style'], + position: { width: '600', height: 'auto' }, + actions: { + reset: this.reset, + save: this.save + }, + form: { handler: this.updateData, submitOnChange: true } + }; + + static PARTS = { + main: { + template: 'systems/daggerheart/templates/settings/automation-settings.hbs' + } + }; + + async _prepareContext(_options) { + const context = await super._prepareContext(_options); + context.settingFields = this.settings; + + return context; + } + + static async updateData(event, element, formData) { + const updatedSettings = foundry.utils.expandObject(formData.object); + + await this.settings.updateSource(updatedSettings); + this.render(); + } + + static async reset() { + this.settings = new DhAutomation(); + this.render(); + } + + static async save() { + await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation, this.settings.toObject()); + this.close(); + } +} diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs new file mode 100644 index 00000000..e1b60726 --- /dev/null +++ b/module/applications/settings/homebrewSettings.mjs @@ -0,0 +1,60 @@ +import { DhHomebrew } from '../../data/settings/_module.mjs'; + +const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; + +export default class DhAutomationSettings extends HandlebarsApplicationMixin(ApplicationV2) { + constructor() { + super({}); + + this.settings = new DhHomebrew(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).toObject()); + } + + get title() { + return game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Name'); + } + + static DEFAULT_OPTIONS = { + tag: 'form', + id: 'daggerheart-homebrew-settings', + classes: ['daggerheart', 'setting', 'dh-style'], + position: { width: '600', height: 'auto' }, + actions: { + reset: this.reset, + save: this.save + }, + form: { handler: this.updateData, submitOnChange: true } + }; + + static PARTS = { + main: { + template: 'systems/daggerheart/templates/settings/homebrew-settings.hbs' + } + }; + + async _prepareContext(_options) { + const context = await super._prepareContext(_options); + context.settingFields = this.settings; + + return context; + } + + static async updateData(event, element, formData) { + const updatedSettings = foundry.utils.expandObject(formData.object); + + await this.settings.updateSource({ + ...updatedSettings, + traitArray: Object.values(updatedSettings.traitArray) + }); + this.render(); + } + + static async reset() { + this.settings = new DhHomebrew(); + this.render(); + } + + static async save() { + await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); + this.close(); + } +} diff --git a/module/applications/settings/rangeMeasurementSettings.mjs b/module/applications/settings/rangeMeasurementSettings.mjs new file mode 100644 index 00000000..8e90b462 --- /dev/null +++ b/module/applications/settings/rangeMeasurementSettings.mjs @@ -0,0 +1,59 @@ +import { DhRangeMeasurement } from '../../data/settings/_module.mjs'; + +const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; + +export default class DhRangeMeasurementSettings extends HandlebarsApplicationMixin(ApplicationV2) { + constructor() { + super({}); + + this.settings = new DhRangeMeasurement( + game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement).toObject() + ); + } + + get title() { + return game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'); + } + + static DEFAULT_OPTIONS = { + tag: 'form', + id: 'daggerheart-automation-settings', + classes: ['daggerheart', 'setting', 'dh-style'], + position: { width: '600', height: 'auto' }, + actions: { + reset: this.reset, + save: this.save + }, + form: { handler: this.updateData, submitOnChange: true } + }; + + static PARTS = { + main: { + template: 'systems/daggerheart/templates/settings/range-measurement-settings.hbs' + } + }; + + async _prepareContext(_options) { + const context = await super._prepareContext(_options); + context.settingFields = this.settings; + + return context; + } + + static async updateData(event, element, formData) { + const updatedSettings = foundry.utils.expandObject(formData.object); + + await this.settings.updateSource(updatedSettings); + this.render(); + } + + static async reset() { + this.settings = new DhRangeMeasurement(); + this.render(); + } + + static async save() { + await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement, this.settings.toObject()); + this.close(); + } +} diff --git a/module/applications/sheets/character.mjs b/module/applications/sheets/character.mjs index bea918e6..fe0beec9 100644 --- a/module/applications/sheets/character.mjs +++ b/module/applications/sheets/character.mjs @@ -165,18 +165,18 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { context.config = SYSTEM; const selectedAttributes = Object.values(this.document.system.traits).map(x => x.base); - context.abilityScoreArray = JSON.parse( - await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.AbilityArray) - ).reduce((acc, x) => { - const selectedIndex = selectedAttributes.indexOf(x); - if (selectedIndex !== -1) { - selectedAttributes.splice(selectedIndex, 1); - } else { - acc.push({ name: x, value: x }); - } + context.abilityScoreArray = await game.settings + .get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew) + .traitArray.reduce((acc, x) => { + const selectedIndex = selectedAttributes.indexOf(x); + if (selectedIndex !== -1) { + selectedAttributes.splice(selectedIndex, 1); + } else { + acc.push({ name: x, value: x }); + } - return acc; - }, []); + return acc; + }, []); if (!context.abilityScoreArray.includes(0)) context.abilityScoreArray.push({ name: 0, value: 0 }); context.abilityScoresFinished = context.abilityScoreArray.every(x => x.value === 0); diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 978e32cb..76fd12a0 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -337,3 +337,9 @@ export const rollTypes = { label: 'DAGGERHEART.RollTypes.ability.name' } }; + +export const fearDisplay = { + token: { value: 'token', label: 'DAGGERHEART.Settings.Appearance.FearDisplay.Token' }, + bar: { value: 'bar', label: 'DAGGERHEART.Settings.Appearance.FearDisplay.Bar' }, + hide: { value: 'hide', label: 'DAGGERHEART.Settings.Appearance.FearDisplay.Hide' } +}; diff --git a/module/config/settingsConfig.mjs b/module/config/settingsConfig.mjs index 3a33e61b..be793199 100644 --- a/module/config/settingsConfig.mjs +++ b/module/config/settingsConfig.mjs @@ -18,23 +18,15 @@ export const menu = { }; export const gameSettings = { - Automation: { - Hope: 'AutomationHope', - ActionPoints: 'AutomationActionPoints' - }, - Resources: { - Fear: 'ResourcesFear', - MaxFear: 'ResourcesMaxFear', - DisplayFear: 'DisplayFear' - }, - General: { - AbilityArray: 'AbilityArray', - RangeMeasurement: 'RangeMeasurement' - }, - DualityRollColor: 'DualityRollColor', - LevelTiers: 'LevelTiers', + Automation: 'Automation', + Homebrew: 'Homebrew', + RangeMeasurement: 'RangeMeasurement', appearance: 'Appearance', - variantRules: 'VariantRules' + variantRules: 'VariantRules', + Resources: { + Fear: 'ResourcesFear' + }, + LevelTiers: 'LevelTiers' }; export const DualityRollColor = { diff --git a/module/data/settings/Appearance.mjs b/module/data/settings/Appearance.mjs index fdbd925c..6382b613 100644 --- a/module/data/settings/Appearance.mjs +++ b/module/data/settings/Appearance.mjs @@ -1,7 +1,15 @@ +import { fearDisplay } from '../../config/generalConfig.mjs'; + export default class DhAppearance extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; return { + displayFear: new fields.StringField({ + required: true, + choices: fearDisplay, + initial: fearDisplay.token.value, + label: 'DAGGERHEART.Settings.Appearance.FIELDS.displayFear.label' + }), dualityColorScheme: new fields.StringField({ required: true, choices: DualityRollColor, @@ -35,8 +43,6 @@ export default class DhAppearance extends foundry.abstract.DataModel { }) }; } - - static defaultSchema = {}; } export const DualityRollColor = { diff --git a/module/data/settings/Automation.mjs b/module/data/settings/Automation.mjs new file mode 100644 index 00000000..85ed8bd4 --- /dev/null +++ b/module/data/settings/Automation.mjs @@ -0,0 +1,11 @@ +export default class DhAutomation extends foundry.abstract.DataModel { + static LOCALIZATION_PREFIXES = ['DAGGERHEART.Settings.Automation']; // Doesn't work for some reason + + static defineSchema() { + const fields = foundry.data.fields; + return { + hope: new fields.BooleanField({ required: true, initial: false }), + actionPoints: new fields.BooleanField({ required: true, initial: false }) + }; + } +} diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs new file mode 100644 index 00000000..92999c1a --- /dev/null +++ b/module/data/settings/Homebrew.mjs @@ -0,0 +1,19 @@ +export default class DhHomebrew extends foundry.abstract.DataModel { + static LOCALIZATION_PREFIXES = ['DAGGERHEART.Settings.Homebrew']; // Doesn't work for some reason + + static defineSchema() { + const fields = foundry.data.fields; + return { + maxFear: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 12, + label: 'DAGGERHEART.Settings.Homebrew.FIELDS.maxFear.label' + }), + traitArray: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }), { + initial: () => [2, 1, 1, 0, 0, -1] + }) + }; + } +} diff --git a/module/data/settings/RangeMeasurement.mjs b/module/data/settings/RangeMeasurement.mjs new file mode 100644 index 00000000..5d3e1125 --- /dev/null +++ b/module/data/settings/RangeMeasurement.mjs @@ -0,0 +1,17 @@ +export default class DhRangeMeasurement extends foundry.abstract.DataModel { + static defineSchema() { + const fields = foundry.data.fields; + return { + enabled: new fields.BooleanField({ required: true, initial: false, label: 'DAGGERHEART.General.Enabled' }), + melee: new fields.NumberField({ required: true, initial: 5, label: 'DAGGERHEART.Range.melee.name' }), + veryClose: new fields.NumberField({ + required: true, + initial: 15, + label: 'DAGGERHEART.Range.veryClose.name' + }), + close: new fields.NumberField({ required: true, initial: 30, label: 'DAGGERHEART.Range.close.name' }), + far: new fields.NumberField({ required: true, initial: 60, label: 'DAGGERHEART.Range.far.name' }), + veryFar: new fields.NumberField({ required: true, initial: 120, label: 'DAGGERHEART.Range.veryFar.name' }) + }; + } +} diff --git a/module/data/settings/VariantRules.mjs b/module/data/settings/VariantRules.mjs index 7d28a1d7..25e012bc 100644 --- a/module/data/settings/VariantRules.mjs +++ b/module/data/settings/VariantRules.mjs @@ -5,12 +5,22 @@ export default class DhVariantRules extends foundry.abstract.DataModel { const fields = foundry.data.fields; return { actionTokens: new fields.SchemaField({ - enabled: new fields.BooleanField({ required: true, initial: false }), - tokens: new fields.NumberField({ required: true, integer: true, initial: 3 }) + enabled: new fields.BooleanField({ + required: true, + initial: false, + label: 'DAGGERHEART.Settings.VariantRules.FIELDS.actionTokens.enabled.label' + }), + tokens: new fields.NumberField({ + required: true, + integer: true, + initial: 3, + label: 'DAGGERHEART.Settings.VariantRules.FIELDS.actionTokens.tokens.label' + }) }), - useCoins: new fields.BooleanField({ initial: false }) + useCoins: new fields.BooleanField({ + initial: false, + label: 'DAGGERHEART.Settings.VariantRules.FIELDS.useCoins.label' + }) }; } - - static defaultSchema = {}; } diff --git a/module/data/settings/_module.mjs b/module/data/settings/_module.mjs new file mode 100644 index 00000000..dc99ed36 --- /dev/null +++ b/module/data/settings/_module.mjs @@ -0,0 +1,7 @@ +import DhAppearance from './Appearance.mjs'; +import DhAutomation from './Automation.mjs'; +import DhHomebrew from './Homebrew.mjs'; +import DhRangeMeasurement from './RangeMeasurement.mjs'; +import DhVariantRules from './VariantRules.mjs'; + +export { DhAppearance, DhAutomation, DhHomebrew, DhRangeMeasurement, DhVariantRules }; diff --git a/module/ui/ruler.mjs b/module/ui/ruler.mjs index 2c6848d2..71588c81 100644 --- a/module/ui/ruler.mjs +++ b/module/ui/ruler.mjs @@ -3,7 +3,7 @@ export default class DhpRuler extends foundry.canvas.interaction.Ruler { const context = super._getWaypointLabelContext(waypoint, state); if (!context) return; - const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.RangeMeasurement); + const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement); if (range.enabled) { const distance = this.#getRangeLabel(waypoint.measurement.distance.toNearest(0.01), range); diff --git a/module/ui/tokenRuler.mjs b/module/ui/tokenRuler.mjs index 4faa516e..fd7e9036 100644 --- a/module/ui/tokenRuler.mjs +++ b/module/ui/tokenRuler.mjs @@ -3,7 +3,7 @@ export default class DhpTokenRuler extends foundry.canvas.placeables.tokens.Toke const context = super._getWaypointLabelContext(waypoint, state); if (!context) return; - const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.RangeMeasurement); + const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement); if (range.enabled) { const distance = this.#getRangeLabel(waypoint.measurement.distance.toNearest(0.01), range); diff --git a/styles/daggerheart.css b/styles/daggerheart.css index e5d27cb5..fee3a88b 100755 --- a/styles/daggerheart.css +++ b/styles/daggerheart.css @@ -2816,6 +2816,31 @@ div.daggerheart.views.multiclass { #resources:has(.fear-bar) { min-width: 200px; } +.daggerheart.dh-style.setting .settings-col { + display: flex; + flex-direction: column; + gap: 4px; +} +.daggerheart.dh-style.setting .trait-array-container { + display: flex; + justify-content: space-evenly; + gap: 8px; + margin-bottom: 16px; +} +.daggerheart.dh-style.setting .trait-array-container .trait-array-item { + position: relative; + display: flex; + justify-content: center; +} +.daggerheart.dh-style.setting .trait-array-container .trait-array-item label { + position: absolute; + top: -7px; + font-size: 12px; + font-variant: petite-caps; +} +.daggerheart.dh-style.setting .trait-array-container .trait-array-item input { + text-align: center; +} .application.sheet.daggerheart.actor.dh-style.adversary .window-content { overflow: auto; } diff --git a/styles/daggerheart.less b/styles/daggerheart.less index 0b0f3926..9965015b 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -11,6 +11,7 @@ @import './levelup.less'; @import '../node_modules/@yaireo/tagify/dist/tagify.css'; @import './resources.less'; +@import './settings.less'; // new styles imports @import './less/actors/character.less'; diff --git a/styles/settings.less b/styles/settings.less new file mode 100644 index 00000000..e37f9891 --- /dev/null +++ b/styles/settings.less @@ -0,0 +1,31 @@ +.daggerheart.dh-style.setting { + .settings-col { + display: flex; + flex-direction: column; + gap: 4px; + } + + .trait-array-container { + display: flex; + justify-content: space-evenly; + gap: 8px; + margin-bottom: 16px; + + .trait-array-item { + position: relative; + display: flex; + justify-content: center; + + label { + position: absolute; + top: -7px; + font-size: 12px; + font-variant: petite-caps; + } + + input { + text-align: center; + } + } + } +} diff --git a/templates/settings/appearance-settings.hbs b/templates/settings/appearance-settings.hbs index e0a16235..6464f9c9 100644 --- a/templates/settings/appearance-settings.hbs +++ b/templates/settings/appearance-settings.hbs @@ -1,4 +1,6 @@
+ {{formGroup settingFields.schema.fields.displayFear value=settingFields._source.displayFear localize=true}} +
{{localize "DAGGERHEART.Settings.Menu.Appearance.duality"}} diff --git a/templates/settings/automation-settings.hbs b/templates/settings/automation-settings.hbs new file mode 100644 index 00000000..bd50c548 --- /dev/null +++ b/templates/settings/automation-settings.hbs @@ -0,0 +1,26 @@ +
+
+ +
+ {{formInput settingFields.schema.fields.hope value=settingFields._source.hope }} +
+
+
+ +
+ {{formInput settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints }} +
+
+ +
+ + +
+
+ \ No newline at end of file diff --git a/templates/settings/homebrew-settings.hbs b/templates/settings/homebrew-settings.hbs new file mode 100644 index 00000000..aa866378 --- /dev/null +++ b/templates/settings/homebrew-settings.hbs @@ -0,0 +1,25 @@ +
+ {{formGroup settingFields.schema.fields.maxFear value=settingFields._source.maxFear localize=true}} + +

{{localize "DAGGERHEART.Settings.Homebrew.FIELDS.traitArray.label"}}

+
+ {{#each settingFields._source.traitArray as |trait index|}} +
+ + +
+ {{/each}} +
+ +
+ + +
+
+ \ No newline at end of file diff --git a/templates/settings/range-measurement-settings.hbs b/templates/settings/range-measurement-settings.hbs new file mode 100644 index 00000000..36357d57 --- /dev/null +++ b/templates/settings/range-measurement-settings.hbs @@ -0,0 +1,22 @@ +
+
+ {{formGroup settingFields.schema.fields.enabled value=settingFields._source.enabled localize=true}} + {{formGroup settingFields.schema.fields.melee value=settingFields._source.melee localize=true}} + {{formGroup settingFields.schema.fields.veryClose value=settingFields._source.veryClose localize=true}} + {{formGroup settingFields.schema.fields.close value=settingFields._source.close localize=true}} + {{formGroup settingFields.schema.fields.far value=settingFields._source.far localize=true}} + {{formGroup settingFields.schema.fields.veryFar value=settingFields._source.veryFar localize=true}} +
+ +
+ + +
+
+ \ No newline at end of file diff --git a/templates/settings/variant-rules.hbs b/templates/settings/variant-rules.hbs index 2c4d7d30..f4fa3fdf 100644 --- a/templates/settings/variant-rules.hbs +++ b/templates/settings/variant-rules.hbs @@ -3,8 +3,8 @@
- {{formInput settingFields.schema.fields.actionTokens.fields.enabled value=settingFields._source.actionTokens.enabled}} - {{formInput settingFields.schema.fields.actionTokens.fields.tokens value=settingFields._source.actionTokens.tokens disabled=(not settingFields._source.actionTokens.enabled)}} + {{formGroup settingFields.schema.fields.actionTokens.fields.enabled value=settingFields._source.actionTokens.enabled localize=true}} + {{formGroup settingFields.schema.fields.actionTokens.fields.tokens value=settingFields._source.actionTokens.tokens disabled=(not settingFields._source.actionTokens.enabled) localize=true}}
diff --git a/templates/views/automation-settings.hbs b/templates/views/automation-settings.hbs deleted file mode 100644 index de4f1131..00000000 --- a/templates/views/automation-settings.hbs +++ /dev/null @@ -1,19 +0,0 @@ -
-
- -
- -
-
-
- -
- -
-
- - -
\ No newline at end of file diff --git a/templates/views/homebrew-settings.hbs b/templates/views/homebrew-settings.hbs deleted file mode 100644 index 6d9c9a90..00000000 --- a/templates/views/homebrew-settings.hbs +++ /dev/null @@ -1,13 +0,0 @@ -
-
- -
- -
-
- - -
\ No newline at end of file diff --git a/templates/views/range-settings.hbs b/templates/views/range-settings.hbs deleted file mode 100644 index fec4f7fb..00000000 --- a/templates/views/range-settings.hbs +++ /dev/null @@ -1,44 +0,0 @@ -
-
- -
- - -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
- - -
\ No newline at end of file