diff --git a/lang/en.json b/lang/en.json
index a6dde5c..4a235b7 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -17,5 +17,14 @@
"COSMOS_DH_TWEAKS.Settings.ResetFearPosition.ButtonText": "Reset Position",
"COSMOS_DH_TWEAKS.Settings.ResetFearPosition.Success": "Fear tracker position has been reset.",
"COSMOS_DH_TWEAKS.ContextMenu.LockPosition": "Lock Position",
- "COSMOS_DH_TWEAKS.ContextMenu.UnlockPosition": "Unlock Position"
+ "COSMOS_DH_TWEAKS.ContextMenu.UnlockPosition": "Unlock Position",
+ "COSMOS_DH_TWEAKS.Settings.FearTrackerScale.Name": "Fear Tracker Scale",
+ "COSMOS_DH_TWEAKS.Settings.FearTrackerScale.Hint": "Scale the size of the Fear Tracker window and its icons.",
+ "COSMOS_DH_TWEAKS.Settings.ResetFearScale.Name": "Reset Fear Tracker Scale",
+ "COSMOS_DH_TWEAKS.Settings.ResetFearScale.Hint": "Resets the Fear Tracker scale back to 100%.",
+ "COSMOS_DH_TWEAKS.Settings.ResetFearScale.ButtonText": "Reset Scale",
+ "COSMOS_DH_TWEAKS.Settings.ResetFearScale.Success": "Fear tracker scale has been reset.",
+ "COSMOS_DH_TWEAKS.ContextMenu.ResetPosition": "Reset Position",
+ "COSMOS_DH_TWEAKS.ContextMenu.ResetScale": "Reset Scale",
+ "COSMOS_DH_TWEAKS.ContextMenu.ScaleHeader": "Scale"
}
diff --git a/scripts/cosmos-dh-tweaks.mjs b/scripts/cosmos-dh-tweaks.mjs
index 6240cff..eac433a 100644
--- a/scripts/cosmos-dh-tweaks.mjs
+++ b/scripts/cosmos-dh-tweaks.mjs
@@ -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", () => {
+
+
+
+
`;
@@ -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 = ` ${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);
+ }
+ }
+ }
});
diff --git a/styles/cosmos-dh-tweaks.css b/styles/cosmos-dh-tweaks.css
index 38264d7..6847e08 100644
--- a/styles/cosmos-dh-tweaks.css
+++ b/styles/cosmos-dh-tweaks.css
@@ -156,8 +156,8 @@
text-align: center;
}
-/* Reset button styling */
-button.cosmo-reset-fear-pos-btn {
+button.cosmo-reset-fear-pos-btn,
+button.cosmo-reset-fear-scale-btn {
background: rgba(197, 164, 94, 0.1);
border: 1px solid rgb(153, 122, 79);
color: #d3d3d3;
@@ -172,8 +172,123 @@ button.cosmo-reset-fear-pos-btn {
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}
-button.cosmo-reset-fear-pos-btn:hover {
+button.cosmo-reset-fear-pos-btn:hover,
+button.cosmo-reset-fear-scale-btn:hover {
background: rgba(197, 164, 94, 0.25);
border-color: #ffffff;
color: #ffffff;
}
+
+/* Fear Tracker Scaling */
+#resources {
+ --cosmo-fear-scale: 1;
+}
+
+/* Scale the skull icons */
+#resources #resource-fear i {
+ width: calc(3rem * var(--cosmo-fear-scale, 1)) !important;
+ height: calc(3rem * var(--cosmo-fear-scale, 1)) !important;
+ font-size: calc(1.125rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+/* Scale hover state font-size for GMs */
+#resources.isGM #resource-fear i:hover {
+ font-size: calc(1.25rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+/* Scale the control buttons (+ and -) */
+#resources #resource-fear .controls {
+ width: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+ height: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+ font-size: calc(1.25rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+#resources #resource-fear .controls:hover {
+ font-size: calc(1.5rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+/* Scale the resource bar */
+#resources #resource-fear .resource-bar {
+ font-size: calc(1.25rem * var(--cosmo-fear-scale, 1)) !important;
+ padding: calc(0.25rem * var(--cosmo-fear-scale, 1)) calc(0.5rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+/* Scale the window padding and flex gap */
+#resources .window-content {
+ padding: calc(0.5rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+#resources #resource-fear {
+ gap: calc(0.5rem * var(--cosmo-fear-scale, 1)) calc(0.25rem * var(--cosmo-fear-scale, 1)) !important;
+}
+
+/* Scale the window header */
+#resources header.window-header {
+ font-size: calc(14px * var(--cosmo-fear-scale, 1)) !important;
+ min-height: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+ height: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+}
+
+#resources header.window-header h1 {
+ font-size: calc(14px * var(--cosmo-fear-scale, 1)) !important;
+}
+
+#resources header.window-header button,
+#resources header.window-header a,
+#resources header.window-header i {
+ font-size: calc(14px * var(--cosmo-fear-scale, 1)) !important;
+}
+
+#resources header.window-header button,
+#resources header.window-header a {
+ width: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+ height: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+ line-height: calc(30px * var(--cosmo-fear-scale, 1)) !important;
+}
+
+/* Context menu scale controls styling */
+.cosmo-context-menu-header {
+ padding: 6px 12px 2px 12px;
+ font-size: 11px;
+ text-transform: uppercase;
+ color: #a49a85;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ border-top: 1px solid rgba(153, 122, 79, 0.3);
+ margin-top: 4px;
+}
+
+.cosmo-context-menu-scale-controls {
+ display: flex;
+ padding: 4px 12px 8px 12px;
+ gap: 4px;
+ justify-content: space-between;
+}
+
+.cosmo-context-menu-scale-controls button.scale-btn {
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(153, 122, 79, 0.4);
+ color: #d3d3d3;
+ padding: 2px 6px;
+ border-radius: 3px;
+ cursor: pointer;
+ font-size: 11px;
+ font-family: inherit;
+ transition: all 0.2s ease;
+ flex: 1;
+ text-align: center;
+}
+
+.cosmo-context-menu-scale-controls button.scale-btn:hover {
+ background: rgba(197, 164, 94, 0.25);
+ border-color: #ffffff;
+ color: #ffffff;
+}
+
+.cosmo-context-menu-scale-controls button.scale-btn.active {
+ background: rgba(197, 164, 94, 0.4);
+ border-color: rgb(197, 164, 94);
+ color: #ffffff;
+ font-weight: bold;
+}
+