Fix Effect Action & Add Hope tumation settings to hook

This commit is contained in:
Dapoolp 2025-07-06 22:52:25 +02:00
parent 532c245ca3
commit 74c657992c
10 changed files with 66 additions and 78 deletions

View file

@ -63,18 +63,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
const context = await super._prepareContext(_options); const context = await super._prepareContext(_options);
context.rollConfig = this.config; context.rollConfig = this.config;
context.hasRoll = !!this.config.roll; context.hasRoll = !!this.config.roll;
context.roll = this.roll;
context.rollType = this.roll?.constructor.name;
context.experiences = Object.keys(this.config.data.experiences).map(id => ({
id,
...this.config.data.experiences[id]
}));
context.selectedExperiences = this.config.experiences;
context.advantage = this.config.roll?.advantage;
context.disadvantage = this.config.roll?.disadvantage;
context.diceOptions = CONFIG.DH.GENERAL.diceTypes;
context.canRoll = true;
context.isLite = this.config.roll?.lite;
if (this.config.costs?.length) { if (this.config.costs?.length) {
const updatedCosts = this.action.calcCosts(this.config.costs); const updatedCosts = this.action.calcCosts(this.config.costs);
context.costs = updatedCosts; context.costs = updatedCosts;
@ -85,8 +73,22 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
context.uses = this.action.calcUses(this.config.uses); context.uses = this.action.calcUses(this.config.uses);
context.canRoll = context.canRoll && this.action.hasUses(context.uses); context.canRoll = context.canRoll && this.action.hasUses(context.uses);
} }
context.extraFormula = this.config.extraFormula; if(this.roll) {
context.formula = this.roll.constructFormula(this.config); context.roll = this.roll;
context.rollType = this.roll?.constructor.name;
context.experiences = Object.keys(this.config.data.experiences).map(id => ({
id,
...this.config.data.experiences[id]
}));
context.selectedExperiences = this.config.experiences;
context.advantage = this.config.roll?.advantage;
context.disadvantage = this.config.roll?.disadvantage;
context.diceOptions = CONFIG.DH.GENERAL.diceTypes;
context.canRoll = true;
context.isLite = this.config.roll?.lite;
context.extraFormula = this.config.extraFormula;
context.formula = this.roll.constructFormula(this.config);
}
return context; return context;
} }

View file

@ -158,7 +158,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
const targetSelection = event.target const targetSelection = event.target
.closest('.message-content') .closest('.message-content')
.querySelector('.button-target-selection.target-selected'), .querySelector('.button-target-selection.target-selected'),
isHit = Boolean(targetSelection.dataset.targetHit); isHit = Boolean(targetSelection?.dataset?.targetHit) ?? false;
return { return {
isHit, isHit,
targets: isHit targets: isHit

View file

@ -123,6 +123,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
return extraSchemas; return extraSchemas;
} }
prepareData() {}
get index() { get index() {
return foundry.utils.getProperty(this.parent, this.systemPath).indexOf(this); return foundry.utils.getProperty(this.parent, this.systemPath).indexOf(this);
} }
@ -229,7 +231,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
// Display configuration window if necessary // Display configuration window if necessary
// if (config.dialog?.configure && this.requireConfigurationDialog(config)) { // if (config.dialog?.configure && this.requireConfigurationDialog(config)) {
if (this.requireConfigurationDialog(config)) { if (this.requireConfigurationDialog(config)) {
config = await D20RollDialog.configure(config); config = await D20RollDialog.configure(null, config);
if (!config) return; if (!config) return;
} }
@ -288,11 +290,12 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
} }
prepareTarget() { prepareTarget() {
if(!this.target?.type) return [];
let targets; let targets;
if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id) if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id)
targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken); targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken);
targets = Array.from(game.user.targets); targets = Array.from(game.user.targets);
if (this.target?.type && this.target.type !== CONFIG.DH.ACTIONS.targetTypes.any.id) { if (this.target.type !== CONFIG.DH.ACTIONS.targetTypes.any.id) {
targets = targets.filter(t => this.isTargetFriendly(t)); targets = targets.filter(t => this.isTargetFriendly(t));
if (this.target.amount && targets.length > this.target.amount) targets = []; if (this.target.amount && targets.length > this.target.amount) targets = [];
} }

View file

@ -3,38 +3,16 @@ import DHBaseAction from './baseAction.mjs';
export default class DHEffectAction extends DHBaseAction { export default class DHEffectAction extends DHBaseAction {
static extraSchemas = ['effects', 'target']; static extraSchemas = ['effects', 'target'];
/* async use(event, ...args) {
const config = await super.use(event, args);
if (['error', 'warning'].includes(config.type)) return;
return await this.chatApplyEffects(event, config);
} */
async trigger(event, data) { async trigger(event, data) {
const cls = getDocumentClass('ChatMessage'), if(this.effects.length) {
systemData = { const cls = getDocumentClass('ChatMessage'),
title: game.i18n.format('DAGGERHEART.Chat.ApplyEffect.Title', { name: this.name }), msg = {
origin: this.actor._id, type: 'applyEffect',
description: '', user: game.user.id,
targets: data.targets.map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })), system: data
action: { };
itemId: this.item._id,
actionId: this._id
}
},
msg = new cls({
type: 'applyEffect',
user: game.user.id,
system: systemData,
content: await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/ui/chat/apply-effects.hbs',
systemData
)
});
cls.create(msg.toObject()); return await cls.create(msg);
} } else this.toChat(this.id);
get chatTemplate() {
return 'systems/daggerheart/templates/ui/chat/apply-effects.hbs';
} }
} }

View file

