// Import document classes. import { Shadowrun6Actor } from './documents/actor.mjs'; import { Shadowrun6Item } from './documents/item.mjs'; // Import sheet classes. import { Shadowrun6ActorSheet } from './sheets/actor-sheet.mjs'; import { Shadowrun6ItemSheet } from './sheets/item-sheet.mjs'; // Import helper/utility classes and constants. import { preloadHandlebarsTemplates } from './helpers/templates.mjs'; import { SHADOWRUN_6 } from './helpers/config.mjs'; // Import DataModel classes import * as models from './data/_module.mjs'; /* -------------------------------------------- */ /* Init Hook */ /* -------------------------------------------- */ Hooks.once('init', function () { // Add utility classes to the global game object so that they're more easily // accessible in global contexts. game.shadowrun6eultimate = { Shadowrun6Actor, Shadowrun6Item, rollItemMacro, }; // Add custom constants for configuration. CONFIG.SHADOWRUN_6 = SHADOWRUN_6; /** * Set an initiative formula for the system * @type {String} */ CONFIG.Combat.initiative = { formula: '1d20 + @abilities.dex.mod', decimals: 2, }; // Define custom Document and DataModel classes CONFIG.Actor.documentClass = Shadowrun6Actor; // Note that you don't need to declare a DataModel // for the base actor/item classes - they are included // with the Character/NPC as part of super.defineSchema() CONFIG.Actor.dataModels = { character: models.Shadowrun6Character, npc: models.Shadowrun6NPC } CONFIG.Item.documentClass = Shadowrun6Item; CONFIG.Item.dataModels = { item: models.Shadowrun6Item, feature: models.Shadowrun6Feature, spell: models.Shadowrun6Spell } // Active Effects are never copied to the Actor, // but will still apply to the Actor from within the Item // if the transfer property on the Active Effect is true. CONFIG.ActiveEffect.legacyTransferral = false; // Register sheet application classes Actors.unregisterSheet('core', ActorSheet); Actors.registerSheet('shadowrun-6e-ultimate', Shadowrun6ActorSheet, { makeDefault: true, label: 'SHADOWRUN_6.SheetLabels.Actor', }); Items.unregisterSheet('core', ItemSheet); Items.registerSheet('shadowrun-6e-ultimate', Shadowrun6ItemSheet, { makeDefault: true, label: 'SHADOWRUN_6.SheetLabels.Item', }); // Preload Handlebars templates. return preloadHandlebarsTemplates(); }); /* -------------------------------------------- */ /* Handlebars Helpers */ /* -------------------------------------------- */ // If you need to add Handlebars helpers, here is a useful example: Handlebars.registerHelper('toLowerCase', function (str) { return str.toLowerCase(); }); /* -------------------------------------------- */ /* Ready Hook */ /* -------------------------------------------- */ Hooks.once('ready', function () { // Wait to register hotbar drop hook on ready so that modules could register earlier if they want to Hooks.on('hotbarDrop', (bar, data, slot) => createItemMacro(data, slot)); }); /* -------------------------------------------- */ /* Hotbar Macros */ /* -------------------------------------------- */ /** * Create a Macro from an Item drop. * Get an existing item macro if one exists, otherwise create a new one. * @param {Object} data The dropped data * @param {number} slot The hotbar slot to use * @returns {Promise} */ async function createItemMacro(data, slot) { // First, determine if this is a valid owned item. if (data.type !== 'Item') return; if (!data.uuid.includes('Actor.') && !data.uuid.includes('Token.')) { return ui.notifications.warn( 'You can only create macro buttons for owned Items' ); } // If it is, retrieve it based on the uuid. const item = await Item.fromDropData(data); // Create the macro command using the uuid. const command = `game.shadowrun6eultimate.rollItemMacro("${data.uuid}");`; let macro = game.macros.find( (m) => m.name === item.name && m.command === command ); if (!macro) { macro = await Macro.create({ name: item.name, type: 'script', img: item.img, command: command, flags: { 'shadowrun-6e-ultimate.itemMacro': true }, }); } game.user.assignHotbarMacro(macro, slot); return false; } /** * Create a Macro from an Item drop. * Get an existing item macro if one exists, otherwise create a new one. * @param {string} itemUuid */ function rollItemMacro(itemUuid) { // Reconstruct the drop data so that we can load the item. const dropData = { type: 'Item', uuid: itemUuid, }; // Load the item from the uuid. Item.fromDropData(dropData).then((item) => { // Determine if the item loaded and if it's an owned item. if (!item || !item.parent) { const itemName = item?.name ?? itemUuid; return ui.notifications.warn( `Could not find item ${itemName}. You may need to delete and recreate this macro.` ); } // Trigger the item roll item.roll(); }); }