Compare commits

...

4 commits
1.0.1 ... main

Author SHA1 Message Date
a169881a25 make tooltips update instantly 2026-03-24 02:56:30 +01:00
59527962ba feat: add requst spotlight feature for players and update tooltips 2026-03-24 02:51:46 +01:00
b01167c6d8 icon alignment fix 2026-03-24 02:45:43 +01:00
3e6a6183c2 version bump 2026-03-24 02:39:39 +01:00
3 changed files with 77 additions and 16 deletions

View file

@ -4,8 +4,8 @@
"description": "Adds a button to the token hover HUD to toggle the spotlight for Daggerheart.", "description": "Adds a button to the token hover HUD to toggle the spotlight for Daggerheart.",
"url": "https://git.geeks.gay/cosmo/dh-token-spotlight", "url": "https://git.geeks.gay/cosmo/dh-token-spotlight",
"manifest": "https://git.geeks.gay/cosmo/dh-token-spotlight/raw/branch/main/module.json", "manifest": "https://git.geeks.gay/cosmo/dh-token-spotlight/raw/branch/main/module.json",
"download": "https://git.geeks.gay/cosmo/dh-token-spotlight/releases/download/1.0.1/dh-token-spotlight.zip", "download": "https://git.geeks.gay/cosmo/dh-token-spotlight/releases/download/1.1.1/dh-token-spotlight.zip",
"version": "1.0.0", "version": "1.1.1",
"compatibility": { "compatibility": {
"minimum": "13", "minimum": "13",
"verified": "13" "verified": "13"

View file

@ -7,14 +7,28 @@ Hooks.on('renderTokenHUD', (app, html, data) => {
// In Daggerheart, the combatant with the spotlight is the one whose turn it currently is. // In Daggerheart, the combatant with the spotlight is the one whose turn it currently is.
const hasSpotlight = viewedCombat.combatant?.id === token.combatant.id; const hasSpotlight = viewedCombat.combatant?.id === token.combatant.id;
const isRequesting = token.combatant.system?.spotlight?.requesting;
// Determine icon and classes based on spotlight state // Determine icon and classes based on spotlight state
const iconClass = hasSpotlight let iconClass = "fa-regular fa-hand-sparkles";
? "fa-solid fa-hand-sparkles dh-spotlight-glow" let activeClass = "";
: "fa-regular fa-hand-sparkles"; if (hasSpotlight) {
iconClass = "fa-solid fa-hand-sparkles dh-spotlight-glow";
activeClass = "active";
} else if (isRequesting) {
iconClass = "fa-solid fa-hand-sparkles dh-spotlight-request";
activeClass = "active";
}
let tooltipText = "";
if (game.user.isGM) {
tooltipText = hasSpotlight ? "Take Spotlight" : "Grant Spotlight";
} else {
tooltipText = hasSpotlight ? "Remove Spotlight" : (isRequesting ? "Cancel Spotlight Request" : "Request Spotlight");
}
const buttonHtml = ` const buttonHtml = `
<div class="control-icon ${hasSpotlight ? 'active' : ''}" data-action="toggle-spotlight" title="Toggle Spotlight"> <div class="control-icon ${activeClass}" data-action="toggle-spotlight" title="${tooltipText}">
<i class="${iconClass}"></i> <i class="${iconClass}"></i>
</div> </div>
`; `;
@ -28,22 +42,56 @@ Hooks.on('renderTokenHUD', (app, html, data) => {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
if (ui.combat && typeof ui.combat.setCombatantSpotlight === "function") { if (ui.combat) {
const btn = $(event.currentTarget); const btn = $(event.currentTarget);
const icon = btn.find('i'); const icon = btn.find('i');
const wasActive = btn.hasClass('active'); const wasActive = btn.hasClass('active');
const isRequestingMsg = icon.hasClass('dh-spotlight-request');
// Optimistic UI update if (game.user.isGM) {
if (wasActive) { if (typeof ui.combat.setCombatantSpotlight === "function") {
// Optimistic UI update for GM
if (wasActive && !isRequestingMsg) {
btn.removeClass('active'); btn.removeClass('active');
icon.removeClass('fa-solid dh-spotlight-glow').addClass('fa-regular'); icon.removeClass('fa-solid dh-spotlight-glow').addClass('fa-regular');
btn.attr('title', 'Grant Spotlight');
} else { } else {
btn.addClass('active'); btn.addClass('active');
icon.removeClass('fa-regular').addClass('fa-solid dh-spotlight-glow'); icon.removeClass('fa-regular dh-spotlight-request').addClass('fa-solid dh-spotlight-glow');
btn.attr('title', 'Take Spotlight');
}
await ui.combat.setCombatantSpotlight(token.combatant.id);
}
} else {
// Players request the spotlight
const combat = ui.combat.viewed;
if (!combat) return;
const characters = combat.turns?.filter(x => !x.isNPC) ?? [];
// Fallback to maxRequestIndex = 0 if necessary
const orderValues = characters.map(c => c.system?.spotlight?.requestOrderIndex || 0);
const maxRequestIndex = orderValues.length > 0 ? Math.max(...orderValues) : 0;
const currentlyRequesting = !!token.combatant.system?.spotlight?.requesting;
// Optimistic UI update for Player
if (currentlyRequesting) {
btn.removeClass('active');
icon.removeClass('fa-solid dh-spotlight-request').addClass('fa-regular');
btn.attr('title', 'Request Spotlight');
} else {
btn.addClass('active');
icon.removeClass('fa-regular').addClass('fa-solid dh-spotlight-request');
btn.attr('title', 'Cancel Spotlight Request');
} }
// Call the system's spotlight toggle function await token.combatant.update({
await ui.combat.setCombatantSpotlight(token.combatant.id); 'system.spotlight': {
requesting: !currentlyRequesting,
requestOrderIndex: !currentlyRequesting ? maxRequestIndex + 1 : 0
}
});
}
} else { } else {
ui.notifications.warn("System does not support spotlight or combat is not initialized."); ui.notifications.warn("System does not support spotlight or combat is not initialized.");
} }

View file

@ -8,3 +8,16 @@
#token-hud .control-icon.active i.dh-spotlight-glow { #token-hud .control-icon.active i.dh-spotlight-glow {
color: #ffd700; color: #ffd700;
} }
/* Vertically center the generic FontAwesome icon */
#token-hud .control-icon[data-action="toggle-spotlight"] {
display: flex;
justify-content: center;
align-items: center;
}
/* Player spotlight request effect */
#token-hud .control-icon.active i.dh-spotlight-request {
color: #4da6ff;
text-shadow: 0 0 5px #007bff, 0 0 10px #007bff;
}