mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 06:26:13 +01:00
Initial
This commit is contained in:
parent
340abbc98c
commit
ef128b88eb
19 changed files with 80 additions and 203 deletions
|
|
@ -220,7 +220,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
!roll.system.isCritical && criticalRoll
|
!roll.system.isCritical && criticalRoll
|
||||||
? (await getCritDamageBonus(damage.formula)) + damage.total
|
? (await getCritDamageBonus(damage.formula)) + damage.total
|
||||||
: damage.total;
|
: damage.total;
|
||||||
const updatedDamageParts = damage.parts;
|
const updatedDamageParts = Object.values(damage.parts);
|
||||||
if (systemData.damage[key]) {
|
if (systemData.damage[key]) {
|
||||||
if (!roll.system.isCritical && criticalRoll) {
|
if (!roll.system.isCritical && criticalRoll) {
|
||||||
for (let part of updatedDamageParts) {
|
for (let part of updatedDamageParts) {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ export default class DhCompanionLevelUp extends BaseLevelUp {
|
||||||
break;
|
break;
|
||||||
case 'summary':
|
case 'summary':
|
||||||
const levelKeys = Object.keys(this.levelup.levels);
|
const levelKeys = Object.keys(this.levelup.levels);
|
||||||
const actorDamageDice = this.actor.system.attack.damage.parts[0].value.dice;
|
const actorDamageDice = this.actor.system.attack.damage.parts.hitPoints.value.dice;
|
||||||
const actorRange = this.actor.system.attack.range;
|
const actorRange = this.actor.system.attack.range;
|
||||||
|
|
||||||
let achievementExperiences = [];
|
let achievementExperiences = [];
|
||||||
|
|
|
||||||
|
|
@ -499,7 +499,8 @@ export default function DHApplicationMixin(Base) {
|
||||||
icon: 'fa-solid fa-explosion',
|
icon: 'fa-solid fa-explosion',
|
||||||
condition: target => {
|
condition: target => {
|
||||||
const doc = getDocFromElementSync(target);
|
const doc = getDocFromElementSync(target);
|
||||||
return doc?.system?.attack?.damage.parts.length || doc?.damage?.parts.length;
|
const damageData = doc?.system?.attack?.damage ?? doc?.damage;
|
||||||
|
return !foundry.utils.isEmpty(damageData?.parts);
|
||||||
},
|
},
|
||||||
callback: async (target, event) => {
|
callback: async (target, event) => {
|
||||||
const doc = await getDocFromElement(target),
|
const doc = await getDocFromElement(target),
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export default class DHAttackAction extends DHDamageAction {
|
||||||
if (!!this.item?.system?.attack) {
|
if (!!this.item?.system?.attack) {
|
||||||
if (this.damage.includeBase) {
|
if (this.damage.includeBase) {
|
||||||
const baseDamage = this.getParentDamage();
|
const baseDamage = this.getParentDamage();
|
||||||
this.damage.parts.unshift(new DHDamageData(baseDamage));
|
this.damage.hitPoints = new DHDamageData(baseDamage);
|
||||||
}
|
}
|
||||||
if (this.roll.useDefault) {
|
if (this.roll.useDefault) {
|
||||||
this.roll.trait = this.item.system.attack.roll.trait;
|
this.roll.trait = this.item.system.attack.roll.trait;
|
||||||
|
|
@ -26,23 +26,16 @@ export default class DHAttackAction extends DHDamageAction {
|
||||||
return {
|
return {
|
||||||
value: {
|
value: {
|
||||||
multiplier: 'prof',
|
multiplier: 'prof',
|
||||||
dice: this.item?.system?.attack.damage.parts[0].value.dice,
|
dice: this.item?.system?.attack.damage.parts.hitPoints.value.dice,
|
||||||
bonus: this.item?.system?.attack.damage.parts[0].value.bonus ?? 0
|
bonus: this.item?.system?.attack.damage.parts.hitPoints.value.bonus ?? 0
|
||||||
},
|
},
|
||||||
type: this.item?.system?.attack.damage.parts[0].type,
|
type: this.item?.system?.attack.damage.parts.hitPoints.type,
|
||||||
base: true
|
base: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get damageFormula() {
|
|
||||||
const hitPointsPart = this.damage.parts.find(x => x.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id);
|
|
||||||
if (!hitPointsPart) return '0';
|
|
||||||
|
|
||||||
return hitPointsPart.value.getFormula();
|
|
||||||
}
|
|
||||||
|
|
||||||
get altDamageFormula() {
|
get altDamageFormula() {
|
||||||
const hitPointsPart = this.damage.parts.find(x => x.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id);
|
const hitPointsPart = this.damage.parts.hitPoints;
|
||||||
if (!hitPointsPart) return '0';
|
if (!hitPointsPart) return '0';
|
||||||
|
|
||||||
return hitPointsPart.valueAlt.getFormula();
|
return hitPointsPart.valueAlt.getFormula();
|
||||||
|
|
@ -72,7 +65,7 @@ export default class DHAttackAction extends DHDamageAction {
|
||||||
if (range) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`));
|
if (range) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`));
|
||||||
|
|
||||||
const useAltDamage = this.actor?.effects?.find(x => x.type === 'horde')?.active;
|
const useAltDamage = this.actor?.effects?.find(x => x.type === 'horde')?.active;
|
||||||
for (const { value, valueAlt, type } of damage.parts) {
|
for (const { value, valueAlt, type } of Object.values(damage.parts)) {
|
||||||
const usedValue = useAltDamage ? valueAlt : value;
|
const usedValue = useAltDamage ? valueAlt : value;
|
||||||
const str = Roll.replaceFormulaData(usedValue.getFormula(), this.actor?.getRollData() ?? {});
|
const str = Roll.replaceFormulaData(usedValue.getFormula(), this.actor?.getRollData() ?? {});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -352,11 +352,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasDamage() {
|
get hasDamage() {
|
||||||
return this.damage?.parts?.length && this.type !== 'healing';
|
return !foundry.utils.isEmpty(this.damage?.parts) && this.type !== 'healing';
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasHealing() {
|
get hasHealing() {
|
||||||
return this.damage?.parts?.length && this.type === 'healing';
|
return !foundry.utils.isEmpty(this.damage?.parts) && this.type === 'healing';
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasSave() {
|
get hasSave() {
|
||||||
|
|
@ -376,6 +376,15 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static migrateData(source) {
|
||||||
|
if (source.damage?.parts && Array.isArray(source.damage.parts)) {
|
||||||
|
source.damage.parts = source.damage.parts.reduce((acc, part) => {
|
||||||
|
acc[part.applyTo] = part;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResourceUpdateMap extends Map {
|
export class ResourceUpdateMap extends Map {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export default class DHDamageAction extends DHBaseAction {
|
||||||
*/
|
*/
|
||||||
getDamageFormula() {
|
getDamageFormula() {
|
||||||
const strings = [];
|
const strings = [];
|
||||||
for (const { value } of this.damage.parts) {
|
for (const { value } of Object.values(this.damage.parts)) {
|
||||||
strings.push(Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {}));
|
strings.push(Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,14 +89,14 @@ export default class DhpAdversary extends DhCreature {
|
||||||
type: 'attack'
|
type: 'attack'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: {
|
||||||
{
|
hitPoints: {
|
||||||
type: ['physical'],
|
type: ['physical'],
|
||||||
value: {
|
value: {
|
||||||
multiplier: 'flat'
|
multiplier: 'flat'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -374,13 +374,9 @@ export default class DhpAdversary extends DhCreature {
|
||||||
* @returns the converted formula and value as a simplified term
|
* @returns the converted formula and value as a simplified term
|
||||||
*/
|
*/
|
||||||
#adjustActionDamage(action, damageMeta) {
|
#adjustActionDamage(action, damageMeta) {
|
||||||
// The current algorithm only returns a value if there is a single damage part
|
|
||||||
const hpDamageParts = action.damage.parts.filter(d => d.applyTo === 'hitPoints');
|
|
||||||
if (hpDamageParts.length !== 1) throw new Error('incorrect number of hp parts');
|
|
||||||
|
|
||||||
const result = {};
|
const result = {};
|
||||||
for (const property of ['value', 'valueAlt']) {
|
for (const property of ['value', 'valueAlt']) {
|
||||||
const data = hpDamageParts[0][property];
|
const data = action.damage.parts.hitPoints[property];
|
||||||
const previousFormula = data.custom.enabled
|
const previousFormula = data.custom.enabled
|
||||||
? data.custom.formula
|
? data.custom.formula
|
||||||
: [data.flatMultiplier ? `${data.flatMultiplier}${data.dice}` : 0, data.bonus ?? 0]
|
: [data.flatMultiplier ? `${data.flatMultiplier}${data.dice}` : 0, data.bonus ?? 0]
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,8 @@ export default class DhCharacter extends DhCreature {
|
||||||
trait: 'strength'
|
trait: 'strength'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: {
|
||||||
{
|
hitPoints: {
|
||||||
type: ['physical'],
|
type: ['physical'],
|
||||||
value: {
|
value: {
|
||||||
custom: {
|
custom: {
|
||||||
|
|
@ -128,7 +128,7 @@ export default class DhCharacter extends DhCreature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -704,7 +704,7 @@ export default class DhCharacter extends DhCreature {
|
||||||
isReversed: true
|
isReversed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
this.attack.damage.parts[0].value.custom.formula = `@prof${this.basicAttackDamageDice}${this.rules.attack.damage.bonus ? ` + ${this.rules.attack.damage.bonus}` : ''}`;
|
this.attack.damage.parts.hitPoints.value.custom.formula = `@prof${this.basicAttackDamageDice}${this.rules.attack.damage.bonus ? ` + ${this.rules.attack.damage.bonus}` : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRollData() {
|
getRollData() {
|
||||||
|
|
|
||||||
|
|
@ -85,15 +85,15 @@ export default class DhCompanion extends DhCreature {
|
||||||
bonus: 0
|
bonus: 0
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: {
|
||||||
{
|
hitPoints: {
|
||||||
type: ['physical'],
|
type: ['physical'],
|
||||||
value: {
|
value: {
|
||||||
dice: 'd6',
|
dice: 'd6',
|
||||||
multiplier: 'prof'
|
multiplier: 'prof'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -138,7 +138,9 @@ export default class DhCompanion extends DhCreature {
|
||||||
break;
|
break;
|
||||||
case 'vicious':
|
case 'vicious':
|
||||||
if (selection.data[0] === 'damage') {
|
if (selection.data[0] === 'damage') {
|
||||||
this.attack.damage.parts[0].value.dice = adjustDice(this.attack.damage.parts[0].value.dice);
|
this.attack.damage.parts.hitPoints.value.dice = adjustDice(
|
||||||
|
this.attack.damage.parts.hitPoints.value.dice
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.attack.range = adjustRange(this.attack.range).id;
|
this.attack.range = adjustRange(this.attack.range).id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,4 @@ export { default as FormulaField } from './formulaField.mjs';
|
||||||
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
||||||
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
||||||
export { default as TriggerField } from './triggerField.mjs';
|
export { default as TriggerField } from './triggerField.mjs';
|
||||||
export { default as MappingField } from './mappingField.mjs';
|
|
||||||
export * as ActionFields from './action/_module.mjs';
|
export * as ActionFields from './action/_module.mjs';
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export default class DamageField extends fields.SchemaField {
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
constructor(options, context = {}) {
|
constructor(options, context = {}) {
|
||||||
const damageFields = {
|
const damageFields = {
|
||||||
parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData)),
|
parts: new DHDamageField(new fields.EmbeddedDataField(DHDamageData)),
|
||||||
includeBase: new fields.BooleanField({
|
includeBase: new fields.BooleanField({
|
||||||
initial: false,
|
initial: false,
|
||||||
label: 'DAGGERHEART.ACTIONS.Settings.includeBase.label'
|
label: 'DAGGERHEART.ACTIONS.Settings.includeBase.label'
|
||||||
|
|
@ -38,7 +38,7 @@ export default class DamageField extends fields.SchemaField {
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let formulas = this.damage.parts.map(p => ({
|
let formulas = Object.values(this.damage.parts).map(p => ({
|
||||||
formula: DamageField.getFormulaValue.call(this, p, config).getFormula(this.actor),
|
formula: DamageField.getFormulaValue.call(this, p, config).getFormula(this.actor),
|
||||||
damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type,
|
damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type,
|
||||||
applyTo: p.applyTo
|
applyTo: p.applyTo
|
||||||
|
|
@ -300,3 +300,6 @@ export class DHDamageData extends DHResourceData {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Could be expanded to constrain the object keys to only correct ones */
|
||||||
|
class DHDamageField extends fields.TypedObjectField {}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import DHActionConfig from '../../applications/sheets-configs/action-config.mjs';
|
import DHActionConfig from '../../applications/sheets-configs/action-config.mjs';
|
||||||
import { itemAbleRollParse } from '../../helpers/utils.mjs';
|
import { itemAbleRollParse } from '../../helpers/utils.mjs';
|
||||||
import MappingField from './mappingField.mjs';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized collection type for stored actions.
|
* Specialized collection type for stored actions.
|
||||||
|
|
@ -61,7 +60,7 @@ export class ActionCollection extends Collection {
|
||||||
/**
|
/**
|
||||||
* Field that stores actions.
|
* Field that stores actions.
|
||||||
*/
|
*/
|
||||||
export class ActionsField extends MappingField {
|
export class ActionsField extends foundry.data.fields.TypedObjectField {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(new ActionField(), options);
|
super(new ActionField(), options);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -65,15 +65,15 @@ export default class DHWeapon extends AttachableItem {
|
||||||
type: 'attack'
|
type: 'attack'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: {
|
||||||
{
|
hitPoints: {
|
||||||
type: ['physical'],
|
type: ['physical'],
|
||||||
value: {
|
value: {
|
||||||
multiplier: 'prof',
|
multiplier: 'prof',
|
||||||
dice: 'd8'
|
dice: 'd8'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -117,7 +117,10 @@ export default class DHWeapon extends AttachableItem {
|
||||||
const tier = game.i18n.localize(`DAGGERHEART.GENERAL.Tiers.${this.tier}`);
|
const tier = game.i18n.localize(`DAGGERHEART.GENERAL.Tiers.${this.tier}`);
|
||||||
const trait = game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.attack.roll.trait].label);
|
const trait = game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.attack.roll.trait].label);
|
||||||
const range = game.i18n.localize(`DAGGERHEART.CONFIG.Range.${this.attack.range}.name`);
|
const range = game.i18n.localize(`DAGGERHEART.CONFIG.Range.${this.attack.range}.name`);
|
||||||
const damage = Roll.replaceFormulaData(this.attack.damageFormula, this.parent.parent ?? this.parent);
|
const damage = Roll.replaceFormulaData(
|
||||||
|
this.attack.damage.parts.hitPoints.value.getFormula(),
|
||||||
|
this.parent.parent ?? this.parent
|
||||||
|
);
|
||||||
const burden = game.i18n.localize(CONFIG.DH.GENERAL.burden[this.burden].label);
|
const burden = game.i18n.localize(CONFIG.DH.GENERAL.burden[this.burden].label);
|
||||||
|
|
||||||
const allFeatures = CONFIG.DH.ITEM.allWeaponFeatures();
|
const allFeatures = CONFIG.DH.ITEM.allWeaponFeatures();
|
||||||
|
|
@ -232,7 +235,7 @@ export default class DHWeapon extends AttachableItem {
|
||||||
game.i18n.localize(`DAGGERHEART.CONFIG.Burden.${burden}`)
|
game.i18n.localize(`DAGGERHEART.CONFIG.Burden.${burden}`)
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const { value, type } of attack.damage.parts) {
|
for (const { value, type } of Object.values(attack.damage.parts)) {
|
||||||
const parts = value.custom.enabled ? [game.i18n.localize('DAGGERHEART.GENERAL.custom')] : [value.dice];
|
const parts = value.custom.enabled ? [game.i18n.localize('DAGGERHEART.GENERAL.custom')] : [value.dice];
|
||||||
if (!value.custom.enabled && value.bonus) parts.push(value.bonus.signedString());
|
if (!value.custom.enabled && value.bonus) parts.push(value.bonus.signedString());
|
||||||
|
|
||||||
|
|
@ -260,7 +263,7 @@ export default class DHWeapon extends AttachableItem {
|
||||||
if (roll.trait) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`));
|
if (roll.trait) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`));
|
||||||
if (range) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`));
|
if (range) labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`));
|
||||||
|
|
||||||
for (const { value, type } of damage.parts) {
|
for (const { value, type } of Object.values(damage.parts)) {
|
||||||
const str = Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {});
|
const str = Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {});
|
||||||
|
|
||||||
const icons = Array.from(type)
|
const icons = Array.from(type)
|
||||||
|
|
|
||||||
|
|
@ -596,7 +596,7 @@ export default class DhpActor extends Actor {
|
||||||
const updates = [];
|
const updates = [];
|
||||||
|
|
||||||
Object.entries(damages).forEach(([key, damage]) => {
|
Object.entries(damages).forEach(([key, damage]) => {
|
||||||
damage.parts.forEach(part => {
|
Object.values(damage.parts).forEach(part => {
|
||||||
if (part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id)
|
if (part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id)
|
||||||
part.total = this.calculateDamage(part.total, part.damageTypes);
|
part.total = this.calculateDamage(part.total, part.damageTypes);
|
||||||
const update = updates.find(u => u.key === key);
|
const update = updates.find(u => u.key === key);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export default class RegisterHandlebarsHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
static damageFormula(attack) {
|
static damageFormula(attack) {
|
||||||
return attack.getDamageFormula();
|
return attack.damage.hitPoints?.value?.getFormula?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
static formulaValue(formula, item) {
|
static formulaValue(formula, item) {
|
||||||
|
|
@ -49,7 +49,7 @@ export default class RegisterHandlebarsHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
static damageSymbols(damageParts) {
|
static damageSymbols(damageParts) {
|
||||||
const symbols = [...new Set(damageParts.reduce((a, c) => a.concat([...c.type]), []))].map(
|
const symbols = [...new Set(Object.values(damageParts).reduce((a, c) => a.concat([...c.type]), []))].map(
|
||||||
p => CONFIG.DH.GENERAL.damageTypes[p].icon
|
p => CONFIG.DH.GENERAL.damageTypes[p].icon
|
||||||
);
|
);
|
||||||
return new Handlebars.SafeString(Array.from(symbols).map(symbol => `<i class="fa-solid ${symbol}"></i>`));
|
return new Handlebars.SafeString(Array.from(symbols).map(symbol => `<i class="fa-solid ${symbol}"></i>`));
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
{{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}}
|
{{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}}
|
||||||
{{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}}
|
{{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}}
|
||||||
<span> - </span>
|
<span> - </span>
|
||||||
{{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}}
|
{{item.system.attack.damage.parts.hitPoints.value.dice}}{{#if item.system.attack.damage.parts.hitPoints.value.bonus}} + {{item.system.attack.damage.parts.hitPoints.value.bonus}}{{/if}}
|
||||||
{{#each item.system.attack.damage.parts.0.type as | type | }}
|
{{#each item.system.attack.damage.parts.hitPoints.type as | type | }}
|
||||||
{{#with (lookup @root.config.GENERAL.damageTypes type)}}
|
{{#with (lookup @root.config.GENERAL.damageTypes type)}}
|
||||||
<i class="fa-solid {{icon}}"></i>
|
<i class="fa-solid {{icon}}"></i>
|
||||||
{{/with}}
|
{{/with}}
|
||||||
|
|
@ -31,9 +31,9 @@
|
||||||
{{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}}
|
{{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}}
|
||||||
</div>
|
</div>
|
||||||
<div class="tag">
|
<div class="tag">
|
||||||
{{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}}
|
{{item.system.attack.damage.parts.hitPoints.value.dice}}{{#if item.system.attack.damage.parts.hitPoints.value.bonus}} + {{item.system.attack.damage.parts.hitPoints.value.bonus}}{{/if}}
|
||||||
(
|
(
|
||||||
{{#each item.system.attack.damage.parts.0.type}}
|
{{#each item.system.attack.damage.parts.hitPoints.type}}
|
||||||
{{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}}
|
{{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
{{localize (concat 'DAGGERHEART.CONFIG.Range.' source.system.attack.range '.name')}}
|
{{localize (concat 'DAGGERHEART.CONFIG.Range.' source.system.attack.range '.name')}}
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
{{#if source.system.attack.damage.parts.0.value.custom.enabled}}
|
{{#if source.system.attack.damage.parts.hitPoints.value.custom.enabled}}
|
||||||
{{localize "DAGGERHEART.GENERAL.custom"}}
|
{{localize "DAGGERHEART.GENERAL.custom"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{source.system.attack.damage.parts.0.value.dice}}{{#if source.system.attack.damage.parts.0.value.bonus}} + {{source.system.attack.damage.parts.0.value.bonus}}{{/if}}
|
{{source.system.attack.damage.parts.hitPoints.value.dice}}{{#if source.system.attack.damage.parts.hitPoints.value.bonus}} + {{source.system.attack.damage.parts.hitPoints.value.bonus}}{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
(
|
(
|
||||||
{{#each source.system.attack.damage.parts.0.type}}
|
{{#each source.system.attack.damage.parts.hitPoints.type}}
|
||||||
{{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}}
|
{{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,25 +19,25 @@
|
||||||
|
|
||||||
<fieldset class="two-columns">
|
<fieldset class="two-columns">
|
||||||
{{#with systemFields.attack.fields.damage.fields.parts.element.fields as | fields | }}
|
{{#with systemFields.attack.fields.damage.fields.parts.element.fields as | fields | }}
|
||||||
{{#with (lookup ../document.system.attack.damage.parts 0) as | source | }}
|
{{#with ../document.system.attack.damage.parts.hitPoints as | source | }}
|
||||||
<legend>{{localize "DAGGERHEART.GENERAL.damage"}}</legend>
|
<legend>{{localize "DAGGERHEART.GENERAL.damage"}}</legend>
|
||||||
<span>{{localize "DAGGERHEART.ACTIONS.Config.general.customFormula"}}</span>
|
<span>{{localize "DAGGERHEART.ACTIONS.Config.general.customFormula"}}</span>
|
||||||
{{formInput fields.value.fields.custom.fields.enabled value=source.value.custom.enabled name="system.attack.damage.parts.0.value.custom.enabled"}}
|
{{formInput fields.value.fields.custom.fields.enabled value=source.value.custom.enabled name="system.attack.damage.parts.hitPoints.value.custom.enabled"}}
|
||||||
{{#if source.value.custom.enabled}}
|
{{#if source.value.custom.enabled}}
|
||||||
<span>{{localize "DAGGERHEART.ACTIONS.Config.general.formula"}}</span>
|
<span>{{localize "DAGGERHEART.ACTIONS.Config.general.formula"}}</span>
|
||||||
{{formInput fields.value.fields.custom.fields.formula value=source.value.custom.formula name="system.attack.damage.parts.0.value.custom.formula"}}
|
{{formInput fields.value.fields.custom.fields.formula value=source.value.custom.formula name="system.attack.damage.parts.hitPoints.value.custom.formula"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.Dice.single"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.Dice.single"}}</span>
|
||||||
{{formInput fields.value.fields.dice value=source.value.dice name="system.attack.damage.parts.0.value.dice"}}
|
{{formInput fields.value.fields.dice value=source.value.dice name="system.attack.damage.parts.hitPoints.value.dice"}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.bonus"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.bonus"}}</span>
|
||||||
{{formInput fields.value.fields.bonus value=source.value.bonus name="system.attack.damage.parts.0.value.bonus" localize=true}}
|
{{formInput fields.value.fields.bonus value=source.value.bonus name="system.attack.damage.parts.hitPoints.value.bonus" localize=true}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.type"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.type"}}</span>
|
||||||
{{formInput fields.type value=source.type name="system.attack.damage.parts.0.type" localize=true}}
|
{{formInput fields.type value=source.type name="system.attack.damage.parts.hitPoints.type" localize=true}}
|
||||||
<span>{{localize "DAGGERHEART.CONFIG.DamageType.direct.name"}}</span>
|
<span>{{localize "DAGGERHEART.CONFIG.DamageType.direct.name"}}</span>
|
||||||
{{formInput @root.systemFields.attack.fields.damage.fields.direct value=@root.document.system.attack.damage.direct name="system.attack.damage.direct" localize=true}}
|
{{formInput @root.systemFields.attack.fields.damage.fields.direct value=@root.document.system.attack.damage.direct name="system.attack.damage.direct" localize=true}}
|
||||||
<input type="hidden" name="system.attack.damage.parts.0.value.multiplier" value="{{source.value.multiplier}}">
|
<input type="hidden" name="system.attack.damage.parts.hitPoints.value.multiplier" value="{{source.value.multiplier}}">
|
||||||
{{/with}}
|
{{/with}}
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="two-columns">
|
<fieldset class="two-columns">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue