mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-18 07:59:03 +01:00
s
This commit is contained in:
parent
1b511a587e
commit
a54efaeb48
8 changed files with 160 additions and 71 deletions
|
|
@ -20,7 +20,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
id: 'roll-selection',
|
||||
// id: 'roll-selection',
|
||||
classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'roll-selection'],
|
||||
position: {
|
||||
width: 'auto'
|
||||
|
|
@ -42,7 +42,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
};
|
||||
|
||||
get title() {
|
||||
return this.config.title;
|
||||
return `${this.config.title}${this.actor ? `: ${this.actor.name}` : ''}`;
|
||||
}
|
||||
|
||||
get actor() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import DhpActor from '../../documents/actor.mjs';
|
||||
import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
|
||||
import { ActionMixin } from '../fields/actionField.mjs';
|
||||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
|
|
@ -50,6 +49,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
Object.values(this.schema.fields).forEach(s => {
|
||||
if(s.execute) workflow.push( { order: s.order, execute: s.execute } );
|
||||
});
|
||||
if(this.schema.fields.damage) workflow.push( { order: 75, execute: this.schema.fields.damage.applyDamage } );
|
||||
workflow.sort((a, b) => a.order - b.order);
|
||||
return workflow.map(s => s.execute);
|
||||
}
|
||||
|
|
@ -383,16 +383,16 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
// });
|
||||
// }
|
||||
|
||||
updateSaveMessage(result, message, targetId) {
|
||||
if (!result) return;
|
||||
const updateMsg = this.updateChatMessage.bind(this, message, targetId, {
|
||||
result: result.roll.total,
|
||||
success: result.roll.success
|
||||
});
|
||||
if (game.modules.get('dice-so-nice')?.active)
|
||||
game.dice3d.waitFor3DAnimationByMessageID(result.message.id ?? result.message._id).then(() => updateMsg());
|
||||
else updateMsg();
|
||||
}
|
||||
// updateSaveMessage(result, message, targetId) {
|
||||
// if (!result) return;
|
||||
// const updateMsg = this.updateChatMessage.bind(this, message, targetId, {
|
||||
// result: result.roll.total,
|
||||
// success: result.roll.success
|
||||
// });
|
||||
// if (game.modules.get('dice-so-nice')?.active)
|
||||
// game.dice3d.waitFor3DAnimationByMessageID(result.message.id ?? result.message._id).then(() => updateMsg());
|
||||
// else updateMsg();
|
||||
// }
|
||||
|
||||
// static rollSaveQuery({ actionId, actorId, event, message }) {
|
||||
// return new Promise(async (resolve, reject) => {
|
||||
|
|
@ -404,28 +404,20 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
// }
|
||||
/* SAVE */
|
||||
|
||||
async updateChatMessage(message, targetId, changes, chain = true) {
|
||||
async updateChatMessage(message, targetId, changes/* , chain = true */) {
|
||||
setTimeout(async () => {
|
||||
const chatMessage = ui.chat.collection.get(message._id);
|
||||
|
||||
await chatMessage.update({
|
||||
flags: {
|
||||
[game.system.id]: {
|
||||
reactionRolls: {
|
||||
[targetId]: changes
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
await chatMessage.update(changes);
|
||||
}, 100);
|
||||
if (chain) {
|
||||
if (message.system.source.message)
|
||||
this.updateChatMessage(ui.chat.collection.get(message.system.source.message), targetId, changes, false);
|
||||
const relatedChatMessages = ui.chat.collection.filter(c => c.system.source?.message === message._id);
|
||||
relatedChatMessages.forEach(c => {
|
||||
this.updateChatMessage(c, targetId, changes, false);
|
||||
});
|
||||
}
|
||||
// if (chain) {
|
||||
// if (message.system.source.message)
|
||||
// this.updateChatMessage(ui.chat.collection.get(message.system.source.message), targetId, changes, false);
|
||||
// const relatedChatMessages = ui.chat.collection.filter(c => c.system.source?.message === message._id);
|
||||
// relatedChatMessages.forEach(c => {
|
||||
// this.updateChatMessage(c, targetId, changes, false);
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default class DamageField extends fields.SchemaField {
|
|||
}
|
||||
|
||||
async execute(data, force = false) {
|
||||
if((this.hasRoll && DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.never.id) && !force) return false;
|
||||
if((this.hasRoll && DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.never.id) && !force) return;
|
||||
|
||||
const systemData = data.system ?? data;
|
||||
|
||||
|
|
@ -52,7 +52,38 @@ export default class DamageField extends fields.SchemaField {
|
|||
if(config.source?.message && game.modules.get('dice-so-nice')?.active)
|
||||
await game.dice3d.waitFor3DAnimationByMessageID(config.source.message);
|
||||
|
||||
if(!CONFIG.Dice.daggerheart.DamageRoll.build(config)) return false;
|
||||
if(!(await CONFIG.Dice.daggerheart.DamageRoll.build(config))) return false;
|
||||
|
||||
if(DamageField.getAutomation()) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async applyDamage(config, targets) {
|
||||
console.log(config, this)
|
||||
targets ??= config.targets;
|
||||
if(!config.damage || !targets?.length || !DamageField.getApplyAutomation()) return;
|
||||
for (let target of targets) {
|
||||
const actor = fromUuidSync(target.actorId);
|
||||
if (
|
||||
!this.hasHealing &&
|
||||
this.onSave &&
|
||||
this.system.hitTargets.find(t => t.id === target.id)?.saved?.success === true
|
||||
) {
|
||||
const mod = CONFIG.DH.ACTIONS.damageOnSave[this.onSave]?.mod ?? 1;
|
||||
Object.entries(config.damage).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.hasHealing) actor.takeHealing(config.damage);
|
||||
else actor.takeDamage(config.damage, this.isDirect);
|
||||
}
|
||||
}
|
||||
|
||||
static getFormulaValue(part, data) {
|
||||
|
|
@ -86,6 +117,10 @@ export default class DamageField extends fields.SchemaField {
|
|||
static getAutomation() {
|
||||
return (game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damage.gm) || (!game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damage.players)
|
||||
}
|
||||
|
||||
static getApplyAutomation() {
|
||||
return (game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damageApply.gm) || (!game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damageApply.players)
|
||||
}
|
||||
}
|
||||
|
||||
export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
export default class EffectsField extends fields.ArrayField {
|
||||
order = 60;
|
||||
order = 100;
|
||||
|
||||
constructor(options = {}, context = {}) {
|
||||
const element = new fields.SchemaField({
|
||||
|
|
@ -12,19 +12,20 @@ export default class EffectsField extends fields.ArrayField {
|
|||
}
|
||||
|
||||
async execute(config) {
|
||||
if(!this.hasRoll) {
|
||||
if(!this.hasEffect) return;
|
||||
if(!config.message) {
|
||||
const roll = new CONFIG.Dice.daggerheart.DHRoll('');
|
||||
roll._evaluated = true;
|
||||
await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
||||
} else {
|
||||
return;
|
||||
config.message = await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
||||
}
|
||||
if(EffectsField.getAutomation()) {
|
||||
EffectsField.applyEffects.call(this, config.targets);
|
||||
}
|
||||
}
|
||||
|
||||
async applyEffects(data, targets) {
|
||||
targets ??= data.system.targets;
|
||||
static async applyEffects(targets) {
|
||||
const force = true; /* Where should this come from? */
|
||||
if (!this.effects?.length || !targets.length) return;
|
||||
if (!this.effects?.length || !targets?.length) return;
|
||||
let effects = this.effects;
|
||||
targets.forEach(async token => {
|
||||
if (!token.hit && !force) return;
|
||||
|
|
@ -36,12 +37,12 @@ export default class EffectsField extends fields.ArrayField {
|
|||
const actor = canvas.tokens.get(token.id)?.actor,
|
||||
effect = this.item.effects.get(e._id);
|
||||
if (!actor || !effect) return;
|
||||
await this.applyEffect(effect, actor);
|
||||
await EffectsField.applyEffect(effect, actor);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async applyEffect(effect, actor) {
|
||||
static async applyEffect(effect, actor) {
|
||||
const existingEffect = actor.effects.find(e => e.origin === effect.uuid);
|
||||
if (existingEffect) {
|
||||
return effect.update(
|
||||
|
|
@ -61,4 +62,8 @@ export default class EffectsField extends fields.ArrayField {
|
|||
});
|
||||
await ActiveEffect.implementation.create(effectData, { parent: actor });
|
||||
}
|
||||
|
||||
static getAutomation() {
|
||||
return (game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.effect.gm) || (!game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.effect.players)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import { abilities } from "../../../config/actorConfig.mjs";
|
||||
import { emitAsGM, GMUpdateEvent } from "../../../systemRegistration/socket.mjs";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class SaveField extends fields.SchemaField {
|
||||
|
|
@ -20,36 +23,95 @@ export default class SaveField extends fields.SchemaField {
|
|||
}
|
||||
|
||||
async execute(config) {
|
||||
if(!this.hasRoll) {
|
||||
if(!this.hasSave) return;
|
||||
if(!config.message) {
|
||||
const roll = new CONFIG.Dice.daggerheart.DHRoll('');
|
||||
roll._evaluated = true;
|
||||
await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
||||
config.message = await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
||||
}
|
||||
if(true) {
|
||||
|
||||
if(SaveField.getAutomation() !== CONFIG.DH.SETTINGS.actionAutomationChoices.never.id) {
|
||||
SaveField.rollAllSave.call(this, config.targets, config.event, config.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async rollSave(actor, event, message) {
|
||||
static async rollAllSave(targets, event, message) {
|
||||
if(!targets) return;
|
||||
targets.forEach(target => {
|
||||
const actor = fromUuidSync(target.actorId);
|
||||
if(actor) {
|
||||
if (game.user === actor.owner)
|
||||
SaveField.rollSave.call(this, actor, event, message)
|
||||
.then(result =>
|
||||
emitAsGM(
|
||||
GMUpdateEvent.UpdateSaveMessage,
|
||||
SaveField.updateSaveMessage.bind(this, result, message, target.id),
|
||||
{
|
||||
action: this.uuid,
|
||||
message: message._id,
|
||||
token: target.id,
|
||||
result
|
||||
}
|
||||
)
|
||||
);
|
||||
else
|
||||
actor.owner
|
||||
.query('reactionRoll', {
|
||||
actionId: this.uuid,
|
||||
actorId: actor.uuid,
|
||||
event,
|
||||
message
|
||||
})
|
||||
.then(result => SaveField.updateSaveMessage.call(this, result, message, target.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async rollSave(actor, event, message) {
|
||||
if (!actor) return;
|
||||
const title = actor.isNPC
|
||||
? game.i18n.localize('DAGGERHEART.GENERAL.reactionRoll')
|
||||
: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||
ability: game.i18n.localize(abilities[this.save.trait]?.label)
|
||||
});
|
||||
return actor.diceRoll({
|
||||
event,
|
||||
title,
|
||||
roll: {
|
||||
trait: this.save.trait,
|
||||
difficulty: this.save.difficulty ?? this.actor?.baseSaveDifficulty,
|
||||
type: 'reaction'
|
||||
},
|
||||
type: 'trait',
|
||||
hasRoll: true,
|
||||
data: actor.getRollData()
|
||||
});
|
||||
}),
|
||||
rollConfig = {
|
||||
event,
|
||||
title,
|
||||
roll: {
|
||||
trait: this.save.trait,
|
||||
difficulty: this.save.difficulty ?? this.actor?.baseSaveDifficulty,
|
||||
type: 'reaction'
|
||||
},
|
||||
type: 'trait',
|
||||
hasRoll: true,
|
||||
data: actor.getRollData()
|
||||
};
|
||||
if(SaveField.getAutomation() == CONFIG.DH.SETTINGS.actionAutomationChoices.always.id) rollConfig.dialog = { configure: false };
|
||||
return actor.diceRoll(rollConfig);
|
||||
}
|
||||
|
||||
static updateSaveMessage(result, message, targetId) {
|
||||
if (!result) return;
|
||||
const updateMsg = this.updateChatMessage.bind(this, message, targetId, {
|
||||
flags: {
|
||||
[game.system.id]: {
|
||||
reactionRolls: {
|
||||
[targetId]:
|
||||
{
|
||||
result: result.roll.total,
|
||||
success: result.roll.success
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (game.modules.get('dice-so-nice')?.active)
|
||||
game.dice3d.waitFor3DAnimationByMessageID(result.message.id ?? result.message._id).then(() => updateMsg());
|
||||
else updateMsg();
|
||||
}
|
||||
|
||||
static getAutomation() {
|
||||
return (game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.save.gm) || (!game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.save.players)
|
||||
}
|
||||
|
||||
static rollSaveQuery({ actionId, actorId, event, message }) {
|
||||
|
|
@ -57,7 +119,8 @@ export default class SaveField extends fields.SchemaField {
|
|||
const actor = await fromUuid(actorId),
|
||||
action = await fromUuid(actionId);
|
||||
if (!actor || !actor?.isOwner) reject();
|
||||
action.rollSave(actor, event, message).then(result => resolve(result));
|
||||
SaveField.rollSave.call(action, actor, event, message)
|
||||
.then(result => resolve(result));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,10 +41,8 @@ export default class DamageRoll extends DHRoll {
|
|||
await game.dice3d.showForRoll(diceRoll, game.user, true, chatMessage.whisper, chatMessage.blind);
|
||||
}
|
||||
await super.buildPost(roll, config, message);
|
||||
// console.log(config, config.source?.message)
|
||||
if (config.source?.message) {
|
||||
if (config.source?.message)
|
||||
chatMessage.update({ 'system.damage': config.damage });
|
||||
}
|
||||
}
|
||||
|
||||
static unifyDamageRoll(rolls) {
|
||||
|
|
|
|||
|
|
@ -45,10 +45,7 @@ export default class DHRoll extends Roll {
|
|||
}
|
||||
|
||||
for (const hook of config.hooks) {
|
||||
if (
|
||||
Hooks.call(`${CONFIG.DH.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false
|
||||
)
|
||||
return [];
|
||||
if (Hooks.call(`${CONFIG.DH.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false) return [];
|
||||
}
|
||||
return roll;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs';
|
||||
import SaveField from '../data/fields/action/saveField.mjs';
|
||||
|
||||
export function handleSocketEvent({ action = null, data = {} } = {}) {
|
||||
switch (action) {
|
||||
|
|
@ -79,7 +78,7 @@ export const registerSocketHooks = () => {
|
|||
|
||||
export const registerUserQueries = () => {
|
||||
CONFIG.queries.armorSlot = DamageReductionDialog.armorSlotQuery;
|
||||
CONFIG.queries.reactionRoll = SaveField.rollSaveQuery;
|
||||
CONFIG.queries.reactionRoll = game.system.api.fields.ActionFields.SaveField.rollSaveQuery;
|
||||
};
|
||||
|
||||
export const emitAsGM = async (eventName, callback, update, uuid = null) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue