Task/415 action refactor part 2 (#1094)

This commit is contained in:
Dapoulp 2025-08-27 09:00:18 +02:00 committed by GitHub
parent 8e5dd22370
commit 1eb3ff11c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 1244 additions and 641 deletions

View file

@ -1,3 +1,5 @@
import { emitAsGM, GMUpdateEvent } from "../systemRegistration/socket.mjs";
export default class DhpChatMessage extends foundry.documents.ChatMessage {
targetHook = null;
@ -102,20 +104,30 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
});
if (itemDesc && autoExpandRoll.desc) itemDesc.setAttribute('open', '');
}
if (!game.user.isGM) {
const applyButtons = html.querySelector('.apply-buttons');
if(!this.isAuthor && !this.speakerActor?.isOwner) {
const applyButtons = html.querySelector(".apply-buttons");
applyButtons?.remove();
if (!this.isAuthor && !this.speakerActor?.isOwner) {
const buttons = html.querySelectorAll('.ability-card-footer > .ability-use-button');
buttons.forEach(b => b.remove());
}
const buttons = html.querySelectorAll(".ability-card-footer > .ability-use-button");
buttons.forEach(b => b.remove());
}
}
addChatListeners(html) {
html.querySelectorAll('.duality-action-damage').forEach(element =>
element.addEventListener('click', this.onRollDamage.bind(this))
);
html.querySelectorAll('.damage-button').forEach(element =>
element.addEventListener('click', this.onDamage.bind(this))
element.addEventListener('click', this.onApplyDamage.bind(this))
);
html.querySelectorAll('.target-save').forEach(element =>
element.addEventListener('click', this.onRollSave.bind(this))
);
html.querySelectorAll('.roll-all-save-button').forEach(element =>
element.addEventListener('click', this.onRollAllSave.bind(this))
);
html.querySelectorAll('.duality-action-effect').forEach(element =>
@ -133,17 +145,21 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
});
}
getTargetList() {
const targets = this.system.hitTargets ?? [];
return targets.map(target => game.canvas.tokens.documentCollection.find(t => t.actor?.uuid === target.actorId));
async onRollDamage(event) {
event.stopPropagation();
const config = foundry.utils.deepClone(this.system);
config.event = event;
this.system.action?.workflow.get("damage")?.execute(config, this._id, true);
}
async onDamage(event) {
async onApplyDamage(event) {
event.stopPropagation();
const targets = this.getTargetList();
const targets = this.filterPermTargets(this.system.hitTargets),
config = foundry.utils.deepClone(this.system);
config.event = event;
if (this.system.onSave) {
const pendingingSaves = this.system.hitTargets.filter(t => t.saved.success === null);
const pendingingSaves = targets.filter(t => t.saved.success === null);
if (pendingingSaves.length) {
const confirm = await foundry.applications.api.DialogV2.confirm({
window: { title: 'Pending Reaction Rolls found' },
@ -154,62 +170,62 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
}
if (targets.length === 0)
return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected'));
return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelectedOrPerm'));
this.consumeOnSuccess();
this.system.action?.workflow.get("applyDamage")?.execute(config, targets, true);
}
for (let target of targets) {
let damages = foundry.utils.deepClone(this.system.damage);
if (
!this.system.hasHealing &&
this.system.onSave &&
this.system.hitTargets.find(t => t.id === target.id)?.saved?.success === true
) {
const mod = CONFIG.DH.ACTIONS.damageOnSave[this.system.onSave]?.mod ?? 1;
Object.entries(damages).forEach(([k, v]) => {
v.total = 0;
v.parts.forEach(part => {
part.total = Math.ceil(part.total * mod);
v.total += part.total;
});
});
}
this.consumeOnSuccess();
if (this.system.hasHealing) target.actor.takeHealing(damages);
else target.actor.takeDamage(damages, this.system.isDirect);
async onRollSave(event) {
event.stopPropagation();
const tokenId = event.target.closest('[data-token]')?.dataset.token,
token = game.canvas.tokens.get(tokenId);
if (!token?.actor || !token.isOwner) return true;
if (this.system.source.item && this.system.source.action) {
const action = this.system.action;
if (!action || !action?.hasSave) return;
game.system.api.fields.ActionFields.SaveField.rollSave.call(action, token.actor, event).then(result =>
emitAsGM(
GMUpdateEvent.UpdateSaveMessage,
game.system.api.fields.ActionFields.SaveField.updateSaveMessage.bind(action, result, this, token.id),
{
action: action.uuid,
message: this._id,
token: token.id,
result
}
)
);
}
}
getAction(actor, itemId, actionId) {
const item = actor.items.get(itemId),
action =
actor.system.attack?._id === actionId
? actor.system.attack
: item.system.attack?._id === actionId
? item.system.attack
: item?.system?.actions?.get(actionId);
return action;
async onRollAllSave(event) {
event.stopPropagation();
if (!game.user.isGM) return;
const targets = this.system.hitTargets,
config = foundry.utils.deepClone(this.system);
config.event = event;
this.system.action?.workflow.get("save")?.execute(config, targets, true);
}
async onApplyEffect(event) {
event.stopPropagation();
const actor = await foundry.utils.fromUuid(this.system.source.actor);
if (!actor || !game.user.isGM) return true;
if (this.system.source.item && this.system.source.action) {
const action = this.getAction(actor, this.system.source.item, this.system.source.action);
if (!action || !action?.applyEffects) return;
const targets = this.getTargetList();
if (targets.length === 0)
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected'));
this.consumeOnSuccess();
await action.applyEffects(event, this, targets);
}
const targets = this.filterPermTargets(this.system.hitTargets),
config = foundry.utils.deepClone(this.system);
config.event = event;
if (targets.length === 0)
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelectedOrPerm'));
this.consumeOnSuccess();
this.system.action?.workflow.get("effects")?.execute(config, targets, true);
}
filterPermTargets(targets) {
return targets.filter(t => fromUuidSync(t.actorId)?.canUserModify(game.user, "update"))
}
consumeOnSuccess() {
if (!this.system.successConsumed && !this.targetSelection) {
const action = this.system.action;
if (action) action.consume(this.system, true);
}
if (!this.system.successConsumed && !this.targetSelection)
this.system.action?.consume(this.system, true);
}
hoverTarget(event) {