From 479e1476404a3091aef53b2b6e1b48529f709df8 Mon Sep 17 00:00:00 2001 From: Dapoolp Date: Thu, 24 Jul 2025 15:28:43 +0200 Subject: [PATCH] f --- .../sheets-configs/action-config.mjs | 12 +- .../sheets/api/application-mixin.mjs | 4 + module/data/action/attackAction.mjs | 4 - module/data/action/baseAction.mjs | 83 ++--------- module/data/action/subDatas/rollData.mjs | 0 module/data/fields/_module.mjs | 1 + module/data/fields/action/_module.mjs | 7 + module/data/fields/action/beastformField.mjs | 12 ++ module/data/fields/action/costField.mjs | 18 +++ module/data/fields/action/damageField.mjs | 0 module/data/fields/action/effectField.mjs | 11 ++ module/data/fields/action/healingField.mjs | 0 module/data/fields/action/rangeField.mjs | 12 ++ module/data/fields/action/rollField.mjs | 0 module/data/fields/action/saveField.mjs | 19 +++ module/data/fields/action/targetField.mjs | 16 +++ module/data/fields/action/usesField.mjs | 16 +++ module/data/fields/actionField.mjs | 132 +----------------- module/data/fields/mappingField.mjs | 128 +++++++++++++++++ module/data/item/weapon.mjs | 2 +- module/documents/item.mjs | 2 +- module/helpers/handlebarsHelper.mjs | 7 +- styles/less/global/elements.less | 6 + templates/actionTypes/damage.hbs | 132 ++++++++---------- .../adversary-settings/attack.hbs | 4 +- 25 files changed, 339 insertions(+), 289 deletions(-) create mode 100644 module/data/action/subDatas/rollData.mjs create mode 100644 module/data/fields/action/_module.mjs create mode 100644 module/data/fields/action/beastformField.mjs create mode 100644 module/data/fields/action/costField.mjs create mode 100644 module/data/fields/action/damageField.mjs create mode 100644 module/data/fields/action/effectField.mjs create mode 100644 module/data/fields/action/healingField.mjs create mode 100644 module/data/fields/action/rangeField.mjs create mode 100644 module/data/fields/action/rollField.mjs create mode 100644 module/data/fields/action/saveField.mjs create mode 100644 module/data/fields/action/targetField.mjs create mode 100644 module/data/fields/action/usesField.mjs create mode 100644 module/data/fields/mappingField.mjs diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index bc2d83b0..6a3f4b8a 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -105,7 +105,6 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { if (!!this.action.effects) context.effects = this.action.effects.map(e => this.action.item.effects.get(e._id)); if (this.action.damage?.hasOwnProperty('includeBase') && this.action.type === 'attack') context.hasBaseDamage = !!this.action.parent.attack; - context.getRealIndex = this.getRealIndex.bind(this); context.getEffectDetails = this.getEffectDetails.bind(this); context.costOptions = this.getCostOptions(); context.disableOption = this.disableOption.bind(this); @@ -147,11 +146,6 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { return filtered; } - getRealIndex(index) { - const data = this.action.toObject(false); - return data.damage.parts.find(d => d.base) ? index - 1 : index; - } - getEffectDetails(id) { return this.action.item.effects.get(id); } @@ -199,8 +193,10 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { static addDamage(event) { if (!this.action.damage.parts) return; - const data = this.action.toObject(); - data.damage.parts.push({}); + const data = this.action.toObject(), + part = {}; + if(this.action.actor.isNPC) part.value = { multiplier: 'flat' }; + data.damage.parts.push(part); this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index b5853694..544ab575 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -283,6 +283,10 @@ export default function DHApplicationMixin(Base) { { name: 'CONTROLS.CommonEdit', icon: 'fa-solid fa-pen-to-square', + condition: target => { + const doc = getDocFromElement(target); + return !doc.hasOwnProperty('systemPath') || doc.inCollection + }, callback: target => getDocFromElement(target).sheet.render({ force: true }) } ]; diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index a4f65735..ddcccfca 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -46,8 +46,4 @@ export default class DHAttackAction extends DHDamageAction { return result; } - - // get modifiers() { - // return []; - // } } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 48e70939..9f6d088d 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -2,6 +2,7 @@ import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField, DHReso import DhpActor from '../../documents/actor.mjs'; import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs'; import { ActionMixin } from '../fields/actionField.mjs'; +import * as ActionFields from '../fields/action/_module.mjs'; const fields = foundry.data.fields; @@ -18,10 +19,11 @@ const fields = foundry.data.fields; */ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel) { - static extraSchemas = []; + static baseFields = ['cost', 'uses', 'range']; + static extraFields = []; static defineSchema() { - return { + const schemaFields = { _id: new fields.DocumentIdField({ initial: () => foundry.utils.randomID() }), systemPath: new fields.StringField({ required: true, initial: 'actions' }), type: new fields.StringField({ initial: undefined, readonly: true, required: true }), @@ -33,76 +35,25 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel choices: CONFIG.DH.ITEM.actionTypes, initial: 'action', nullable: true - }), - cost: new fields.ArrayField( - new fields.SchemaField({ - key: new fields.StringField({ - nullable: false, - required: true, - initial: 'hope' - }), - keyIsID: new fields.BooleanField(), - value: new fields.NumberField({ nullable: true, initial: 1 }), - scalable: new fields.BooleanField({ initial: false }), - step: new fields.NumberField({ nullable: true, initial: null }) - }) - ), - uses: new fields.SchemaField({ - value: new fields.NumberField({ nullable: true, initial: null }), - max: new fields.NumberField({ nullable: true, initial: null }), - recovery: new fields.StringField({ - choices: CONFIG.DH.GENERAL.refreshTypes, - initial: null, - nullable: true - }) - }), - range: new fields.StringField({ - choices: CONFIG.DH.GENERAL.range, - required: false, - blank: true - // initial: null - }), - ...this.defineExtraSchema() + }) }; + + [...this.baseFields, ...extraFields].forEach(s => { + // const clsField = + }); + + return schemaFields; } static defineExtraSchema() { const extraFields = { damage: new DHDamageField(), roll: new fields.EmbeddedDataField(DHActionRollData), - save: new fields.SchemaField({ - trait: new fields.StringField({ - nullable: true, - initial: null, - choices: CONFIG.DH.ACTOR.abilities - }), - difficulty: new fields.NumberField({ nullable: true, initial: 10, integer: true, min: 0 }), - damageMod: new fields.StringField({ - initial: CONFIG.DH.ACTIONS.damageOnSave.none.id, - choices: CONFIG.DH.ACTIONS.damageOnSave - }) - }), - target: new fields.SchemaField({ - type: new fields.StringField({ - choices: CONFIG.DH.ACTIONS.targetTypes, - initial: CONFIG.DH.ACTIONS.targetTypes.any.id, - nullable: true, - initial: null - }), - amount: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }) - }), - effects: new fields.ArrayField( // ActiveEffect - new fields.SchemaField({ - _id: new fields.DocumentIdField(), - onSave: new fields.BooleanField({ initial: false }) - }) - ), + save: new ActionFields.SaveField(), + target: new ActionFields.TargetField(), + effects: new ActionFields.EffectField(), healing: new fields.EmbeddedDataField(DHResourceData), - beastform: new fields.SchemaField({ - tierAccess: new fields.SchemaField({ - exact: new fields.NumberField({ integer: true, nullable: true, initial: null }) - }) - }) + beastform: new ActionFields.BeastformField() }, extraSchemas = {}; @@ -115,10 +66,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel this.img = this.img ?? this.parent?.parent?.img; } - get index() { - return foundry.utils.getProperty(this.parent, this.systemPath).indexOf(this); - } - get id() { return this._id; } diff --git a/module/data/action/subDatas/rollData.mjs b/module/data/action/subDatas/rollData.mjs new file mode 100644 index 00000000..e69de29b diff --git a/module/data/fields/_module.mjs b/module/data/fields/_module.mjs index 9ad789eb..78de9e98 100644 --- a/module/data/fields/_module.mjs +++ b/module/data/fields/_module.mjs @@ -2,3 +2,4 @@ export { ActionCollection } from './actionField.mjs'; export { default as FormulaField } from './formulaField.mjs'; export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs'; export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs'; +export { default as MappingField } from './mappingField.mjs'; diff --git a/module/data/fields/action/_module.mjs b/module/data/fields/action/_module.mjs new file mode 100644 index 00000000..2ac58aa7 --- /dev/null +++ b/module/data/fields/action/_module.mjs @@ -0,0 +1,7 @@ +export { default as CostField } from './costField.mjs'; +export { default as UsesField } from './usesField.mjs'; +export { default as RangeField } from './rangeField.mjs'; +export { default as TargetField } from './targetField.mjs'; +export { default as EffectField } from './effectField.mjs'; +export { default as SaveField } from './saveField.mjs'; +export { default as BeastformField } from './beastformField.mjs'; \ No newline at end of file diff --git a/module/data/fields/action/beastformField.mjs b/module/data/fields/action/beastformField.mjs new file mode 100644 index 00000000..19836f33 --- /dev/null +++ b/module/data/fields/action/beastformField.mjs @@ -0,0 +1,12 @@ +const fields = foundry.data.fields; + +export default class BeastformField extends fields.SchemaField { + constructor(options={}, context={}) { + const beastformFields = { + tierAccess: new fields.SchemaField({ + exact: new fields.NumberField({ integer: true, nullable: true, initial: null }) + }) + }; + super(beastformFields, options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/action/costField.mjs b/module/data/fields/action/costField.mjs new file mode 100644 index 00000000..c9e179bc --- /dev/null +++ b/module/data/fields/action/costField.mjs @@ -0,0 +1,18 @@ +const fields = foundry.data.fields; + +export default class CostField extends fields.ArrayField { + constructor(options={}, context={}) { + const element = new fields.SchemaField({ + key: new fields.StringField({ + nullable: false, + required: true, + initial: 'hope' + }), + keyIsID: new fields.BooleanField(), + value: new fields.NumberField({ nullable: true, initial: 1 }), + scalable: new fields.BooleanField({ initial: false }), + step: new fields.NumberField({ nullable: true, initial: null }) + }); + super(element, options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/action/damageField.mjs b/module/data/fields/action/damageField.mjs new file mode 100644 index 00000000..e69de29b diff --git a/module/data/fields/action/effectField.mjs b/module/data/fields/action/effectField.mjs new file mode 100644 index 00000000..381da6f9 --- /dev/null +++ b/module/data/fields/action/effectField.mjs @@ -0,0 +1,11 @@ +const fields = foundry.data.fields; + +export default class EffectField extends fields.ArrayField { + constructor(options={}, context={}) { + const element = new fields.SchemaField({ + _id: new fields.DocumentIdField(), + onSave: new fields.BooleanField({ initial: false }) + }); + super(element, options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/action/healingField.mjs b/module/data/fields/action/healingField.mjs new file mode 100644 index 00000000..e69de29b diff --git a/module/data/fields/action/rangeField.mjs b/module/data/fields/action/rangeField.mjs new file mode 100644 index 00000000..89942721 --- /dev/null +++ b/module/data/fields/action/rangeField.mjs @@ -0,0 +1,12 @@ +const fields = foundry.data.fields; + +export default class RangeField extends fields.StringField { + constructor(context={}) { + const options = { + choices: CONFIG.DH.GENERAL.range, + required: false, + blank: true + }; + super(options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/action/rollField.mjs b/module/data/fields/action/rollField.mjs new file mode 100644 index 00000000..e69de29b diff --git a/module/data/fields/action/saveField.mjs b/module/data/fields/action/saveField.mjs new file mode 100644 index 00000000..c70ba3b1 --- /dev/null +++ b/module/data/fields/action/saveField.mjs @@ -0,0 +1,19 @@ +const fields = foundry.data.fields; + +export default class SaveField extends fields.SchemaField { + constructor(options={}, context={}) { + const saveFields = { + trait: new fields.StringField({ + nullable: true, + initial: null, + choices: CONFIG.DH.ACTOR.abilities + }), + difficulty: new fields.NumberField({ nullable: true, initial: 10, integer: true, min: 0 }), + damageMod: new fields.StringField({ + initial: CONFIG.DH.ACTIONS.damageOnSave.none.id, + choices: CONFIG.DH.ACTIONS.damageOnSave + }) + }; + super(saveFields, options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/action/targetField.mjs b/module/data/fields/action/targetField.mjs new file mode 100644 index 00000000..45dcd6ca --- /dev/null +++ b/module/data/fields/action/targetField.mjs @@ -0,0 +1,16 @@ +const fields = foundry.data.fields; + +export default class TargetField extends fields.SchemaField { + constructor(options={}, context={}) { + const targetFields = { + type: new fields.StringField({ + choices: CONFIG.DH.ACTIONS.targetTypes, + initial: CONFIG.DH.ACTIONS.targetTypes.any.id, + nullable: true, + initial: null + }), + amount: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }) + }; + super(targetFields, options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/action/usesField.mjs b/module/data/fields/action/usesField.mjs new file mode 100644 index 00000000..6e5c7502 --- /dev/null +++ b/module/data/fields/action/usesField.mjs @@ -0,0 +1,16 @@ +const fields = foundry.data.fields; + +export default class UsesField extends fields.SchemaField { + constructor(options={}, context={}) { + const usesFields = { + value: new fields.NumberField({ nullable: true, initial: null }), + max: new fields.NumberField({ nullable: true, initial: null }), + recovery: new fields.StringField({ + choices: CONFIG.DH.GENERAL.refreshTypes, + initial: null, + nullable: true + }) + }; + super(usesFields, options, context); + } +} \ No newline at end of file diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 8e02f4e6..bc28943a 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -1,4 +1,5 @@ import DHActionConfig from "../../applications/sheets-configs/action-config.mjs"; +import MappingField from "./mappingField.mjs"; /** * Specialized collection type for stored actions. @@ -56,137 +57,6 @@ export class ActionCollection extends Collection { /* -------------------------------------------- */ -/** - * A subclass of ObjectField that represents a mapping of keys to the provided DataField type. - * - * @param {DataField} model The class of DataField which should be embedded in this field. - * @param {MappingFieldOptions} [options={}] Options which configure the behavior of the field. - * @property {string[]} [initialKeys] Keys that will be created if no data is provided. - * @property {MappingFieldInitialValueBuilder} [initialValue] Function to calculate the initial value for a key. - * @property {boolean} [initialKeysOnly=false] Should the keys in the initialized data be limited to the keys provided - * by `options.initialKeys`? - */ -export class MappingField extends foundry.data.fields.ObjectField { - constructor(model, options) { - if ( !(model instanceof foundry.data.fields.DataField) ) { - throw new Error("MappingField must have a DataField as its contained element"); - } - super(options); - - /** - * The embedded DataField definition which is contained in this field. - * @type {DataField} - */ - this.model = model; - model.parent = this; - } - - /* -------------------------------------------- */ - - /** @inheritDoc */ - static get _defaults() { - return foundry.utils.mergeObject(super._defaults, { - initialKeys: null, - initialValue: null, - initialKeysOnly: false - }); - } - - /* -------------------------------------------- */ - - /** @inheritDoc */ - _cleanType(value, options) { - Object.entries(value).forEach(([k, v]) => { - if ( k.startsWith("-=") ) return; - value[k] = this.model.clean(v, options); - }); - return value; - } - - /* -------------------------------------------- */ - - /** @inheritDoc */ - getInitialValue(data) { - let keys = this.initialKeys; - const initial = super.getInitialValue(data); - if ( !keys || !foundry.utils.isEmpty(initial) ) return initial; - if ( !(keys instanceof Array) ) keys = Object.keys(keys); - for ( const key of keys ) initial[key] = this._getInitialValueForKey(key); - return initial; - } - - /* -------------------------------------------- */ - - /** - * Get the initial value for the provided key. - * @param {string} key Key within the object being built. - * @param {object} [object] Any existing mapping data. - * @returns {*} Initial value based on provided field type. - */ - _getInitialValueForKey(key, object) { - const initial = this.model.getInitialValue(); - return this.initialValue?.(key, initial, object) ?? initial; - } - - /* -------------------------------------------- */ - - /** @override */ - _validateType(value, options={}) { - if ( foundry.utils.getType(value) !== "Object" ) throw new Error("must be an Object"); - const errors = this._validateValues(value, options); - if ( !foundry.utils.isEmpty(errors) ) { - const failure = new foundry.data.validation.DataModelValidationFailure(); - failure.elements = Object.entries(errors).map(([id, failure]) => ({ id, failure })); - throw failure.asError(); - } - } - - /* -------------------------------------------- */ - - /** - * Validate each value of the object. - * @param {object} value The object to validate. - * @param {object} options Validation options. - * @returns {Record} An object of value-specific errors by key. - */ - _validateValues(value, options) { - const errors = {}; - for ( const [k, v] of Object.entries(value) ) { - if ( k.startsWith("-=") ) continue; - const error = this.model.validate(v, options); - if ( error ) errors[k] = error; - } - return errors; - } - - /* -------------------------------------------- */ - - /** @override */ - initialize(value, model, options={}) { - if ( !value ) return value; - const obj = {}; - const initialKeys = (this.initialKeys instanceof Array) ? this.initialKeys : Object.keys(this.initialKeys ?? {}); - const keys = this.initialKeysOnly ? initialKeys : Object.keys(value); - for ( const key of keys ) { - const data = value[key] ?? this._getInitialValueForKey(key, value); - obj[key] = this.model.initialize(data, model, options); - } - return obj; - } - - /* -------------------------------------------- */ - - /** @inheritDoc */ - _getField(path) { - if ( path.length === 0 ) return this; - else if ( path.length === 1 ) return this.model; - path.shift(); - return this.model._getField(path); - } -} - -/* -------------------------------------------- */ - /** * Field that stores actions. */ diff --git a/module/data/fields/mappingField.mjs b/module/data/fields/mappingField.mjs new file mode 100644 index 00000000..83504536 --- /dev/null +++ b/module/data/fields/mappingField.mjs @@ -0,0 +1,128 @@ +/** + * A subclass of ObjectField that represents a mapping of keys to the provided DataField type. + * + * @param {DataField} model The class of DataField which should be embedded in this field. + * @param {MappingFieldOptions} [options={}] Options which configure the behavior of the field. + * @property {string[]} [initialKeys] Keys that will be created if no data is provided. + * @property {MappingFieldInitialValueBuilder} [initialValue] Function to calculate the initial value for a key. + * @property {boolean} [initialKeysOnly=false] Should the keys in the initialized data be limited to the keys provided + * by `options.initialKeys`? + */ +export default class MappingField extends foundry.data.fields.ObjectField { + constructor(model, options) { + if ( !(model instanceof foundry.data.fields.DataField) ) { + throw new Error("MappingField must have a DataField as its contained element"); + } + super(options); + + /** + * The embedded DataField definition which is contained in this field. + * @type {DataField} + */ + this.model = model; + model.parent = this; + } + + /* -------------------------------------------- */ + + /** @inheritDoc */ + static get _defaults() { + return foundry.utils.mergeObject(super._defaults, { + initialKeys: null, + initialValue: null, + initialKeysOnly: false + }); + } + + /* -------------------------------------------- */ + + /** @inheritDoc */ + _cleanType(value, options) { + Object.entries(value).forEach(([k, v]) => { + if ( k.startsWith("-=") ) return; + value[k] = this.model.clean(v, options); + }); + return value; + } + + /* -------------------------------------------- */ + + /** @inheritDoc */ + getInitialValue(data) { + let keys = this.initialKeys; + const initial = super.getInitialValue(data); + if ( !keys || !foundry.utils.isEmpty(initial) ) return initial; + if ( !(keys instanceof Array) ) keys = Object.keys(keys); + for ( const key of keys ) initial[key] = this._getInitialValueForKey(key); + return initial; + } + + /* -------------------------------------------- */ + + /** + * Get the initial value for the provided key. + * @param {string} key Key within the object being built. + * @param {object} [object] Any existing mapping data. + * @returns {*} Initial value based on provided field type. + */ + _getInitialValueForKey(key, object) { + const initial = this.model.getInitialValue(); + return this.initialValue?.(key, initial, object) ?? initial; + } + + /* -------------------------------------------- */ + + /** @override */ + _validateType(value, options={}) { + if ( foundry.utils.getType(value) !== "Object" ) throw new Error("must be an Object"); + const errors = this._validateValues(value, options); + if ( !foundry.utils.isEmpty(errors) ) { + const failure = new foundry.data.validation.DataModelValidationFailure(); + failure.elements = Object.entries(errors).map(([id, failure]) => ({ id, failure })); + throw failure.asError(); + } + } + + /* -------------------------------------------- */ + + /** + * Validate each value of the object. + * @param {object} value The object to validate. + * @param {object} options Validation options. + * @returns {Record} An object of value-specific errors by key. + */ + _validateValues(value, options) { + const errors = {}; + for ( const [k, v] of Object.entries(value) ) { + if ( k.startsWith("-=") ) continue; + const error = this.model.validate(v, options); + if ( error ) errors[k] = error; + } + return errors; + } + + /* -------------------------------------------- */ + + /** @override */ + initialize(value, model, options={}) { + if ( !value ) return value; + const obj = {}; + const initialKeys = (this.initialKeys instanceof Array) ? this.initialKeys : Object.keys(this.initialKeys ?? {}); + const keys = this.initialKeysOnly ? initialKeys : Object.keys(value); + for ( const key of keys ) { + const data = value[key] ?? this._getInitialValueForKey(key, value); + obj[key] = this.model.initialize(data, model, options); + } + return obj; + } + + /* -------------------------------------------- */ + + /** @inheritDoc */ + _getField(path) { + if ( path.length === 0 ) return this; + else if ( path.length === 1 ) return this.model; + path.shift(); + return this.model._getField(path); + } +} \ No newline at end of file diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 234b4303..f9e2ae1a 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -69,7 +69,7 @@ export default class DHWeapon extends AttachableItem { } get actionsList() { - return [this.attack, ...this.actions]; + return new Set([this.attack, ...this.actions]); } get customActions() { diff --git a/module/documents/item.mjs b/module/documents/item.mjs index fe72b5ab..a3cf8116 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -125,7 +125,7 @@ export default class DHItem extends foundry.documents.Item { async use(event) { const actions = this.system.actionsList; if (actions?.size) { - let action = actions.contents[0]; + let action = actions.first(0); if (actions.size > 1 && !event?.shiftKey) { // Actions Choice Dialog action = await this.selectActionDialog(event); diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 0c919191..9e769d2e 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -9,7 +9,8 @@ export default class RegisterHandlebarsHelpers { damageFormula: this.damageFormula, damageSymbols: this.damageSymbols, rollParsed: this.rollParsed, - hasProperty: foundry.utils.hasProperty + hasProperty: foundry.utils.hasProperty, + setVar: this.setVar }); } static add(a, b) { @@ -50,4 +51,8 @@ export default class RegisterHandlebarsHelpers { const result = itemAbleRollParse(value, actor, item); return isNumerical && !result ? 0 : result; } + + static setVar(name, value, context) { + this[name] = value; + } } diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 29a2c1dd..4c319ed5 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -346,6 +346,12 @@ &:has(.list-w-img) { gap: 0; } + + &.no-style { + border-width: 0; + margin: 0; + padding: 0; + } } .two-columns { diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index ad45fc33..9ae25e0e 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -4,90 +4,78 @@ {{localize "DAGGERHEART.GENERAL.damage"}} {{#unless (eq path 'system.attack.')}}{{/unless}} - {{#unless (or @root.isNPC path)}} - {{#if @root.hasBaseDamage}} - {{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase name="damage.includeBase" classes="checkbox" localize=true }} - {{/if}} - {{/unless}} + {{#if @root.hasBaseDamage}} + {{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase name="damage.includeBase" classes="checkbox" localize=true }} + {{/if}} {{#each source.parts as |dmg index|}} - {{#if (or @root.isNPC ../path)}} - {{formField ../fields.value.fields.custom.fields.enabled value=dmg.value.custom.enabled name=(concat ../path "damage.parts." index ".value.custom.enabled") classes="checkbox"}} - - {{#if dmg.value.custom.enabled}} - {{formField ../fields.value.fields.custom.fields.formula value=dmg.value.custom.formula name=(concat ../path "damage.parts." index ".value.custom.formula") localize=true}} - {{else}} -
- {{#if @root.isNPC}}{{formField ../fields.value.fields.flatMultiplier value=dmg.value.flatMultiplier name=(concat ../path "damage.parts." index ".value.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }}{{/if}} - {{formField ../fields.value.fields.dice value=dmg.value.dice name=(concat ../path "damage.parts." index ".value.dice") classes="inline-child"}} - {{formField ../fields.value.fields.bonus value=dmg.value.bonus name=(concat ../path "damage.parts." index ".value.bonus") localize=true classes="inline-child"}} -
- {{/if}} -
- {{formField ../fields.applyTo value=dmg.applyTo name=(concat ../path "damage.parts." realIndex ".applyTo") localize=true}} - {{#if (eq dmg.applyTo 'hitPoints')}} - {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." index ".type") localize=true}} - {{/if}} -
- {{#if ../horde}} -
- {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} -
- {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." index ".valueAlt.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }} - {{formField ../fields.valueAlt.fields.dice value=dmg.valueAlt.dice name=(concat ../path "damage.parts." index ".valueAlt.dice") classes="inline-child"}} - {{formField ../fields.valueAlt.fields.bonus value=dmg.valueAlt.bonus name=(concat ../path "damage.parts." index ".valueAlt.bonus") localize=true classes="inline-child"}} -
-
- {{/if}} + {{#if (and @root.hasBaseDamage @root.source.damage.includeBase)}} + {{setVar 'realIndex' (add index -1)}} {{else}} - {{#with (@root.getRealIndex index) as | realIndex |}} -
- - {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base))}} - {{formField ../../fields.resultBased value=dmg.resultBased name=(concat "damage.parts." realIndex ".resultBased") localize=true classes="checkbox"}} - {{/if}} - {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base) dmg.resultBased)}} -
-
- {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}} - {{> formula fields=../../fields.value.fields type=../../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}} -
-
- {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}} - {{> formula fields=../../fields.valueAlt.fields type=../../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" realIndex=realIndex}} -
-
- {{else}} - - {{> formula fields=../../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}} - - {{/if}} -
- {{formField ../../fields.applyTo value=dmg.applyTo name=(concat "damage.parts." realIndex ".applyTo") localize=true}} - {{#if (eq dmg.applyTo 'hitPoints')}} - {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} - {{/if}} -
- - - {{#unless dmg.base}}
{{/unless}} -
- {{/with}} + {{setVar 'realIndex' index}} {{/if}} +
+ + {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base))}} + {{formField ../fields.resultBased value=dmg.resultBased name=(concat "damage.parts." realIndex ".resultBased") localize=true classes="checkbox"}} + {{/if}} + {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base) dmg.resultBased)}} +
+
+ {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}} + {{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex path=../path}} +
+
+ {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}} + {{> formula fields=../fields.valueAlt.fields type=../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" realIndex=realIndex path=../path}} +
+
+ {{else}} + + {{localize "DAGGERHEART.GENERAL.formula"}} + {{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex path=../path}} + + {{/if}} +
+ {{formField ../fields.applyTo value=dmg.applyTo name=(concat ../path "damage.parts." realIndex ".applyTo") localize=true}} + {{#if (eq dmg.applyTo 'hitPoints')}} + {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." realIndex ".type") localize=true}} + {{/if}} +
+ {{#if ../horde}} +
+ {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} +
+ + {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." realIndex ".valueAlt.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }} + {{formField ../fields.valueAlt.fields.dice value=dmg.valueAlt.dice name=(concat ../path "damage.parts." realIndex ".valueAlt.dice") classes="inline-child"}} + {{formField ../fields.valueAlt.fields.bonus value=dmg.valueAlt.bonus name=(concat ../path "damage.parts." realIndex ".valueAlt.bonus") localize=true classes="inline-child"}} +
+
+ {{/if}} + + + {{#unless (or dmg.base ../path)}}
{{/unless}} +
{{/each}} {{#*inline "formula"}} {{#unless dmg.base}} - {{formField fields.custom.fields.enabled value=source.custom.enabled name=(concat "damage.parts." realIndex "." target ".custom.enabled") classes="checkbox"}} + {{formField fields.custom.fields.enabled value=source.custom.enabled name=(concat path "damage.parts." realIndex "." target ".custom.enabled") classes="checkbox"}} {{/unless}} {{#if source.custom.enabled}} - {{formField fields.custom.fields.formula value=source.custom.formula name=(concat "damage.parts." realIndex "." target ".custom.formula") localize=true}} + {{formField fields.custom.fields.formula value=source.custom.formula name=(concat path "damage.parts." realIndex "." target ".custom.formula") localize=true}} {{else}}
- {{formField fields.multiplier value=source.multiplier name=(concat "damage.parts." realIndex "." target ".multiplier") localize=true}} - {{#if (eq source.multiplier 'flat')}}{{formField fields.flatMultiplier value=source.flatMultiplier name=(concat "damage.parts." realIndex ".flatMultiplier") }}{{/if}} - {{formField fields.dice value=source.dice name=(concat "damage.parts." realIndex "." target ".dice")}} - {{formField fields.bonus value=source.bonus name=(concat "damage.parts." realIndex "." target ".bonus") localize=true}} + {{#unless @root.isNPC}} + {{formField fields.multiplier value=source.multiplier name=(concat path "damage.parts." realIndex "." target ".multiplier") localize=true}} + {{/unless}} + {{#if (eq source.multiplier 'flat')}}{{formField fields.flatMultiplier value=source.flatMultiplier name=(concat ../path "damage.parts." realIndex "." target ".flatMultiplier") }}{{/if}} + {{formField fields.dice value=source.dice name=(concat path "damage.parts." realIndex "." target ".dice")}} + {{formField fields.bonus value=source.bonus name=(concat path "damage.parts." realIndex "." target ".bonus") localize=true}}
{{/if}} + {{#if @root.isNPC}} + + {{/if}} {{/inline}} \ No newline at end of file diff --git a/templates/sheets-settings/adversary-settings/attack.hbs b/templates/sheets-settings/adversary-settings/attack.hbs index bdb6da5b..a51128a1 100644 --- a/templates/sheets-settings/adversary-settings/attack.hbs +++ b/templates/sheets-settings/adversary-settings/attack.hbs @@ -19,7 +19,5 @@ {{/if}} {{/if}} - {{#if (eq document.system.type 'horde')}} - {{> 'systems/daggerheart/templates/actionTypes/damage.hbs' fields=systemFields.attack.fields.damage.fields.parts.element.fields source=document.system.attack.damage path="system.attack." horde=true}} - {{/if}} + {{> 'systems/daggerheart/templates/actionTypes/damage.hbs' fields=systemFields.attack.fields.damage.fields.parts.element.fields source=document.system.attack.damage path="system.attack." horde=(eq document.system.type 'horde')}} \ No newline at end of file