diff --git a/scripts/ikonis-data.js b/scripts/ikonis-data.js index 66a0766..7907b02 100644 --- a/scripts/ikonis-data.js +++ b/scripts/ikonis-data.js @@ -13,43 +13,29 @@ export const DEFAULT_AUGMENTS = [ // Global caches for resolved features to keep getters fast const _featureCache = new Map(); -export function getAugments() { - return game.settings.get('dh-ikonis', 'augmentsList') || DEFAULT_AUGMENTS; -} - /** - * Pre-loads all features from the compendium into memory. - * This is necessary because sheetLists getter is synchronous. + * Scans the Daggerheart system config for any weapon features starting with "Ikonis:". + * These are treated as available augments for our slot system. */ -export async function loadIkonisFeatures() { - console.log("DH-Ikonis | Pre-loading features into cache..."); - const allAugs = getAugments(); - const bondedUuid = game.settings.get('dh-ikonis', 'defaultBondedUuid'); - - const uuids = new Set(allAugs.map(a => a.featureUuid).filter(Boolean)); - if (bondedUuid) uuids.add(bondedUuid); +export function getAugments() { + // We get the resolved features from CONFIG.DH.ITEM which includes system + homebrew + const allFeatures = CONFIG.DH.ITEM.allWeaponFeatures() || {}; + const augments = []; - for (const uuid of uuids) { - try { - const item = await fromUuid(uuid); - if (item) { - _featureCache.set(uuid, item); - console.log(`DH-Ikonis | Cached feature: ${item.name} [${uuid}]`); - } - } catch (e) { - console.error(`DH-Ikonis | Failed to load feature ${uuid}`, e); + for (const [id, feature] of Object.entries(allFeatures)) { + const name = feature.label || feature.name || ""; + if (name.startsWith("Ikonis:")) { + augments.push({ + id: id, // This is the native system key (e.g., "force" or "ikonis-guard") + name: name.replace("Ikonis:", "").trim(), + fullName: name, + effect: feature.description ? feature.description.replace(/<[^>]*>?/gm, '').substring(0, 100) + "..." : "Native Feature", + cost: "Homebrew" + }); } } - console.log(`DH-Ikonis | Cache size: ${_featureCache.size}`); -} -/** - * Robust feature fetching. Tries cache first, then async fromUuid. - */ -export async function getAttachedFeature(uuid) { - if (!uuid) return null; - if (_featureCache.has(uuid)) return _featureCache.get(uuid); - return await fromUuid(uuid); + return augments; } export function getSlotCount(item) { @@ -68,59 +54,11 @@ export function getSlotCount(item) { } } -/** - * Synchronizes Ikonis Augments into the Daggerheart Homebrew settings. - * This makes them "Real" Weapon Features to the system. - */ -export async function syncIkonisToHomebrew() { - if (!game.user.isGM) return; - - const MODULE_ID = 'dh-ikonis'; - const homebrewKey = game.settings.settings.has('daggerheart.Homebrew') ? 'Homebrew' : 'homebrew'; - const homebrew = game.settings.get('daggerheart', homebrewKey); - - if (!homebrew.itemFeatures) homebrew.itemFeatures = { weaponFeatures: {}, armorFeatures: {} }; - if (!homebrew.itemFeatures.weaponFeatures) homebrew.itemFeatures.weaponFeatures = {}; - - let updates = false; - const allAugments = getAugments(); - - for (const aug of allAugments) { - const feature = _featureCache.get(aug.featureUuid) || await fromUuid(aug.featureUuid); - if (feature && !homebrew.itemFeatures.weaponFeatures[aug.id]) { - console.log(`DH-Ikonis | Registering ${aug.name} as native weapon feature...`); - - // Format actions for the system's Homebrew model - const actions = {}; - if (feature.system.actions) { - for (const [id, action] of Object.entries(feature.system.actions)) { - actions[id] = action.toObject(); - } - } - - homebrew.itemFeatures.weaponFeatures[aug.id] = { - name: aug.name, - img: aug.img || feature.img, - description: feature.system.description, - actions: actions, - effects: Array.from(feature.effects || []).map(e => e.toObject()) - }; - updates = true; - } - } - - if (updates) { - await game.settings.set('daggerheart', homebrewKey, homebrew); - console.log("DH-Ikonis | Homebrew settings synchronized."); - } -} - /** * Patches the system's weapon data preparation to handle slot counts. */ export function patchIkonisLogic() { - // We no longer need to patch Actor.allApplicableEffects - // because the system handles native weapon features automatically. + // Current slot logic is handled via getSlotCount in the sheet context } /** diff --git a/scripts/ikonis-sheet.js b/scripts/ikonis-sheet.js index 03b59f3..684a9e8 100644 --- a/scripts/ikonis-sheet.js +++ b/scripts/ikonis-sheet.js @@ -49,11 +49,11 @@ export function patchIkonisSheet() { const processedAugments = []; for (const featureRef of weaponFeatures) { - const id = featureRef.value; - const base = allAugmentsList.find(a => String(a.id) === String(id)); + const nativeId = featureRef.value; + const base = allAugmentsList.find(a => String(a.id) === String(nativeId)); if (!base) continue; - const aug = { ...base, installed: true }; - processedAugments.push(aug); + + processedAugments.push({ ...base, installed: true }); } const bondedUuid = doc.getFlag('dh-ikonis', 'bondedFeatureUuid') || game.settings.get('dh-ikonis', 'defaultBondedUuid'); @@ -169,7 +169,8 @@ export function patchIkonisSheet() { Weapon.prototype._onRemoveAugment = async function(event, target) { const weaponFeatures = this.document.system.weaponFeatures || []; - const newFeatures = weaponFeatures.filter(f => f.value !== String(target.dataset.id)); + const targetId = target.dataset.id; + const newFeatures = weaponFeatures.filter(f => f.value !== targetId); await this.document.update({ "system.weaponFeatures": newFeatures }); this.render(true); }; diff --git a/scripts/main.js b/scripts/main.js index 45a31fd..ad4cb36 100644 --- a/scripts/main.js +++ b/scripts/main.js @@ -1,28 +1,12 @@ -import { patchDHWeapon, patchIkonisLogic, patchDhCharacter, loadIkonisFeatures, DEFAULT_AUGMENTS } from './ikonis-data.js'; +import { patchDHWeapon, patchIkonisLogic, patchDhCharacter } from './ikonis-data.js'; import { patchIkonisSheet } from './ikonis-sheet.js'; -import { IkonisAugmentConfig } from './ikonis-config.js'; const MODULE_ID = 'dh-ikonis'; Hooks.once('init', () => { console.log(`${MODULE_ID} | Initializing Ikonis Module`); - // --- Settings Registration --- - - game.settings.register(MODULE_ID, "augmentsList", { - scope: "world", - config: false, - type: Array, - default: DEFAULT_AUGMENTS - }); - - game.settings.register(MODULE_ID, "defaultBondedUuid", { - scope: "world", - config: false, - type: String, - default: "" - }); - + // --- Slot Settings --- [1, 2, 3, 4].forEach(tier => { game.settings.register(MODULE_ID, `slotsTier${tier}`, { name: `Slots at Tier ${tier}`, @@ -54,21 +38,6 @@ Hooks.once('init', () => { default: true }); - // Configuration Menu - game.settings.registerMenu(MODULE_ID, "augmentsMenu", { - name: "Manage Ikonis Augments", - label: "Open Augment Manager", - hint: "Add, remove, or edit the global list of Ikonis augments.", - icon: "fa-solid fa-microchip", - type: class extends foundry.applications.api.ApplicationV2 { - render() { - IkonisAugmentConfig.open(); - return this; - } - }, - restricted: true - }); - const DhCharacter = CONFIG.Actor.dataModels?.character; if (DhCharacter) patchDhCharacter(DhCharacter); }); @@ -76,7 +45,6 @@ Hooks.once('init', () => { Hooks.on('setup', () => { // Damage Type Rename if (game.settings.get(MODULE_ID, "enableTechRename")) { - console.log(`${MODULE_ID} | Renaming Magical damage to Tech...`); const mag = CONFIG.DH?.GENERAL?.damageTypes?.magical; if (mag) { mag.label = "Tech"; @@ -88,55 +56,17 @@ Hooks.on('setup', () => { patchDHWeapon(); patchIkonisLogic(); patchIkonisSheet(); - - const DhCharacter = CONFIG.Actor.dataModels?.character; - if (DhCharacter) patchDhCharacter(DhCharacter); -}); - -Hooks.on('updateItem', (item, changes, options, userId) => { - const isTierUpdate = foundry.utils.hasProperty(changes, "system.tier"); - const isIkonisUpdate = foundry.utils.hasProperty(changes, "flags.dh-ikonis"); - const isEquipUpdate = foundry.utils.hasProperty(changes, "system.equipped"); - - if (isTierUpdate || isIkonisUpdate || isEquipUpdate) { - Object.values(item.apps || {}).forEach(app => { - if (app.render) app.render(true); - }); - - if (item.actor) { - item.actor.prepareData(); - item.actor.sheet?.render(false); - } - } }); Hooks.once('ready', async () => { - console.log(`${MODULE_ID} | Ready hook triggered.`); + console.log(`${MODULE_ID} | Ready.`); - if (game.user.isGM) { - await syncIkonisFeatures(); - - // Currency Override - if (game.settings.get(MODULE_ID, "enableCurrencyOverride")) { - await overrideCurrency(); - } - - // Sync to Native Homebrew - await syncIkonisToHomebrew(); + if (game.user.isGM && game.settings.get(MODULE_ID, "enableCurrencyOverride")) { + await overrideCurrency(); } - await loadIkonisFeatures(); - const DhCharacter = game.system.api?.models?.actors?.DhCharacter || CONFIG.Actor.dataModels?.character; if (DhCharacter) patchDhCharacter(DhCharacter); - - Object.values(ui.windows).forEach(w => { - if (w.document?.type === 'character') w.render(true); - }); - - if (game.user.isGM) { - ui.notifications.info("DH-Ikonis | Ikonis Module initialized."); - } }); async function overrideCurrency() { @@ -147,45 +77,17 @@ async function overrideCurrency() { } const homebrew = game.settings.get('daggerheart', key); - if (!homebrew) return; + if (!homebrew || homebrew.currency?.title === "Quantum") return; - if (homebrew.currency?.title !== "Quantum") { - console.log(`${MODULE_ID} | Overriding currency settings to Quantum...`); - const newHomebrew = (typeof homebrew.toObject === 'function') ? homebrew.toObject() : foundry.utils.deepClone(homebrew); - - newHomebrew.currency = { - title: "Quantum", - coins: { enabled: true, label: "Quantum", icon: "fa-solid fa-atom" }, - handfuls: { enabled: false, label: "Handfuls", icon: "fa-solid fa-coins" }, - bags: { enabled: false, label: "Bags", icon: "fa-solid fa-sack" }, - chests: { enabled: false, label: "Chests", icon: "fa-solid fa-treasure-chest" } - }; + const newHomebrew = (typeof homebrew.toObject === 'function') ? homebrew.toObject() : foundry.utils.deepClone(homebrew); + newHomebrew.currency = { + title: "Quantum", + coins: { enabled: true, label: "Quantum", icon: "fa-solid fa-atom" }, + handfuls: { enabled: false, label: "Handfuls", icon: "fa-solid fa-coins" }, + bags: { enabled: false, label: "Bags", icon: "fa-solid fa-sack" }, + chests: { enabled: false, label: "Chests", icon: "fa-solid fa-treasure-chest" } + }; - await game.settings.set('daggerheart', key, newHomebrew); - ui.notifications.info("DH-Ikonis | Currency system updated to Quantum Credits."); - } -} - -async function syncIkonisFeatures() { - const pack = game.packs.get("dh-ikonis.ikonis-features"); - if (!pack) return; - const index = await pack.getIndex(); - const currentAugs = game.settings.get(MODULE_ID, 'augmentsList') || []; - let updates = false; - const newAugs = currentAugs.map(aug => { - if (!aug.featureUuid) { - const match = index.find(i => i.name === aug.name); - if (match) { - aug.featureUuid = match.uuid; - updates = true; - } - } - return aug; - }); - if (updates) await game.settings.set(MODULE_ID, 'augmentsList', newAugs); - let bondedUuid = game.settings.get(MODULE_ID, 'defaultBondedUuid'); - if (!bondedUuid) { - const bondMatch = index.find(i => i.name === "Ikonis Bond"); - if (bondMatch) await game.settings.set(MODULE_ID, 'defaultBondedUuid', bondMatch.uuid); - } + await game.settings.set('daggerheart', key, newHomebrew); + console.log(`${MODULE_ID} | Currency system updated to Quantum Credits.`); } diff --git a/templates/ikonis-config.hbs b/templates/ikonis-config.hbs index 547a17e..dcc8108 100644 --- a/templates/ikonis-config.hbs +++ b/templates/ikonis-config.hbs @@ -1,17 +1,6 @@