add scaling option for fear tracker

This commit is contained in:
CPTN Cosmo 2026-07-12 19:22:20 +02:00
parent 318498489b
commit 737690f42a
3 changed files with 262 additions and 16 deletions

View file

@ -69,6 +69,35 @@ Hooks.once("init", () => {
default: false
});
game.settings.register("cosmos-dh-tweaks", "fearTrackerScale", {
name: "COSMOS_DH_TWEAKS.Settings.FearTrackerScale.Name",
hint: "COSMOS_DH_TWEAKS.Settings.FearTrackerScale.Hint",
scope: "client",
config: true,
type: Number,
range: {
min: 0.5,
max: 1.5,
step: 0.05
},
default: 1.0,
onChange: () => {
if (ui.resources && ui.resources.rendered) {
ui.resources.updateScale();
ui.resources.adjustSizeToMaxFear();
}
}
});
game.settings.register("cosmos-dh-tweaks", "resetFearScale", {
name: "COSMOS_DH_TWEAKS.Settings.ResetFearScale.Name",
hint: "COSMOS_DH_TWEAKS.Settings.ResetFearScale.Hint",
scope: "client",
config: true,
type: Boolean,
default: false
});
// Override the FearTracker class in CONFIG
const OriginalFearTracker = CONFIG.ui.resources;
if (OriginalFearTracker) {
@ -106,9 +135,16 @@ Hooks.once("init", () => {
this.updateTitleBarStatus();
this.updateLockStatus();
this.updateScale();
this.adjustSizeToMaxFear();
}
updateScale() {
if (!this.element) return;
const scale = game.settings.get("cosmos-dh-tweaks", "fearTrackerScale") ?? 1.0;
this.element.style.setProperty('--cosmo-fear-scale', scale);
}
updateTitleBarStatus() {
if (!this.element) return;
const removeTitleBar = game.settings.get("cosmos-dh-tweaks", "removeFearTitleBar");
@ -192,24 +228,35 @@ Hooks.once("init", () => {
}
calculatePerfectSize(targetWidth, measurements) {
const { skullW, skullH, gapX, gapY, padX, padY, headerH } = measurements;
const scale = game.settings.get("cosmos-dh-tweaks", "fearTrackerScale") ?? 1.0;
// Divide measurements by scale to work with unscaled base measurements
const skullW = measurements.skullW / scale;
const skullH = measurements.skullH / scale;
const gapX = measurements.gapX / scale;
const gapY = measurements.gapY / scale;
const padX = measurements.padX / scale;
const padY = measurements.padY / scale;
const headerH = measurements.headerH / scale;
const display = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).displayFear;
const maxFear = this.maxFear;
if (display === 'bar') {
const barElement = this.element.querySelector('#resource-fear');
const barH = barElement ? barElement.getBoundingClientRect().height : 30;
const barH = barElement ? (barElement.getBoundingClientRect().height / scale) : 30;
const perfectH = barH + padY + headerH;
const minW = 200;
const perfectW = Math.max(minW, targetWidth || 222);
const targetWUnscaled = targetWidth ? (targetWidth / scale) : 222;
const perfectW = Math.max(minW, targetWUnscaled);
return {
width: perfectW,
height: perfectH
width: perfectW * scale,
height: perfectH * scale
};
} else {
const w = targetWidth || 222;
let cols = Math.round((w - padX + gapX) / (skullW + gapX));
const targetWUnscaled = targetWidth ? (targetWidth / scale) : 222;
let cols = Math.round((targetWUnscaled - padX + gapX) / (skullW + gapX));
cols = Math.max(1, Math.min(maxFear, cols));
const perfectW = cols * skullW + (cols - 1) * gapX + padX + 2;
@ -217,8 +264,8 @@ Hooks.once("init", () => {
const perfectH = rows * skullH + (rows - 1) * gapY + padY + headerH + 2;
return {
width: perfectW,
height: perfectH
width: perfectW * scale,
height: perfectH * scale
};
}
}
@ -289,6 +336,7 @@ Hooks.once("init", () => {
if (existing) existing.remove();
const isLocked = game.settings.get("cosmos-dh-tweaks", "lockFearTrackerPosition");
const currentScale = game.settings.get("cosmos-dh-tweaks", "fearTrackerScale") ?? 1.0;
const menu = document.createElement('div');
menu.className = 'cosmo-fear-context-menu';
@ -301,6 +349,20 @@ Hooks.once("init", () => {
<li class="cosmo-context-menu-item lock-toggle" data-action="toggle-lock">
${lockText}
</li>
<li class="cosmo-context-menu-item reset-position" data-action="reset-position">
<i class="fa-solid fa-arrows-rotate"></i> ${game.i18n.localize("COSMOS_DH_TWEAKS.ContextMenu.ResetPosition")}
</li>
<li class="cosmo-context-menu-item reset-scale" data-action="reset-scale">
<i class="fa-solid fa-expand"></i> ${game.i18n.localize("COSMOS_DH_TWEAKS.ContextMenu.ResetScale")}
</li>
<li class="cosmo-context-menu-header">${game.i18n.localize("COSMOS_DH_TWEAKS.ContextMenu.ScaleHeader")}</li>
<li class="cosmo-context-menu-scale-controls">
<button class="scale-btn ${Math.abs(currentScale - 0.7) < 0.01 ? 'active' : ''}" data-scale="0.7">70%</button>
<button class="scale-btn ${Math.abs(currentScale - 0.85) < 0.01 ? 'active' : ''}" data-scale="0.85">85%</button>
<button class="scale-btn ${Math.abs(currentScale - 1.0) < 0.01 ? 'active' : ''}" data-scale="1.0">100%</button>
<button class="scale-btn ${Math.abs(currentScale - 1.15) < 0.01 ? 'active' : ''}" data-scale="1.15">115%</button>
<button class="scale-btn ${Math.abs(currentScale - 1.3) < 0.01 ? 'active' : ''}" data-scale="1.3">130%</button>
</li>
</ul>
`;
@ -319,6 +381,37 @@ Hooks.once("init", () => {
menu.remove();
});
menu.querySelector('[data-action="reset-position"]').addEventListener('click', async (event) => {
event.preventDefault();
await game.user.unsetFlag(CONFIG.DH.id, 'app.resources.position');
if (this.rendered) {
const defaultPos = CONFIG.ui.resources.DEFAULT_OPTIONS.position;
await this.setPosition(defaultPos);
}
ui.notifications.info(game.i18n.localize("COSMOS_DH_TWEAKS.Settings.ResetFearPosition.Success"));
menu.remove();
});
menu.querySelector('[data-action="reset-scale"]').addEventListener('click', async (event) => {
event.preventDefault();
await game.settings.set("cosmos-dh-tweaks", "fearTrackerScale", 1.0);
this.updateScale();
this.adjustSizeToMaxFear();
ui.notifications.info(game.i18n.localize("COSMOS_DH_TWEAKS.Settings.ResetFearScale.Success"));
menu.remove();
});
menu.querySelectorAll('.scale-btn').forEach(btn => {
btn.addEventListener('click', async (event) => {
event.preventDefault();
const newScale = parseFloat(btn.dataset.scale);
await game.settings.set("cosmos-dh-tweaks", "fearTrackerScale", newScale);
this.updateScale();
this.adjustSizeToMaxFear();
menu.remove();
});
});
const closeMenu = (event) => {
if (!menu.contains(event.target)) {
menu.remove();
@ -628,12 +721,12 @@ Hooks.on("destroyToken", (token) => {
});
Hooks.on("renderSettingsConfig", (app, html, data) => {
const input = html.querySelector
const posInput = html.querySelector
? html.querySelector('[name="cosmos-dh-tweaks.resetFearPosition"]')
: html.find('[name="cosmos-dh-tweaks.resetFearPosition"]')[0];
if (input) {
const formGroup = input.closest('.form-group');
if (posInput) {
const formGroup = posInput.closest('.form-group');
if (formGroup) {
const formFields = formGroup.querySelector('.form-fields');
if (formFields) {
@ -656,4 +749,33 @@ Hooks.on("renderSettingsConfig", (app, html, data) => {
}
}
}
const scaleInput = html.querySelector
? html.querySelector('[name="cosmos-dh-tweaks.resetFearScale"]')
: html.find('[name="cosmos-dh-tweaks.resetFearScale"]')[0];
if (scaleInput) {
const formGroup = scaleInput.closest('.form-group');
if (formGroup) {
const formFields = formGroup.querySelector('.form-fields');
if (formFields) {
const button = document.createElement('button');
button.type = 'button';
button.className = 'cosmo-reset-fear-scale-btn';
button.innerHTML = `<i class="fa-solid fa-arrows-rotate"></i> ${game.i18n.localize("COSMOS_DH_TWEAKS.Settings.ResetFearScale.ButtonText")}`;
button.addEventListener('click', async (e) => {
e.preventDefault();
await game.settings.set("cosmos-dh-tweaks", "fearTrackerScale", 1.0);
if (ui.resources && ui.resources.rendered) {
ui.resources.updateScale();
ui.resources.adjustSizeToMaxFear();
}
ui.notifications.info(game.i18n.localize("COSMOS_DH_TWEAKS.Settings.ResetFearScale.Success"));
});
formFields.innerHTML = '';
formFields.appendChild(button);
}
}
}
});