mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 13:34:42 +00:00
Import gk-greyknight-0.5.3.zip do wg-greyknights (2025-08-22T10:31:14Z)
This commit is contained in:
@@ -1,13 +1,7 @@
|
|||||||
Grey Knights — Compendium (Wrath & Glory) v0.4.1
|
Grey Knights — Compendium (Wrath & Glory) v0.5.3
|
||||||
Built from: GK_Foundry_GreyKnight_v5.zip (ONLY the 'foundry/*.json' files)
|
Fix: New items lacked _id in 0.5.1; v11+ migration skipped them. This build assigns IDs and reverts to v11 folder-path pack.
|
||||||
Built at: 2025-08-21 20:55:51 UTC
|
|
||||||
|
|
||||||
How to install (manual):
|
Install:
|
||||||
1) Unzip so that you have: Data/modules/gk-greyknight/module.json (i.e. the FOLDER name == id).
|
1) Replace Data/modules/gk-greyknight with this folder.
|
||||||
2) Restart your World and enable module: 'Grey Knights — Compendium (Wrath & Glory)'.
|
2) Start world, let Foundry migrate packs/gk-items.db -> packs/gk-items/ (LevelDB).
|
||||||
3) Open Compendium sidebar → you will see: 'Grey Knights — Items'.
|
3) In Compendium sidebar → right-click "Grey Knights — Items" → Rebuild Index.
|
||||||
4) Import by drag&drop or context menu 'Import All'.
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
- The compendium path in module.json uses 'packs/gk-items' (no .db) per v11+ packaging.
|
|
||||||
- The actual data ships as 'packs/gk-items.db'. Foundry will auto‑migrate it to the new format on first load.
|
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "gk-greyknight",
|
"id": "gk-greyknight",
|
||||||
"title": "Grey Knights — Compendium (Wrath & Glory)",
|
"title": "Grey Knights — Compendium (Wrath & Glory)",
|
||||||
"esmodules": [
|
"version": "0.5.3",
|
||||||
"scripts/auto-loadout.js"
|
|
||||||
],
|
|
||||||
"description": "Compendium pack built ONLY from the provided 'foundry/' JSONs (6 items).",
|
|
||||||
"version": "0.5.2",
|
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "11",
|
"minimum": "11",
|
||||||
"verified": "13"
|
"verified": "13"
|
||||||
@@ -22,11 +18,14 @@
|
|||||||
{
|
{
|
||||||
"name": "gk-items",
|
"name": "gk-items",
|
||||||
"label": "Grey Knights — Items",
|
"label": "Grey Knights — Items",
|
||||||
"path": "packs/gk-items.db",
|
"path": "packs/gk-items",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"system": "wrath-and-glory",
|
"system": "wrath-and-glory",
|
||||||
"private": false
|
"private": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"esmodules": [
|
||||||
|
"scripts/auto-loadout.js"
|
||||||
|
],
|
||||||
"readme": "README.txt"
|
"readme": "README.txt"
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
// gk-greyknight — auto-attach loadout (scoped + incognito revamp + ORDO MALLEUS) v0.4.9
|
// gk-greyknight — auto-attach loadout (scoped + incognito + ORDO) v0.5.3
|
||||||
Hooks.once("ready", () => {
|
Hooks.once("ready", () => {
|
||||||
const PACK_KEY = "gk-greyknight.gk-items"; // our compendium
|
const PACK_KEY = "gk-greyknight.gk-items"; // v11-style pack id
|
||||||
const PACK_SRC_PREFIX = `Compendium.${PACK_KEY}.`; // prefix in core.sourceId
|
const PACK_SRC_PREFIX = `Compendium.${PACK_KEY}.`;
|
||||||
const CORE = {
|
const CORE = {
|
||||||
knife: "Compendium.wng-core.items.Item.4QVBQYWXXLyvFWkj",
|
knife: "Compendium.wng-core.items.Item.4QVBQYWXXLyvFWkj",
|
||||||
pistol: "Compendium.wng-core.items.Item.7b2xcPWBB7up65PM",
|
pistol: "Compendium.wng-core.items.Item.7b2xcPWBB7up65PM",
|
||||||
@@ -18,7 +18,6 @@ Hooks.once("ready", () => {
|
|||||||
};
|
};
|
||||||
const FLAG_SCOPE = "gk-greyknight"; const FLAG_DONE = "autoLoadoutDone";
|
const FLAG_SCOPE = "gk-greyknight"; const FLAG_DONE = "autoLoadoutDone";
|
||||||
|
|
||||||
// helpers
|
|
||||||
async function fetchFromCompendium(name) {
|
async function fetchFromCompendium(name) {
|
||||||
const pack = game.packs.get(PACK_KEY);
|
const pack = game.packs.get(PACK_KEY);
|
||||||
if (!pack) return null;
|
if (!pack) return null;
|
||||||
@@ -28,17 +27,11 @@ Hooks.once("ready", () => {
|
|||||||
const doc = await pack.getDocument(hit._id);
|
const doc = await pack.getDocument(hit._id);
|
||||||
return doc?.toObject();
|
return doc?.toObject();
|
||||||
}
|
}
|
||||||
async function fetchFromUuid(uuid) {
|
async function fetchFromUuid(uuid) { try { const doc = await fromUuid(uuid); return doc?.toObject(); } catch(e){ return null; } }
|
||||||
try { const doc = await fromUuid(uuid); return doc?.toObject(); } catch(e){ return null; }
|
|
||||||
}
|
|
||||||
async function ensureOnActor(actor, srcDoc, equip=false) {
|
async function ensureOnActor(actor, srcDoc, equip=false) {
|
||||||
const name = srcDoc?.name;
|
const name = srcDoc?.name; if (!name) return null;
|
||||||
if (!name) return null;
|
|
||||||
let have = actor.items.getName(name);
|
let have = actor.items.getName(name);
|
||||||
if (have) {
|
if (have) { if (typeof have.system?.equipped !== "undefined") await have.update({"system.equipped": !!equip}); return 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;
|
if (equip && srcDoc.system && typeof srcDoc.system.equipped !== "undefined") srcDoc.system.equipped = true;
|
||||||
const [created] = await actor.createEmbeddedDocuments("Item", [srcDoc]);
|
const [created] = await actor.createEmbeddedDocuments("Item", [srcDoc]);
|
||||||
return created;
|
return created;
|
||||||
@@ -56,7 +49,6 @@ Hooks.once("ready", () => {
|
|||||||
if (it && typeof it.system?.equipped !== "undefined") await it.update({"system.equipped": !!on});
|
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; }
|
if (window._gkAutoLoadoutHookId) { Hooks.off("createItem", window._gkAutoLoadoutHookId); window._gkAutoLoadoutHookId = null; }
|
||||||
|
|
||||||
window._gkAutoLoadoutHookId = Hooks.on("createItem", async (item, opts, userId) => {
|
window._gkAutoLoadoutHookId = Hooks.on("createItem", async (item, opts, userId) => {
|
||||||
@@ -65,19 +57,17 @@ Hooks.once("ready", () => {
|
|||||||
const src = item?.flags?.core?.sourceId || "";
|
const src = item?.flags?.core?.sourceId || "";
|
||||||
const isFromOurPack = src.startsWith(PACK_SRC_PREFIX);
|
const isFromOurPack = src.startsWith(PACK_SRC_PREFIX);
|
||||||
const isOurGKByName = item?.name === "Grey Knight (Archetype)";
|
const isOurGKByName = item?.name === "Grey Knight (Archetype)";
|
||||||
if (!isFromOurPack && !isOurGKByName) return; // ignore non-GK archetypes
|
if (!isFromOurPack && !isOurGKByName) return;
|
||||||
if (game.userId !== userId) return;
|
if (game.userId !== userId) return;
|
||||||
const actor = item.parent; if (!actor) return;
|
const actor = item.parent; if (!actor) return;
|
||||||
if (actor.getFlag(FLAG_SCOPE, FLAG_DONE)) return;
|
if (actor.getFlag(FLAG_SCOPE, FLAG_DONE)) return;
|
||||||
await actor.setFlag(FLAG_SCOPE, FLAG_DONE, true);
|
await actor.setFlag(FLAG_SCOPE, FLAG_DONE, true);
|
||||||
|
|
||||||
// Always add ability + ORDO MALLEUS (choice)
|
|
||||||
await ensureByName(actor, ITEMS.ability, false);
|
await ensureByName(actor, ITEMS.ability, false);
|
||||||
let ordoDoc = await fetchFromUuid(CORE.ordo);
|
let ordoDoc = await fetchFromUuid(CORE.ordo);
|
||||||
if (!ordoDoc) ordoDoc = await fetchFromCompendium(ITEMS.ordo);
|
if (!ordoDoc) ordoDoc = await fetchFromCompendium(ITEMS.ordo);
|
||||||
if (ordoDoc) await ensureOnActor(actor, ordoDoc, false);
|
if (ordoDoc) await ensureOnActor(actor, ordoDoc, false);
|
||||||
|
|
||||||
// Labelled dialog (incognito changed)
|
|
||||||
const content = `
|
const content = `
|
||||||
<style>
|
<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{display:flex;gap:.6rem;align-items:flex-start;padding:.35rem .5rem;border:1px solid #6663;border-radius:6px;margin:.35rem 0}
|
||||||
@@ -89,19 +79,17 @@ Hooks.once("ready", () => {
|
|||||||
<input type="radio" name="mode" value="incog" id="gk-incog">
|
<input type="radio" name="mode" value="incog" id="gk-incog">
|
||||||
<label for="gk-incog">Incognito — Pilgrim Astartes Power Armor + Combat Knife + Bolt Pistol</label>
|
<label for="gk-incog">Incognito — Pilgrim Astartes Power Armor + Combat Knife + Bolt Pistol</label>
|
||||||
</div>
|
</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="hint">Low‑profile loadout (bez Nemesis/SB)</div>
|
||||||
|
|
||||||
<div class="opt">
|
<div class="opt">
|
||||||
<input type="radio" name="mode" value="war" id="gk-war" checked>
|
<input type="radio" name="mode" value="war" id="gk-war" checked>
|
||||||
<label for="gk-war">War‑Plate — Aegis Power Armour</label>
|
<label for="gk-war">War‑Plate — Aegis Power Armour</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="hint">Wyposaża: Aegis Power Armour + Nemesis + Integrated Storm Bolter. Włącza synergię Aegis.</div>
|
<div class="hint">Aegis PA + Nemesis + Integrated Storm Bolter</div>
|
||||||
|
|
||||||
<div class="opt">
|
<div class="opt">
|
||||||
<input type="radio" name="mode" value="term" id="gk-term">
|
<input type="radio" name="mode" value="term" id="gk-term">
|
||||||
<label for="gk-term">Terminator — Terminator Aegis</label>
|
<label for="gk-term">Terminator — Terminator Aegis</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="hint">Wyposaża: Terminator Aegis + Nemesis + Integrated Storm Bolter. Włącza synergię Aegis.</div>
|
<div class="hint">Terminator Aegis + Nemesis + Integrated Storm Bolter</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
const choice = await new Promise(resolve => {
|
const choice = await new Promise(resolve => {
|
||||||
@@ -117,7 +105,6 @@ Hooks.once("ready", () => {
|
|||||||
});
|
});
|
||||||
if (!choice) return;
|
if (!choice) return;
|
||||||
|
|
||||||
// clear equips
|
|
||||||
await setEquipped(actor, ITEMS.aegisPA, false);
|
await setEquipped(actor, ITEMS.aegisPA, false);
|
||||||
await setEquipped(actor, ITEMS.aegisTerm, false);
|
await setEquipped(actor, ITEMS.aegisTerm, false);
|
||||||
await setEquipped(actor, ITEMS.nemesis, false);
|
await setEquipped(actor, ITEMS.nemesis, false);
|
||||||
@@ -125,12 +112,9 @@ Hooks.once("ready", () => {
|
|||||||
await setEquipped(actor, ITEMS.pilgrim, false);
|
await setEquipped(actor, ITEMS.pilgrim, false);
|
||||||
|
|
||||||
if (choice === "incog") {
|
if (choice === "incog") {
|
||||||
// Equip Pilgrim armour + core knife + core bolt pistol
|
|
||||||
await ensureByName(actor, ITEMS.pilgrim, true);
|
await ensureByName(actor, ITEMS.pilgrim, true);
|
||||||
const knife = await fetchFromUuid(CORE.knife);
|
const knife = await fetchFromUuid(CORE.knife); if (knife) await ensureOnActor(actor, knife, true);
|
||||||
if (knife) await ensureOnActor(actor, knife, true);
|
const pistol = await fetchFromUuid(CORE.pistol); if (pistol) await ensureOnActor(actor, pistol, true);
|
||||||
const pistol = await fetchFromUuid(CORE.pistol);
|
|
||||||
if (pistol) await ensureOnActor(actor, pistol, true);
|
|
||||||
} else if (choice === "war") {
|
} else if (choice === "war") {
|
||||||
await ensureByName(actor, ITEMS.nemesis, true);
|
await ensureByName(actor, ITEMS.nemesis, true);
|
||||||
await ensureByName(actor, ITEMS.storm, true);
|
await ensureByName(actor, ITEMS.storm, true);
|
||||||
@@ -141,7 +125,6 @@ Hooks.once("ready", () => {
|
|||||||
await ensureByName(actor, ITEMS.aegisTerm, true);
|
await ensureByName(actor, ITEMS.aegisTerm, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// toggle synergy based on equipped Aegis
|
|
||||||
const abil = actor.items.getName(ITEMS.ability);
|
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);
|
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});
|
if (abil?.effects?.length) for (const ef of abil.effects) if (ef.name?.toLowerCase().includes("synergy")) await ef.update({disabled: !anyAegisOn});
|
||||||
@@ -150,5 +133,5 @@ Hooks.once("ready", () => {
|
|||||||
} catch (e) { console.error("gk-greyknight auto-loadout error:", e); }
|
} catch (e) { console.error("gk-greyknight auto-loadout error:", e); }
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("gk-greyknight: auto-loadout hook active (v0.4.9)");
|
console.log("gk-greyknight: auto-loadout hook active (v0.5.3, pack=gk-items)");
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user