[Fix] Hit/Miss Display (#1711)

* Added an AppearanceSetting that decided if players should get to see information about hit/miss in chat messages

* .

* Improved setting name

* Introduced metagaming settings

* Raised verison
This commit is contained in:
WBHarry 2026-03-10 18:48:44 +01:00 committed by GitHub
parent f920fa7ba2
commit af04fb33d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 142 additions and 6 deletions

View file

@ -2644,6 +2644,14 @@
"title": "Triggers"
}
},
"Metagaming": {
"FIELDS": {
"hideObserverPermissionInChat": {
"label": "Hide Chat Info From Players",
"hint": "Information such as hit/miss on attack rolls against adversaries will be hidden"
}
}
},
"Homebrew": {
"newDowntimeMove": "Downtime Move",
"downtimeMove": "Downtime Move",
@ -2703,6 +2711,11 @@
"label": "Configure Automation",
"hint": "Various settings automating resource management and more"
},
"metagaming": {
"name": "Metagaming Settings",
"label": "Configure Metagaming",
"hint": "Various settings controlling the flow of information to players"
},
"homebrew": {
"name": "Homebrew Settings",
"label": "Configure Homebrew",

View file

@ -1,4 +1,5 @@
export { default as DhAppearanceSettings } from './appearanceSettings.mjs';
export { default as DhAutomationSettings } from './automationSettings.mjs';
export { default as DhHomebrewSettings } from './homebrewSettings.mjs';
export { default as DhMetagamingSettings } from './metagamingSettings.mjs';
export { default as DhVariantRuleSettings } from './variantRuleSettings.mjs';

View file

@ -31,8 +31,8 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App
};
static PARTS = {
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
header: { template: 'systems/daggerheart/templates/settings/automation-settings/header.hbs' },
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
general: { template: 'systems/daggerheart/templates/settings/automation-settings/general.hbs' },
rules: { template: 'systems/daggerheart/templates/settings/automation-settings/deathMoves.hbs' },
roll: { template: 'systems/daggerheart/templates/settings/automation-settings/roll.hbs' },

View file

@ -0,0 +1,62 @@
import { DhMetagaming } from '../../data/settings/_module.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
export default class DhMetagamingSettings extends HandlebarsApplicationMixin(ApplicationV2) {
constructor() {
super({});
this.settings = new DhMetagaming(
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming).toObject()
);
}
get title() {
return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.title');
}
static DEFAULT_OPTIONS = {
tag: 'form',
id: 'daggerheart-metagaming-settings',
classes: ['daggerheart', 'dh-style', 'dialog', 'setting'],
position: { width: '600', height: 'auto' },
window: {
icon: 'fa-solid fa-eye-low-vision'
},
actions: {
reset: this.reset,
save: this.save
},
form: { handler: this.updateData, submitOnChange: true }
};
static PARTS = {
header: { template: 'systems/daggerheart/templates/settings/metagaming-settings/header.hbs' },
general: { template: 'systems/daggerheart/templates/settings/metagaming-settings/general.hbs' },
footer: { template: 'systems/daggerheart/templates/settings/metagaming-settings/footer.hbs' }
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.settingFields = this.settings;
return context;
}
static async updateData(_event, _element, formData) {
const updatedSettings = foundry.utils.expandObject(formData.object);
await this.settings.updateSource(updatedSettings);
this.render();
}
static async reset() {
this.settings = new DhMetagaming();
this.render();
}
static async save() {
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming, this.settings.toObject());
this.close();
}
}

View file

@ -3,6 +3,10 @@ export const menu = {
Name: 'GameSettingsAutomation',
Icon: 'fa-solid fa-robot'
},
Metagaming: {
Name: 'GameSettingsMetagaming',
Icon: 'fa-solid fa-eye-low-vision'
},
Homebrew: {
Name: 'GameSettingsHomebrew',
Icon: 'fa-solid fa-flask-vial'
@ -19,6 +23,7 @@ export const menu = {
export const gameSettings = {
Automation: 'Automation',
Metagaming: 'Metagaming',
Homebrew: 'Homebrew',
appearance: 'Appearance',
variantRules: 'VariantRules',

View file

@ -0,0 +1,12 @@
export default class DhMetagaming extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
hideObserverPermissionInChat: new fields.BooleanField({
initial: false,
label: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.label',
hint: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.hint'
})
};
}
}

