This commit is contained in:
Aurélien LEBOURGEOIS 2025-06-22 15:29:41 +02:00
parent 385d414d7d
commit 1695c80388
10 changed files with 157 additions and 55 deletions

View file

@ -928,6 +928,7 @@
"AttackRoll": {
"Title": "Attack - {attack}",
"RollDamage": "Roll Damage",
"RollHealing": "Roll Healing",
"ApplyEffect": "Apply Effects"
},
"DamageRoll": {
@ -939,6 +940,7 @@
"Title": "Apply Effects - {name}"
},
"HealingRoll": {
"Title": "Heal - {healing}",
"Heal": "Heal"
},
"DeathMove": {

View file

@ -73,11 +73,14 @@ export class DHRoll extends Roll {
const cls = getDocumentClass("ChatMessage"),
msg = {
type: this.messageType,
user: game.user.id,
sound: config.mute ? null : CONFIG.sounds.dice,
system: config,
content: config.chatMessage.template,
// content: this.messageTemplate,
content: await this.messageTemplate(config),
rolls: [roll]
};
console.log(msg)
await cls.create(msg);
}
@ -117,6 +120,12 @@ export class D20Roll extends DHRoll {
static messageType = 'adversaryRoll';
// static messageTemplate = 'systems/daggerheart/templates/chat/adversary-roll.hbs';
static messageTemplate = async (config) => {
return 'systems/daggerheart/templates/chat/adversary-roll.hbs';
}
static CRITICAL_TRESHOLD = 20;
static DefaultDialog = D20RollDialog;
@ -215,11 +224,15 @@ export class D20Roll extends DHRoll {
static async postEvaluate(roll, config={}) {
if (config.targets?.length) {
targets = config.targets.map(target => {
/* targets = config.targets.map(target => {
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
target.hit = roll.total >= difficulty;
return target;
});
}); */
config.targets.forEach(target => {
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
target.hit = roll.total >= difficulty;
})
} else if(config.roll.difficulty) roll.success = roll.total >= config.roll.difficulty;
// config.roll.advantage = {
// dice: roll.dHope.faces,
@ -256,6 +269,12 @@ export class DualityRoll extends D20Roll {
static messageType = 'dualityRoll';
// static messageTemplate = 'systems/daggerheart/templates/chat/duality-roll.hbs';
static messageTemplate = async (config) => {
return 'systems/daggerheart/templates/chat/duality-roll.hbs';
}
static DefaultDialog = D20RollDialog;
get dHope() {
@ -358,11 +377,12 @@ export class DualityRoll extends D20Roll {
value: this.options.actor.traits[this.options.roll.trait].total
}
);
console.log(this.options)
// } else if(this.options.trait) this.terms.push(...this.formatModifier(this.options.actor.system.traits[this.options.roll.trait].total));
}
static async postEvaluate(roll, config={}) {
console.log(roll,config)
console.log(roll,config);
super.postEvaluate(roll, config);
config.roll.hope = {
dice: roll.dHope.denomination,
@ -387,9 +407,41 @@ export class DamageRoll extends DHRoll {
static messageType = 'damageRoll';
static DefaultDialog = DamageDialog;
// static messageTemplate = 'systems/daggerheart/templates/chat/damage-roll.hbs';
static messageTemplate = async (config) => {
return await foundry.applications.handlebars.renderTemplate(
config.messageTemplate ?? 'systems/daggerheart/templates/chat/damage-roll.hbs',
config
)
}
get messageTemplate() {
return 'systems/daggerheart/templates/chat/damage-roll.hbs';
static DefaultDialog = DamageDialog;
static async postEvaluate(roll, config={}) {
console.log(roll, config)
config.roll = {
// formula : config.formula,
result: roll.total,
dice: roll.dice
}
if(roll.healing) config.roll.type = roll.healing.type
/* const dice = [];
const modifiers = [];
for (var i = 0; i < roll.terms.length; i++) {
const term = roll.terms[i];
if (term.faces) {
dice.push({
type: `d${term.faces}`,
rolls: term.results.map(x => x.result),
total: term.results.reduce((acc, x) => acc + x.result, 0)
});
} else if (term.operator) {
} else if (term.number) {
const operator = i === 0 ? '' : roll.terms[i - 1].operator;
modifiers.push({ value: term.number, operator: operator });
}
}
config.roll.dice = dice;
config.roll.modifiers = modifiers; */
}
}

View file

@ -200,13 +200,11 @@ export class DHBaseAction extends foundry.abstract.DataModel {
},
type: this.type,
hasDamage: !!this.damage?.parts?.length,
hasEffect: !!this.effects?.length,
chatMessage: {
template: this.chatTemplate
}
hasHealing: !!this.healing,
hasEffect: !!this.effects?.length
};
this.proceedChatDisplay(config);
// this.proceedChatDisplay(config);
// Filter selected targets based on Target parameters
config.targets = await this.getTarget(config);
@ -385,6 +383,7 @@ export class DHDamageAction extends DHBaseAction {
}
async rollDamage(event, data) {
console.log(event, data)
let formula = this.damage.parts.map(p => p.getFormula(this.actor)).join(' + ');
if (!formula || formula == '') return;
@ -394,9 +393,6 @@ export class DHDamageAction extends DHBaseAction {
const config = {
title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }),
formula,
chatMessage: {
template: 'systems/daggerheart/templates/chat/damage-roll.hbs'
},
targets: (data.system?.targets ?? data.targets).map(x => ({ id: x.id, name: x.name, img: x.img, hit: true }))
}
@ -458,10 +454,6 @@ export class DHDamageAction extends DHBaseAction {
cls.create(msg.toObject()); */
}
get chatTemplate() {
return 'systems/daggerheart/templates/chat/damage-roll.hbs';
}
}
export class DHAttackAction extends DHDamageAction {
@ -497,9 +489,20 @@ export class DHAttackAction extends DHDamageAction {
}
export class DHHealingAction extends DHBaseAction {
static extraSchemas = ['target', 'effects', 'healing'];
static extraSchemas = ['target', 'effects', 'healing', 'roll'];
static getRollType(parent) {
return 'spellcast';
}
async use(event, ...args) {
const config = await super.use(event, args);
if(['error', 'warning'].includes(config.type)) return;
if(this.hasRoll()) return;
return await this.rollHealing(event, config);
}
/* async use(event, ...args) {
const config = await super.use(event, args);
if(['error', 'warning'].includes(config.type)) return;
const roll = await this.rollHealing(),
@ -516,10 +519,25 @@ export class DHHealingAction extends DHBaseAction {
});
cls.create(msg.toObject());
}
} */
async rollHealing() {
const formula = this.healing.value.getFormula(this.actor);
async rollHealing(event, data) {
console.log(event, data)
let formula = this.healing.value.getFormula(this.actor);
if (!formula || formula == '') return;
let roll = { formula: formula, total: formula },
bonusDamage = [];
const config = {
title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', { healing: game.i18n.localize(SYSTEM.GENERAL.healingTypes[this.healing.type].label) }),
formula,
targets: (data.system?.targets ?? data.targets).map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })),
messageTemplate: 'systems/daggerheart/templates/chat/healing-roll.hbs'
}
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config)
/* const formula = this.healing.value.getFormula(this.actor);
if (!formula || formula == '') return;
let roll = { formula: formula, total: formula };
@ -531,7 +549,7 @@ export class DHHealingAction extends DHBaseAction {
total: roll.total,
dice: roll.dice,
type: this.healing.type
}
} */
}
get chatTemplate() {

View file

@ -4,8 +4,9 @@ export default class DHDamageRoll extends foundry.abstract.TypeDataModel {
return {
title: new fields.StringField(),
roll: new fields.StringField({ required: true }),
damage: new fields.SchemaField({
// roll: new fields.StringField({ required: true }),
roll: new fields.DataField({}),
/* damage: new fields.SchemaField({
total: new fields.NumberField({ required: true, integer: true }),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
}),
@ -21,7 +22,7 @@ export default class DHDamageRoll extends foundry.abstract.TypeDataModel {
value: new fields.NumberField({ required: true, integer: true }),
operator: new fields.StringField({ required: true, choices: ['+', '-', '*', '/'] })
})
),
), */
targets: new fields.ArrayField(
new fields.SchemaField({
id: new fields.StringField({ required: true }),

View file

@ -40,6 +40,7 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
})
),
hasDamage: new fields.BooleanField({ initial: false }),
hasHealing: new fields.BooleanField({ initial: false }),
hasEffect: new fields.BooleanField({ initial: false }),
source: new fields.SchemaField({
actor: new fields.StringField(),

View file

@ -271,7 +271,8 @@ export default class DhpActor extends Actor {
// data: {
...config,
/* action, */
actor: this.getRollData(),
// actor: this.getRollData(),
actor: this.system
// },
// options: {
// dialog: false,
@ -507,13 +508,13 @@ export default class DhpActor extends Actor {
async takeDamage(damage, type) {
const hpDamage =
damage >= this.system.damageThresholds.severe
? 3
? -3
: damage >= this.system.damageThresholds.major
? 2
? -2
: damage >= this.system.damageThresholds.minor
? 1
? -1
: 0;
await this.modifyResource({value: hpDamage, type});
await this.modifyResource([{value: hpDamage, type}]);
/* const update = {
'system.resources.hitPoints.value': Math.min(
this.system.resources.hitPoints.value + hpDamage,

View file

@ -17,6 +17,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
html.querySelectorAll('.duality-action-damage').forEach(element =>
element.addEventListener('click', event => this.onRollDamage(event, data.message))
);
html.querySelectorAll('.duality-action-healing').forEach(element =>
element.addEventListener('click', event => this.onRollHealing(event, data.message))
);
html.querySelectorAll('.duality-action-effect').forEach(element =>
element.addEventListener('click', event => this.onApplyEffect(event, data.message))
);
@ -54,9 +57,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
onRollDamage = async (event, message) => {
event.stopPropagation();
console.log(message.system)
const actor = game.actors.get(message.system.source.actor);
console.log(message.system)
if (!actor || !game.user.isGM) return true;
if(message.system.source.item && message.system.source.action) {
const item = actor.items.get(message.system.source.item),
@ -73,6 +74,18 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
}
};
onRollHealing = async (event, message) => {
event.stopPropagation();
const actor = game.actors.get(message.system.source.actor);
if (!actor || !game.user.isGM) return true;
if(message.system.source.item && message.system.source.action) {
const item = actor.items.get(message.system.source.item),
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
if(!item || !action || !action?.rollHealing) return;
await action.rollHealing(event, message);
}
};
onApplyEffect = async (event, message) => {
event.stopPropagation();
const actor = game.actors.get(message.system.source.actor);
@ -80,7 +93,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
if(message.system.source.item && message.system.source.action) {
const item = actor.items.get(message.system.source.item),
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
if(!item || !action) return;
if(!item || !action || !action.applyEffects) return;
await action.applyEffects(event, message);
}
}

View file

@ -1,21 +1,20 @@
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
<div class="dice-flavor">{{title}}</div>
<div class="dice-result">
<div class="dice-formula">{{roll}}</div>
<div class="dice-formula">{{formula}}</div>
<div class="dice-tooltip">
<div class="wrapper">
<section class="tooltip-part">
{{#each dice}}
{{#each roll.dice}}
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{rolls.length}}{{type}}</span>
<span class="part-formula">{{formula}}</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
{{#each rolls}}
<li class="roll die {{../type}} min">{{this}}</li>
{{#each results}}
<li class="roll die {{../denomination}} min">{{result}}</li>
{{/each}}
</ol>
</div>
@ -23,7 +22,7 @@
</section>
</div>
</div>
<div class="dice-total">{{damage.total}}</div>
<div class="dice-total">{{roll.result}}</div>
<div class="dice-actions">
<button class="damage-button" data-target-hit="true" {{#if (eq targets.length 0)}}disabled{{/if}}>{{localize "DAGGERHEART.Chat.DamageRoll.DealDamageToTargets"}}</button>
<button class="damage-button">{{localize "DAGGERHEART.Chat.DamageRoll.DealDamage"}}</button>

View file

@ -107,9 +107,13 @@
<div class="dice-actions{{#unless (or hasDamage hasEffect)}} duality-alone{{/unless}}">
{{#if hasDamage}}
<button class="duality-action duality-action-damage" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.Chat.AttackRoll.RollDamage"}}</span></button>
{{else}}
{{#if hasHealing}}
<button class="duality-action duality-action-healing" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.Chat.AttackRoll.RollHealing"}}</span></button>
{{/if}}
{{/if}}
{{#if hasEffect}}
<button class="duality-action{{#if hasDamage}} duality-action-effect{{/if}}" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.Chat.AttackRoll.ApplyEffect"}}</span></button>
<button class="duality-action{{#if (or hasDamage hasHealing)}} duality-action-effect{{/if}}" data-value="{{roll.total}}"><span>{{localize "DAGGERHEART.Chat.AttackRoll.ApplyEffect"}}</span></button>
{{/if}}
<div class="duality-result">
<div>{{roll.total}} {{#if (eq roll.result.duality 1)}}With Hope{{else}}{{#if (eq roll.result.duality -1)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>

View file

@ -1,19 +1,30 @@
<div class="dice-roll daggerheart chat roll">
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
<div class="dice-flavor">{{title}}</div>
<div class="dice-result">
<div class="dice-formula">{{roll}}</div>
<div class="dice-formula">{{formula}}</div>
<div class="dice-tooltip">
<ol class="dice-rolls">
{{#each dice}}
<li class="roll die {{type}}">{{value}}</li>
{{/each}}
{{#each modifiers}}
<li class="modifier-value">{{this}}</li>
{{/each}}
</ol>
<div class="wrapper">
<section class="tooltip-part">
{{#each roll.dice}}
<div class="dice">
<header class="part-header flexrow">
<span class="part-formula">{{formula}}</span>
<span class="part-total">{{total}}</span>
</header>
<ol class="dice-rolls">
{{#each results}}
<li class="roll die {{../denomination}} min">{{result}}</li>
{{/each}}
</ol>
</div>
{{/each}}
</section>
</div>
</div>
<div class="dice-total">{{total}}</div>
<div class="dice-total">{{roll.result}}</div>
<div class="flexrow">
<button class="healing-button" data-value="{{total}}" data-type="{{type}}"><span>{{localize "DAGGERHEART.Chat.HealingRoll.Heal"}}</span></button>
<button class="healing-button" data-value="{{roll.result}}" data-type="{{roll.type}}"><span>{{localize "DAGGERHEART.Chat.HealingRoll.Heal"}}</span></button>
</div>
</div>
</div>