110 lines
4.6 KiB
JavaScript
110 lines
4.6 KiB
JavaScript
/**
|
|
* main.js
|
|
* Module entry point for NPC Quick Card Deck.
|
|
*
|
|
* Load order:
|
|
* 1. Hooks.once("init") — register Handlebars helpers before any template renders
|
|
* 2. Hooks.once("ready") — create the singleton deck, register token hooks,
|
|
* and inject the toolbar button into the Actor Directory
|
|
*/
|
|
|
|
import { NPCCardDeck } from "./card-deck.js";
|
|
import { registerTokenHooks } from "./token-hooks.js";
|
|
|
|
// ── init ───────────────────────────────────────────────────────────────────────
|
|
Hooks.once("init", () => {
|
|
console.log("NPC Quick Cards | Initialising");
|
|
|
|
// Register Handlebars helpers.
|
|
// `eq` is built-in from Foundry v10 onward but we register defensively
|
|
// in case a stripped-down environment doesn't have it.
|
|
if (!Handlebars.helpers["eq"]) {
|
|
Handlebars.registerHelper("eq", (a, b) => a === b);
|
|
}
|
|
|
|
// Useful for attitude slider label comparisons in templates
|
|
Handlebars.registerHelper("nqc-gt", (a, b) => Number(a) > Number(b));
|
|
Handlebars.registerHelper("nqc-lt", (a, b) => Number(a) < Number(b));
|
|
|
|
// Pre-load templates so they are cached before the deck first opens.
|
|
// v13 moved loadTemplates under foundry.applications.handlebars; fall back
|
|
// to the global for v12 compatibility.
|
|
const _loadTemplates =
|
|
foundry.applications?.handlebars?.loadTemplates?.bind(foundry.applications.handlebars)
|
|
?? globalThis.loadTemplates;
|
|
_loadTemplates([
|
|
"modules/npc-quick-cards/templates/card-deck.hbs",
|
|
"modules/npc-quick-cards/templates/npc-card.hbs",
|
|
"modules/npc-quick-cards/templates/card-tooltip.hbs",
|
|
]);
|
|
});
|
|
|
|
// ── ready ──────────────────────────────────────────────────────────────────────
|
|
Hooks.once("ready", () => {
|
|
// Only the GM needs the deck; bail out for players
|
|
if (!game.user.isGM) return;
|
|
|
|
// Create singleton and expose on game so macros can call game.npcCardDeck.toggle()
|
|
game.npcCardDeck = new NPCCardDeck();
|
|
|
|
// Register canvas token interaction hooks
|
|
registerTokenHooks(game.npcCardDeck);
|
|
|
|
console.log("NPC Quick Cards | Ready");
|
|
});
|
|
|
|
// ── Actor Directory toolbar button ─────────────────────────────────────────────
|
|
// Injected here (outside "ready") so it re-fires every time the directory re-renders.
|
|
//
|
|
// Foundry v13 passes a plain HTMLElement as the second argument; v12 passed a
|
|
// jQuery object. We normalise to a plain element so the same code works on both.
|
|
// We also try every known selector for the header actions area across v12 / v13
|
|
// because the DOM structure changed between versions.
|
|
Hooks.on("renderActorDirectory", (_app, html) => {
|
|
if (!game.user?.isGM) return;
|
|
if (!game.npcCardDeck) return;
|
|
|
|
// Resolve to a plain HTMLElement regardless of Foundry version
|
|
const root = (html instanceof HTMLElement) ? html : (html[0] ?? html);
|
|
if (!(root instanceof HTMLElement)) return;
|
|
|
|
if (root.querySelector(".npc-deck-toggle")) return; // prevent duplicates
|
|
|
|
const btn = document.createElement("button");
|
|
btn.type = "button";
|
|
btn.className = "npc-deck-toggle";
|
|
btn.title = "NPC Quick Card Deck";
|
|
btn.innerHTML = '<i class="fas fa-address-card"></i> NPC Deck';
|
|
btn.addEventListener("click", () => game.npcCardDeck.toggle());
|
|
|
|
// Try every known header-action selector across Foundry v12 and v13.
|
|
// Log which one we find so the console makes it easy to debug.
|
|
const SELECTORS = [
|
|
".directory-header .header-actions", // v12 standard
|
|
".directory-header .action-buttons", // v13 variant
|
|
"header .header-actions", // v13 <header> element
|
|
"header .action-buttons", // v13 variant
|
|
".header-actions", // any version, loose
|
|
".action-buttons", // any version, loose
|
|
".directory-header", // fallback: whole header
|
|
"header", // fallback: <header> element
|
|
];
|
|
|
|
let target = null;
|
|
for (const sel of SELECTORS) {
|
|
target = root.querySelector(sel);
|
|
if (target) {
|
|
console.log(`NPC Quick Cards | Injecting button into "${sel}"`);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (target) {
|
|
target.prepend(btn);
|
|
} else {
|
|
// Absolute last resort — prepend directly to the directory root
|
|
console.warn("NPC Quick Cards | Could not find a header target; prepending to root.");
|
|
root.prepend(btn);
|
|
}
|
|
});
|