[Feature] Extended Scene Range Measurements (#1255)

* Extended the capabilities of scene rangemeasurement settings

* Corrected darkmode tab title
This commit is contained in:
WBHarry 2025-11-11 00:25:31 +01:00 committed by GitHub
parent 7055591a76
commit 052b6baefe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 182 additions and 21 deletions

View file

@ -2426,7 +2426,13 @@
"resetConfirmationText": "Are you sure you want to reset the {settings}?"
},
"Scene": {
"rangeMeasurementOverride": "Override Global Range Measurement Settings"
"FIELDS": {
"rangeMeasurement": {
"setting": { "label": "Setting" }
}
},
"disabledText": "Daggerheart Measurements are disabled in System Settings - Variant Rules",
"rangeMeasurement": "Range Measurement"
}
},
"UI": {

View file

@ -1,11 +1,17 @@
export default class DhSceneConfigSettings extends foundry.applications.sheets.SceneConfig {
constructor(options, ...args) {
super(options, ...args);
}
// static DEFAULT_OPTIONS = {
// ...super.DEFAULT_OPTIONS,
// form: {
// handler: this.updateData,
// closeOnSubmit: true
// }
// };
static buildParts() {
const { footer, ...parts } = super.PARTS;
const { footer, tabs, ...parts } = super.PARTS;
const tmpParts = {
// tabs,
tabs: { template: 'systems/daggerheart/templates/scene/tabs.hbs' },
...parts,
dh: { template: 'systems/daggerheart/templates/scene/dh-config.hbs' },
footer
@ -16,9 +22,42 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S
static PARTS = DhSceneConfigSettings.buildParts();
static buildTabs() {
super.TABS.sheet.tabs.push({ id: 'dh', icon: 'fa-solid' });
super.TABS.sheet.tabs.push({ id: 'dh', src: 'systems/daggerheart/assets/logos/FoundryBorneLogoWhite.svg' });
return super.TABS;
}
static TABS = DhSceneConfigSettings.buildTabs();
_attachPartListeners(partId, htmlElement, options) {
super._attachPartListeners(partId, htmlElement, options);
switch (partId) {
case 'dh':
htmlElement.querySelector('#rangeMeasurementSetting')?.addEventListener('change', async event => {
const flagData = foundry.utils.mergeObject(this.document.flags.daggerheart, {
rangeMeasurement: { setting: event.target.value }
});
this.document.flags.daggerheart = flagData;
this.render();
});
break;
}
}
/** @inheritDoc */
async _preparePartContext(partId, context, options) {
context = await super._preparePartContext(partId, context, options);
switch (partId) {
case 'dh':
context.data = new game.system.api.data.scenes.DHScene(canvas.scene.flags.daggerheart);
context.variantRules = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules);
break;
}
return context;
}
// static async updateData(event, _, formData) {
// const data = foundry.utils.expandObject(formData.object);
// this.close(data);
// }
}

View file

@ -18,30 +18,37 @@ export default class DhMeasuredTemplate extends foundry.canvas.placeables.Measur
static getRangeLabels(distanceValue, settings) {
let result = { distance: distanceValue, units: '' };
const rangeMeasurementOverride = canvas.scene.flags.daggerheart?.rangeMeasurementOverride;
const sceneRangeMeasurement = canvas.scene.flags.daggerheart?.rangeMeasurement;
if (rangeMeasurementOverride === true) {
const { disable, custom } = CONFIG.DH.GENERAL.sceneRangeMeasurementSetting;
if (sceneRangeMeasurement.setting === disable.id) {
result.distance = distanceValue;
result.units = canvas.scene?.grid?.units;
return result;
}
if (distanceValue <= settings.melee) {
const melee = sceneRangeMeasurement.setting === custom.id ? sceneRangeMeasurement.melee : settings.melee;
const veryClose =
sceneRangeMeasurement.setting === custom.id ? sceneRangeMeasurement.veryClose : settings.veryClose;
const close = sceneRangeMeasurement.setting === custom.id ? sceneRangeMeasurement.close : settings.close;
const far = sceneRangeMeasurement.setting === custom.id ? sceneRangeMeasurement.far : settings.far;
if (distanceValue <= melee) {
result.distance = game.i18n.localize('DAGGERHEART.CONFIG.Range.melee.name');
return result;
}
if (distanceValue <= settings.veryClose) {
if (distanceValue <= veryClose) {
result.distance = game.i18n.localize('DAGGERHEART.CONFIG.Range.veryClose.name');
return result;
}
if (distanceValue <= settings.close) {
if (distanceValue <= close) {
result.distance = game.i18n.localize('DAGGERHEART.CONFIG.Range.close.name');
return result;
}
if (distanceValue <= settings.far) {
if (distanceValue <= far) {
result.distance = game.i18n.localize('DAGGERHEART.CONFIG.Range.far.name');
return result;
}
if (distanceValue > settings.far) {
if (distanceValue > far) {
result.distance = game.i18n.localize('DAGGERHEART.CONFIG.Range.veryFar.name');
}

View file

@ -685,3 +685,18 @@ export const countdownAppMode = {
textIcon: 'text-icon',
iconOnly: 'icon-only'
};
export const sceneRangeMeasurementSetting = {
disable: {
id: 'disable',
label: 'Disable Daggerheart Range Measurement'
},
default: {
id: 'default',
label: 'Default'
},
custom: {
id: 'custom',
label: 'Custom'
}
};

View file

@ -7,3 +7,4 @@ export * as actors from './actor/_module.mjs';
export * as chatMessages from './chat-message/_modules.mjs';
export * as fields from './fields/_module.mjs';
export * as items from './item/_module.mjs';
export * as scenes from './scene/_module.mjs';

View file

@ -0,0 +1 @@
export { default as DHScene } from './scene.mjs';

View file

@ -0,0 +1,19 @@
export default class DHScene extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
rangeMeasurement: new fields.SchemaField({
setting: new fields.StringField({
choices: CONFIG.DH.GENERAL.sceneRangeMeasurementSetting,
initial: CONFIG.DH.GENERAL.sceneRangeMeasurementSetting.default.id,
label: 'DAGGERHEART.SETTINGS.Scene.FIELDS.rangeMeasurement.setting.label'
}),
melee: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.melee.name' }),
veryClose: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.veryClose.name' }),
close: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.close.name' }),
far: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.far.name' })
})
};
}
}

View file

@ -1,11 +1,13 @@
export const preloadHandlebarsTemplates = async function () {
foundry.applications.handlebars.loadTemplates({
'daggerheart.inventory-item-compact': 'systems/daggerheart/templates/sheets/global/partials/inventory-item-compact.hbs',
'daggerheart.inventory-item-compact':
'systems/daggerheart/templates/sheets/global/partials/inventory-item-compact.hbs',
'daggerheart.inventory-items':
'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs',
'daggerheart.inventory-item': 'systems/daggerheart/templates/sheets/global/partials/inventory-item-V2.hbs'
});
return foundry.applications.handlebars.loadTemplates([
'templates/generic/tab-navigation.hbs',
'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs',
'systems/daggerheart/templates/sheets/global/partials/action-item.hbs',
'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs',

View file

@ -28,3 +28,5 @@
@import './sidebar/tabs.less';
@import './sidebar/daggerheartMenu.less';
@import './scene-config/scene-config.less';

View file

@ -0,0 +1,40 @@
.theme-light .application.sheet.scene-config {
.sheet-tabs.tabs a[data-tab='dh'] {
&.active img,
&:hover img {
filter: @grey-filter drop-shadow(0 0 4px var(--color-shadow-primary));
}
img {
filter: @grey-filter;
}
}
}
.application.sheet.scene-config {
.sheet-tabs.tabs {
a[data-tab='dh'] {
display: flex;
align-items: center;
gap: 4px;
&.active,
&:hover {
img {
filter: @beige-filter drop-shadow(0 0 4px var(--color-shadow-primary));
}
}
img {
width: 18px;
position: relative;
top: -3px;
filter: @beige-filter;
}
}
}
.helper-text {
font-style: italic;
}
}

View file

@ -56,6 +56,8 @@
@dark-80: #22222280;
@dark-filter: brightness(0) saturate(100%);
@grey-filter: brightness(15%) saturate(20%);
@deep-black: #0e0d15;
@beige: #efe6d8;

View file

@ -1,9 +1,24 @@
<div class="tab{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
<div class="form-group">
<div class="form-fields">
<label>{{localize 'DAGGERHEART.SETTINGS.Scene.rangeMeasurementOverride'}}</label>
<input type="checkbox" name="flags.daggerheart.rangeMeasurementOverride" {{checked
document.flags.daggerheart.rangeMeasurementOverride}} />
</div>
</div>
<fieldset>
<legend>{{localize "DAGGERHEART.SETTINGS.Scene.rangeMeasurement"}}</legend>
{{#if variantRules.rangeMeasurement.enabled}}
{{formGroup data.schema.fields.rangeMeasurement.fields.setting value=data._source.rangeMeasurement.setting name="flags.daggerheart.rangeMeasurement.setting" id="rangeMeasurementSetting" localize=true blank=false}}
{{#if (eq data.rangeMeasurement.setting "custom")}}
{{formGroup data.schema.fields.rangeMeasurement.fields.melee value=data._source.rangeMeasurement.melee name="flags.daggerheart.rangeMeasurement.melee" localize=true}}
{{formGroup data.schema.fields.rangeMeasurement.fields.veryClose value=data._source.rangeMeasurement.veryClose name="flags.daggerheart.rangeMeasurement.veryClose" localize=true}}
{{formGroup data.schema.fields.rangeMeasurement.fields.close value=data._source.rangeMeasurement.close name="flags.daggerheart.rangeMeasurement.close" localize=true}}
{{formGroup data.schema.fields.rangeMeasurement.fields.far value=data._source.rangeMeasurement.far name="flags.daggerheart.rangeMeasurement.far" localize=true}}
{{/if}}
{{#if (eq data.rangeMeasurement.setting "default")}}
{{formGroup variantRules.schema.fields.rangeMeasurement.fields.melee value=variantRules._source.rangeMeasurement.melee localize=true disabled=true}}
{{formGroup variantRules.schema.fields.rangeMeasurement.fields.veryClose value=variantRules._source.rangeMeasurement.veryClose localize=true disabled=true}}
{{formGroup variantRules.schema.fields.rangeMeasurement.fields.close value=variantRules._source.rangeMeasurement.close localize=true disabled=true}}
{{formGroup variantRules.schema.fields.rangeMeasurement.fields.far value=variantRules._source.rangeMeasurement.far localize=true disabled=true}}
{{/if}}
{{else}}
<span class="helper-text">{{localize "DAGGERHEART.SETTINGS.Scene.disabledText"}}</span>
{{/if}}
</fieldset>
</div>

12
templates/scene/tabs.hbs Normal file
View file

@ -0,0 +1,12 @@
<nav class="sheet-tabs tabs{{#if verticalTabs}} vertical{{/if}}"
aria-roledescription="{{localize "SHEETS.FormNavLabel"}}">
{{#each tabs as |tab|}}
<a data-action="tab" data-group="{{tab.group}}" data-tab="{{tab.id}}"
{{#if tab.cssClass}}class="{{tab.cssClass}}"{{/if}}
{{#if tab.tooltip}}data-tooltip="{{tab.tooltip}}"{{/if}}>
{{#if tab.icon}}<i class="{{tab.icon}}" inert></i>{{/if}}
{{#if tab.src}}<img src="{{tab.src}}" />{{/if}}
{{#if tab.label}}<span>{{localize tab.label}}</span>{{/if}}
</a>
{{/each}}
</nav>