mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 13:34:42 +00:00
Import gk-greyknight-0.4.4-patch.zip do wg-greyknights (2025-08-21T21:44:57Z)
This commit is contained in:
@@ -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">War‑Plate — 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); }
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user