* Fixes

* Remove comment
This commit is contained in:
Dapoulp 2025-08-10 01:23:00 +02:00 committed by GitHub
parent 7faec34597
commit 2aaab73699
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 87 additions and 53 deletions

View file

@ -505,7 +505,8 @@
}, },
"CLASS": { "CLASS": {
"Feature": { "Feature": {
"rallyDice": "Bardic Rally Dice" "rallyDice": "Bardic Rally Dice",
"short": "Rally"
} }
}, },
"CONFIG": { "CONFIG": {

View file

@ -146,7 +146,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
else if (this.hasSave || this.hasEffect) { else if (this.hasSave || this.hasEffect) {
const roll = new CONFIG.Dice.daggerheart.DHRoll(''); const roll = new CONFIG.Dice.daggerheart.DHRoll('');
roll._evaluated = true; roll._evaluated = true;
if(config.hasTarget) config.targetSelection = config.targets.length > 0;
await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config); await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
} }
} }
@ -227,15 +226,18 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
(!successCost && (!c.consumeOnSuccess || config.roll?.success)) || (!successCost && (!c.consumeOnSuccess || config.roll?.success)) ||
(successCost && c.consumeOnSuccess) (successCost && c.consumeOnSuccess)
) )
.map(c => { .reduce((a, c) => {
const resource = usefulResources[c.key]; const resource = usefulResources[c.key];
return { if( resource ) {
key: c.key, a.push({
value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1), key: c.key,
target: resource.target, value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1),
keyIsID: resource.keyIsID target: resource.target,
}; keyIsID: resource.keyIsID
}); });
return a;
}
}, []);
await (this.actor.system.partner ?? this.actor).modifyResource(resources); await (this.actor.system.partner ?? this.actor).modifyResource(resources);
if ( if (

View file

@ -49,8 +49,7 @@ export default class DHDamageAction extends DHBaseAction {
...systemData, ...systemData,
roll: formulas, roll: formulas,
dialog: {}, dialog: {},
data: this.getRollData(), data: this.getRollData()
targetSelection: systemData.targets.length > 0
}; };
if (this.hasSave) config.onSave = this.save.damageMod; if (this.hasSave) config.onSave = this.save.damageMod;
if (data.system) { if (data.system) {

View file

@ -18,14 +18,12 @@ const targetsField = () =>
); );
export default class DHActorRoll extends foundry.abstract.TypeDataModel { export default class DHActorRoll extends foundry.abstract.TypeDataModel {
targetHook = null;
static defineSchema() { static defineSchema() {
return { return {
title: new fields.StringField(), title: new fields.StringField(),
roll: new fields.ObjectField(), roll: new fields.ObjectField(),
targets: targetsField(), targets: targetsField(),
targetSelection: new fields.BooleanField({ initial: false }),
hasRoll: new fields.BooleanField({ initial: false }), hasRoll: new fields.BooleanField({ initial: false }),
hasDamage: new fields.BooleanField({ initial: false }), hasDamage: new fields.BooleanField({ initial: false }),
hasHealing: new fields.BooleanField({ initial: false }), hasHealing: new fields.BooleanField({ initial: false }),
@ -63,42 +61,45 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
} }
get targetMode() { get targetMode() {
return this.targetSelection; return this.parent.targetSelection;
} }
set targetMode(mode) { set targetMode(mode) {
this.targetSelection = mode; if(!this.parent.isAuthor) return;
this.parent.targetSelection = mode;
this.registerTargetHook(); this.registerTargetHook();
this.updateTargets(); this.updateTargets();
} }
get hitTargets() { get hitTargets() {
return this.currentTargets.filter(t => t.hit || !this.hasRoll || !this.targetSelection); return this.currentTargets.filter(t => t.hit || !this.hasRoll || !this.targetMode);
} }
async updateTargets() { async updateTargets() {
if(!ui.chat.collection.get(this.parent.id)) return; if(!ui.chat.collection.get(this.parent.id)) return;
let targets; let targets;
if(this.targetSelection) if(this.targetMode)
targets = this.targets; targets = this.targets;
else else
targets = Array.from(game.user.targets).map(t => game.system.api.fields.ActionFields.TargetField.formatTarget(t)); targets = Array.from(game.user.targets).map(t => game.system.api.fields.ActionFields.TargetField.formatTarget(t));
this.parent.setFlag(game.system.id, "targets", targets); await this.parent.update({
await this.parent.updateSource({ flags: {
system: { [game.system.id]: {
targetSelection: this.targetSelection targets: targets,
targetMode: this.targetMode
}
} }
}); })
} }
registerTargetHook() { registerTargetHook() {
if(!this.parent.isAuthor) return; if(!this.parent.isAuthor) return;
if(this.targetSelection && this.targetHook !== null) { if(this.targetMode && this.parent.targetHook !== null) {
Hooks.off("targetToken", this.targetHook); Hooks.off("targetToken", this.parent.targetHook);
this.targetHook = null; return this.parent.targetHook = null;
} else if (!this.targetSelection && this.targetHook === null) { } else if (!this.targetMode && this.parent.targetHook === null) {
this.targetHook = Hooks.on('targetToken', foundry.utils.debounce(this.updateTargets.bind(this), 50)); return this.parent.targetHook = Hooks.on('targetToken', foundry.utils.debounce(this.updateTargets.bind(this), 50));
} }
} }
@ -106,9 +107,8 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
if (this.hasTarget) { if (this.hasTarget) {
this.hasHitTarget = this.targets.filter(t => t.hit === true).length > 0; this.hasHitTarget = this.targets.filter(t => t.hit === true).length > 0;
this.currentTargets = this.getTargetList(); this.currentTargets = this.getTargetList();
this. registerTargetHook();
if(this.targetSelection === true && this.hasRoll) { if(this.targetMode === true && this.hasRoll) {
this.targetShort = this.targets.reduce((a,c) => { this.targetShort = this.targets.reduce((a,c) => {
if(c.hit) a.hit += 1; if(c.hit) a.hit += 1;
else a.miss += 1; else a.miss += 1;
@ -123,7 +123,7 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
} }
getTargetList() { getTargetList() {
const targets = this.targetSelection && this.parent.isAuthor ? this.targets : (this.parent.getFlag(game.system.id, "targets") ?? this.targets), const targets = this.targetMode && this.parent.isAuthor ? this.targets : (this.parent.getFlag(game.system.id, "targets") ?? this.targets),
reactionRolls = this.parent.getFlag(game.system.id, "reactionRolls"); reactionRolls = this.parent.getFlag(game.system.id, "reactionRolls");
if(reactionRolls) { if(reactionRolls) {
@ -137,7 +137,7 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
} }
setPendingSaves() { setPendingSaves() {
this.pendingSaves = this.targetSelection this.pendingSaves = this.targetMode
? this.targets.filter(target => target.hit && target.saved.success === null).length > 0 ? this.targets.filter(target => target.hit && target.saved.success === null).length > 0
: this.currentTargets.filter(target => target.saved.success === null).length > 0; : this.currentTargets.filter(target => target.saved.success === null).length > 0;
} }

View file

@ -229,7 +229,7 @@ export function ActionMixin(Base) {
} }
return this.inCollection return this.inCollection
? foundry.utils.getProperty(result, basePath).get(this.id) ? foundry.utils.getProperty(result, basePath)?.get(this.id)
: foundry.utils.getProperty(result, basePath); : foundry.utils.getProperty(result, basePath);
} }

View file

@ -141,7 +141,6 @@ export default class D20Roll extends DHRoll {
data.type = config.roll?.type; data.type = config.roll?.type;
data.difficulty = config.roll.difficulty; data.difficulty = config.roll.difficulty;
if (config.targets?.length) { if (config.targets?.length) {
config.targetSelection = true;
config.targets.forEach(target => { config.targets.forEach(target => {
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
target.hit = roll.isCritical || roll.total >= difficulty; target.hit = roll.isCritical || roll.total >= difficulty;

View file

@ -15,7 +15,6 @@ export default class DamageRoll extends DHRoll {
const parts = config.roll.map(r => this.postEvaluate(r)); const parts = config.roll.map(r => this.postEvaluate(r));
config.damage = this.unifyDamageRoll(parts); config.damage = this.unifyDamageRoll(parts);
// config.targetSelection = config.targets?.length
} }
static postEvaluate(roll, config = {}) { static postEvaluate(roll, config = {}) {

View file

@ -644,16 +644,20 @@ export default class DhpActor extends Actor {
); );
break; break;
case 'armor': case 'armor':
updates.armor.resources['system.marks.value'] = Math.max( if(this.system.armor?.system?.marks) {
Math.min(this.system.armor.system.marks.value + r.value, this.system.armorScore), updates.armor.resources['system.marks.value'] = Math.max(
0 Math.min(this.system.armor.system.marks.value + r.value, this.system.armorScore),
); 0
);
}
break; break;
default: default:
updates.actor.resources[`system.resources.${r.key}.value`] = Math.max( if(this.system.resources?.[r.key]) {
Math.min(this.system.resources[r.key].value + r.value, this.system.resources[r.key].max), updates.actor.resources[`system.resources.${r.key}.value`] = Math.max(
0 Math.min(this.system.resources[r.key].value + r.value, this.system.resources[r.key].max),
); 0
);
}
break; break;
} }
} }

View file

@ -1,4 +1,7 @@
export default class DhpChatMessage extends foundry.documents.ChatMessage { export default class DhpChatMessage extends foundry.documents.ChatMessage {
targetHook = null;
targetSelection = null;
async renderHTML() { async renderHTML() {
const actor = game.actors.get(this.speaker.actor); const actor = game.actors.get(this.speaker.actor);
const actorData = actor && this.isContentVisible ? actor : { const actorData = actor && this.isContentVisible ? actor : {
@ -14,6 +17,32 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
return html; return html;
} }
/* -------------------------------------------- */
/** @inheritDoc */
prepareData() {
if(this.isAuthor && this.targetSelection === null)
this.targetSelection = this.system.targets?.length > 0;
super.prepareData();
}
/* -------------------------------------------- */
/** @inheritDoc */
_onCreate(data, options, userId) {
super._onCreate(data, options, userId);
if(this.system.registerTargetHook) this.system.registerTargetHook();
}
/* -------------------------------------------- */
/** @inheritDoc */
async _preDelete(options, user) {
if(this.targetHook !== null) Hooks.off("targetToken", this.targetHook);
return super._preDelete(options, user);
}
enrichChatMessage(html) { enrichChatMessage(html) {
const elements = html.querySelectorAll('[data-perm-id]'); const elements = html.querySelectorAll('[data-perm-id]');
elements.forEach(e => { elements.forEach(e => {
@ -62,7 +91,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
} }
getTargetList() { getTargetList() {
const targets = this.system.hitTargets; const targets = this.system.hitTargets ?? [];
return targets.map(target => game.canvas.tokens.documentCollection.find(t => t.actor?.uuid === target.actorId)); return targets.map(target => game.canvas.tokens.documentCollection.find(t => t.actor?.uuid === target.actorId));
} }
@ -134,7 +163,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
} }
consumeOnSuccess() { consumeOnSuccess() {
if (!this.system.successConsumed && !this.system.targetSelection) { if (!this.system.successConsumed && !this.targetSelection) {
const action = this.system.action; const action = this.system.action;
if (action) action.consume(this.system, true); if (action) action.consume(this.system, true);
} }
@ -143,12 +172,12 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
hoverTarget(event) { hoverTarget(event) {
event.stopPropagation(); event.stopPropagation();
const token = canvas.tokens.get(event.currentTarget.dataset.token); const token = canvas.tokens.get(event.currentTarget.dataset.token);
if (!token?.controlled) token._onHoverIn(event, { hoverOutOthers: true }); if (token && !token?.controlled) token._onHoverIn(event, { hoverOutOthers: true });
} }
unhoverTarget(event) { unhoverTarget(event) {
const token = canvas.tokens.get(event.currentTarget.dataset.token); const token = canvas.tokens.get(event.currentTarget.dataset.token);
if (!token?.controlled) token._onHoverOut(event); if (token && !token?.controlled) token._onHoverOut(event);
} }
clickTarget(event) { clickTarget(event) {
@ -163,6 +192,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
onTargetSelection(event) { onTargetSelection(event) {
event.stopPropagation(); event.stopPropagation();
this.system.targetMode = Boolean(event.target.dataset.targetHit); if(!event.target.classList.contains("target-selected"))
this.system.targetMode = Boolean(event.target.dataset.targetHit);
} }
} }

View file

@ -57,7 +57,7 @@
{{/if}} {{/if}}
{{#if roll.rally.dice}} {{#if roll.rally.dice}}
<div class="roll-die has-plus"> <div class="roll-die has-plus">
<label>{{localize "DAGGERHEART.GENERAL.fear"}}</label> <label>{{localize "DAGGERHEART.CLASS.Feature.short"}}</label>
<div class="dice {{roll.rally.dice}}">{{roll.rally.value}}</div> <div class="dice {{roll.rally.dice}}">{{roll.rally.value}}</div>
</div> </div>
{{/if}} {{/if}}

View file

@ -18,8 +18,8 @@
<div class="target-selector"> <div class="target-selector">
<div class="roll-part-header"><div></div></div> <div class="roll-part-header"><div></div></div>
<div class="target-choice"> <div class="target-choice">
<div class="button-target-selection{{#if targetSelection}} target-selected{{/if}}" data-target-hit="true">{{localize "DAGGERHEART.UI.Chat.damageRoll.hitTarget"}}</div> <div class="button-target-selection{{#if targetMode}} target-selected{{/if}}" data-target-hit="true">{{localize "DAGGERHEART.UI.Chat.damageRoll.hitTarget"}}</div>
<div class="button-target-selection{{#unless targetSelection}} target-selected{{/unless}}">{{localize "DAGGERHEART.UI.Chat.damageRoll.currentTarget"}}</div> <div class="button-target-selection{{#unless targetMode}} target-selected{{/unless}}">{{localize "DAGGERHEART.UI.Chat.damageRoll.currentTarget"}}</div>
</div> </div>
<div class="roll-part-header"><div></div></div> <div class="roll-part-header"><div></div></div>
</div> </div>
@ -30,7 +30,7 @@
<img class="target-img" src="{{img}}"> <img class="target-img" src="{{img}}">
<div class="target-data"> <div class="target-data">
<div class="target-name" data-perm-id="{{actorId}}"><span>{{name}}</span></div> <div class="target-name" data-perm-id="{{actorId}}"><span>{{name}}</span></div>
{{#if (and ../targetSelection ../hasRoll)}} {{#if (and ../targetMode ../hasRoll)}}
<div class="target-hit-status {{#if hit}}is-hit{{else}}is-miss{{/if}}"> <div class="target-hit-status {{#if hit}}is-hit{{else}}is-miss{{/if}}">
{{#if hit}} {{#if hit}}
{{localize "DAGGERHEART.GENERAL.hit.single"}} {{localize "DAGGERHEART.GENERAL.hit.single"}}