@ -1,11 +1,11 @@
import DHBaseAction from "../action/baseAction.mjs";
export default class DHApplyEffect extends foundry.abstract.TypeDataModel { export default class DHApplyEffect extends foundry.abstract.TypeDataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
title: new fields.StringField(), title: new fields.StringField(),
origin: new fields.StringField({}),
description: new fields.StringField({}),
targets: new fields.ArrayField( targets: new fields.ArrayField(
new fields.SchemaField({ new fields.SchemaField({
id: new fields.StringField({ required: true }), id: new fields.StringField({ required: true }),
@ -14,10 +14,24 @@ export default class DHApplyEffect extends foundry.abstract.TypeDataModel {
hit: new fields.BooleanField({ initial: false }) hit: new fields.BooleanField({ initial: false })
}) })
), ),
action: new fields.SchemaField({ targetSelection: new fields.BooleanField({ initial: true }),
itemId: new fields.StringField(), source: new fields.SchemaField({
actionId: new fields.StringField() actor: new fields.StringField(),
item: new fields.StringField(),
action: new fields.StringField()
}) })
}; };
} }
prepareDerivedData() {
this.hasHitTarget = this.targets.filter(t => t.hit === true).length > 0;
this.currentTargets =
this.targetSelection !== true
? Array.from(game.user.targets).map(t => DHBaseAction.formatTarget(t))
: this.targets;
}
get messageTemplate() {
return 'systems/daggerheart/templates/ui/chat/apply-effects.hbs';
}
} }

View file

@ -4,9 +4,9 @@ export default class DhAutomation extends foundry.abstract.DataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
hope: new fields.BooleanField({ required: true, initial: false }), hope: new fields.BooleanField({ required: true, initial: false, label: "DAGGERHEART.Settings.Automation.FIELDS.hope.label" }), // Label need to be updated into something like "Duality Roll Auto Gain" + a hint
actionPoints: new fields.BooleanField({ required: true, initial: false }), actionPoints: new fields.BooleanField({ required: true, initial: false, label: "DAGGERHEART.Settings.Automation.FIELDS.actionPoints.label" }),
countdowns: new fields.BooleanField({ requireD: true, initial: false }) countdowns: new fields.BooleanField({ requireD: true, initial: false, label: "DAGGERHEART.Settings.Automation.FIELDS.countdowns.label" })
}; };
} }
} }

View file

@ -138,10 +138,10 @@ export default class DHRoll extends Roll {
export const registerRollDiceHooks = () => { export const registerRollDiceHooks = () => {
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async(config, message) => { Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async(config, message) => {
if(config.roll.type !== 'action') return; if(!game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hope || config.roll.type !== 'action' || (!config.roll.hasOwnProperty('success') && !config.targets.length)) return;
const actor = await fromUuid(config.source.actor), const actor = await fromUuid(config.source.actor),
rollResult = config.roll.result || config.targets.some(t => t.hit), rollResult = config.roll.success || config.targets.some(t => t.hit),
updates = []; updates = [];
let looseSpotlight = false; let looseSpotlight = false;
if(!actor) return; if(!actor) return;

View file

@ -1,6 +1,6 @@
<div> <div>
{{#if @root.hasRoll}}
<div class="roll-dialog-container"> <div class="roll-dialog-container">
{{#if @root.hasRoll}}
{{#unless @root.isLite}} {{#unless @root.isLite}}
<div class="dices-section"> <div class="dices-section">
{{#if (eq @root.rollType 'D20Roll')}} {{#if (eq @root.rollType 'D20Roll')}}
@ -121,6 +121,10 @@
<i class="fa-solid fa-dice"></i> <i class="fa-solid fa-dice"></i>
<span class="label">Roll</span> <span class="label">Roll</span>
</button> </button>
</div> {{else}}
<button class="sunmit-btn" data-action="submitRoll"{{#unless canRoll}} disabled{{/unless}}>
<span class="label">Continue</span>
</button>
{{/if}} {{/if}}
</div>
</div> </div>

View file

@ -1,22 +1,7 @@
<div> <div>
<div class="form-group"> {{formGroup settingFields.schema.fields.hope value=settingFields._source.hope localize=true}}
<label>{{localize "DAGGERHEART.Settings.Automation.FIELDS.hope.label"}}</label> {{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}}
<div class="form-fields"> {{formGroup settingFields.schema.fields.countdowns value=settingFields._source.countdowns localize=true}}
{{formInput settingFields.schema.fields.hope value=settingFields._source.hope }}
</div>
</div>
<div class="form-group">
<label>{{localize "DAGGERHEART.Settings.Automation.FIELDS.actionPoints.label"}}</label>
<div class="form-fields">
{{formInput settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints }}
</div>
</div>
<div class="form-group">
<label>{{localize "DAGGERHEART.Settings.Automation.FIELDS.countdowns.label"}}</label>
<div class="form-fields">
{{formInput settingFields.schema.fields.countdowns value=settingFields._source.countdowns }}
</div>
</div>
<footer class="form-footer"> <footer class="form-footer">
<button data-action="reset"> <button data-action="reset">

View file

@ -1,6 +1,8 @@
<div class="dice-roll daggerheart chat roll" data-action="expandRoll"> <div class="dice-roll daggerheart chat roll" data-action="expandRoll">
<div class="dice-flavor">{{title}}</div> <div class="dice-flavor">{{title}}</div>
<div>{{{description}}}</div> <div>{{{description}}}</div>
</div>
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
<div class="dice-result"> <div class="dice-result">
<div class="dice-actions"> <div class="dice-actions">
<button class="duality-action-effect">{{localize "DAGGERHEART.Chat.AttackRoll.ApplyEffect"}}</button> <button class="duality-action-effect">{{localize "DAGGERHEART.Chat.AttackRoll.ApplyEffect"}}</button>