Merged with main

This commit is contained in:
WBHarry 2025-08-24 21:31:57 +02:00
commit 990c73987e
65 changed files with 567 additions and 424 deletions

View file

@ -51,11 +51,13 @@ export default class DHAttackAction extends DHDamageAction {
const labels = [];
const { roll, range, damage } = this;
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`));
for (const { value, type } of damage.parts) {
const str = Roll.replaceFormulaData(value.getFormula(), this.actor?.getRollData() ?? {});
const useAltDamage = this.actor?.effects?.find(x => x.type === 'horde')?.active;
for (const { value, valueAlt, type } of damage.parts) {
const usedValue = useAltDamage ? valueAlt : value;
const str = Roll.replaceFormulaData(usedValue.getFormula(), this.actor?.getRollData() ?? {});
const icons = Array.from(type)
.map(t => CONFIG.DH.GENERAL.damageTypes[t]?.icon)

View file

@ -172,7 +172,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
dialog: {
configure: hasRoll
},
type: this.type,
type: this.roll?.type ?? this.type,
hasRoll: hasRoll,
hasDamage: this.damage?.parts?.length && this.type !== 'healing',
hasHealing: this.damage?.parts?.length && this.type === 'healing',

View file

@ -130,7 +130,7 @@ export default class DhpAdversary extends BaseDataActor {
CONFIG.DH.id,
CONFIG.DH.SETTINGS.gameSettings.Automation
).hordeDamage;
if (autoHordeDamage && changes.system?.resources?.hitPoints?.value) {
if (autoHordeDamage && changes.system?.resources?.hitPoints?.value !== undefined) {
const hordeActiveEffect = this.parent.effects.find(x => x.type === 'horde');
if (hordeActiveEffect) {
const halfHP = Math.ceil(this.resources.hitPoints.max / 2);

View file

@ -130,11 +130,16 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
const typeForDefeated = ['character', 'adversary', 'companion'].find(x => x === this.parent.type);
if (defeatedSettings.enabled && typeForDefeated) {
const resource = typeForDefeated === 'companion' ? 'stress' : 'hitPoints';
if (changes.system.resources[resource]) {
const becameMax = changes.system.resources[resource].value === this.resources[resource].max;
const resourceValue = changes.system.resources[resource];
if (
resourceValue &&
this.resources[resource].max &&
resourceValue.value !== this.resources[resource].value
) {
const becameMax = resourceValue.value === this.resources[resource].max;
const wasMax =
this.resources[resource].value === this.resources[resource].max &&
this.resources[resource].value !== changes.system.resources[resource].value;
this.resources[resource].value !== resourceValue.value;
if (becameMax) {
this.parent.toggleDefeated(true);
} else if (wasMax) {

View file

@ -317,7 +317,7 @@ export default class DhCharacter extends BaseDataActor {
}
get multiclass() {
const value = this.parent.items.find(x => x.type === 'Class' && x.system.isMulticlass);
const value = this.parent.items.find(x => x.type === 'class' && x.system.isMulticlass);
const subclass = this.parent.items.find(x => x.type === 'subclass' && x.system.isMulticlass);
return {
@ -443,7 +443,9 @@ export default class DhCharacter extends BaseDataActor {
classFeatures.push(item);
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
if (this.class.subclass) {
const subclassState = this.class.subclass.system.featureState;
const prop = item.system.multiclassOrigin ? 'multiclass' : 'class';
const subclassState = this[prop].subclass?.system?.featureState;
if (!subclassState) continue;
if (
item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.foundation ||

View file

@ -113,7 +113,7 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
this.currentTargets = this.getTargetList();
// this.registerTargetHook();
if (this.targetMode === true && this.hasRoll) {
if (this.hasRoll) {
this.targetShort = this.targets.reduce(
(a, c) => {
if (c.hit) a.hit += 1;
@ -127,7 +127,8 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
}
this.canViewSecret = this.parent.speakerActor?.testUserPermission(game.user, 'OBSERVER');
this.canButtonApply = game.user.isGM;
this.canButtonApply = game.user.isGM; //temp
this.isGM = game.user.isGM; //temp
}
getTargetList() {

View file

@ -162,7 +162,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
for (let f of this.features) {
const fBase = f.item ?? f;
const feature = fBase.system ? fBase : await foundry.utils.fromUuid(fBase.uuid);
const multiclass = this.isMulticlass ? 'multiclass' : null;
features.push(
foundry.utils.mergeObject(
feature.toObject(),
@ -170,7 +169,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
_stats: { compendiumSource: fBase.uuid },
system: {
originItemType: this.parent.type,
identifier: multiclass ?? (f.item ? f.type : null)
identifier: f.item ? f.type : null,
multiclassOrigin: this.isMulticlass
}
},
{ inplace: false }

View file

@ -29,6 +29,7 @@ export default class DHFeature extends BaseDataItem {
nullable: true,
initial: null
}),
multiclassOrigin: new fields.BooleanField({ initial: false }),
identifier: new fields.StringField()
};
}

View file

@ -1,3 +1,4 @@
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
import ItemLinkFields from '../fields/itemLinkFields.mjs';
import BaseDataItem from './base.mjs';
@ -25,7 +26,8 @@ export default class DHSubclass extends BaseDataItem {
}),
features: new ItemLinkFields(),
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
isMulticlass: new fields.BooleanField({ initial: false })
isMulticlass: new fields.BooleanField({ initial: false }),
linkedClass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true, initial: null })
};
}