110 lines
4.4 KiB
JavaScript
110 lines
4.4 KiB
JavaScript
export const DEFAULT_AUGMENTS = [
|
|
{ id: "force", name: "Kinetic Amplifier", effect: "+1 Damage on Melee attacks", cost: "2 Iron", precompile: 1 },
|
|
{ id: "fire", name: "Thermal Core", effect: "Deals Fire damage instead of Physical", cost: "1 Blaze Glass", precompile: 1 },
|
|
{ id: "shock", name: "Static Coil", effect: "Targets hit are Dazed", cost: "3 Copper", precompile: 2 },
|
|
{ id: "shield", name: "Reactive Plating", effect: "+1 Armor while equipped", cost: "2 Steel", precompile: 1 },
|
|
{ id: "range", name: "Long-Range Optics", effect: "Increases Range by 1 step", cost: "1 Lens", precompile: 2 },
|
|
{ id: "crit", name: "Precision Chip", effect: "+1 to Crit range", cost: "1 Gold", precompile: 3 },
|
|
{ id: "multi", name: "Burst Module", effect: "Can target 2 enemies (Half damage)", cost: "2 Gears", precompile: 4 },
|
|
{ id: "drain", name: "Siphon Link", effect: "Recover 1 Hope on kill", cost: "1 Soul Gem", precompile: 4 },
|
|
{ id: "weight", name: "Gravity Plate", effect: "Weapon is Heavy (more damage)", cost: "4 Lead", precompile: 2 }
|
|
];
|
|
|
|
// Global cache for resolved features to keep generators fast
|
|
const _featureCache = new Map();
|
|
|
|
export function getAugments() {
|
|
return game.settings.get('dh-ikonis', 'augmentsList') || DEFAULT_AUGMENTS;
|
|
}
|
|
|
|
export function getSlotCount(item) {
|
|
const flags = item.getFlag('dh-ikonis') || {};
|
|
if (typeof flags.slotOverride === "number") return flags.slotOverride;
|
|
|
|
let tier = item.system?.tier?.value;
|
|
if (tier === undefined) tier = item.system?.tier;
|
|
const tierNum = parseInt(tier) || 1;
|
|
|
|
const settingKey = `slotsTier${tierNum}`;
|
|
try {
|
|
return game.settings.get('dh-ikonis', settingKey);
|
|
} catch (e) {
|
|
return tierNum >= 2 ? 3 : 2;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Robust feature fetching with timeout and caching.
|
|
*/
|
|
export async function getAttachedFeature(uuid) {
|
|
if (!uuid) return null;
|
|
if (_featureCache.has(uuid)) return _featureCache.get(uuid);
|
|
|
|
const timeout = new Promise((_, reject) =>
|
|
setTimeout(() => reject(new Error("Timeout fetching feature")), 2000)
|
|
);
|
|
|
|
try {
|
|
const item = await Promise.race([fromUuid(uuid), timeout]);
|
|
if (item) _featureCache.set(uuid, item);
|
|
return item;
|
|
} catch (err) {
|
|
console.warn(`DH-Ikonis | Failed or timed out fetching feature [${uuid}]:`, err.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Patches the system to ensure Ikonis effects are applied to the actor.
|
|
*/
|
|
export function patchIkonisLogic() {
|
|
console.log("DH-Ikonis | Patching Actor for Ikonis effect injection...");
|
|
|
|
// 1. Patch allApplicableEffects to inject Active Effects from Augments
|
|
const originalAllEffects = Actor.prototype.allApplicableEffects;
|
|
Actor.prototype.allApplicableEffects = function* () {
|
|
// Yield standard effects
|
|
yield* originalAllEffects.call(this);
|
|
|
|
// Inject effects from equipped Ikonis weapons
|
|
for (const item of this.items) {
|
|
if (item.type !== 'weapon' || !item.system.equipped) continue;
|
|
|
|
const installedIds = item.getFlag('dh-ikonis', 'installedAugments') || [];
|
|
const allAugs = getAugments();
|
|
|
|
for (const id of installedIds) {
|
|
const aug = allAugs.find(a => String(a.id) === String(id));
|
|
if (!aug?.featureUuid) continue;
|
|
|
|
// We use sync lookup here because generators must be synchronous.
|
|
// The features should already be in the cache from the sheet rendering.
|
|
const feature = fromUuidSync(aug.featureUuid);
|
|
if (!feature || !feature.effects) continue;
|
|
|
|
for (const effect of feature.effects) {
|
|
// Only yield transfer effects (those meant to apply to the actor)
|
|
if (effect.transfer) yield effect;
|
|
}
|
|
}
|
|
|
|
// Also check Bonded feature
|
|
const bondedUuid = item.getFlag('dh-ikonis', 'bondedFeatureUuid');
|
|
if (bondedUuid) {
|
|
const feature = fromUuidSync(bondedUuid);
|
|
if (feature?.effects) {
|
|
for (const effect of feature.effects) {
|
|
if (effect.transfer) yield effect;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
console.log("DH-Ikonis | Actor patches complete.");
|
|
}
|
|
|
|
export function patchDHWeapon() {
|
|
console.log("DH-Ikonis | Patching DH Weapon system...");
|
|
// Future: Add damage type override logic here
|
|
}
|