mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 21:38:39 +00:00
Import gk-greyknight-0.4.9-patch.zip do wg-greyknights (2025-08-21T23:12:29Z)
This commit is contained in:
+2
-1
File diff suppressed because one or more lines are too long
+58
-26
@@ -1,16 +1,24 @@
|
||||
// gk-greyknight — auto-attach loadout (scoped, no clashes) v0.4.7
|
||||
// gk-greyknight — auto-attach loadout (scoped + incognito revamp + ORDO MALLEUS) v0.4.9
|
||||
Hooks.once("ready", () => {
|
||||
const PACK_KEY = "gk-greyknight.gk-items"; // our compendium
|
||||
const PACK_SRC_PREFIX = `Compendium.${PACK_KEY}.`; // prefix in core.sourceId
|
||||
const CORE = {
|
||||
knife: "Compendium.wng-core.items.Item.4QVBQYWXXLyvFWkj",
|
||||
pistol: "Compendium.wng-core.items.Item.7b2xcPWBB7up65PM",
|
||||
ordo: "Compendium.wng-core.items.Item.mpcvHYlffwcBy9gP"
|
||||
};
|
||||
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)"
|
||||
aegisTerm: "Terminator Aegis (Grey Knights)",
|
||||
pilgrim: "Pilgrim Astartes Power Armor",
|
||||
ordo: "ORDO MALLEUS"
|
||||
};
|
||||
const FLAG_SCOPE = "gk-greyknight"; const FLAG_DONE = "autoLoadoutDone";
|
||||
|
||||
// helpers
|
||||
async function fetchFromCompendium(name) {
|
||||
const pack = game.packs.get(PACK_KEY);
|
||||
if (!pack) return null;
|
||||
@@ -20,47 +28,56 @@ Hooks.once("ready", () => {
|
||||
const doc = await pack.getDocument(hit._id);
|
||||
return doc?.toObject();
|
||||
}
|
||||
async function ensureOnActor(actor, name, equip=false) {
|
||||
async function fetchFromUuid(uuid) {
|
||||
try { const doc = await fromUuid(uuid); return doc?.toObject(); } catch(e){ return null; }
|
||||
}
|
||||
async function ensureOnActor(actor, srcDoc, equip=false) {
|
||||
const name = srcDoc?.name;
|
||||
if (!name) return null;
|
||||
let have = actor.items.getName(name);
|
||||
if (have) {
|
||||
if (typeof have.system?.equipped !== "undefined") await have.update({"system.equipped": !!equip});
|
||||
return have;
|
||||
}
|
||||
if (equip && srcDoc.system && typeof srcDoc.system.equipped !== "undefined") srcDoc.system.equipped = true;
|
||||
const [created] = await actor.createEmbeddedDocuments("Item", [srcDoc]);
|
||||
return created;
|
||||
}
|
||||
async function ensureByName(actor, name, equip=false) {
|
||||
const 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;
|
||||
return ensureOnActor(actor, src, equip);
|
||||
}
|
||||
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});
|
||||
}
|
||||
|
||||
// Dedupe our hook
|
||||
if (window._gkAutoLoadoutHookId) {
|
||||
Hooks.off("createItem", window._gkAutoLoadoutHookId);
|
||||
window._gkAutoLoadoutHookId = null;
|
||||
}
|
||||
// dedupe our hook
|
||||
if (window._gkAutoLoadoutHookId) { Hooks.off("createItem", window._gkAutoLoadoutHookId); window._gkAutoLoadoutHookId = null; }
|
||||
|
||||
window._gkAutoLoadoutHookId = Hooks.on("createItem", async (item, opts, userId) => {
|
||||
try {
|
||||
// 1) only archetypes
|
||||
if (item?.type !== "archetype") return;
|
||||
// 2) only our GK archetype coming from our pack (prevents clashes with Cubicle7 archetypes)
|
||||
const src = item?.flags?.core?.sourceId || "";
|
||||
const isFromOurPack = src.startsWith(PACK_SRC_PREFIX);
|
||||
const isOurGKByName = item?.name === "Grey Knight (Archetype)";
|
||||
if (!isFromOurPack && !isOurGKByName) return; // ignore all others (e.g. Inquisitor, Guardsman, etc.)
|
||||
// 3) only the client that created the item
|
||||
if (!isFromOurPack && !isOurGKByName) return; // ignore non-GK archetypes
|
||||
if (game.userId !== userId) return;
|
||||
// 4) once per actor
|
||||
const actor = item.parent; if (!actor) return;
|
||||
if (actor.getFlag(FLAG_SCOPE, FLAG_DONE)) return;
|
||||
await actor.setFlag(FLAG_SCOPE, FLAG_DONE, true);
|
||||
|
||||
// Dialog
|
||||
// Always add ability + ORDO MALLEUS (choice)
|
||||
await ensureByName(actor, ITEMS.ability, false);
|
||||
let ordoDoc = await fetchFromUuid(CORE.ordo);
|
||||
if (!ordoDoc) ordoDoc = await fetchFromCompendium(ITEMS.ordo);
|
||||
if (ordoDoc) await ensureOnActor(actor, ordoDoc, false);
|
||||
|
||||
// Labelled dialog (incognito changed)
|
||||
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}
|
||||
@@ -70,9 +87,9 @@ Hooks.once("ready", () => {
|
||||
<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>
|
||||
<label for="gk-incog">Incognito — Pilgrim Astartes Power Armor + Combat Knife + Bolt Pistol</label>
|
||||
</div>
|
||||
<div class="hint">Brak Aegis na starcie; dodam Ability i broń, ale nie będą <i>equipped</i>.</div>
|
||||
<div class="hint">Wyposaża pancerz pielgrzyma i broń „low‑profile” z Core. <i>Nie</i> dodaje Nemesis ani zintegrowanego Storm Boltera.</div>
|
||||
|
||||
<div class="opt">
|
||||
<input type="radio" name="mode" value="war" id="gk-war" checked>
|
||||
@@ -100,16 +117,31 @@ Hooks.once("ready", () => {
|
||||
});
|
||||
if (!choice) return;
|
||||
|
||||
await ensureOnActor(actor, ITEMS.ability, false);
|
||||
await ensureOnActor(actor, ITEMS.nemesis, choice!=="incog");
|
||||
await ensureOnActor(actor, ITEMS.storm, choice!=="incog");
|
||||
|
||||
// clear equips
|
||||
await setEquipped(actor, ITEMS.aegisPA, false);
|
||||
await setEquipped(actor, ITEMS.aegisTerm, false);
|
||||
await setEquipped(actor, ITEMS.nemesis, false);
|
||||
await setEquipped(actor, ITEMS.storm, false);
|
||||
await setEquipped(actor, ITEMS.pilgrim, false);
|
||||
|
||||
if (choice === "war") await ensureOnActor(actor, ITEMS.aegisPA, true);
|
||||
else if (choice === "term") await ensureOnActor(actor, ITEMS.aegisTerm, true);
|
||||
if (choice === "incog") {
|
||||
// Equip Pilgrim armour + core knife + core bolt pistol
|
||||
await ensureByName(actor, ITEMS.pilgrim, true);
|
||||
const knife = await fetchFromUuid(CORE.knife);
|
||||
if (knife) await ensureOnActor(actor, knife, true);
|
||||
const pistol = await fetchFromUuid(CORE.pistol);
|
||||
if (pistol) await ensureOnActor(actor, pistol, true);
|
||||
} else if (choice === "war") {
|
||||
await ensureByName(actor, ITEMS.nemesis, true);
|
||||
await ensureByName(actor, ITEMS.storm, true);
|
||||
await ensureByName(actor, ITEMS.aegisPA, true);
|
||||
} else if (choice === "term") {
|
||||
await ensureByName(actor, ITEMS.nemesis, true);
|
||||
await ensureByName(actor, ITEMS.storm, true);
|
||||
await ensureByName(actor, ITEMS.aegisTerm, true);
|
||||
}
|
||||
|
||||
// toggle synergy based on equipped Aegis
|
||||
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});
|
||||
@@ -118,5 +150,5 @@ Hooks.once("ready", () => {
|
||||
} catch (e) { console.error("gk-greyknight auto-loadout error:", e); }
|
||||
});
|
||||
|
||||
console.log("gk-greyknight: auto-loadout hook active (scoped)");
|
||||
console.log("gk-greyknight: auto-loadout hook active (v0.4.9)");
|
||||
});
|
||||
Reference in New Issue
Block a user