This commit is contained in:
Dapoolp 2025-07-24 15:28:43 +02:00
parent 17dd9b1f61
commit 479e147640
25 changed files with 339 additions and 289 deletions

View file

@ -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) });
}

View file

@ -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 })
}
];

View file

@ -46,8 +46,4 @@ export default class DHAttackAction extends DHDamageAction {
return result;
}
// get modifiers() {
// return [];
// }
}

View file

@ -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;
}

View file

View file

@ -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';

View file

@ -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';

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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<string, Error>} 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.
*/

View file

@ -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<string, Error>} 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);
}
}

View file

@ -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() {

View file

@ -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);

View file

@ -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;
}
}

View file

@ -346,6 +346,12 @@
&:has(.list-w-img) {
gap: 0;
}
&.no-style {
border-width: 0;
margin: 0;
padding: 0;
}
}
.two-columns {

View file

@ -4,90 +4,78 @@
{{localize "DAGGERHEART.GENERAL.damage"}}
{{#unless (eq path 'system.attack.')}}<a><i class="fa-solid fa-plus icon-button" data-action="addDamage"></i></a>{{/unless}}
</legend>
{{#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"}}
<input type="hidden" name="{{../path}}damage.parts.{{index}}.value.multiplier" value="{{dmg.value.multiplier}}">
{{#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}}
<div class="nest-inputs">
{{#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"}}
</div>
{{/if}}
<div class="nest-inputs">
{{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}}
</div>
{{#if ../horde}}
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}}</legend>
<div class="nest-inputs">
{{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"}}
</div>
</fieldset>
{{/if}}
{{#if (and @root.hasBaseDamage @root.source.damage.includeBase)}}
{{setVar 'realIndex' (add index -1)}}
{{else}}
{{#with (@root.getRealIndex index) as | realIndex |}}
<div class="nest-inputs">
<fieldset{{#if dmg.base}} disabled{{/if}} class="one-column">
{{#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)}}
<div class="nest-inputs">
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}}</legend>
{{> formula fields=../../fields.value.fields type=../../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}}
</fieldset>
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}}</legend>
{{> formula fields=../../fields.valueAlt.fields type=../../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" realIndex=realIndex}}
</fieldset>
</div>
{{else}}
<fieldset{{#if dmg.base}} disabled{{/if}} class="one-column">
{{> formula fields=../../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}}
</fieldset>
{{/if}}
<div class="nest-inputs">
{{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}}
</div>
<input type="hidden" name="damage.parts.{{realIndex}}.base" value="{{dmg.base}}">
</fieldset>
{{#unless dmg.base}}<div class="fas fa-trash" data-action="removeDamage" data-index="{{realIndex}}"></div>{{/unless}}
</div>
{{/with}}
{{setVar 'realIndex' index}}
{{/if}}
<div class="nest-inputs">
<fieldset{{#if dmg.base}} disabled{{/if}} class="one-column{{#if ../path}} no-style{{/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)}}
<div class="nest-inputs">
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}}</legend>
{{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex path=../path}}
</fieldset>
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}}</legend>
{{> formula fields=../fields.valueAlt.fields type=../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" realIndex=realIndex path=../path}}
</fieldset>
</div>
{{else}}
<fieldset{{#if dmg.base}} disabled{{/if}} class="one-column">
<legend>{{localize "DAGGERHEART.GENERAL.formula"}}</legend>
{{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex path=../path}}
</fieldset>
{{/if}}
<div class="nest-inputs">
{{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}}
</div>
{{#if ../horde}}
<fieldset class="one-column">
<legend>{{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}}</legend>
<div class="nest-inputs">
<input type="hidden" name="{{../path}}damage.parts.{{realIndex}}.valueAlt.multiplier" value="flat">
{{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"}}
</div>
</fieldset>
{{/if}}
<input type="hidden" name="damage.parts.{{realIndex}}.base" value="{{dmg.base}}">
</fieldset>
{{#unless (or dmg.base ../path)}}<div class="fas fa-trash" data-action="removeDamage" data-index="{{realIndex}}"></div>{{/unless}}
</div>
{{/each}}
</fieldset>
{{#*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}}
<div class="nest-inputs">
{{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}}
</div>
{{/if}}
{{#if @root.isNPC}}
<input type="hidden" name="{{path}}damage.parts.{{realIndex}}.{{target}}.multiplier" value="flat">
{{/if}}
{{/inline}}

View file

@ -19,7 +19,5 @@
{{/if}}
{{/if}}
</fieldset>
{{#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')}}
</section>