Hooks.on('renderTokenHUD', (app, html, data) => { const token = app.object; if (!token?.combatant) return; const viewedCombat = ui.combat?.viewed; if (!viewedCombat) return; // In Daggerheart, the combatant with the spotlight is the one whose turn it currently is. const hasSpotlight = viewedCombat.combatant?.id === token.combatant.id; const isRequesting = token.combatant.system?.spotlight?.requesting; // Determine icon and classes based on spotlight state let iconClass = "fa-regular fa-hand-sparkles"; let activeClass = ""; 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 = `
`; // Append to the right column of the Token HUD const colRight = $(html).find('.col.right'); colRight.append(buttonHtml); // Add click listener $(html).find('[data-action="toggle-spotlight"]').click(async event => { event.preventDefault(); event.stopPropagation(); if (ui.combat) { const btn = $(event.currentTarget); const icon = btn.find('i'); const wasActive = btn.hasClass('active'); const isRequestingMsg = icon.hasClass('dh-spotlight-request'); if (game.user.isGM) { if (typeof ui.combat.setCombatantSpotlight === "function") { // Optimistic UI update for GM if (wasActive && !isRequestingMsg) { btn.removeClass('active'); icon.removeClass('fa-solid dh-spotlight-glow').addClass('fa-regular'); } else { btn.addClass('active'); icon.removeClass('fa-regular dh-spotlight-request').addClass('fa-solid dh-spotlight-glow'); } 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'); } else { btn.addClass('active'); icon.removeClass('fa-regular').addClass('fa-solid dh-spotlight-request'); } await token.combatant.update({ 'system.spotlight': { requesting: !currentlyRequesting, requestOrderIndex: !currentlyRequesting ? maxRequestIndex + 1 : 0 } }); } } else { ui.notifications.warn("System does not support spotlight or combat is not initialized."); } }); });