194 lines
7.2 KiB
JavaScript
194 lines
7.2 KiB
JavaScript
export const DEFAULT_AUGMENTS = [
|
|
{
|
|
id: "bonded",
|
|
name: "Bonded",
|
|
effect: "Primary module for Ikonis hardware synchronization.",
|
|
cost: "Cost: None",
|
|
img: "icons/magic/control/debuff-energy-hold-blue-yellow.webp",
|
|
effects: [
|
|
{
|
|
_id: "ikonisBondedEff",
|
|
name: "Ikonis: Bonded",
|
|
type: "base",
|
|
img: "icons/magic/control/debuff-energy-hold-blue-yellow.webp",
|
|
system: {
|
|
changes: [
|
|
{
|
|
key: "system.bonuses.damage.primaryWeapon.bonus",
|
|
type: "add",
|
|
value: "@tier",
|
|
priority: null,
|
|
phase: "initial"
|
|
}
|
|
],
|
|
duration: {
|
|
description: "",
|
|
type: ""
|
|
},
|
|
rangeDependence: {
|
|
enabled: false,
|
|
type: "withinRange",
|
|
target: "hostile",
|
|
range: "melee"
|
|
},
|
|
stacking: null,
|
|
targetDispositions: []
|
|
},
|
|
disabled: false,
|
|
transfer: true,
|
|
statuses: [],
|
|
showIcon: 1,
|
|
flags: {}
|
|
}
|
|
]
|
|
},
|
|
{ id: "force", name: "Force", effect: "+1 Damage on Melee attacks.", cost: "Cost: 2 Iron" },
|
|
{ id: "fire", name: "Fire", effect: "Deals Fire damage instead of Physical.", cost: "Cost: 1 Blaze Glass" },
|
|
{ id: "shield", name: "Shield", effect: "+1 Armor while equipped.", cost: "Cost: 2 Steel" },
|
|
{ id: "range", name: "Range", effect: "Increases Range by 1 step.", cost: "Cost: 1 Lens" }
|
|
];
|
|
|
|
// Global caches for resolved features to keep getters fast
|
|
const _featureCache = new Map();
|
|
|
|
/**
|
|
* Injects Ikonis defaults directly into the system configuration.
|
|
*/
|
|
export function registerIkonisFeatures() {
|
|
if (!CONFIG.DH?.ITEM?.weaponFeatures) return;
|
|
console.log("DH-Ikonis | Registering features in CONFIG...");
|
|
for (const aug of DEFAULT_AUGMENTS) {
|
|
const nativeId = `ikonis-${aug.id}`;
|
|
CONFIG.DH.ITEM.weaponFeatures[nativeId] = {
|
|
name: `Ikonis: ${aug.name}`,
|
|
img: aug.img || "systems/daggerheart/assets/icons/documents/items/chip.svg",
|
|
description: `<p>${aug.effect}</p><p>${aug.cost}</p>`,
|
|
actions: aug.actions || {},
|
|
effects: aug.effects || []
|
|
};
|
|
}
|
|
console.log("DH-Ikonis | Features registered in CONFIG.");
|
|
}
|
|
|
|
/**
|
|
* Seeds the Daggerheart Homebrew settings with Ikonis defaults if they don't exist.
|
|
*/
|
|
export async function seedIkonisHomebrew() {
|
|
if (!game.user.isGM) return;
|
|
|
|
let homebrewKey = 'Homebrew';
|
|
if (!game.settings.settings.has('daggerheart.Homebrew')) {
|
|
if (game.settings.settings.has('daggerheart.homebrew')) homebrewKey = 'homebrew';
|
|
else {
|
|
console.warn("DH-Ikonis | Daggerheart Homebrew setting not found.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
const current = game.settings.get('daggerheart', homebrewKey) || {};
|
|
const homebrew = (typeof current.toObject === 'function') ? current.toObject() : foundry.utils.deepClone(current);
|
|
|
|
console.log(`DH-Ikonis | Seeding homebrew features (key: ${homebrewKey})...`);
|
|
|
|
if (!homebrew.itemFeatures) homebrew.itemFeatures = { weaponFeatures: {}, armorFeatures: {} };
|
|
if (!homebrew.itemFeatures.weaponFeatures) homebrew.itemFeatures.weaponFeatures = {};
|
|
|
|
let updates = false;
|
|
for (const aug of DEFAULT_AUGMENTS) {
|
|
const nativeId = `ikonis-${aug.id}`;
|
|
const existing = homebrew.itemFeatures.weaponFeatures[nativeId];
|
|
|
|
// We update if it's missing OR if it's an Ikonis feature that needs an update (like Bonded getting effects)
|
|
const hasEffects = aug.effects && aug.effects.length > 0;
|
|
const needsUpdate = !existing || (hasEffects && (!existing.effects || existing.effects.length === 0));
|
|
|
|
if (needsUpdate) {
|
|
console.log(`DH-Ikonis | Seeding/Updating feature: ${aug.name}`);
|
|
homebrew.itemFeatures.weaponFeatures[nativeId] = {
|
|
name: `Ikonis: ${aug.name}`,
|
|
img: aug.img || "systems/daggerheart/assets/icons/documents/items/chip.svg",
|
|
description: `<p>${aug.effect}</p><p>${aug.cost}</p>`,
|
|
actions: aug.actions || {},
|
|
effects: aug.effects || []
|
|
};
|
|
updates = true;
|
|
}
|
|
}
|
|
|
|
if (updates) {
|
|
await game.settings.set('daggerheart', homebrewKey, homebrew);
|
|
console.log("DH-Ikonis | Default blueprints seeded into Homebrew settings.");
|
|
} else {
|
|
console.log("DH-Ikonis | Homebrew features are already up to date.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scans the Daggerheart system config for any weapon features starting with "Ikonis:".
|
|
* These are treated as available augments for our slot system.
|
|
*/
|
|
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 [id, feature] of Object.entries(allFeatures)) {
|
|
const name = feature.label || feature.name || "";
|
|
if (name.startsWith("Ikonis:")) {
|
|
let desc = feature.description || "";
|
|
// Replace common line-breaking tags with actual newlines before stripping
|
|
desc = desc.replace(/<\/p>|<br\s*\/?>/gi, '\n');
|
|
desc = desc.replace(/<[^>]*>?/gm, '').trim();
|
|
|
|
const lines = desc.split('\n').map(l => l.trim()).filter(l => l.length > 0);
|
|
|
|
const costLine = lines.find(l => l.toLowerCase().startsWith("cost:"));
|
|
const effectLine = lines.find(l => !l.toLowerCase().startsWith("cost:"));
|
|
|
|
augments.push({
|
|
id: id,
|
|
name: name.replace("Ikonis:", "").trim(),
|
|
fullName: name,
|
|
img: feature.img || "systems/daggerheart/assets/icons/documents/items/chip.svg",
|
|
effect: effectLine || "Native Feature",
|
|
cost: costLine || ""
|
|
});
|
|
}
|
|
}
|
|
|
|
return 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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Patches the system's weapon data preparation to handle slot counts.
|
|
*/
|
|
export function patchIkonisLogic() {
|
|
// Current slot logic is handled via getSlotCount in the sheet context
|
|
}
|
|
|
|
/**
|
|
* Placeholder for character patching - no longer needed for virtual items
|
|
*/
|
|
export function patchDhCharacter(DhCharacter) {
|
|
// Injection is deprecated in favor of native weapon features
|
|
}
|
|
|
|
export function patchDHWeapon() {
|
|
// Future: Add damage type override logic here
|
|
}
|