This commit is contained in:
WBHarry 2026-01-08 01:00:49 +01:00
parent 80595f4e79
commit 148aca7235
7 changed files with 129 additions and 57 deletions

View file

@ -78,7 +78,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
icon
}));
context.hasSelectedEffects = Boolean(Object.keys(this.selectedEffects).length);
context.hasSelectedEffects = Boolean(this.selectedEffects && Object.keys(this.selectedEffects).length);
context.selectedEffects = this.selectedEffects;
this.config.costs ??= [];

View file

@ -337,15 +337,20 @@ export default class CharacterSheet extends DHBaseActorSheet {
}
const type = 'effect';
const cls = game.system.api.models.actions.actionsTypes[type];
const action = new cls({
...cls.getSourceConfig(doc.system),
type: type,
chatDisplay: false,
cost: [{
key: 'stress',
value: doc.system.recallCost
}]
}, { parent: doc.system });
const action = new cls(
{
...cls.getSourceConfig(doc.system),
type: type,
chatDisplay: false,
cost: [
{
key: 'stress',
value: doc.system.recallCost
}
]
},
{ parent: doc.system }
);
const config = await action.use(event);
if (config) {
return doc.update({ 'system.inVault': false });
@ -706,8 +711,10 @@ export default class CharacterSheet extends DHBaseActorSheet {
headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
ability: abilityLabel
}),
effects: Array.from(await this.document.allApplicableEffects()),
roll: {
trait: button.dataset.attribute
trait: button.dataset.attribute,
type: 'trait'
},
hasRoll: true,
actionType: 'action',

View file

