Import gk-greyknight-0.4.4-patch.zip do wg-greyknights (2025-08-21T21:44:57Z)

This commit is contained in:
2025-08-21 21:44:57 +00:00
parent 0ab17ffe3d
commit 305edfa775
3 changed files with 112 additions and 68 deletions
@@ -1,68 +0,0 @@
// gk-greyknight — auto-attach loadout on Grey Knight Archetype
Hooks.once("ready", () => {
const PACK_KEY = "gk-greyknight.gk-items"; // moduleId.packName
const NAMES = [
"Aegis of Titan (Ability)",
"Nemesis Force Halberd",
"Grey Knight Armour Integrated Storm Bolter",
"Aegis Power Armour"
];
async function fetchFromCompendium(name) {
const pack = game.packs.get(PACK_KEY);
if (!pack) return null;
const index = await pack.getIndex();
const hit = index.find(e => e.name === name);
if (!hit) return null;
const doc = await pack.getDocument(hit._id);
return doc?.toObject();
}
async function ensureOnActor(actor, name, equip=false) {
const have = actor.items.getName(name);
if (have) return have;
let src = await fetchFromCompendium(name);
if (!src) {
// fallback: look in world items directory
const world = game.items.getName(name);
if (world) src = world.toObject();
}
if (!src) return null;
// set equipped if item supports it
if (equip && src.system && typeof src.system.equipped !== "undefined") {
src.system.equipped = true;
}
const created = await actor.createEmbeddedDocuments("Item", [src]);
return created[0];
}
// Hook: when the Grey Knight Archetype is added to an actor
Hooks.on("createItem", async (item, opts, userId) => {
try {
if (item?.type !== "archetype") return;
if (item?.name !== "Grey Knight (Archetype)") return;
const actor = item.parent;
if (!actor || game.userId !== userId) return;
// Attach base loadout (War-Plate default) + ability
await ensureOnActor(actor, "Aegis of Titan (Ability)", false);
await ensureOnActor(actor, "Nemesis Force Halberd", true);
await ensureOnActor(actor, "Grey Knight Armour Integrated Storm Bolter", true);
await ensureOnActor(actor, "Aegis Power Armour", true);
// Optional: enable Aegis Synergy effect if present and Aegis is equipped
const abil = actor.items.getName("Aegis of Titan (Ability)");
const aegis = actor.items.getName("Aegis Power Armour");
const hasAegis = !!(aegis?.system?.equipped);
if (abil && abil.effects) {
for (const ef of abil.effects) {
if (ef.name?.toLowerCase().includes("synergy")) await ef.update({disabled: !hasAegis});
}
}
ui.notifications.info("Grey Knight loadout attached.");
} catch (e) {
console.error("gk-greyknight auto-loadout error:", e);
}
});
});
@@ -0,0 +1,112 @@
// gk-greyknight — auto-attach loadout with clear choices
Hooks.once("ready", () => {
const PACK_KEY = "gk-greyknight.gk-items"; // moduleId.packName
const ITEMS = {
ability: "Aegis of Titan (Ability)",
nemesis: "Nemesis Force Halberd",
storm: "Grey Knight Armour Integrated Storm Bolter",
aegisPA: "Aegis Power Armour",
aegisTerm: "Terminator Aegis (Grey Knights)"
};
async function fetchFromCompendium(name) {
const pack = game.packs.get(PACK_KEY);
if (!pack) return null;
const index = await pack.getIndex();
const hit = index.find(e => e.name === name);
if (!hit) return null;
const doc = await pack.getDocument(hit._id);
return doc?.toObject();
}
async function ensureOnActor(actor, name, equip=false) {
let have = actor.items.getName(name);
if (have) {
if (typeof have.system?.equipped !== "undefined") await have.update({"system.equipped": !!equip});
return have;
}
let src = await fetchFromCompendium(name);
if (!src) { const world = game.items.getName(name); if (world) src = world.toObject(); }
if (!src) return null;
if (equip && src.system && typeof src.system.equipped !== "undefined") src.system.equipped = true;
const [created] = await actor.createEmbeddedDocuments("Item", [src]);
return created;
}
async function setEquipped(actor, name, on) {
const it = actor.items.getName(name);
if (it && typeof it.system?.equipped !== "undefined") await it.update({"system.equipped": !!on});
}
Hooks.on("createItem", async (item, opts, userId) => {
try {
if (item?.type !== "archetype") return;
if (item?.name !== "Grey Knight (Archetype)") return;
const actor = item.parent;
if (!actor || game.userId !== userId) return;
// Build labeled dialog (no more "Choice1 / Choice2")
const content = `
<style>
.gk-choices .opt{display:flex;gap:.6rem;align-items:flex-start;padding:.35rem .5rem;border:1px solid #6663;border-radius:6px;margin:.35rem 0}
.gk-choices .opt label{font-weight:600}
.gk-choices .hint{font-size:.9em;opacity:.85;margin-left:1.7rem}
</style>
<div class="gk-choices">
<div class="opt">
<input type="radio" name="mode" value="incog" id="gk-incog">
<label for="gk-incog">Incognito (bez Aegis)</label>
</div>
<div class="hint">Brak Aegis na starcie; dodam Ability i broń, ale nie będą <i>equipped</i>.</div>
<div class="opt">
<input type="radio" name="mode" value="war" id="gk-war" checked>
<label for="gk-war">WarPlate — Aegis Power Armour</label>
</div>
<div class="hint">Wyposaża: Aegis Power Armour + Nemesis + Integrated Storm Bolter. Włącza synergię Aegis.</div>
<div class="opt">
<input type="radio" name="mode" value="term" id="gk-term">
<label for="gk-term">Terminator — Terminator Aegis</label>
</div>
<div class="hint">Wyposaża: Terminator Aegis + Nemesis + Integrated Storm Bolter. Włącza synergię Aegis.</div>
</div>`;
const choice = await new Promise(resolve => {
new Dialog({
title: "Grey Knight — Wybierz Loadout",
content,
buttons: {
ok: {label: "Zastosuj", icon:"<i class='fas fa-check'></i>", callback: html => resolve(html.find('input[name=\"mode\"]:checked').val() || "war")},
cancel: {label:"Anuluj", callback: ()=>resolve(null)}
},
default: "ok"
}).render(true);
});
if (!choice) return;
// Always add Ability
await ensureOnActor(actor, ITEMS.ability, false);
// Add base weapons
const n = await ensureOnActor(actor, ITEMS.nemesis, choice!=="incog");
const s = await ensureOnActor(actor, ITEMS.storm, choice!=="incog");
// Clear both armours equipped
await setEquipped(actor, ITEMS.aegisPA, false);
await setEquipped(actor, ITEMS.aegisTerm, false);
if (choice === "war") {
await ensureOnActor(actor, ITEMS.aegisPA, true);
} else if (choice === "term") {
await ensureOnActor(actor, ITEMS.aegisTerm, true);
}
// Synergy toggle in Aegis of Titan
const abil = actor.items.getName(ITEMS.ability);
const anyAegisOn = !!actor.items.find(i => ["armour","armor"].includes(i.type) && /Aegis/.test(i.name) && i.system?.equipped);
if (abil?.effects?.length) {
for (const ef of abil.effects) if (ef.name?.toLowerCase().includes("synergy")) await ef.update({disabled: !anyAegisOn});
}
ui.notifications.info(`GK loadout: ${choice.toUpperCase()} ustawiony.`);
} catch (e) { console.error("gk-greyknight auto-loadout error:", e); }
});
});