import { SYSTEM } from "./module/config/system.mjs" globalThis.SYSTEM = SYSTEM import * as models from "./module/models/_module.mjs" import * as documents from "./module/documents/_module.mjs" import * as applications from "./module/applications/_module.mjs" import { SystemManager } from "./module/applications/hud/system-manager.js" import { MODULE, REQUIRED_CORE_MODULE_VERSION } from "./module/applications/hud/constants.js" Hooks.once("init", async function () { console.info("Adventures with Emmy | Initializing System") console.info(SYSTEM.ASCII) // Load trait tooltip descriptions from external JSON try { const resp = await fetch("systems/fvtt-adventures-with-emmy/module/config/trait-descriptions.json") const data = await resp.json() // Strip the comment key and populate SYSTEM.TRAIT_DESCRIPTIONS in-place delete data["_comment"] Object.assign(SYSTEM.TRAIT_DESCRIPTIONS, data) } catch (err) { console.warn("Adventures with Emmy | Failed to load trait-descriptions.json", err) } globalThis.adventuresWithEmmy = game.system game.system.CONST = SYSTEM game.system.api = { applications, models, documents } CONFIG.Actor.documentClass = documents.AwEActor CONFIG.Actor.dataModels = { character: models.AwECharacter, creature: models.AwECreature } CONFIG.Item.documentClass = documents.AwEItem CONFIG.Item.dataModels = { ability: models.AwEAbility, field: models.AwEField, specialization: models.AwESpecialization, archetype: models.AwEArchetype, background: models.AwEBackground, kit: models.AwEKit, weapon: models.AwEWeapon, equipment: models.AwEEquipment } // Register actor sheets foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet) foundry.documents.collections.Actors.registerSheet("fvtt-adventures-with-emmy", applications.AwECharacterSheet, { types: ["character"], makeDefault: true }) foundry.documents.collections.Actors.registerSheet("fvtt-adventures-with-emmy", applications.AwECreatureSheet, { types: ["creature"], makeDefault: true }) // Register item sheets foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEAbilitySheet, { types: ["ability"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEFieldSheet, { types: ["field"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwESpecializationSheet, { types: ["specialization"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEArchetypeSheet, { types: ["archetype"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEBackgroundSheet, { types: ["background"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEKitSheet, { types: ["kit"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEWeaponSheet, { types: ["weapon"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("fvtt-adventures-with-emmy", applications.AwEEquipmentSheet, { types: ["equipment"], makeDefault: true }) CONFIG.ChatMessage.documentClass = documents.AwEChatMessage CONFIG.Dice.rolls.push(documents.AwERoll) CONFIG.Combatant.documentClass = documents.AwECombatant // Register conditions as status effects (token HUD overlays) CONFIG.statusEffects = Object.values(SYSTEM.CONDITIONS).map(c => ({ id: c.id, name: c.label, img: `systems/fvtt-adventures-with-emmy/assets/conditions/${c.id}.svg` })) // Handlebars helpers Handlebars.registerHelper("abs", (value) => Math.abs(value ?? 0)) Handlebars.registerHelper("traitTooltip", (traitName) => { const key = (traitName ?? "").toLowerCase() return SYSTEM.TRAIT_DESCRIPTIONS[key] ?? "" }) /** Strip HTML tags and truncate item description for use as a data-tooltip value. */ Handlebars.registerHelper("itemTooltip", (item) => { const raw = item?.system?.description ?? "" if (!raw) return "" const plain = raw.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim() return plain.length > 250 ? plain.slice(0, 247) + "…" : plain }) }) Hooks.once("ready", function () { console.info("Adventures with Emmy | System Ready") }) // Token Action HUD Core integration (only fires if the module is active) Hooks.on('tokenActionHudCoreApiReady', async () => { const module = { api: { requiredCoreModuleVersion: REQUIRED_CORE_MODULE_VERSION, SystemManager } } Hooks.call('tokenActionHudSystemReady', module) }) // Chat message: "Roll Damage" button on weapon attack messages Hooks.on('renderChatMessageHTML', (message, html) => { const btn = html.querySelector('.roll-damage-btn') if (!btn) return btn.addEventListener('click', async () => { const actorId = btn.dataset.actorId const actor = game.actors.get(actorId) if (!actor) return ui.notifications.warn('Actor not found') await actor.rollDamage({ name: btn.dataset.itemName, img: btn.dataset.itemImg, system: { damageFormula: btn.dataset.damageFormula, damageType: btn.dataset.damageType } }) }) })