@ -127,20 +127,53 @@ export default class D20Roll extends DHRoll {
const modifiers = foundry.utils.deepClone(this.options.roll.baseModifiers) ?? [];
modifiers.push(
...this.getBonus(`roll.${this.options.actionType}`, `${this.options.actionType?.capitalize()} Bonus`)
);
modifiers.push(
...this.getBonus(`roll.${this.options.roll.type}`, `${this.options.roll.type?.capitalize()} Bonus`)
...this.getBonus(
`system.bonuses.roll.${this.options.actionType}`,
`${this.options.actionType?.capitalize()} Bonus`
)
);
if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.attack.id) {
modifiers.push(
...this.getBonus(
`system.bonuses.roll.${this.options.roll.type}`,
`${this.options.roll.type?.capitalize()} Bonus`
)
);
}
if (
this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.attack.id ||
(this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id && this.options.hasDamage)
) {
modifiers.push(
...this.getBonus(`system.bonuses.roll.attack`, `${this.options.roll.type?.capitalize()} Bonus`)
);
}
return modifiers;
}
bonusEffectBuilder(config) {
const changeKeys = [`roll.${this.options.actionType}`, `roll.${this.options.roll.type}`];
config.bonusEffects = foundry.utils.deepClone(
config.effects.filter(x => x.changes.some(x => changeKeys.includes(x.key)))
);
getActionChangeKeys() {
const changeKeys = new Set([`system.bonuses.roll.${this.options.actionType}`]);
if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.attack.id) {
changeKeys.add(`system.bonuses.roll.${this.options.roll.type}`);
}
if (
this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.attack.id ||
(this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id && this.options.hasDamage)
) {
changeKeys.add(`system.bonuses.roll.attack`);
}
if (this.options.roll.trait && this.data.traits?.[this.options.roll.trait]) {
if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.spellcast.id)
changeKeys.add('system.bonuses.roll.trait');
}
return changeKeys;
}
static postEvaluate(roll, config = {}) {

View file

@ -107,23 +107,27 @@ export default class DamageRoll extends DHRoll {
return modifiers;
}
bonusEffectBuilder() {
getActionChangeKeys() {
const type = this.options.messageType ?? (this.options.hasHealing ? 'healing' : 'damage');
const changeKeys = [];
return this.options.effects.reduce((acc, effect) => {
if (effect.changes.some(x => x.key.includes(`system.bonuses.${type}`))) {
acc[effect.id] = {
id: effect.id,
name: effect.name,
description: effect.description,
changes: effect.changes,
origEffect: effect,
selected: !effect.disabled
};
for (const roll of this.options.roll) {
for (const damageType of roll.damageTypes) changeKeys.push(`system.bonuses.${type}.${damageType}`);
}
const item = this.data.parent.items?.get(this.options.source.item);
if (item) {
switch (item.type) {
case 'weapon':
if (!this.options.hasHealing)
['primaryWeapon', 'secondaryWeapon'].forEach(w =>
changeKeys.push(`system.bonuses.damage.${w}`)
);
break;
}
}
return acc;
}, {});
return changeKeys;
}
constructFormula(config) {
@ -161,7 +165,7 @@ export default class DamageRoll extends DHRoll {
}
if (config.isCritical && part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) {
const total = part.roll.dice.reduce((acc, term) => acc + term._faces * term._number, 0);
let total = part.roll.dice.reduce((acc, term) => acc + term._faces * term._number, 0);
if (total > 0) {
part.roll.terms.push(...this.formatModifier(total));
}

View file

@ -1,5 +1,4 @@
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
import { BonusFields } from '../data/actor/character.mjs';
export default class DHRoll extends Roll {
baseTerms = [];
@ -249,6 +248,26 @@ export default class DHRoll extends Roll {
}
bonusEffectBuilder() {
const changeKeys = this.getActionChangeKeys();
return (
this.options.effects?.reduce((acc, effect) => {
if (effect.changes.some(x => changeKeys.some(key => x.key.includes(key)))) {
acc[effect.id] = {
id: effect.id,
name: effect.name,
description: effect.description,
changes: effect.changes,
origEffect: effect,
selected: !effect.disabled
};
}
return acc;
}, {}) ?? []
);
}
getActionChangeKeys() {
return [];
}
}

View file

@ -173,21 +173,32 @@ export default class DualityRoll extends D20Roll {
return modifiers;
}
bonusEffectBuilder() {
return this.options.effects.reduce((acc, effect) => {
if (effect.changes.some(x => x.key.includes(`system.bonuses.roll`))) {
acc[effect.id] = {
id: effect.id,
name: effect.name,
description: effect.description,
changes: effect.changes,
origEffect: effect,
selected: !effect.disabled
};
}
getActionChangeKeys() {
const changeKeys = new Set([`system.bonuses.roll.${this.options.actionType}`]);
return acc;
}, {});
if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.attack.id) {
changeKeys.add(`system.bonuses.roll.${this.options.roll.type}`);
}
if (
this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.attack.id ||
(this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id && this.options.hasDamage)
) {
changeKeys.add(`system.bonuses.roll.attack`);
}
if (this.options.roll.trait && this.data.traits?.[this.options.roll.trait]) {
if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.spellcast.id)
changeKeys.add('system.bonuses.roll.trait');
}
const weapons = ['primaryWeapon', 'secondaryWeapon'];
weapons.forEach(w => {
if (this.options.source.item && this.options.source.item === this.data[w]?.id)
changeKeys.add(`system.bonuses.roll.${w}`);
});
return changeKeys;
}
static async buildEvaluate(roll, config = {}, message = {}) {

View file

@ -74,14 +74,12 @@
<fieldset class="experience-container">
<legend>{{localize "DAGGERHEART.GENERAL.Effect.plural"}}</legend>
<div>
{{#each selectedEffects as |effect id|}}
<div class="experience-chip {{#if effect.selected}}selected{{/if}}" data-action="toggleSelectedEffect" data-key="{{id}}" data-tooltip="{{this.description}}">
<span><i class="{{ifThen effect.selected "fa-solid" "fa-regular"}} fa-circle"></i></span>
<span class="label">{{effect.name}}</span>
</div>
{{/each}}
</div>
{{#each selectedEffects as |effect id|}}
<div class="experience-chip {{#if effect.selected}}selected{{/if}}" data-action="toggleSelectedEffect" data-key="{{id}}" data-tooltip="{{this.description}}">
<span><i class="{{ifThen effect.selected "fa-solid" "fa-regular"}} fa-circle"></i></span>
<span class="label">{{effect.name}}</span>
</div>
{{/each}}
</fieldset>
{{/if}}