diff --git a/wg-greyknights/README.txt b/wg-greyknights/README.txt deleted file mode 100644 index 7b6474e..0000000 --- a/wg-greyknights/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -# GK Grey Knight (Wrath & Glory) -This module installs homebrew Grey Knight content for the Wrath & Glory system. - -## Contents -- Items: Aegis Power Armour, Terminator Aegis (Grey Knights), Grey Knight Armour Integrated Storm Bolter, Nemesis Force Halberd, Aegis of Titan (Ability), Grey Knight (Archetype). -- Macros (scripts): Import from module, Loadout Manager, Aegis Glow Toggle. -- Preset Actors: GK – Incognito, GK – Power Armour, GK – Terminator (`foundry/actors/*.json`). - -## Install -1. Copy the `gk-greyknight` folder into `{UserData}/Data/modules/` and restart Foundry **or** use a manifest URL that points to `module.json`. -2. Enable **Grey Knight Add-on (Wrath & Glory)** in your World. -3. Go to *Configuration → Module Settings → Grey Knight Tools* to open the helper dialog. -4. Click **Import Items from Module** to populate your Items Directory. -5. Use **Loadout Manager** on a GK actor to switch between Incognito / Power Armour / Terminator. diff --git a/wg-greyknights/docs/README.txt b/wg-greyknights/docs/README.txt new file mode 100644 index 0000000..185a82e --- /dev/null +++ b/wg-greyknights/docs/README.txt @@ -0,0 +1,5 @@ +Wrath & Glory — Daemonhunters (Grey Knights) v0.2.0 +Updated: 2025-08-21T20:11:54.099941 + +Install: In FoundryVTT, install as a regular module. Ensure the system 'wrath-and-glory' is active. +Note: The auto-loadout hook is provided as an ES module via module.json (no 'world' edmodule needed). \ No newline at end of file diff --git a/wg-greyknights/foundry/items/Aegis Power Armour.json b/wg-greyknights/foundry/items/Aegis Power Armour.json new file mode 100644 index 0000000..d1dd8ed --- /dev/null +++ b/wg-greyknights/foundry/items/Aegis Power Armour.json @@ -0,0 +1,17 @@ +{ + "name": "Aegis Power Armour", + "type": "armor", + "img": "icons/svg/shield.svg", + "system": { + "keywords": [ + "GREY KNIGHTS", + "INQUISITION", + "DAEMONHUNTERS", + "ORDO MALLEUS" + ], + "effects": [ + "Aegis Warding (toggleable barrier; visual runes glow)", + "Psychic Hood Integration (+dice to Deny the Witch)" + ] + } +} \ No newline at end of file diff --git a/wg-greyknights/foundry/items/Aegis Terminator Armour.json b/wg-greyknights/foundry/items/Aegis Terminator Armour.json new file mode 100644 index 0000000..21a4244 --- /dev/null +++ b/wg-greyknights/foundry/items/Aegis Terminator Armour.json @@ -0,0 +1,13 @@ +{ + "name": "Aegis Terminator Armour", + "type": "armor", + "img": "icons/svg/shield.svg", + "system": { + "keywords": [ + "GREY KNIGHTS", + "INQUISITION", + "DAEMONHUNTERS", + "ORDO MALLEUS" + ] + } +} \ No newline at end of file diff --git a/wg-greyknights/foundry/items/Aegis of Titan.json b/wg-greyknights/foundry/items/Aegis of Titan.json new file mode 100644 index 0000000..ff2ddf7 --- /dev/null +++ b/wg-greyknights/foundry/items/Aegis of Titan.json @@ -0,0 +1,14 @@ +{ + "name": "Aegis of Titan", + "type": "ability", + "img": "icons/svg/aura.svg", + "system": { + "keywords": [ + "GREY KNIGHTS", + "INQUISITION", + "DAEMONHUNTERS", + "ORDO MALLEUS" + ], + "description": "Toggle: +Armour Resilience / -Defence (runes glow). Passive: +dice to Deny the Witch; +1 Corruption Resistance (stacks with archetype)." + } +} \ No newline at end of file diff --git a/wg-greyknights/foundry/items/Grey Knight Archetype.json b/wg-greyknights/foundry/items/Grey Knight Archetype.json new file mode 100644 index 0000000..4ab985d --- /dev/null +++ b/wg-greyknights/foundry/items/Grey Knight Archetype.json @@ -0,0 +1,19 @@ +{ + "name": "Grey Knight", + "type": "archetype", + "img": "icons/svg/book.svg", + "system": { + "keywords": [ + "GREY KNIGHTS", + "INQUISITION", + "DAEMONHUNTERS", + "ORDO MALLEUS" + ], + "wargear": [ + "Nemesis Force Halberd", + "Aegis Power Armour", + "Grey Knight Armour Integrated Storm Bolter" + ], + "notes": "Innate: +1 vs Corruption; +1 additional vs Corruption when equipped with Aegis armour. Adds Aegis of Titan ability." + } +} \ No newline at end of file diff --git a/wg-greyknights/foundry/items/Grey Knight Armour Integrated Storm Bolter.json b/wg-greyknights/foundry/items/Grey Knight Armour Integrated Storm Bolter.json new file mode 100644 index 0000000..1d4181d --- /dev/null +++ b/wg-greyknights/foundry/items/Grey Knight Armour Integrated Storm Bolter.json @@ -0,0 +1,15 @@ +{ + "name": "Grey Knight Armour Integrated Storm Bolter", + "type": "weapon", + "img": "icons/svg/bolt.svg", + "system": { + "category": "ranged", + "keywords": [ + "GREY KNIGHTS", + "INQUISITION", + "DAEMONHUNTERS", + "ORDO MALLEUS" + ], + "special": "Mounted; can fire while using two-handed melee weapon (RAW: separate action)." + } +} \ No newline at end of file diff --git a/wg-greyknights/foundry/items/Nemesis Force Halberd.json b/wg-greyknights/foundry/items/Nemesis Force Halberd.json new file mode 100644 index 0000000..ec1a2b6 --- /dev/null +++ b/wg-greyknights/foundry/items/Nemesis Force Halberd.json @@ -0,0 +1,15 @@ +{ + "name": "Nemesis Force Halberd", + "type": "weapon", + "img": "icons/svg/sword.svg", + "system": { + "category": "melee", + "keywords": [ + "GREY KNIGHTS", + "INQUISITION", + "DAEMONHUNTERS", + "ORDO MALLEUS" + ], + "special": "Counts as Force Staff; +ED vs Daemons/Psykers" + } +} \ No newline at end of file diff --git a/wg-greyknights/icons/placeholder.txt b/wg-greyknights/icons/placeholder.txt new file mode 100644 index 0000000..c045b88 --- /dev/null +++ b/wg-greyknights/icons/placeholder.txt @@ -0,0 +1 @@ +Drop your real icons here; JSONs point to icons/svg/ (Foundry stock) to avoid broken paths. \ No newline at end of file diff --git a/wg-greyknights/macros/macro-gk-auto-loadout-on-archetype.js b/wg-greyknights/macros/macro-gk-auto-loadout-on-archetype.js deleted file mode 100644 index 4e3eff4..0000000 --- a/wg-greyknights/macros/macro-gk-auto-loadout-on-archetype.js +++ /dev/null @@ -1,15 +0,0 @@ -// GK – Auto Loadout on Archetype Assignment (world esmodule friendly) -(() => { - if (window._gkAutoLoadoutHook) { return; } - window._gkAutoLoadoutHook = 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; - const macro = game.macros.getName("GK – Loadout Manager") || game.macros.getName("GK-Loadout-Manager"); - if (macro) await macro.execute(); - else ui.notifications.warn("Brak makra 'GK – Loadout Manager'. Dodaj je do świata (macros/)."); - } catch (e) { console.error("GK Auto-Loadout error", e); } - }); -})(); \ No newline at end of file diff --git a/wg-greyknights/macros/macro-gk-importer.js b/wg-greyknights/macros/macro-gk-importer.js new file mode 100644 index 0000000..93eca1e --- /dev/null +++ b/wg-greyknights/macros/macro-gk-importer.js @@ -0,0 +1,29 @@ +// GK Importer: drop a folder path that contains JSON items exported from Foundry and import them. +(async () => { + const dir = await new Promise(resolve => { + new Dialog({ + title: "GK Importer — pick folder URL or paste path", + content: `

