Compare commits

...

7 commits

Author SHA1 Message Date
Chris Ryan
e0501d077f Remove debug message 2026-01-17 14:33:59 +10:00
Chris Ryan
1058b152c2 Pass the actor id through the button; fix /dr and /fr flavor text 2026-01-17 14:22:50 +10:00
Chris Ryan
2c93defd9c Fix the sliders to do the correct maximums 2026-01-17 12:11:21 +10:00
Chris Ryan
a071626e43 Merge branch 'main' into feature/death-moves 2026-01-17 11:29:18 +10:00
WBHarry
4ce8fbb84c Raised version 2026-01-17 01:42:40 +01:00
WBHarry
07bdd48199
[Fix] 1548 - Standalone Item Add Actions (#1549)
* Fixed so that items not on an actor don't error out on creating actions

* Fixed deletion of items error
2026-01-16 21:37:04 +01:00
Chris Ryan
22383613f1
Ensure effect is Applied to Actor (#1547)
Co-authored-by: Chris Ryan <chrisr@blackhole>
2026-01-16 16:43:29 +01:00
15 changed files with 24 additions and 24 deletions

View file

@ -300,8 +300,8 @@ Hooks.on('chatMessage', (_, message) => {
const difficulty = rollCommand.difficulty; const difficulty = rollCommand.difficulty;
const target = getCommandTarget({ allowNull: true }); const target = getCommandTarget({ allowNull: true });
const title = traitValue const title = flavor ??
? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { traitValue ? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label)
}) })
: game.i18n.localize('DAGGERHEART.GENERAL.duality'); : game.i18n.localize('DAGGERHEART.GENERAL.duality');

View file

