add configurable settings for tech damage and currency overrides, and update active effect injection logic to ensure proper parent binding.

This commit is contained in:
CPTN Cosmo 2026-04-26 18:02:08 +02:00
parent e12ac35855
commit 5d8877ff29
2 changed files with 68 additions and 64 deletions

View file

@ -93,7 +93,15 @@ export function patchIkonisLogic() {
if (!feature || !feature.effects) continue; if (!feature || !feature.effects) continue;
for (const effect of feature.effects) { for (const effect of feature.effects) {
if (effect.transfer) yield effect; if (effect.transfer) {
console.log(`DH-Ikonis | Injecting effect '${effect.name}' from augment '${feature.name}' on ${this.name}`);
// Clone the effect and set this actor as parent to ensure application
const effectData = effect.toObject();
effectData.disabled = false;
const effectInstance = new ActiveEffect(effectData, { parent: this });
yield effectInstance;
}
} }
} }
@ -102,7 +110,14 @@ export function patchIkonisLogic() {
const feature = _featureCache.get(bondedUuid) || fromUuidSync(bondedUuid); const feature = _featureCache.get(bondedUuid) || fromUuidSync(bondedUuid);
if (feature?.effects) { if (feature?.effects) {
for (const effect of feature.effects) { for (const effect of feature.effects) {
if (effect.transfer) yield effect; if (effect.transfer) {
console.log(`DH-Ikonis | Injecting bonded effect '${effect.name}' from '${feature.name}' on ${this.name}`);
const effectData = effect.toObject();
effectData.disabled = false;
const effectInstance = new ActiveEffect(effectData, { parent: this });
yield effectInstance;
}
} }
} }
} }

View file

