mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 06:26:13 +01:00
More
This commit is contained in:
parent
5113e37574
commit
c99a76f4f4
15 changed files with 78 additions and 67 deletions
|
|
@ -67,7 +67,7 @@ export default class DhCompanionLevelUp extends BaseLevelUp {
|
|||
break;
|
||||
case 'summary':
|
||||
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;
|
||||
|
||||
let achievementExperiences = [];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { getNextUnusedDamageType } from '../../helpers/utils.mjs';
|
||||
import DaggerheartSheet from '../sheets/daggerheart-sheet.mjs';
|
||||
|
||||
const { ApplicationV2 } = foundry.applications.api;
|
||||
|
|
@ -268,10 +269,11 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
|
||||
static addDamage(_event) {
|
||||
if (!this.action.damage.parts) return;
|
||||
const data = this.action.toObject(),
|
||||
part = {};
|
||||
const data = this.action.toObject();
|
||||
const type = getNextUnusedDamageType(this.action.damage.parts);
|
||||
const part = { applyTo: type };
|
||||
if (this.action.actor?.isNPC) part.value = { multiplier: 'flat' };
|
||||
data.damage.parts.push(part);
|
||||
data.damage.parts[type] = part;
|
||||
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -499,7 +499,10 @@ export default function DHApplicationMixin(Base) {
|
|||
icon: 'fa-solid fa-explosion',
|
||||
condition: target => {
|
||||
const doc = getDocFromElementSync(target);
|
||||
return doc?.system?.attack?.damage.parts.length || doc?.damage?.parts.length;
|
||||
return (
|
||||
!foundry.utils.isEmpty(doc?.system?.attack?.damage.parts) ||
|
||||
!foundry.utils.isEmpty(doc?.damage?.parts)
|
||||
);
|
||||
},
|
||||
callback: async (target, event) => {
|
||||
const doc = await getDocFromElement(target),
|
||||
|
|
|
|||
|
|
@ -26,23 +26,23 @@ export default class DHAttackAction extends DHDamageAction {
|
|||
return {
|
||||
value: {
|
||||
multiplier: 'prof',
|
||||
dice: this.item?.system?.attack.damage.parts[0].value.dice,
|
||||
bonus: this.item?.system?.attack.damage.parts[0].value.bonus ?? 0
|
||||
dice: this.item?.system?.attack.damage.parts.hitPoints.value.dice,
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
get damageFormula() {
|
||||
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';
|
||||
|
||||
return hitPointsPart.value.getFormula();
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
return hitPointsPart.valueAlt.getFormula();
|
||||
|
|
|
|||
|
|
@ -352,11 +352,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
}
|
||||
|
||||
get hasDamage() {
|
||||
return this.damage?.parts?.length && this.type !== 'healing';
|
||||
return !foundry.utils.isEmpty(this.damage.parts) && this.type !== 'healing';
|
||||
}
|
||||
|
||||
get hasHealing() {
|
||||
return this.damage?.parts?.length && this.type === 'healing';
|
||||
return !foundry.utils.isEmpty(this.damage.parts) && this.type === 'healing';
|
||||
}
|
||||
|
||||
get hasSave() {
|
||||
|
|
|
|||
|
|
@ -89,14 +89,14 @@ export default class DhpAdversary extends DhCreature {
|
|||
type: 'attack'
|
||||
},
|
||||
damage: {
|
||||
parts: [
|
||||
{
|
||||
parts: {
|
||||
hitPoints: {
|
||||
type: ['physical'],
|
||||
value: {
|
||||
multiplier: 'flat'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
@ -374,13 +374,9 @@ export default class DhpAdversary extends DhCreature {
|
|||
* @returns the converted formula and value as a simplified term
|
||||
*/
|
||||
#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 = {};
|
||||
for (const property of ['value', 'valueAlt']) {
|
||||
const data = hpDamageParts[0][property];
|
||||
const data = action.damage.parts.hitPoints[property];
|
||||
const previousFormula = data.custom.enabled
|
||||
? data.custom.formula
|
||||
: [data.flatMultiplier ? `${data.flatMultiplier}${data.dice}` : 0, data.bonus ?? 0]
|
||||
|
|
|
|||
|
|
@ -118,8 +118,8 @@ export default class DhCharacter extends DhCreature {
|
|||
trait: 'strength'
|
||||
},
|
||||
damage: {
|
||||
parts: [
|
||||
{
|
||||
parts: {
|
||||
hitPoints: {
|
||||
type: ['physical'],
|
||||
value: {
|
||||
custom: {
|
||||
|
|
@ -128,7 +128,7 @@ export default class DhCharacter extends DhCreature {
|
|||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -85,15 +85,15 @@ export default class DhCompanion extends DhCreature {
|
|||
bonus: 0
|
||||
},
|
||||
damage: {
|
||||
parts: [
|
||||
{
|
||||
parts: {
|
||||
hitPoints: {
|
||||
type: ['physical'],
|
||||
value: {
|
||||
dice: 'd6',
|
||||
multiplier: 'prof'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
@ -138,7 +138,9 @@ export default class DhCompanion extends DhCreature {
|
|||
break;
|
||||
case 'vicious':
|
||||
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 {
|
||||
this.attack.range = adjustRange(this.attack.range).id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export { ActionCollection } from './actionField.mjs';
|
||||
export { default as CollectionField } from './collectionField.mjs';
|
||||
export { default as IterableTypedObjectField } from './iterableTypedObjectField.mjs';
|
||||
export { default as FormulaField } from './formulaField.mjs';
|
||||
export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs';
|
||||
export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import FormulaField from '../formulaField.mjs';
|
||||
import { setsEqual } from '../../../helpers/utils.mjs';
|
||||
import CollectionField from '../collectionField.mjs';
|
||||
import IterableTypedObjectField from '../iterableTypedObjectField.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ export default class DamageField extends fields.SchemaField {
|
|||
/** @inheritDoc */
|
||||
constructor(options, context = {}) {
|
||||
const damageFields = {
|
||||
parts: new CollectionField(DHDamageData, { collectionClass: DamagePartsCollection }),
|
||||
parts: new IterableTypedObjectField(DHDamageData),
|
||||
includeBase: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.ACTIONS.Settings.includeBase.label'
|
||||
|
|
@ -301,9 +301,3 @@ export class DHDamageData extends DHResourceData {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
class DamagePartsCollection extends foundry.utils.Collection {
|
||||
get hitPoints() {
|
||||
return this.get('hitPoints');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
export default class CollectionField extends foundry.data.fields.TypedObjectField {
|
||||
constructor(model, options = { collectionClass: foundry.utils.Collection }, context = {}) {
|
||||
super(new foundry.data.fields.EmbeddedDataField(model), options, context);
|
||||
this.#elementClass = model;
|
||||
this.#collectionClass = options.collectionClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection class
|
||||
*/
|
||||
#collectionClass;
|
||||
|
||||
/**
|
||||
* The collection element class.
|
||||
*/
|
||||
#elementClass;
|
||||
|
||||
initialize(value, model, _options = {}) {
|
||||
console.log(model);
|
||||
const collection = new this.#collectionClass(
|
||||
Object.entries(value).map(([key, value]) => [key, new this.#elementClass(value)])
|
||||
);
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
30
module/data/fields/iterableTypedObjectField.mjs
Normal file
30
module/data/fields/iterableTypedObjectField.mjs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
export default class IterableTypedObjectField extends foundry.data.fields.TypedObjectField {
|
||||
constructor(model, options = { collectionClass: foundry.utils.Collection }, context = {}) {
|
||||
super(new foundry.data.fields.EmbeddedDataField(model), options, context);
|
||||
this.#elementClass = model;
|
||||
}
|
||||
|
||||
#elementClass;
|
||||
|
||||
initialize(value) {
|
||||
return new IterableObject(value, this.#elementClass);
|
||||
}
|
||||
}
|
||||
|
||||
class IterableObject {
|
||||
constructor(values, elementClass) {
|
||||
for (const [key, value] of Object.entries(values)) {
|
||||
this[key] = new elementClass(value);
|
||||
}
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (const value of Object.values(this)) {
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
|
||||
map(func) {
|
||||
return Array.from(this, func);
|
||||
}
|
||||
}
|
||||
|
|
@ -65,15 +65,15 @@ export default class DHWeapon extends AttachableItem {
|
|||
type: 'attack'
|
||||
},
|
||||
damage: {
|
||||
parts: [
|
||||
{
|
||||
parts: {
|
||||
hitPoints: {
|
||||
type: ['physical'],
|
||||
value: {
|
||||
multiplier: 'prof',
|
||||
dice: 'd8'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -557,3 +557,12 @@ export function calculateExpectedValue(formulaOrTerms) {
|
|||
: [formulaOrTerms];
|
||||
return terms.reduce((r, t) => r + (t.bonus ?? 0) + (t.diceQuantity ? (t.diceQuantity * (t.faces + 1)) / 2 : 0), 0);
|
||||
}
|
||||
|
||||
export function getNextUnusedDamageType(parts) {
|
||||
const usedKeys = Object.keys(parts);
|
||||
for (const key of Object.keys(CONFIG.DH.GENERAL.healingTypes)) {
|
||||
if (!usedKeys.includes(key)) return key;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@
|
|||
<span>-</span>
|
||||
{{localize (concat 'DAGGERHEART.CONFIG.Range.' source.system.attack.range '.name')}}
|
||||
<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"}}
|
||||
{{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}}
|
||||
(
|
||||
{{#each source.system.attack.damage.parts.0.type}}
|
||||
{{#each source.system.attack.damage.parts.hitPoints.type}}
|
||||
{{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}}
|
||||
{{/each}}
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue