diff --git a/module/applications/sheets-configs/prototype-token-config.mjs b/module/applications/sheets-configs/prototype-token-config.mjs index 0bb9703a..9faf6e71 100644 --- a/module/applications/sheets-configs/prototype-token-config.mjs +++ b/module/applications/sheets-configs/prototype-token-config.mjs @@ -1,41 +1,30 @@ -export default class DhPrototypeTokenConfig extends foundry.applications.sheets.PrototypeTokenConfig { - /** @override */ - static PARTS = { - tabs: super.PARTS.tabs, - identity: super.PARTS.identity, - appearance: { - template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', - scrollable: [''] - }, - vision: super.PARTS.vision, - light: super.PARTS.light, - resources: super.PARTS.resources, - footer: super.PARTS.footer +import DHTokenConfigMixin from './token-config-mixin.mjs'; +import { getActorSizeFromForm } from './token-config-mixin.mjs'; + +export default class DhPrototypeTokenConfig extends DHTokenConfigMixin( + foundry.applications.sheets.PrototypeTokenConfig +) { + /** @inheritDoc */ + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + form: { handler: DhPrototypeTokenConfig.#onSubmit } }; - /** @inheritDoc */ - async _prepareResourcesTab() { - const token = this.token; - const usesTrackableAttributes = !foundry.utils.isEmpty(CONFIG.Actor.trackableAttributes); - const attributeSource = - this.actor?.system instanceof foundry.abstract.DataModel && usesTrackableAttributes - ? this.actor?.type - : this.actor?.system; - const TokenDocument = foundry.utils.getDocumentClass('Token'); - const attributes = TokenDocument.getTrackedAttributes(attributeSource); - return { - barAttributes: TokenDocument.getTrackedAttributeChoices(attributes, attributeSource), - bar1: token.getBarAttribute?.('bar1'), - bar2: token.getBarAttribute?.('bar2'), - turnMarkerModes: DhPrototypeTokenConfig.TURN_MARKER_MODES, - turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations - }; - } + /** + * Process form submission for the sheet + * @this {PrototypeTokenConfig} + * @type {ApplicationFormSubmission} + */ + static async #onSubmit(event, form, formData) { + const submitData = this._processFormData(event, form, formData); + submitData.detectionModes ??= []; // Clear detection modes array + this._processChanges(submitData); + const changes = { prototypeToken: submitData }; - async _prepareAppearanceTab() { - const context = await super._prepareAppearanceTab(); - context.actorSizeUsed = this.token.actor ? Boolean(this.token.actor.system.size) : false; + const changedTokenSizeValue = getActorSizeFromForm(this.element, this.actor); + if (changedTokenSizeValue) changes.system = { size: changedTokenSizeValue }; - return context; + this.actor.validate({ changes, clean: true, fallback: false }); + await this.actor.update(changes); } } diff --git a/module/applications/sheets-configs/token-config-mixin.mjs b/module/applications/sheets-configs/token-config-mixin.mjs new file mode 100644 index 00000000..c29b54ff --- /dev/null +++ b/module/applications/sheets-configs/token-config-mixin.mjs @@ -0,0 +1,114 @@ +export default function DHTokenConfigMixin(Base) { + class DHTokenConfigBase extends Base { + /** @override */ + static PARTS = { + tabs: super.PARTS.tabs, + identity: super.PARTS.identity, + appearance: { + template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', + scrollable: [''] + }, + vision: super.PARTS.vision, + light: super.PARTS.light, + resources: super.PARTS.resources, + footer: super.PARTS.footer + }; + + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + + switch (partId) { + case 'appearance': + htmlElement + .querySelector('#dhTokenSize') + ?.addEventListener('change', this.onTokenSizeChange.bind(this)); + break; + } + } + + /** @inheritDoc */ + async _prepareResourcesTab() { + const token = this.token; + const usesTrackableAttributes = !foundry.utils.isEmpty(CONFIG.Actor.trackableAttributes); + const attributeSource = + this.actor?.system instanceof foundry.abstract.DataModel && usesTrackableAttributes + ? this.actor?.type + : this.actor?.system; + const TokenDocument = foundry.utils.getDocumentClass('Token'); + const attributes = TokenDocument.getTrackedAttributes(attributeSource); + return { + barAttributes: TokenDocument.getTrackedAttributeChoices(attributes, attributeSource), + bar1: token.getBarAttribute?.('bar1'), + bar2: token.getBarAttribute?.('bar2'), + turnMarkerModes: DHTokenConfigBase.TURN_MARKER_MODES, + turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations + }; + } + + async _prepareAppearanceTab() { + const context = await super._prepareAppearanceTab(); + context.tokenSizes = CONFIG.DH.ACTOR.tokenSize; + context.tokenSize = this.actor?.system?.size; + context.usesActorSize = this.actor?.system?.metadata?.usesSize; + context.actorSizeDisable = context.usesActorSize && this.actor.system.size !== 'custom'; + + return context; + } + + /** @inheritDoc */ + _previewChanges(changes) { + if (!changes || !this._preview) return; + + const tokenSizeSelect = this.element?.querySelector('#dhTokenSize'); + if (this.actor && tokenSizeSelect && tokenSizeSelect.value !== 'custom') { + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + const tokenSize = tokenSizes[tokenSizeSelect.value]; + changes.width = tokenSize; + changes.height = tokenSize; + } + + const deletions = { '-=actorId': null, '-=actorLink': null }; + const mergeOptions = { inplace: false, performDeletions: true }; + this._preview.updateSource(mergeObject(changes, deletions, mergeOptions)); + + if (this._preview?.object?.destroyed === false) { + this._preview.object.initializeSources(); + this._preview.object.renderFlags.set({ refresh: true }); + } + } + + async onTokenSizeChange(event) { + const value = event.target.value; + const tokenSizeDimensions = this.element.querySelector('#tokenSizeDimensions'); + if (tokenSizeDimensions) { + const disabled = value !== 'custom'; + + tokenSizeDimensions.dataset.tooltip = disabled + ? game.i18n.localize('DAGGERHEART.APPLICATIONS.TokenConfig.actorSizeUsed') + : ''; + + const disabledIcon = tokenSizeDimensions.querySelector('i'); + if (disabledIcon) { + disabledIcon.style.opacity = disabled ? '' : '0'; + } + + const dimensionsInputs = tokenSizeDimensions.querySelectorAll('.form-fields input'); + for (const input of dimensionsInputs) { + input.disabled = disabled; + } + } + } + } + + return DHTokenConfigBase; +} + +export function getActorSizeFromForm(element, actor) { + const tokenSizeSelect = element.querySelector('#dhTokenSize'); + const isSizeDifferent = tokenSizeSelect?.value !== actor?.system?.size; + if (tokenSizeSelect && actor && isSizeDifferent) { + return tokenSizeSelect.value; + } + + return null; +} diff --git a/module/applications/sheets-configs/token-config.mjs b/module/applications/sheets-configs/token-config.mjs index 5f4e4f56..d7450bd6 100644 --- a/module/applications/sheets-configs/token-config.mjs +++ b/module/applications/sheets-configs/token-config.mjs @@ -1,41 +1,11 @@ -export default class DhTokenConfig extends foundry.applications.sheets.TokenConfig { - /** @override */ - static PARTS = { - tabs: super.PARTS.tabs, - identity: super.PARTS.identity, - appearance: { - template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', - scrollable: [''] - }, - vision: super.PARTS.vision, - light: super.PARTS.light, - resources: super.PARTS.resources, - footer: super.PARTS.footer - }; +import DHTokenConfigMixin from './token-config-mixin.mjs'; +import { getActorSizeFromForm } from './token-config-mixin.mjs'; - /** @inheritDoc */ - async _prepareResourcesTab() { - const token = this.token; - const usesTrackableAttributes = !foundry.utils.isEmpty(CONFIG.Actor.trackableAttributes); - const attributeSource = - this.actor?.system instanceof foundry.abstract.DataModel && usesTrackableAttributes - ? this.actor?.type - : this.actor?.system; - const TokenDocument = foundry.utils.getDocumentClass('Token'); - const attributes = TokenDocument.getTrackedAttributes(attributeSource); - return { - barAttributes: TokenDocument.getTrackedAttributeChoices(attributes, attributeSource), - bar1: token.getBarAttribute?.('bar1'), - bar2: token.getBarAttribute?.('bar2'), - turnMarkerModes: DhTokenConfig.TURN_MARKER_MODES, - turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations - }; - } +export default class DhTokenConfig extends DHTokenConfigMixin(foundry.applications.sheets.TokenConfig) { + async _processSubmitData(event, form, submitData, options) { + const changedTokenSizeValue = getActorSizeFromForm(this.element, this.actor); + if (changedTokenSizeValue) this.token.actor.update({ 'system.size': changedTokenSizeValue }); - async _prepareAppearanceTab() { - const context = await super._prepareAppearanceTab(); - context.actorSizeUsed = this.token.actor ? Boolean(this.token.actor.system.size) : false; - - return context; + super._processSubmitData(event, form, submitData, options); } } diff --git a/module/config/actionConfig.mjs b/module/config/actionConfig.mjs index d64fd9e9..c9b70193 100644 --- a/module/config/actionConfig.mjs +++ b/module/config/actionConfig.mjs @@ -2,7 +2,7 @@ export const actionTypes = { attack: { id: 'attack', name: 'DAGGERHEART.ACTIONS.TYPES.attack.name', - icon: 'fa-khanda', + icon: 'fa-hand-fist', tooltip: 'DAGGERHEART.ACTIONS.TYPES.attack.tooltip' }, countdown: { diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 239bfa1e..6c7b8c59 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -162,12 +162,9 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel * @returns {object} */ getRollData(data = {}) { - if (!this.actor) return null; - const actorData = this.actor.getRollData(false); + const actorData = this.actor ? this.actor.getRollData(false) : {}; - // Add Roll results to RollDatas actorData.result = data.roll?.total ?? 1; - actorData.scale = data.costs?.length // Right now only return the first scalable cost. ? (data.costs.find(c => c.scalable)?.total ?? 1) : 1; diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 06b60447..9f4db5e2 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -539,7 +539,10 @@ export default class DhpActor extends Actor { /**@inheritdoc */ getRollData() { - const rollData = super.getRollData().clone(); + const rollData = foundry.utils.deepClone(super.getRollData()); + /* system gets repeated infinately which causes issues when trying to use the data for document creation */ + delete rollData.system; + rollData.name = this.name; rollData.system = this.system.getRollData(); rollData.prof = this.system.proficiency ?? 1; diff --git a/module/enrichers/LookupEnricher.mjs b/module/enrichers/LookupEnricher.mjs index 3566e112..cc9af608 100644 --- a/module/enrichers/LookupEnricher.mjs +++ b/module/enrichers/LookupEnricher.mjs @@ -3,6 +3,11 @@ import { parseInlineParams } from './parser.mjs'; export default function DhLookupEnricher(match, { rollData }) { const results = parseInlineParams(match[1], { first: 'formula' }); const element = document.createElement('span'); - element.textContent = Roll.replaceFormulaData(String(results.formula), rollData); + + const lookupCommand = match[0]; + const lookupParam = match[1]; + const lookupText = Roll.replaceFormulaData(String(results.formula), rollData); + element.textContent = lookupText === lookupParam ? lookupCommand : lookupText; + return element; } diff --git a/system.json b/system.json index ef2c2432..0dcbc398 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "1.4.1", + "version": "1.4.2", "compatibility": { "minimum": "13.346", "verified": "13.351", @@ -54,6 +54,12 @@ { "name": "chrisryan10", "discord": "lazjen" + }, + { + "name": "nsalyzyn", + "url": "https://github.com/nsalyzyn", + "email": "nsalyzyn@gmail.com", + "discord": "nsalyzyn" } ], "esmodules": ["build/daggerheart.js"], diff --git a/templates/sheets-settings/token-config/appearance.hbs b/templates/sheets-settings/token-config/appearance.hbs index 0f6019ba..abdb49c2 100644 --- a/templates/sheets-settings/token-config/appearance.hbs +++ b/templates/sheets-settings/token-config/appearance.hbs @@ -10,22 +10,31 @@ {{/if}} +
+ {{localize "Token Size"}} + {{#if usesActorSize}} +
+ + +
+ {{/if}} -
- -
- - {{formInput fields.width value=source.width id=(concat rootId "-width") disabled=actorSizeUsed}} - - {{formInput fields.height value=source.height id=(concat rootId "-height") disabled=actorSizeUsed}} +
+ +
+ + {{formInput fields.width value=source.width id=(concat rootId "-width") disabled=actorSizeDisable}} + + {{formInput fields.height value=source.height id=(concat rootId "-height") disabled=actorSizeDisable}} +
-
+
{{#if shapes}} {{formGroup fields.shape value=source.shape choices=shapes classes="slim" rootId=rootId}}