Paste a data path (e.g. /worlds/your-world/foundry/items)

`, + buttons: { + ok: { label: "Import", callback: html => resolve(html.find('input[name="path"]').val()) }, + cancel: { label: "Cancel", callback: () => resolve(null) } + }, + default: "ok" + }).render(true); + }); + if (!dir) return; + const response = await FilePicker.browse("data", dir); + const files = response.files.filter(f => f.endsWith(".json")); + for (const f of files) { + try { + const json = await (await fetch(f)).json(); + if (json.type && (json.name || json.label)) { + if (!json.name && json.label) json.name = json.label; + await Item.create(json); + } + } catch (err) { + ui.notifications.error(`Import failed for ${f}: ${err.message}`); + } + } + ui.notifications.info("GK Import complete."); +})(); \ No newline at end of file diff --git a/wg-greyknights/manifest.json b/wg-greyknights/manifest.json new file mode 100644 index 0000000..7052432 --- /dev/null +++ b/wg-greyknights/manifest.json @@ -0,0 +1,36 @@ +{ + "id": "wrath-and-glory-gk", + "title": "Wrath & Glory — Daemonhunters (Grey Knights)", + "description": "Grey Knights add-on: archetype, Aegis armours, Nemesis force halberd, integrated Storm Bolter, Aegis of Titan ability, and helper macros.", + "version": "0.2.0", + "compatibility": { + "minimum": "10", + "verified": "11" + }, + "authors": [ + { + "name": "ChatGPT (assistant)" + } + ], + "systems": [ + { + "id": "wrath-and-glory", + "type": "system", + "compatibility": { + "minimum": "5" + } + } + ], + "esmodules": [ + "scripts/macro-gk-auto-loadout-on-archetype.js" + ], + "scripts": [], + "packs": [], + "relationships": { + "systems": [ + { + "id": "wrath-and-glory" + } + ] + } +} \ No newline at end of file diff --git a/wg-greyknights/module.json b/wg-greyknights/module.json index b0636fb..7052432 100644 --- a/wg-greyknights/module.json +++ b/wg-greyknights/module.json @@ -1,26 +1,36 @@ { - "id": "gk-greyknight", - "title": "Grey Knight Add-on (Wrath & Glory)", - "description": "Homebrew Grey Knights kit for Wrath & Glory: archetype, Aegis armours, integrated storm bolter, Nemesis halberd, ability, macros, and preset actors.", - "version": "0.1.0", + "id": "wrath-and-glory-gk", + "title": "Wrath & Glory — Daemonhunters (Grey Knights)", + "description": "Grey Knights add-on: archetype, Aegis armours, Nemesis force halberd, integrated Storm Bolter, Aegis of Titan ability, and helper macros.", + "version": "0.2.0", "compatibility": { - "minimum": "13", - "verified": "13" + "minimum": "10", + "verified": "11" }, "authors": [ { - "name": "User & Assistant" + "name": "ChatGPT (assistant)" } ], "systems": [ - "wrath-and-glory" + { + "id": "wrath-and-glory", + "type": "system", + "compatibility": { + "minimum": "5" + } + } ], "esmodules": [ - "scripts/auto-loadout.js" + "scripts/macro-gk-auto-loadout-on-archetype.js" ], - "readme": "README.txt", - "license": "LICENSE", - "url": "https://example.com/gk-greyknight", - "manifest": "https://example.com/gk-greyknight/module.json", - "download": "https://example.com/gk-greyknight/gk-greyknight-0.1.0.zip" + "scripts": [], + "packs": [], + "relationships": { + "systems": [ + { + "id": "wrath-and-glory" + } + ] + } } \ No newline at end of file diff --git a/wg-greyknights/scripts/macro-gk-auto-loadout-on-archetype.js b/wg-greyknights/scripts/macro-gk-auto-loadout-on-archetype.js new file mode 100644 index 0000000..01bf305 --- /dev/null +++ b/wg-greyknights/scripts/macro-gk-auto-loadout-on-archetype.js @@ -0,0 +1,20 @@ +// Auto loadout on archetype creation (hook Actor creation) +Hooks.on("createActor", async (actor, options, userId) => { + try { + const arch = actor.items.find(i => i.type === "archetype" && i.name?.includes("Grey Knight")); + if (!arch) return; + const names = ["Nemesis Force Halberd","Aegis Power Armour","Grey Knight Armour Integrated Storm Bolter","Aegis of Titan"]; + const toAdd = []; + for (const n of names) { + const packItem = game.items.getName?.(n); + if (packItem) toAdd.push(packItem.toObject()); + else { + // fallback: create minimal items + toAdd.push({name:n, type: n.includes("Armour") ? "armor" : (n.includes("Bolter") ? "weapon" : "ability"), img:"icons/svg/placeholder.svg", system:{}}); + } + } + await actor.createEmbeddedDocuments("Item", toAdd); + } catch(e) { + console.error(e); + } +}); \ No newline at end of file