@ -7,7 +7,8 @@ const MODULE_ID = 'dh-ikonis';
Hooks.once('init', () => { Hooks.once('init', () => {
console.log(`${MODULE_ID} | Initializing Ikonis Module`); console.log(`${MODULE_ID} | Initializing Ikonis Module`);
// Global Augments List // --- Settings Registration ---
game.settings.register(MODULE_ID, "augmentsList", { game.settings.register(MODULE_ID, "augmentsList", {
scope: "world", scope: "world",
config: false, config: false,
@ -15,7 +16,6 @@ Hooks.once('init', () => {
default: DEFAULT_AUGMENTS default: DEFAULT_AUGMENTS
}); });
// Default Bonded Feature
game.settings.register(MODULE_ID, "defaultBondedUuid", { game.settings.register(MODULE_ID, "defaultBondedUuid", {
scope: "world", scope: "world",
config: false, config: false,
@ -23,7 +23,6 @@ Hooks.once('init', () => {
default: "" default: ""
}); });
// Slot Scaling for Tiers 1, 2, 3, 4
[1, 2, 3, 4].forEach(tier => { [1, 2, 3, 4].forEach(tier => {
game.settings.register(MODULE_ID, `slotsTier${tier}`, { game.settings.register(MODULE_ID, `slotsTier${tier}`, {
name: `Slots at Tier ${tier}`, name: `Slots at Tier ${tier}`,
@ -35,6 +34,26 @@ Hooks.once('init', () => {
}); });
}); });
// Toggle for Tech Rename
game.settings.register(MODULE_ID, "enableTechRename", {
name: "Rename Magic to Tech",
hint: "Renames 'Magical' damage to 'Tech' damage and updates the icon to a microchip.",
scope: "world",
config: true,
type: Boolean,
default: true
});
// Toggle for Currency Override
game.settings.register(MODULE_ID, "enableCurrencyOverride", {
name: "Enable Quantum Currency",
hint: "Automatically overrides homebrew settings to use 'Quantum' credits and atomic icons.",
scope: "world",
config: true,
type: Boolean,
default: true
});
// Configuration Menu // Configuration Menu
game.settings.registerMenu(MODULE_ID, "augmentsMenu", { game.settings.registerMenu(MODULE_ID, "augmentsMenu", {
name: "Manage Ikonis Augments", name: "Manage Ikonis Augments",
@ -50,123 +69,93 @@ Hooks.once('init', () => {
restricted: true restricted: true
}); });
// Try to patch character model early if available
const DhCharacter = CONFIG.Actor.dataModels?.character; const DhCharacter = CONFIG.Actor.dataModels?.character;
if (DhCharacter) { if (DhCharacter) patchDhCharacter(DhCharacter);
patchDhCharacter(DhCharacter);
}
}); });
Hooks.on('setup', () => { 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";
mag.abbreviation = "TCH";
mag.icon = "fa-solid fa-microchip";
}
}
patchDHWeapon(); patchDHWeapon();
patchIkonisLogic(); patchIkonisLogic();
patchIkonisSheet(); patchIkonisSheet();
// Ensure character model is patched if missed in init
const DhCharacter = CONFIG.Actor.dataModels?.character; const DhCharacter = CONFIG.Actor.dataModels?.character;
if (DhCharacter) { if (DhCharacter) patchDhCharacter(DhCharacter);
patchDhCharacter(DhCharacter);
}
}); });
// Watch for Tier/Ikonis changes and force a refresh
Hooks.on('updateItem', (item, changes, options, userId) => { Hooks.on('updateItem', (item, changes, options, userId) => {
const isTierUpdate = foundry.utils.hasProperty(changes, "system.tier"); const isTierUpdate = foundry.utils.hasProperty(changes, "system.tier");
const isIkonisUpdate = foundry.utils.hasProperty(changes, "flags.dh-ikonis"); const isIkonisUpdate = foundry.utils.hasProperty(changes, "flags.dh-ikonis");
const isEquipUpdate = foundry.utils.hasProperty(changes, "system.equipped"); const isEquipUpdate = foundry.utils.hasProperty(changes, "system.equipped");
if (isTierUpdate || isIkonisUpdate || isEquipUpdate) { if (isTierUpdate || isIkonisUpdate || isEquipUpdate) {
console.log(`DH-Ikonis | Update detected for ${item.name}.`);
// Refresh sheets
Object.values(item.apps || {}).forEach(app => { Object.values(item.apps || {}).forEach(app => {
if (app.render) app.render(true); if (app.render) app.render(true);
}); });
// If it's on an actor, we need to force the actor to recalculate its effects
if (item.actor) { if (item.actor) {
console.log(`DH-Ikonis | Resetting actor data for ${item.actor.name}...`);
item.actor.prepareData(); item.actor.prepareData();
// Force sheet re-render for the actor
item.actor.sheet?.render(false); item.actor.sheet?.render(false);
} }
} }
}); });
Hooks.once('ready', async () => { Hooks.once('ready', async () => {
console.log("DH-Ikonis | Ready hook triggered."); console.log(`${MODULE_ID} | Ready hook triggered.`);
// Sync features from compendium if needed
if (game.user.isGM) { if (game.user.isGM) {
await syncIkonisFeatures(); await syncIkonisFeatures();
// Currency Override
if (game.settings.get(MODULE_ID, "enableCurrencyOverride")) {
await overrideCurrency(); await overrideCurrency();
} }
}
// Load features into memory for sync getters
await loadIkonisFeatures(); await loadIkonisFeatures();
// Final check for Character Data Model patch
const DhCharacter = game.system.api?.models?.actors?.DhCharacter || CONFIG.Actor.dataModels?.character; const DhCharacter = game.system.api?.models?.actors?.DhCharacter || CONFIG.Actor.dataModels?.character;
if (DhCharacter) { if (DhCharacter) patchDhCharacter(DhCharacter);
patchDhCharacter(DhCharacter);
} else {
console.warn("DH-Ikonis | Could not find DhCharacter class for patching visual features.");
}
// Force re-render of open character sheets to show newly patched features
Object.values(ui.windows).forEach(w => { Object.values(ui.windows).forEach(w => {
if (w.document?.type === 'character') { if (w.document?.type === 'character') w.render(true);
console.log(`DH-Ikonis | Forcing refresh of character sheet: ${w.document.name}`);
w.render(true);
}
}); });
if (game.user.isGM) { if (game.user.isGM) {
ui.notifications.info("DH-Ikonis | Ikonis Module initialized and features synchronized."); ui.notifications.info("DH-Ikonis | Ikonis Module initialized.");
} }
}); });
async function overrideCurrency() { async function overrideCurrency() {
// Robust key check for Daggerheart Homebrew settings
let key = 'Homebrew'; let key = 'Homebrew';
if (!game.settings.settings.has('daggerheart.Homebrew')) { if (!game.settings.settings.has('daggerheart.Homebrew')) {
if (game.settings.settings.has('daggerheart.homebrew')) key = 'homebrew'; if (game.settings.settings.has('daggerheart.homebrew')) key = 'homebrew';
else return; // Setting not found else return;
} }
const homebrew = game.settings.get('daggerheart', key); const homebrew = game.settings.get('daggerheart', key);
if (!homebrew) return; if (!homebrew) return;
// Check if we already have Quantum to avoid spamming updates if (homebrew.currency?.title !== "Quantum") {
const currentTitle = homebrew.currency?.title; console.log(`${MODULE_ID} | Overriding currency settings to Quantum...`);
if (currentTitle !== "Quantum") {
console.log(`DH-Ikonis | Overriding currency settings to Quantum (using key: ${key})...`);
// Handle both DataModel and plain object
const newHomebrew = (typeof homebrew.toObject === 'function') ? homebrew.toObject() : foundry.utils.deepClone(homebrew); const newHomebrew = (typeof homebrew.toObject === 'function') ? homebrew.toObject() : foundry.utils.deepClone(homebrew);
newHomebrew.currency = { newHomebrew.currency = {
title: "Quantum", title: "Quantum",
coins: { coins: { enabled: true, label: "Quantum", icon: "fa-solid fa-atom" },
enabled: true, handfuls: { enabled: false, label: "Handfuls", icon: "fa-solid fa-coins" },
label: "Quantum", bags: { enabled: false, label: "Bags", icon: "fa-solid fa-sack" },
icon: "fa-solid fa-atom" chests: { enabled: false, label: "Chests", icon: "fa-solid fa-treasure-chest" }
},
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); await game.settings.set('daggerheart', key, newHomebrew);