@ -180,7 +180,8 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
'systems/daggerheart/templates/ui/chat/deathMove.hbs', 'systems/daggerheart/templates/ui/chat/deathMove.hbs',
{ {
player: this.actor.name, player: this.actor.name,
actor: { name: this.actor.name, img: this.actor.img }, actor: this.actor,
actorId: this.actor._id,
author: game.users.get(game.user.id), author: game.users.get(game.user.id),
title: game.i18n.localize(this.selectedMove.name), title: game.i18n.localize(this.selectedMove.name),
img: this.selectedMove.img, img: this.selectedMove.img,

View file

@ -41,6 +41,8 @@ export default class RiskItAllDialog extends HandlebarsApplicationMixin(Applicat
async _prepareContext(_options) { async _prepareContext(_options) {
const context = await super._prepareContext(_options); const context = await super._prepareContext(_options);
context.resourceValue = this.resourceValue; context.resourceValue = this.resourceValue;
context.maxHitPointsValue = Math.min(this.resourceValue, this.actor.system.resources.hitPoints.max);
context.maxStressValue = Math.min(this.resourceValue, this.actor.system.resources.stress.max);
context.remainingResource = this.resourceValue - this.choices.hitPoints - this.choices.stress; context.remainingResource = this.resourceValue - this.choices.hitPoints - this.choices.stress;
context.unfinished = context.remainingResource !== 0; context.unfinished = context.remainingResource !== 0;

View file

@ -391,6 +391,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
async riskItAllClearStressAndHitPoints(event, data) { async riskItAllClearStressAndHitPoints(event, data) {
const resourceValue = event.target.dataset.resourceValue; const resourceValue = event.target.dataset.resourceValue;
new game.system.api.applications.dialogs.RiskItAllDialog(data.actor, resourceValue).render({ force: true }); const actor = game.actors.get(event.target.dataset.actorId);
new game.system.api.applications.dialogs.RiskItAllDialog(actor, resourceValue).render({ force: true });
} }
} }

View file

@ -240,7 +240,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
game.system.registeredTriggers.unregisterTriggers(triggersToRemove, this.parent.uuid); game.system.registeredTriggers.unregisterTriggers(triggersToRemove, this.parent.uuid);
if (!(this.parent.parent.token instanceof game.system.api.documents.DhToken)) { if (this.parent.parent && !(this.parent.parent.token instanceof game.system.api.documents.DhToken)) {
for (const token of this.parent.parent.getActiveTokens()) { for (const token of this.parent.parent.getActiveTokens()) {
game.system.registeredTriggers.unregisterTriggers( game.system.registeredTriggers.unregisterTriggers(
triggersToRemove, triggersToRemove,

View file

@ -60,7 +60,7 @@ export default class RegisteredTriggers extends Map {
unregisterItemTriggers(items) { unregisterItemTriggers(items) {
for (const item of items) { for (const item of items) {
if (!item.system.actions.size) continue; if (!item.system.actions?.size) continue;
const triggers = (item.system.actions ?? []).reduce((acc, action) => { const triggers = (item.system.actions ?? []).reduce((acc, action) => {
acc.push(...action.triggers.map(x => x.trigger)); acc.push(...action.triggers.map(x => x.trigger));

View file

@ -118,10 +118,6 @@ export default class DualityRoll extends D20Roll {
/** @inheritDoc */ /** @inheritDoc */
static fromData(data) { static fromData(data) {
if (data.options.guaranteedCritical) {
console.log('TODO: set the max values for Hope and Fear here?');
}
data.terms[0].class = foundry.dice.terms.Die.name; data.terms[0].class = foundry.dice.terms.Die.name;
data.terms[2].class = foundry.dice.terms.Die.name; data.terms[2].class = foundry.dice.terms.Die.name;
return super.fromData(data); return super.fromData(data);

View file

@ -217,7 +217,7 @@ export default class DHItem extends foundry.documents.Item {
game.system.registeredTriggers.unregisterTriggers(triggerKeys, this.uuid); game.system.registeredTriggers.unregisterTriggers(triggerKeys, this.uuid);
if (!(this.actor.parent instanceof game.system.api.documents.DhToken)) { if (this.actor && !(this.actor.parent instanceof game.system.api.documents.DhToken)) {
for (const token of this.actor.getActiveTokens()) { for (const token of this.actor.getActiveTokens()) {
game.system.registeredTriggers.unregisterTriggers(triggerKeys, `${token.document.uuid}.${this.uuid}`); game.system.registeredTriggers.unregisterTriggers(triggerKeys, `${token.document.uuid}.${this.uuid}`);
} }

View file

@ -2,7 +2,7 @@ import { abilities } from '../config/actorConfig.mjs';
import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs'; import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs';
export default function DhDualityRollEnricher(match, _options) { export default function DhDualityRollEnricher(match, _options) {
const roll = rollCommandToJSON(match[1], match[0]); const roll = rollCommandToJSON(match[0]);
if (!roll) return match[0]; if (!roll) return match[0];
return getDualityMessage(roll.result, roll.flavor); return getDualityMessage(roll.result, roll.flavor);

View file

@ -1,7 +1,7 @@
import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs'; import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs';
export default function DhFateRollEnricher(match, _options) { export default function DhFateRollEnricher(match, _options) {
const roll = rollCommandToJSON(match[1], match[0]); const roll = rollCommandToJSON(match[0]);
if (!roll) return match[0]; if (!roll) return match[0];
return getFateMessage(roll.result, roll?.flavor); return getFateMessage(roll.result, roll?.flavor);
@ -45,7 +45,6 @@ function getFateMessage(roll, flavor) {
export const renderFateButton = async event => { export const renderFateButton = async event => {
const button = event.currentTarget, const button = event.currentTarget,
target = getCommandTarget({ allowNull: true }); target = getCommandTarget({ allowNull: true });
console.log('button', button);
const fateTypeData = getFateTypeData(button.dataset?.fatetype); const fateTypeData = getFateTypeData(button.dataset?.fatetype);

View file

@ -5,10 +5,10 @@ export const capitalize = string => {
return string.charAt(0).toUpperCase() + string.slice(1); return string.charAt(0).toUpperCase() + string.slice(1);
}; };
export function rollCommandToJSON(text, raw) { export function rollCommandToJSON(text) {
if (!text) return {}; if (!text) return {};
const flavorMatch = raw?.match(/{(.*)}$/); const flavorMatch = text?.match(/{(.*)}$/);
const flavor = flavorMatch ? flavorMatch[1] : null; const flavor = flavorMatch ? flavorMatch[1] : null;
// Match key="quoted string" OR key=unquotedValue // Match key="quoted string" OR key=unquotedValue
@ -31,7 +31,7 @@ export function rollCommandToJSON(text, raw) {
} }
result[key] = value; result[key] = value;
} }
return Object.keys(result).length > 0 ? { result, flavor } : null; return { result, flavor };
} }
export const getCommandTarget = (options = {}) => { export const getCommandTarget = (options = {}) => {

View file

@ -81,7 +81,7 @@
"name": "Bold Presence", "name": "Bold Presence",
"img": "icons/magic/holy/barrier-shield-winged-blue.webp", "img": "icons/magic/holy/barrier-shield-winged-blue.webp",
"origin": "Compendium.daggerheart.domains.Item.tdsL00yTSLNgZWs6", "origin": "Compendium.daggerheart.domains.Item.tdsL00yTSLNgZWs6",
"transfer": false, "transfer": true,
"_id": "2XEYhuAcRGTtqvED", "_id": "2XEYhuAcRGTtqvED",
"type": "base", "type": "base",
"system": { "system": {

View file

@ -2,7 +2,7 @@
"id": "daggerheart", "id": "daggerheart",
"title": "Daggerheart", "title": "Daggerheart",
"description": "An unofficial implementation of the Daggerheart system", "description": "An unofficial implementation of the Daggerheart system",
"version": "1.5.2", "version": "1.5.4",
"compatibility": { "compatibility": {
"minimum": "13.346", "minimum": "13.346",
"verified": "13.351", "verified": "13.351",

View file

@ -10,11 +10,11 @@
<div class="resource-section"> <div class="resource-section">
<div class="resource-container"> <div class="resource-container">
<label>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.clearResource" resource=(localize "DAGGERHEART.GENERAL.HitPoints.short")}}: {{this.choices.hitPoints}}</label> <label>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.clearResource" resource=(localize "DAGGERHEART.GENERAL.HitPoints.short")}}: {{this.choices.hitPoints}}</label>
<input type="range" step="1" min="0" max="{{this.resourceValue}}" value="{{this.choices.hitPoints}}" name="choices.hitPoints" data-choice="hitPoints" /> <input type="range" step="1" min="0" max="{{this.maxHitPointsValue}}" value="{{this.choices.hitPoints}}" name="choices.hitPoints" data-choice="hitPoints" />
</div> </div>
<div class="resource-container"> <div class="resource-container">
<label>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.clearResource" resource=(localize "DAGGERHEART.GENERAL.stress")}}: {{this.choices.stress}}</label> <label>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.clearResource" resource=(localize "DAGGERHEART.GENERAL.stress")}}: {{this.choices.stress}}</label>
<input type="range" step="1" min="0" max="{{this.resourceValue}}" value="{{this.choices.stress}}" name="choices.stress" data-choice="stress" /> <input type="range" step="1" min="0" max="{{this.maxStressValue}}" value="{{this.choices.stress}}" name="choices.stress" data-choice="stress" />
</div> </div>
</div> </div>

View file

@ -19,7 +19,7 @@
</div> </div>
{{#if this.showRiskItAllButton}} {{#if this.showRiskItAllButton}}
<div> <div>
<button class="risk-it-all-button" data-resource-value="{{this.riskItAllHope}}"> <button class="risk-it-all-button" data-resource-value="{{this.riskItAllHope}}" data-actor-id="{{this.actorId}}">
<span> <span>
{{this.riskItAllButtonLabel}} {{this.riskItAllButtonLabel}}
</span> </span>
@ -28,4 +28,5 @@
{{/if}} {{/if}}
</div> </div>
</div>
</div> </div>