Some fixes

This commit is contained in:
Dapoolp 2025-08-26 13:30:38 +02:00
parent 92a0883806
commit fb9240e130
18 changed files with 94 additions and 82 deletions

View file

@ -146,9 +146,9 @@ export default class AdversarySheet extends DHBaseActorSheet {
title: `Reaction Roll: ${this.actor.name}`,
headerTitle: 'Adversary Reaction Roll',
roll: {
type: 'reaction'
type: 'trait'
},
type: 'trait',
actionType: 'reaction',
hasRoll: true,
data: this.actor.getRollData()
};

View file

@ -208,7 +208,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
prepareBaseConfig(event) {
const config = {
event,
title: `${this.item.name}: ${game.i18n.localize(this.name)}`,
title: `${this.item instanceof CONFIG.Actor.documentClass ? "" : `${this.item.name}: `}${game.i18n.localize(this.name)}`,
source: {
item: this.item._id,
action: this._id,

View file

@ -95,7 +95,7 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
}
registerTargetHook() {
if (!this.parent.isAuthor) return;
if (!this.parent.isAuthor || !this.hasTarget) return;
if (this.targetMode && this.parent.targetHook !== null) {
Hooks.off('targetToken', this.parent.targetHook);
return (this.parent.targetHook = null);

View file

@ -111,7 +111,7 @@ export default class CostField extends fields.ArrayField {
c.key === 'fear'
? game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear)
: resources[c.key].isReversed
? resources[c.key].max
? resources[c.key].max - resources[c.key].value
: resources[c.key].value;
if (c.scalable) c.maxStep = Math.floor((c.max - c.value) / c.step);
return c;

View file

@ -62,6 +62,7 @@ export default class DamageField extends fields.SchemaField {
const damageResult = await CONFIG.Dice.daggerheart.DamageRoll.build(damageConfig);
if(!damageResult) return false;
config.damage = damageResult.damage;
config.message ??= damageConfig.message;
}
/**
@ -71,7 +72,7 @@ export default class DamageField extends fields.SchemaField {
* @param {boolean} force If the method should be executed outside of Action workflow, for ChatMessage button for example.
*/
static async applyDamage(config, targets = null, force = false) {
targets ??= config.targets;
targets ??= config.targets.filter(target => target.hit);
if(!config.damage || !targets?.length || (!DamageField.getApplyAutomation() && !force)) return;
for (let target of targets) {
const actor = fromUuidSync(target.actorId);

View file

@ -1,3 +1,5 @@
import { emitAsGM, GMUpdateEvent } from "../../../systemRegistration/socket.mjs";
const fields = foundry.data.fields;
export default class EffectsField extends fields.ArrayField {
@ -31,8 +33,14 @@ export default class EffectsField extends fields.ArrayField {
message = config.message = await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
}
if(EffectsField.getAutomation() || force) {
targets ??= config.targets.filter(t => !config.hasRoll || t.hit);
EffectsField.applyEffects.call(this, config.targets.filter(t => !config.hasRoll || t.hit));
targets ??= (message.system?.targets ?? config.targets).filter(t => !config.hasRoll || t.hit);
await emitAsGM(
GMUpdateEvent.UpdateEffect,
EffectsField.applyEffects.bind(this),
targets,
this.uuid
);
// EffectsField.applyEffects.call(this, config.targets.filter(t => !config.hasRoll || t.hit));
}
}

View file

@ -71,29 +71,6 @@ export class DHActionRollData extends foundry.abstract.DataModel {
const modifiers = [];
if (!this.parent?.actor) return modifiers;
switch (this.parent.actor.type) {
case 'character':
// const spellcastingTrait =
// this.type === 'spellcast'
// ? (this.parent.actor?.system?.spellcastModifierTrait?.key ?? 'agility')
// : null;
// const trait =
// this.useDefault || !this.trait
// ? (spellcastingTrait ?? this.parent.item.system.attack?.roll?.trait ?? 'agility')
// : this.trait;
// if (
// this.type === CONFIG.DH.GENERAL.rollTypes.attack.id ||
// this.type === CONFIG.DH.GENERAL.rollTypes.trait.id
// )
// modifiers.push({
// label: `DAGGERHEART.CONFIG.Traits.${trait}.name`,
// value: this.parent.actor.system.traits[trait].value
// });
// else if (this.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id)
// modifiers.push({
// label: `DAGGERHEART.CONFIG.RollTypes.spellcast.name`,
// value: this.parent.actor.system.spellcastModifier
// });
break;
case 'companion':
case 'adversary':
if (this.type === CONFIG.DH.GENERAL.rollTypes.attack.id)

View file

@ -35,6 +35,7 @@ export default class SaveField extends fields.SchemaField {
static async execute(config, targets = null, force = false) {
if(!config.hasSave) return;
let message = config.message ?? ui.chat.collection.get(config.parent?._id);
if(!message) {
const roll = new CONFIG.Dice.daggerheart.DHRoll('');
roll._evaluated = true;
@ -42,8 +43,8 @@ export default class SaveField extends fields.SchemaField {
}
if(SaveField.getAutomation() !== CONFIG.DH.SETTINGS.actionAutomationChoices.never.id || force) {
targets ??= config.targets.filter(t => !config.hasRoll || t.hit);
SaveField.rollAllSave.call(this, targets, config.event, message);
}
await SaveField.rollAllSave.call(this, targets, config.event, message);
} else return false;
}
/**
@ -54,22 +55,32 @@ export default class SaveField extends fields.SchemaField {
* @param {ChatMessage} message The ChatMessage the triggered button comes from.
*/
static async rollAllSave(targets, event, message) {
if(!targets || !game.user.isGM) return;
targets.forEach(target => {
const actor = fromUuidSync(target.actorId);
if(actor) {
const rollSave = game.user === actor.owner ?
SaveField.rollSave.call(this, actor, event, message)
: actor.owner
.query('reactionRoll', {
actionId: this.uuid,
actorId: actor.uuid,
event,
message
});
rollSave.then(result => SaveField.updateSaveMessage.call(this, result, message, target.id));
}
});
if(!targets) return;
return new Promise(resolve => {
const aPromise = [];
targets.forEach(target => {
aPromise.push(
new Promise(async subResolve => {
const actor = fromUuidSync(target.actorId);
if(actor) {
const rollSave = game.user === actor.owner ?
SaveField.rollSave.call(this, actor, event)
: actor.owner
.query('reactionRoll', {
actionId: this.uuid,
actorId: actor.uuid,
event,
message
});
const result = await rollSave;
await SaveField.updateSaveMessage.call(this, result, message, target.id);
subResolve();
} else subResolve();
})
)
});
Promise.all(aPromise).then(result => resolve());
})
}
/**
@ -92,13 +103,13 @@ export default class SaveField extends fields.SchemaField {
roll: {
trait: this.save.trait,
difficulty: this.save.difficulty ?? this.actor?.baseSaveDifficulty,
type: 'reaction'
type: 'trait'
},
type: 'trait',
actionType: 'reaction',
hasRoll: true,
data: actor.getRollData()
};
if(SaveField.getAutomation() == CONFIG.DH.SETTINGS.actionAutomationChoices.always.id) rollConfig.dialog = { configure: false };
if(SaveField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.always.id) rollConfig.dialog = { configure: false };
return actor.diceRoll(rollConfig);
}
@ -108,10 +119,10 @@ export default class SaveField extends fields.SchemaField {
* @param {object} message ChatMessage to update
* @param {string} targetId Token ID
*/
static updateSaveMessage(result, message, targetId) {
static async updateSaveMessage(result, message, targetId) {
if (!result) return;
const updateMsg = function(message, targetId, result) {
setTimeout(async () => {
const updateMsg = async function(message, targetId, result) {
// setTimeout(async () => {
const chatMessage = ui.chat.collection.get(message._id),
changes = {
flags: {
@ -127,11 +138,11 @@ export default class SaveField extends fields.SchemaField {
}
};
await chatMessage.update(changes);
}, 100);
// }, 100);
};
if (game.modules.get('dice-so-nice')?.active)
game.dice3d.waitFor3DAnimationByMessageID(result.message.id ?? result.message._id).then(() => updateMsg(message, targetId, result));
else updateMsg(message, targetId, result);
game.dice3d.waitFor3DAnimationByMessageID(result.message.id ?? result.message._id).then(async () => await updateMsg(message, targetId, result));
else await updateMsg(message, targetId, result);
}
/**

View file

@ -28,6 +28,7 @@ export default class DHRoll extends Roll {
static async buildConfigure(config = {}, message = {}) {
config.hooks = [...this.getHooks(), ''];
config.dialog ??= {};
for (const hook of config.hooks) {
if (Hooks.call(`${CONFIG.DH.id}.preRoll${hook.capitalize()}`, config, message) === false) return null;
}

View file

@ -154,7 +154,7 @@ export default class DualityRoll extends D20Roll {
applyBaseBonus() {
const modifiers = super.applyBaseBonus();
if (this.options.roll.trait && this.data.traits[this.options.roll.trait])
if (this.options.roll.trait && this.data.traits?.[this.options.roll.trait])
modifiers.unshift({
label: this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id ? "DAGGERHEART.CONFIG.RollTypes.spellcast.name" : `DAGGERHEART.CONFIG.Traits.${this.options.roll.trait}.name`,
value: this.data.traits[this.options.roll.trait].value

View file

@ -14,7 +14,7 @@ export default class DhpActor extends Actor {
get owner() {
const user =
this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, 'OWNER') && u.active);
if (!user) return game.user.isGM ? game.user : null;
if (!user) return game.users.activeGM;
return user;
}

View file

@ -147,12 +147,16 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
async onRollDamage(event) {
event.stopPropagation();
this.system.action?.workflow.get("damage")?.execute(this.system, this._id, true);
const config = foundry.utils.deepClone(this.system);
config.event = event;
this.system.action?.workflow.get("damage")?.execute(config, this._id, true);
}
async onApplyDamage(event) {
event.stopPropagation();
const targets = this.filterPermTargets(this.system.hitTargets);
const targets = this.filterPermTargets(this.system.hitTargets),
config = foundry.utils.deepClone(this.system);
config.event = event;
if (this.system.onSave) {
const pendingingSaves = targets.filter(t => t.saved.success === null);
@ -169,7 +173,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelectedOrPerm'));
this.consumeOnSuccess();
this.system.action?.workflow.get("applyDamage")?.execute(this.system, targets, true);
this.system.action?.workflow.get("applyDamage")?.execute(config, targets, true);
}
async onRollSave(event) {
@ -198,17 +202,21 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
async onRollAllSave(event) {
event.stopPropagation();
if (!game.user.isGM) return;
const targets = this.system.hitTargets;
this.system.action?.workflow.get("save")?.execute(this.system, targets, true);
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 targets = this.filterPermTargets(this.system.hitTargets);
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(this.system, targets, true);
this.system.action?.workflow.get("effects")?.execute(config, targets, true);
}
filterPermTargets(targets) {

View file

@ -22,6 +22,7 @@ export const socketEvent = {
export const GMUpdateEvent = {
UpdateDocument: 'DhGMUpdateDocument',
UpdateEffect: 'DhGMUpdateEffect',
UpdateSetting: 'DhGMUpdateSetting',
UpdateFear: 'DhGMUpdateFear',
UpdateSaveMessage: 'DhGMUpdateSaveMessage'
@ -37,9 +38,12 @@ export const registerSocketHooks = () => {
const document = data.uuid ? await fromUuid(data.uuid) : null;
switch (data.action) {
case GMUpdateEvent.UpdateDocument:
if (document && data.update) {
if (document && data.update)
await document.update(data.update);
}
break;
case GMUpdateEvent.UpdateEffect:
if (document && data.update)
await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.update);
break;
case GMUpdateEvent.UpdateSetting:
await game.settings.set(CONFIG.DH.id, data.uuid, data.update);