View file

@ -1,4 +1,5 @@
export { default as DhAppearance } from './Appearance.mjs';
export { default as DhAutomation } from './Automation.mjs';
export { default as DhHomebrew } from './Homebrew.mjs';
export { default as DhMetagaming } from './Metagaming.mjs';
export { default as DhVariantRules } from './VariantRules.mjs';

View file

@ -140,8 +140,10 @@ export default class DHRoll extends Roll {
/** @inheritDoc */
async render({ flavor, template = this.constructor.CHAT_TEMPLATE, isPrivate = false, ...options } = {}) {
if (!this._evaluated) return;
const metagamingSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming);
const chatData = await this._prepareChatRenderContext({ flavor, isPrivate, ...options });
return foundry.applications.handlebars.renderTemplate(template, chatData);
return foundry.applications.handlebars.renderTemplate(template, { ...chatData, metagamingSettings });
}
/** @inheritDoc */

View file

@ -68,8 +68,11 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
document = fromUuidSync(uuid);
if (!document) return;
e.setAttribute('data-view-perm', document.testUserPermission(game.user, 'OBSERVER'));
e.setAttribute('data-use-perm', document.testUserPermission(game.user, 'OWNER'));
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming);
if (settings.hideObserverPermissionInChat)
e.setAttribute('data-view-perm', document.testUserPermission(game.user, 'OBSERVER'));
});
if (this.isContentVisible) {

View file

@ -1,10 +1,11 @@
import { defaultLevelTiers, DhLevelTiers } from '../data/levelTier.mjs';
import DhCountdowns from '../data/countdowns.mjs';
import { DhAppearance, DhAutomation, DhHomebrew, DhVariantRules } from '../data/settings/_module.mjs';
import { DhAppearance, DhAutomation, DhHomebrew, DhMetagaming, DhVariantRules } from '../data/settings/_module.mjs';
import {
DhAppearanceSettings,
DhAutomationSettings,
DhHomebrewSettings,
DhMetagamingSettings,
DhVariantRuleSettings
} from '../applications/settings/_module.mjs';
import { CompendiumBrowserSettings, DhTagTeamRoll } from '../data/_module.mjs';
@ -38,6 +39,12 @@ const registerMenuSettings = () => {
type: DhAutomation
});
game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming, {
scope: 'world',
config: false,
type: DhMetagaming
});
game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, {
scope: 'world',
config: false,
@ -76,6 +83,16 @@ const registerMenus = () => {
type: DhAutomationSettings,
restricted: true
});
game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.menu.Metagaming.Name, {
name: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.metagaming.name'),
label: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.metagaming.label'),
hint: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.metagaming.hint'),
icon: CONFIG.DH.SETTINGS.menu.Metagaming.Icon,
type: DhMetagamingSettings,
restricted: true
});
game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.menu.Homebrew.Name, {
name: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.homebrew.name'),
label: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.homebrew.label'),

View file

@ -450,6 +450,10 @@
.target-data {
flex: 1;
.target-name {
text-align: left;
}
}
.target-save {

View file

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

View file

@ -0,0 +1,10 @@
<footer class="form-footer">
<button data-action="reset">
<i class="fa-solid fa-arrow-rotate-left"></i>
<span>{{localize "Reset"}}</span>
</button>
<button data-action="save" >
<i class="fa-solid fa-floppy-disk"></i>
<span>{{localize "Save Changes"}}</span>
</button>
</footer>

View file

@ -0,0 +1,3 @@
<div>
{{formGroup settingFields.schema.fields.hideObserverPermissionInChat value=settingFields._source.hideObserverPermissionInChat localize=true}}
</div>

View file

@ -0,0 +1,3 @@
<header class="dialog-header">
<h1>{{localize 'DAGGERHEART.SETTINGS.Menu.metagaming.name'}}</h1>
</header>

View file

@ -1,6 +1,6 @@
<div class="roll-part target-section dice-roll" data-action="expandRoll">
<div class="roll-part-header"><div><span>{{pluralize currentTargets.length "DAGGERHEART.GENERAL.Target"}}</span></div></div>
{{#if isGM}}
{{#if (or isGM (not metagamingSettings.hideObserverPermissionInChat))}}
<div class="roll-part-extra on-reduced">
<div class="wrapper">
{{#if (or (gt targetShort.hit 0) (gt targetShort.miss 0))}}