146 - Measured Templates (#147)

* Added DhMeasuredTemplate

* Added TemplateEnricher for Template buttons in text
This commit is contained in:
WBHarry 2025-06-15 20:33:34 +02:00 committed by GitHub
parent 7802d18a4d
commit 96ed90b5fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 168 additions and 66 deletions

View file

@ -1,35 +1,42 @@
export const range = {
self: {
id: 'self',
short: 's',
label: 'DAGGERHEART.Range.self.name',
description: 'DAGGERHEART.Range.self.description',
distance: 0
},
melee: {
id: 'melee',
short: 'm',
label: 'DAGGERHEART.Range.melee.name',
description: 'DAGGERHEART.Range.melee.description',
distance: 1
},
veryClose: {
id: 'veryClose',
short: 'vc',
label: 'DAGGERHEART.Range.veryClose.name',
description: 'DAGGERHEART.Range.veryClose.description',
distance: 3
},
close: {
id: 'close',
short: 'c',
label: 'DAGGERHEART.Range.close.name',
description: 'DAGGERHEART.Range.close.description',
distance: 10
},
far: {
id: 'far',
short: 'f',
label: 'DAGGERHEART.Range.far.name',
description: 'DAGGERHEART.Range.far.description',
distance: 20
},
veryFar: {
id: 'veryFar',
short: 'vf',
label: 'DAGGERHEART.Range.veryFar.name',
description: 'DAGGERHEART.Range.veryFar.description',
distance: 30

View file

@ -1,7 +1,7 @@
import { abilities } from '../config/actorConfig.mjs';
import { rollCommandToJSON } from '../helpers/utils.mjs';
import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs';
export function dualityRollEnricher(match, _options) {
export default function DhDualityRollEnricher(match, _options) {
const roll = rollCommandToJSON(match[1]);
if (!roll) return match[0];
@ -39,3 +39,24 @@ export function getDualityMessage(roll) {
return dualityElement;
}
export const renderDualityButton = async event => {
const button = event.currentTarget,
traitValue = button.dataset.trait?.toLowerCase(),
target = getCommandTarget();
if (!target) return;
const config = {
event: event,
title: button.dataset.title,
roll: {
modifier: traitValue ? target.system.traits[traitValue].value : null,
label: button.dataset.label,
type: button.dataset.actionType ?? null // Need check
},
chatMessage: {
template: 'systems/daggerheart/templates/chat/duality-roll.hbs'
}
};
await target.diceRoll(config);
};

View file

@ -0,0 +1,60 @@
import { range as configRange } from '../config/generalConfig.mjs';
export default function DhTemplateEnricher(match, _options) {
const parts = match[1].split('|').map(x => x.trim());
let type = null,
range = null;
parts.forEach(part => {
const split = part.split(':').map(x => x.toLowerCase().trim());
if (split.length === 2) {
switch (split[0]) {
case 'type':
const matchedType = Object.values(CONST.MEASURED_TEMPLATE_TYPES).find(
x => x.toLowerCase() === split[1]
);
type = matchedType;
break;
case 'range':
const matchedRange = Object.values(configRange).find(
x => x.id.toLowerCase() === split[1] || x.short === split[1]
);
range = matchedRange?.id;
break;
}
}
});
if (!type || !range) return match[0];
const templateElement = document.createElement('span');
templateElement.innerHTML = `
<button class="measured-template-button" data-type="${type}" data-range="${range}">
${game.i18n.localize(`TEMPLATE.TYPES.${type}`)} - ${game.i18n.localize(`DAGGERHEART.Range.${range}.name`)}
</button>
`;
return templateElement;
}
export const renderMeasuredTemplate = async event => {
const button = event.currentTarget,
type = button.dataset.type,
range = button.dataset.range;
if (!type || !range || !game.canvas.scene) return;
const distance = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement)[range];
const { width, height } = game.canvas.scene.dimensions;
canvas.scene.createEmbeddedDocuments('MeasuredTemplate', [
{
x: width / 2,
y: height / 2,
t: type,
distance: distance,
width: type === CONST.MEASURED_TEMPLATE_TYPES.RAY ? 5 : undefined,
angle: type === CONST.MEASURED_TEMPLATE_TYPES.CONE ? CONFIG.MeasuredTemplate.defaults.angle : undefined
}
]);
};

View file

@ -0,0 +1,4 @@
import DhDualityRollEnricher from './DualityRollEnricher.mjs';
import DhTemplateEnricher from './TemplateEnricher.mjs';
export { DhDualityRollEnricher, DhTemplateEnricher };

View file

@ -0,0 +1,3 @@
import DhMeasuredTemplate from './measuredTemplate.mjs';
export { DhMeasuredTemplate };

View file

@ -0,0 +1,35 @@
export default class DhMeasuredTemplate extends MeasuredTemplate {
_refreshRulerText() {
super._refreshRulerText();
const rangeMeasurementSettings = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement);
if (rangeMeasurementSettings.enabled) {
const splitRulerText = this.ruler.text.split(' ');
if (splitRulerText.length > 0) {
const rulerValue = Number(splitRulerText[0]);
const vagueLabel = this.constructor.getDistanceLabel(rulerValue, rangeMeasurementSettings);
this.ruler.text = vagueLabel;
}
}
}
static getDistanceLabel(distance, settings) {
if (distance <= settings.melee) {
return game.i18n.localize('DAGGERHEART.Range.melee.name');
}
if (distance <= settings.veryClose) {
return game.i18n.localize('DAGGERHEART.Range.veryClose.name');
}
if (distance <= settings.close) {
return game.i18n.localize('DAGGERHEART.Range.close.name');
}
if (distance <= settings.far) {
return game.i18n.localize('DAGGERHEART.Range.far.name');
}
if (distance <= settings.veryFar) {
return game.i18n.localize('DAGGERHEART.Range.veryFar.name');
}
return '';
}
}

View file

@ -1,3 +1,5 @@
import DhMeasuredTemplate from '../placeables/measuredTemplate.mjs';
export default class DhpRuler extends foundry.canvas.interaction.Ruler {
_getWaypointLabelContext(waypoint, state) {
const context = super._getWaypointLabelContext(waypoint, state);
@ -6,29 +8,11 @@ export default class DhpRuler extends foundry.canvas.interaction.Ruler {
const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement);
if (range.enabled) {
const distance = this.#getRangeLabel(waypoint.measurement.distance.toNearest(0.01), range);
const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range);
context.cost = { total: distance, units: null };
context.distance = { total: distance, units: null };
}
return context;
}
#getRangeLabel(distance, settings) {
if (distance <= settings.melee) {
return game.i18n.localize('DAGGERHEART.Range.melee.name');
}
if (distance <= settings.veryClose) {
return game.i18n.localize('DAGGERHEART.Range.veryClose.name');
}
if (distance <= settings.close) {
return game.i18n.localize('DAGGERHEART.Range.close.name');
}
if (distance <= settings.far) {
return game.i18n.localize('DAGGERHEART.Range.far.name');
}
if (distance <= settings.veryFar) {
return game.i18n.localize('DAGGERHEART.Range.veryFar.name');
}
}
}

View file

@ -1,3 +1,5 @@
import DhMeasuredTemplate from '../placeables/measuredTemplate.mjs';
export default class DhpTokenRuler extends foundry.canvas.placeables.tokens.TokenRuler {
_getWaypointLabelContext(waypoint, state) {
const context = super._getWaypointLabelContext(waypoint, state);
@ -6,29 +8,11 @@ export default class DhpTokenRuler extends foundry.canvas.placeables.tokens.Toke
const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement);
if (range.enabled) {
const distance = this.#getRangeLabel(waypoint.measurement.distance.toNearest(0.01), range);
const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range);
context.cost = { total: distance, units: null };
context.distance = { total: distance, units: null };
}
return context;
}
#getRangeLabel(distance, settings) {
if (distance <= settings.melee) {
return game.i18n.localize('DAGGERHEART.Range.melee.name');
}
if (distance <= settings.veryClose) {
return game.i18n.localize('DAGGERHEART.Range.veryClose.name');
}
if (distance <= settings.close) {
return game.i18n.localize('DAGGERHEART.Range.close.name');
}
if (distance <= settings.far) {
return game.i18n.localize('DAGGERHEART.Range.far.name');
}
if (distance <= settings.veryFar) {
return game.i18n.localize('DAGGERHEART.Range.veryFar.name');
}
}
}