From 584985ede84727dd3d1bf3d8e054fe7fd1c1f51f Mon Sep 17 00:00:00 2001 From: Michal Tuszowski Date: Thu, 18 Sep 2025 23:56:05 +0200 Subject: [PATCH] Working version --- .../packs/wg-voidship-hulls.db | 48 +- .../packs/wg-voidship-items.db | 28 +- .../scripts/voidship-actor.js | 555 ++++++++++-------- .../templates/voidship-sheet.hbs | 87 +-- wg-voidships-builder/wg-voidships-builder.zip | Bin 22419 -> 22973 bytes 5 files changed, 409 insertions(+), 309 deletions(-) diff --git a/wg-voidships-builder/packs/wg-voidship-hulls.db b/wg-voidships-builder/packs/wg-voidship-hulls.db index 7264856..b726df3 100644 --- a/wg-voidships-builder/packs/wg-voidship-hulls.db +++ b/wg-voidships-builder/packs/wg-voidship-hulls.db @@ -1,24 +1,24 @@ -{"name":"Escort Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Escort Hull (Empty)","size":"Escort","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":9,"integrity":18,"manoeuvre":2,"detection":0,"speed":10,"space":30,"power":40},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":9,"hullIntegrity":18,"space":30,"power":40,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":2,"notes":"Empty hull for escorts.","combat":{"size":"colossal","speed":10,"wounds":{"max":18},"resilience":{"total":9},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Frigate Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Frigate Hull (Empty)","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":10,"integrity":24,"manoeuvre":1,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":10,"hullIntegrity":24,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":1,"notes":"Empty frigate hull.","combat":{"size":"colossal","speed":10,"wounds":{"max":24},"resilience":{"total":10},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Light Cruiser Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Light Cruiser Hull (Empty)","size":"Light Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0}},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":0,"speed":9,"space":55,"power":60},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":9,"armour":11,"hullIntegrity":32,"space":55,"power":60,"weapons":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"turret":2},"mnvr":0,"notes":"Empty light cruiser hull.","combat":{"size":"colossal","speed":9,"wounds":{"max":32},"resilience":{"total":11},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Cruiser Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Cruiser Hull (Empty)","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":2,"starboard":2,"keel":0}},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":0,"speed":8,"space":65,"power":75},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":40,"space":65,"power":75,"weapons":{"prow":1,"dorsal":1,"port":2,"starboard":2,"keel":0},"turret":2},"mnvr":-1,"notes":"Empty cruiser hull.","combat":{"size":"colossal","speed":8,"wounds":{"max":40},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Jericho-class Pilgrim Vessel","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Jericho-class Pilgrim Vessel","size":"Transport","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0}},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":0,"speed":8,"space":60,"power":55},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":36,"space":60,"power":55,"weapons":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"turret":1},"mnvr":-1,"notes":"Pilgrim conversions with reliquary holds.","combat":{"size":"colossal","speed":8,"wounds":{"max":36},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Vagabond-class Merchant Trader","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Vagabond-class Merchant Trader","size":"Transport","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0}},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":0,"speed":8,"space":60,"power":55},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":36,"space":60,"power":55,"weapons":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"turret":1},"mnvr":-1,"notes":"Modular cargobays; workhorse trader.","combat":{"size":"colossal","speed":8,"wounds":{"max":36},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Hazeroth-class Privateer","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Hazeroth-class Privateer","size":"Escort","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":9,"hullIntegrity":22,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":2,"notes":"Fast raider with stripped armour.","combat":{"size":"colossal","speed":10,"wounds":{"max":22},"resilience":{"total":9},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Havoc-class Merchant Raider","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Havoc-class Merchant Raider","size":"Escort","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":9,"hullIntegrity":22,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":2,"notes":"Hybrid carrier-raider.","combat":{"size":"colossal","speed":10,"wounds":{"max":22},"resilience":{"total":9},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Sword-class Frigate","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Sword-class Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":10,"hullIntegrity":28,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":1,"notes":"Escort with accurate dorsals.","combat":{"size":"colossal","speed":10,"wounds":{"max":28},"resilience":{"total":10},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Tempest-class Strike Frigate","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Tempest-class Strike Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":10,"hullIntegrity":28,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":1,"notes":"Close-action brawler.","combat":{"size":"colossal","speed":10,"wounds":{"max":28},"resilience":{"total":10},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Dauntless-class Light Cruiser","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Dauntless-class Light Cruiser","size":"Light Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0}},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":0,"speed":9,"space":55,"power":60},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":9,"armour":11,"hullIntegrity":32,"space":55,"power":60,"weapons":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"turret":2},"mnvr":0,"notes":"Versatile patrol light cruiser.","combat":{"size":"colossal","speed":9,"wounds":{"max":32},"resilience":{"total":11},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Lunar-class Cruiser","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Lunar-class Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":2,"starboard":2,"keel":0}},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":0,"speed":8,"space":65,"power":75},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":40,"space":65,"power":75,"weapons":{"prow":1,"dorsal":1,"port":2,"starboard":2,"keel":0},"turret":2},"mnvr":-1,"notes":"Balanced line cruiser.","combat":{"size":"colossal","speed":8,"wounds":{"max":40},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Cobra-class Destroyer","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Cobra-class Destroyer","size":"Escort","slots":{"prow":1,"dorsal":0,"port":0,"starboard":0,"keel":0}},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":0,"speed":10,"space":32,"power":42},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":9,"hullIntegrity":22,"space":32,"power":42,"weapons":{"prow":1,"dorsal":0,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":2,"notes":"Torpedo destroyer; hunts in packs.","combat":{"size":"colossal","speed":10,"wounds":{"max":22},"resilience":{"total":9},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Falchion-class Frigate","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Falchion-class Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":10,"hullIntegrity":28,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":1,"notes":"Modernised frigate for scouting.","combat":{"size":"colossal","speed":10,"wounds":{"max":28},"resilience":{"total":10},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Turbulent-class Heavy Frigate","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Turbulent-class Heavy Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":10,"integrity":30,"manoeuvre":1,"detection":0,"speed":10,"space":35,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":10,"hullIntegrity":30,"space":35,"power":45,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":1,"notes":"Strengthened frame; better arcs.","combat":{"size":"colossal","speed":10,"wounds":{"max":30},"resilience":{"total":10},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Defiant-class Light Cruiser (Carrier)","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Defiant-class Light Cruiser (Carrier)","size":"Light Cruiser","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0}},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":0,"speed":9,"space":55,"power":60},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":9,"armour":11,"hullIntegrity":32,"space":55,"power":60,"weapons":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"turret":2},"mnvr":0,"notes":"Light carrier with strong attack craft.","combat":{"size":"colossal","speed":9,"wounds":{"max":32},"resilience":{"total":11},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Universe-class Mass Conveyor","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Universe-class Mass Conveyor","size":"Transport","slots":{"prow":0,"dorsal":0,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"cargo-bay","min":4,"label":"Cargo Holds"},{"tag":"aux-plasma","min":1,"label":"Auxiliary Plasma Generator"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":0,"speed":8,"space":60,"power":55},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":36,"space":60,"power":55,"weapons":{"prow":0,"dorsal":0,"port":1,"starboard":1,"keel":0},"turret":1},"mnvr":-1,"notes":"Super-massive hauler; logistics linchpin.","combat":{"size":"colossal","speed":8,"wounds":{"max":36},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Goliath-class Factory Ship","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Goliath-class Factory Ship","size":"Transport","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0}},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":0,"speed":8,"space":60,"power":60},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":36,"space":60,"power":60,"weapons":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"turret":1},"mnvr":-1,"notes":"Roving manufactorum/refinery.","combat":{"size":"colossal","speed":8,"wounds":{"max":36},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Conquest-class Star Galleon","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Conquest-class Star Galleon","size":"Transport","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0}},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":0,"speed":8,"space":60,"power":60},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":36,"space":60,"power":60,"weapons":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"turret":1},"mnvr":-1,"notes":"Heavily built merchant galleon.","combat":{"size":"colossal","speed":8,"wounds":{"max":36},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Orion-class Star Clipper","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Orion-class Star Clipper","size":"Transport","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0}},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":0,"speed":9,"space":45,"power":50},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":9,"armour":11,"hullIntegrity":32,"space":45,"power":50,"weapons":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":0,"notes":"Fast passenger/light cargo clipper.","combat":{"size":"colossal","speed":9,"wounds":{"max":32},"resilience":{"total":11},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Cobra-class Destroyer (Renegade)","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Cobra-class Destroyer (Renegade)","size":"Escort","slots":{"prow":1,"dorsal":0,"port":0,"starboard":0,"keel":0}},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":0,"speed":10,"space":32,"power":42},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":10,"armour":9,"hullIntegrity":22,"space":32,"power":42,"weapons":{"prow":1,"dorsal":0,"port":0,"starboard":0,"keel":0},"turret":1},"mnvr":2,"notes":"Privateer refits on a Cobra hull.","combat":{"size":"colossal","speed":10,"wounds":{"max":22},"resilience":{"total":9},"defence":{"bonus":3}}}}},"system":{},"effects":[],"items":[]} -{"name":"Secutor-class Monitor-Cruiser","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Secutor-class Monitor-Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0}},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":0,"speed":8,"space":65,"power":80},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":40,"space":65,"power":80,"weapons":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"turret":2},"mnvr":-1,"notes":"Mechanicus monitor with heavy dorsals.","combat":{"size":"colossal","speed":8,"wounds":{"max":40},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Lathe-class Monitor-Cruiser","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Lathe-class Monitor-Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0}},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":0,"speed":8,"space":65,"power":80},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":40,"space":65,"power":80,"weapons":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"turret":2},"mnvr":-1,"notes":"Lathes-forged variant; resilient sanctified systems.","combat":{"size":"colossal","speed":8,"wounds":{"max":40},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} -{"name":"Tyrant-class Cruiser","type":"vehicle","img":"icons/svg/ship.svg","flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Tyrant-class Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":2,"starboard":2,"keel":0}},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":0,"speed":8,"space":65,"power":75},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"rt":{"speed":8,"armour":12,"hullIntegrity":40,"space":65,"power":75,"weapons":{"prow":1,"dorsal":1,"port":2,"starboard":2,"keel":0},"turret":2},"mnvr":-1,"notes":"Macrobattery-focused broadside cruiser.","combat":{"size":"colossal","speed":8,"wounds":{"max":40},"resilience":{"total":12},"defence":{"bonus":2}}}}},"system":{},"effects":[],"items":[]} +{"name":"Lunar-class Cruiser","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Lunar-class Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":1,"speed":8,"space":70,"power":80},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Archetypal line cruiser—balanced, dependable, easily refitted. Backbone of many squadrons.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":40},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Battlefleet Koronus, p. 24"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Lunar-class Cruiser","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"0b59c38ddda63f42","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Secutor-class Monitor-Cruiser","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Secutor-class Monitor-Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":3,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":1,"speed":8,"space":68,"power":82},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Mechanicus monitor with powerful dorsals and redundant shielding; anchors actions.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":40},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Into the Storm, p. 151"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Secutor-class Monitor-Cruiser","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"0eb071148d375807","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Lathe-class Monitor-Cruiser","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Lathe-class Monitor-Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":3,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":1,"speed":8,"space":68,"power":82},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Lathes-forged variant emphasising resilient sanctified systems.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":40},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Into the Storm, p. 152"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Lathe-class Monitor-Cruiser","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"104965869ffa36bb","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Frigate Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Frigate Hull (Empty)","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":10,"integrity":24,"manoeuvre":1,"detection":1,"speed":10,"space":40,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":1,"notes":"Empty hull. Add Components from Items pack.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":24},"resilience":{"bonus":0,"total":10},"defence":{"bonus":3},"fly":0}}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Frigate Hull (Empty)","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"1f954166473bedf3","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Conquest-class Star Galleon","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Conquest-class Star Galleon","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":1,"speed":8,"space":75,"power":70},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Heavily built merchant galleon with strong batteries and hull.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":36},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Battlefleet Koronus, p. 25"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Conquest-class Star Galleon","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"287a7cd15c95031f","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Goliath-class Factory Ship","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Goliath-class Factory Ship","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":1,"speed":8,"space":75,"power":70},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Roving manufactorum and refinery; long autonomous deployments.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":36},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Battlefleet Koronus, p. 30"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Goliath-class Factory Ship","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"2c612305a7bb853f","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Escort Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Escort Hull (Empty)","size":"Escort","slots":{"prow":1,"dorsal":0,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":9,"integrity":18,"manoeuvre":2,"detection":1,"speed":10,"space":35,"power":40},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":2,"notes":"Empty hull. Add Components from Items pack.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":18},"resilience":{"bonus":0,"total":9},"defence":{"bonus":3},"fly":0}}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Escort Hull (Empty)","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"4412029d26021383","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Hazeroth-class Privateer","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Hazeroth-class Privateer","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":1,"speed":10,"space":38,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":2,"notes":"Knife-fast raider with reinforced internals and stripped armour. Favoured for ambushes and commerce raiding.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":22},"resilience":{"bonus":0,"total":9},"defence":{"bonus":3},"fly":0},"source":"Rogue Trader Core Rulebook, p. 195"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Hazeroth-class Privateer","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"521f6e630bd813a4","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Tyrant-class Cruiser","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Tyrant-class Cruiser","size":"Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":1,"speed":8,"space":70,"power":80},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Macrobattery-focused cruiser optimised for crushing broadsides.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":40},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Into the Storm, p. 153"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Tyrant-class Cruiser","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"6774443321f24e87","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Universe-class Mass Conveyor","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Universe-class Mass Conveyor","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"},{"tag":"cargo-bay","min":4,"label":"Cargo Holds"},{"tag":"aux-plasma","min":1,"label":"Auxiliary Plasma Generator"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":1,"speed":8,"space":80,"power":60},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Super-massive hauler for colony loads and crusade materiel; logistics linchpin.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":36},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Battlefleet Koronus, p. 31"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Universe-class Mass Conveyor","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"6836e238cce8d9fc","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Cobra-class Destroyer (Renegade)","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Cobra-class Destroyer (Renegade)","size":"Escort","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":1,"speed":10,"space":36,"power":42},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":2,"notes":"Ex-Navy Cobra in privateer hands with non-standard prow refits.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":22},"resilience":{"bonus":0,"total":9},"defence":{"bonus":3},"fly":0},"source":"Battlefleet Koronus, p. 66"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Cobra-class Destroyer (Renegade)","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"6da4418bdbd2206c","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Defiant-class Light Cruiser (Carrier)","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Defiant-class Light Cruiser (Carrier)","size":"Light Cruiser","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":1,"speed":9,"space":60,"power":70},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":0,"notes":"Light carrier with significant attack craft; excellent for recon and strikes.","combat":{"size":"colossal","speed":9,"wounds":{"value":0,"bonus":0,"max":32},"resilience":{"bonus":0,"total":11},"defence":{"bonus":2},"fly":0}}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Defiant-class Light Cruiser (Carrier)","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"73eed7c83ea60340","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Orion-class Star Clipper","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Orion-class Star Clipper","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":1,"speed":8,"space":70,"power":70},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Fast passenger/light-cargo clipper for courier missions and risky runs.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":36},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Into the Storm, p. 150"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Orion-class Star Clipper","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"750ee1998f698e08","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Vagabond-class Merchant Trader","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Vagabond-class Merchant Trader","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":1,"speed":8,"space":72,"power":68},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Modular cargobays and adaptable fittings; a chartist workhorse. Simple to keep running in frontier yards; heavily customised.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":36},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Rogue Trader Core Rulebook, p. 195"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Vagabond-class Merchant Trader","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"95fcf7b99d705bd1","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Cruiser Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Cruiser Hull (Empty)","size":"Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":40,"manoeuvre":-1,"detection":1,"speed":8,"space":70,"power":80},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Empty hull. Add Components from Items pack.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":40},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0}}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Cruiser Hull (Empty)","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"96a0dacd77d672bb","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Jericho-class Pilgrim Vessel","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Jericho-class Pilgrim Vessel","size":"Cruiser","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":12,"integrity":36,"manoeuvre":-1,"detection":1,"speed":8,"space":75,"power":68},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":-1,"notes":"Immense conversions for pilgrim passages and reliquary cargo. Cavernous holds and chapels; range and capacity over armour and speed.","combat":{"size":"colossal","speed":8,"wounds":{"value":0,"bonus":0,"max":36},"resilience":{"bonus":0,"total":12},"defence":{"bonus":2},"fly":0},"source":"Rogue Trader Core Rulebook, p. 195"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Jericho-class Pilgrim Vessel","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"a08b1d9ef251ec0b","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Cobra-class Destroyer","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Cobra-class Destroyer","size":"Escort","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":1,"speed":10,"space":36,"power":42},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":2,"notes":"Torpedo raider hunting in packs; strikes, then disengages to reload.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":22},"resilience":{"bonus":0,"total":9},"defence":{"bonus":3},"fly":0},"source":"Battlefleet Koronus, p. 66"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Cobra-class Destroyer","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"b518e981d69324aa","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Havoc-class Merchant Raider","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Havoc-class Merchant Raider","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":9,"integrity":22,"manoeuvre":2,"detection":1,"speed":10,"space":38,"power":45},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":2,"notes":"Hybrid carrier-raider balancing battery weight with cargo. Less protected than Navy hulls but brutal on traffic.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":22},"resilience":{"bonus":0,"total":9},"defence":{"bonus":3},"fly":0},"source":"Rogue Trader Core Rulebook, p. 196"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Havoc-class Merchant Raider","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"c4c69cf1b895c0e1","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Light Cruiser Hull (Empty)","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Light Cruiser Hull (Empty)","size":"Light Cruiser","slots":{"prow":1,"dorsal":1,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":1,"speed":9,"space":60,"power":70},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":0,"notes":"Empty hull. Add Components from Items pack.","combat":{"size":"colossal","speed":9,"wounds":{"value":0,"bonus":0,"max":32},"resilience":{"bonus":0,"total":11},"defence":{"bonus":2},"fly":0}}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Light Cruiser Hull (Empty)","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"c5ca1fc87803b111","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Dauntless-class Light Cruiser","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Dauntless-class Light Cruiser","size":"Light Cruiser","slots":{"prow":1,"dorsal":2,"port":1,"starboard":1,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":11,"integrity":32,"manoeuvre":0,"detection":1,"speed":9,"space":62,"power":72},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":0,"notes":"Versatile patrol cruiser—good acceleration and flexible refits. Often leads Passage Watch patrols.","combat":{"size":"colossal","speed":9,"wounds":{"value":0,"bonus":0,"max":32},"resilience":{"bonus":0,"total":11},"defence":{"bonus":2},"fly":0},"source":"Battlefleet Koronus, p. 36"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Dauntless-class Light Cruiser","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"c8975bb7181d8e12","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Falchion-class Frigate","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Falchion-class Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":1,"speed":10,"space":42,"power":48},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":1,"notes":"Modernised frigate with improved drives for frontier scouting.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":28},"resilience":{"bonus":0,"total":10},"defence":{"bonus":3},"fly":0},"source":"Battlefleet Koronus, p. 28"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Falchion-class Frigate","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"d3853b0270deaf3f","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Sword-class Frigate","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Sword-class Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":1,"speed":10,"space":42,"power":48},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":1,"notes":"Reliable escort with accurate dorsal lasers and stout drives. Squadrons screen convoys and prosecute pirates.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":28},"resilience":{"bonus":0,"total":10},"defence":{"bonus":3},"fly":0},"source":"Battlefleet Koronus, p. 28"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Sword-class Frigate","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"ec53303961ef4fd4","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Turbulent-class Heavy Frigate","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Turbulent-class Heavy Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":1,"speed":10,"space":42,"power":48},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":1,"notes":"Strengthened frame and broader arcs; trades agility for staying power.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":28},"resilience":{"bonus":0,"total":10},"defence":{"bonus":3},"fly":0},"source":"Battlefleet Koronus, p. 28"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Turbulent-class Heavy Frigate","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"f1ea3416a6d0d27e","systemId":"wrath-and-glory","systemVersion":"7.1.1"} +{"name":"Tempest-class Strike Frigate","type":"vehicle","img":"icons/svg/ship.svg","folder":null,"sort":0,"ownership":{"default":0},"flags":{"core":{"sheetClass":"wg-voidships-builder.VoidshipSheet"},"wg-voidships-builder":{"isVoidship":true,"hull":{"class":"Tempest-class Strike Frigate","size":"Frigate","slots":{"prow":1,"dorsal":1,"port":0,"starboard":0,"keel":0},"requirements":[{"tag":"bridge","min":1,"label":"Bridge"},{"tag":"reactor","min":1,"label":"Plasma Reactor"},{"tag":"gellar","min":1,"label":"Gellar Field"},{"tag":"warp","min":1,"label":"Warp Drive"}]},"base":{"armour":10,"integrity":28,"manoeuvre":1,"detection":1,"speed":10,"space":42,"power":48},"crew":{"command":1,"pilot":1,"sensors":1,"engineering":2,"gunnery":2,"security":2,"flightDeck":0,"passengers":0},"rtRaw":{"mnvr":1,"notes":"Close-action brawler for boardings and short-range gunnery. Reinforced prow and over-tuned drives.","combat":{"size":"colossal","speed":10,"wounds":{"value":0,"bonus":0,"max":28},"resilience":{"bonus":0,"total":10},"defence":{"bonus":3},"fly":0},"source":"Rogue Trader Core Rulebook, p. 196"}}},"system":{},"effects":[],"items":[],"prototypeToken":{"name":"Tempest-class Strike Frigate","actorLink":true,"texture":{"src":"icons/svg/ship.svg"},"disposition":1,"displayName":0},"_id":"fb874877eacc7a08","systemId":"wrath-and-glory","systemVersion":"7.1.1"} diff --git a/wg-voidships-builder/packs/wg-voidship-items.db b/wg-voidships-builder/packs/wg-voidship-items.db index 11c7e14..61b38d9 100644 --- a/wg-voidships-builder/packs/wg-voidship-items.db +++ b/wg-voidships-builder/packs/wg-voidship-items.db @@ -1,18 +1,10 @@ -{"_id":"ITM0BRIDGECIV01","name":"Command Bridge (Civilian)","type":"gear","img":"icons/svg/book.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"bridge","tags":["bridge"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Standard command bridge and cogitators.","equipped":true,"voidship":{"slot":"Internal","use":{"space":2,"power":2},"mods":{"detection":1,"manoeuvre":1}}},"effects":[]} -{"_id":"ITM0LIFESUPP001","name":"Life Support","type":"gear","img":"icons/svg/poison.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"life-support","tags":["life-support"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Atmospheric recyclers, grav-amps, habitat.","equipped":true,"voidship":{"slot":"Internal","use":{"space":2,"power":2}}},"effects":[]} -{"_id":"ITM0GELLARSTD01","name":"Gellar Field Projector","type":"gear","img":"icons/svg/temple.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"gellar","tags":["gellar"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Essential protection in the Immaterium.","equipped":true,"voidship":{"slot":"Internal","use":{"space":2,"power":3}}},"effects":[]} -{"_id":"ITM0WARPDRIVE01","name":"Warp Drive (Miloslav)","type":"gear","img":"icons/svg/wing.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"warp-drive","tags":["warp-drive"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Reliable civilian warp drive.","equipped":true,"voidship":{"slot":"Internal","use":{"space":3,"power":6}}},"effects":[]} -{"_id":"ITM0REACTOR001A","name":"Plasma Reactor (Civilian)","type":"gear","img":"icons/svg/energy.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"reactor","tags":["reactor"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Primary plasma power generation.","equipped":true,"voidship":{"slot":"Internal","use":{"space":3,"power":-50},"mods":{"power":50}}},"effects":[]} -{"_id":"ITM0AUGURCIV001","name":"Augur Array (Civilian)","type":"gear","img":"icons/svg/mystery-man.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"augur","tags":["augur"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Standard augur/sensor package.","equipped":true,"voidship":{"slot":"Aetherics","use":{"space":1,"power":2},"mods":{"detection":2}}},"effects":[]} -{"_id":"ITM0VSHIELD001A","name":"Void Shields (Single)","type":"gear","img":"icons/svg/shield.svg","flags":{"wg-voidships-builder":{"component":{"kind":"core","subtype":"void-shields","tags":["void-shields"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Standard void shield emitters.","equipped":true,"voidship":{"slot":"Internal","use":{"space":1,"power":3},"mods":{"integrity":2}}},"effects":[]} - -{"_id":"ITM0CARGOHOLD01","name":"Cargo Hold & Lighter Bay","type":"gear","img":"icons/svg/crate.svg","flags":{"wg-voidships-builder":{"component":{"kind":"upgrade","subtype":"cargo-bay","tags":["cargo-bay"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"General-purpose cargo hold.","equipped":true,"voidship":{"slot":"Internal","use":{"space":-5,"power":1},"mods":{"space":-5}}},"effects":[]} -{"_id":"ITM0AUXPLASMA01","name":"Auxiliary Plasma Generator","type":"gear","img":"icons/svg/energy.svg","flags":{"wg-voidships-builder":{"component":{"kind":"upgrade","subtype":"aux-plasma","tags":["aux-plasma","reactor"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Auxiliary plasma reactor increasing available power.","equipped":true,"voidship":{"slot":"Internal","use":{"space":2,"power":-6},"mods":{"power":6}}},"effects":[]} -{"_id":"ITM0ARMOURPLT01","name":"Reinforced Hull Plating","type":"gear","img":"icons/svg/armor.svg","flags":{"wg-voidships-builder":{"component":{"kind":"upgrade","subtype":"plating","tags":["hull","armour"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Additional armour plates and bracing.","equipped":true,"voidship":{"slot":"Internal","use":{"space":1,"power":0},"mods":{"armour":2,"integrity":4,"manoeuvre":-1}}},"effects":[]} -{"_id":"ITM0MANEUVER01A","name":"High-Output Manoeuvring Thrusters","type":"gear","img":"icons/svg/wing.svg","flags":{"wg-voidships-builder":{"component":{"kind":"upgrade","subtype":"thrusters","tags":["thrusters"],"allowedSlots":[]},"voidOnly":true}},"system":{"description":"Vectorable RCS and trim jets.","equipped":true,"voidship":{"slot":"External","use":{"space":1,"power":2},"mods":{"manoeuvre":2}}},"effects":[]} - -{"_id":"ITM0MACROPORT01","name":"Mars-Pattern Macrobattery (Port)","type":"gear","img":"icons/svg/sword.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"macrobattery","tags":["weapon"],"allowedSlots":["port"]},"voidOnly":true}},"system":{"description":"Port broadside macro-cannons.","equipped":true,"voidship":{"slot":"Port","use":{"space":2,"power":3},"mods":{}}},"effects":[]} -{"_id":"ITM0MACROSTBD01","name":"Mars-Pattern Macrobattery (Starboard)","type":"gear","img":"icons/svg/sword.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"macrobattery","tags":["weapon"],"allowedSlots":["starboard"]},"voidOnly":true}},"system":{"description":"Starboard broadside macro-cannons.","equipped":true,"voidship":{"slot":"Starboard","use":{"space":2,"power":3},"mods":{}}},"effects":[]} -{"_id":"ITM0LANCEDORS01","name":"Sunsear Laser Battery (Dorsal)","type":"gear","img":"icons/svg/sun.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"laser-battery","tags":["weapon"],"allowedSlots":["dorsal"]},"voidOnly":true}},"system":{"description":"High-energy dorsal lasers.","equipped":true,"voidship":{"slot":"Dorsal","use":{"space":2,"power":4},"mods":{}}},"effects":[]} -{"_id":"ITM0PROWTORP01","name":"Prow Torpedo Tubes","type":"gear","img":"icons/svg/anchor.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"torpedoes","tags":["weapon"],"allowedSlots":["prow"]},"voidOnly":true}},"system":{"description":"Prow-mounted torpedo tubes.","equipped":true,"voidship":{"slot":"Prow","use":{"space":3,"power":3},"mods":{}}},"effects":[]} -{"_id":"ITM0KEELNOVA01","name":"Keel Nova Cannon","type":"gear","img":"icons/svg/explosion.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"nova-cannon","tags":["weapon"],"allowedSlots":["keel"]},"voidOnly":true}},"system":{"description":"Spinal nova cannon on the keel.","equipped":true,"voidship":{"slot":"Keel","use":{"space":4,"power":6},"mods":{}}},"effects":[]} +{"_id":"BRIDGECLV0000001","name":"Command Bridge (Civilian)","type":"gear","img":"icons/svg/book.svg","flags":{"wg-voidships-builder":{"component":{"kind":"bridge","subtype":"civilian","tags":["bridge","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":2,"power":2},"mods":{"armour":0,"integrity":0,"manoeuvre":1,"detection":1,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Standard command bridge and cogitators.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"REACTORPLSM00001","name":"Plasma Reactor (Civilian)","type":"gear","img":"icons/svg/energy.svg","flags":{"wg-voidships-builder":{"component":{"kind":"reactor","subtype":"plasma","tags":["reactor","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":4,"power":-10},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":0,"power":10}}}},"system":{"quantity":1,"rarity":"Common","description":"Primary plasma reactor for voidship operations.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"GELLARSTD0000001","name":"Gellar Field Projector","type":"gear","img":"icons/svg/temple.svg","flags":{"wg-voidships-builder":{"component":{"kind":"gellar","subtype":"standard","tags":["gellar","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":2,"power":3},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Essential protection in the Immaterium.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"WARPDRVMILO00001","name":"Miloslav Warp Drive (Civilian)","type":"gear","img":"icons/svg/wing.svg","flags":{"wg-voidships-builder":{"component":{"kind":"drive","subtype":"warp","tags":["drive","warp","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":3,"power":6},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Reliable civilian warp drive.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"AUGURARRAY000001","name":"Augur Array (Civilian)","type":"gear","img":"icons/svg/mystery-man.svg","flags":{"wg-voidships-builder":{"component":{"kind":"sensor","subtype":"augur","tags":["sensor","auspex","aetherics"]},"voidOnly":true,"voidship":{"slot":"Aetherics","use":{"space":1,"power":2},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":2,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Standard augur/sensor package.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"HULLPLATE0000001","name":"Reinforced Hull Plating","type":"gear","img":"icons/svg/armor.svg","flags":{"wg-voidships-builder":{"component":{"kind":"armour","subtype":"plating","tags":["hull","armour","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":1,"power":0},"mods":{"armour":2,"integrity":4,"manoeuvre":-1,"detection":0,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Additional armour plates and bracing.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"CARGOHOLD0000001","name":"Cargo Hold & Lighter Bay","type":"gear","img":"icons/svg/crate.svg","flags":{"wg-voidships-builder":{"component":{"kind":"cargo-bay","subtype":"standard","tags":["cargo-bay","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":-5,"power":1},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":-5,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"General-purpose cargo hold with lighter handling.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"AUXPLASMA0000001","name":"Auxiliary Plasma Generator","type":"gear","img":"icons/svg/energy.svg","flags":{"wg-voidships-builder":{"component":{"kind":"plasma","subtype":"aux-generator","tags":["aux-plasma","internal"]},"voidOnly":true,"voidship":{"slot":"Internal","use":{"space":2,"power":-6},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":0,"power":6}}}},"system":{"quantity":1,"rarity":"Common","description":"Auxiliary plasma reactor increasing available power.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"MACROPROW0000001","name":"Macrobattery (Prow)","type":"gear","img":"icons/svg/sword.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"macrobattery","tags":["weapon","prow"]},"voidOnly":true,"voidship":{"slot":"Prow","use":{"space":2,"power":2},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Prow macrobattery.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} +{"_id":"MACRODORS0000001","name":"Macrobattery (Dorsal)","type":"gear","img":"icons/svg/sword.svg","flags":{"wg-voidships-builder":{"component":{"kind":"weapon","subtype":"macrobattery","tags":["weapon","dorsal"]},"voidOnly":true,"voidship":{"slot":"Dorsal","use":{"space":2,"power":2},"mods":{"armour":0,"integrity":0,"manoeuvre":0,"detection":0,"speed":0,"space":0,"power":0}}}},"system":{"quantity":1,"rarity":"Common","description":"Dorsal macrobattery.","value":0,"keywords":[],"effect":"","test":""},"effects":[]} diff --git a/wg-voidships-builder/scripts/voidship-actor.js b/wg-voidships-builder/scripts/voidship-actor.js index 054083f..2ab6bbd 100644 --- a/wg-voidships-builder/scripts/voidship-actor.js +++ b/wg-voidships-builder/scripts/voidship-actor.js @@ -1,23 +1,29 @@ // W&G Voidships Builder — Voidship Actor Sheet (vehicle+flag emulation) -// v1.1.0 (mapping weapons + core reqs + safer drops) — Foundry v11–v13 +// v1.1.0 — Foundry V11–V13 safe /* eslint-env es2021 */ const VB_MOD = "wg-voidships-builder"; -const VB_DEBUG = true; // debug on; switch later via setting +const VB_DEBUG = true; // Debug on function dbg(...args) { if (VB_DEBUG) console.debug("[VB]", ...args); } -// Canonical slot keys -const SLOT_KEYS = ["prow","dorsal","port","starboard","keel"]; - -// Default RT-like core requirements (if hull.requirements is empty) -const DEFAULT_CORE_REQS = [ - { tag: "bridge", min: 1, label: "Bridge" }, - { tag: "life-support", min: 1, label: "Life Support" }, - { tag: "gellar", min: 1, label: "Gellar Field" }, - { tag: "warp-drive", min: 1, label: "Warp Drive" }, - { tag: "reactor", min: 1, label: "Plasma/Power Reactor" }, - { tag: "augur", min: 1, label: "Augur Array" }, - { tag: "void-shields", min: 1, label: "Void Shields" } -]; +// ---------------- Handlebars helpers ---------------- +Hooks.once("init", () => { + if (!Handlebars.helpers.signed) { + Handlebars.registerHelper("signed", (v) => { + const n = Number(v || 0); + if (!Number.isFinite(n) || n === 0) return "±0"; + return (n > 0 ? "+" : "−") + Math.abs(n); + }); + } + if (!Handlebars.helpers.eq) { + Handlebars.registerHelper("eq", (a, b) => a === b); + } + if (!Handlebars.helpers.json) { + Handlebars.registerHelper("json", (ctx) => { + try { return JSON.stringify(ctx, null, 2); } + catch { return String(ctx); } + }); + } +}); class VoidshipSheet extends ActorSheet { static get defaultOptions() { @@ -27,97 +33,64 @@ class VoidshipSheet extends ActorSheet { template: `modules/${VB_MOD}/templates/voidship-sheet.hbs`, width: 720, height: 680, - tabs: [{ navSelector: ".tabs", contentSelector: ".sheet-body", initial: "wg" }] + tabs: [{ navSelector: ".tabs", contentSelector: ".sheet-body", initial: "wg" }], + dragDrop: [{ dragSelector: ".voidship-sheet", dropSelector: ".voidship-sheet" }] }); } + /** Allow viewing for everyone (adjust if you need perms) */ _canUserView(user) { return !!user; } + get isVoidship() { return this.actor?.getFlag(VB_MOD, "isVoidship") === true; } - /** Sum flags.base + items mods + usage */ - _computeDerived() { - const a = this.actor; - const b = a.getFlag(VB_MOD, "base") || {}; - const base = { - armour: Number(b.armour)||0, - integrity: Number(b.integrity)||0, - manoeuvre: Number(b.manoeuvre)||0, - detection: Number(b.detection)||0, - speed: Number(b.speed)||0, - space: Number(b.space)||0, - power: Number(b.power)||0 - }; + // ---- math helpers ---- + _sumModsFromItems(items) { + const mods = { armour: 0, integrity: 0, manoeuvre: 0, detection: 0, speed: 0, space: 0, power: 0 }; + let useSpace = 0, usePower = 0; + const slotsUsed = { prow: 0, dorsal: 0, port: 0, starboard: 0, keel: 0 }; - const mods = { armour:0, integrity:0, manoeuvre:0, detection:0, speed:0, space:0, power:0 }; - const usage = { space:0, power:0 }; - const slotsUsed = { prow:0, dorsal:0, port:0, starboard:0, keel:0 }; + for (const it of items) { + const vs = it.system?.voidship; + if (!vs) continue; - for (const it of a.items.contents) { - const sys = it.system ?? {}; - const v = sys.voidship ?? {}; - const equipped = (sys.equipped ?? true) === true; // treat true/undefined as mounted - const comp = it.getFlag(VB_MOD, "component") || v.component || {}; // our kind/tags live in flags + const equipped = (it.system?.equipped ?? true); + const slotKey = String(vs.slot || "").toLowerCase(); + if (equipped && ["prow", "dorsal", "port", "starboard", "keel"].includes(slotKey)) { + slotsUsed[slotKey] = (slotsUsed[slotKey] || 0) + 1; + } - if (equipped) { - // accumulate mods - const m = v.mods || {}; - for (const k of Object.keys(mods)) { - const n = Number(m[k]); - if (Number.isFinite(n)) mods[k] += n; - } - // accumulate usage - const u = v.use || {}; - if (Number.isFinite(Number(u.space))) usage.space += Number(u.space); - if (Number.isFinite(Number(u.power))) usage.power += Number(u.power); + // capacity usage (always counts, bo to realne zużycie – jeśli wolisz tylko equipped, to obejmij warunkiem) + const use = vs.use || {}; + if (Number.isFinite(Number(use.space))) useSpace += Number(use.space); + if (Number.isFinite(Number(use.power))) usePower += Number(use.power); - // weapon slots count ONLY for kind === "weapon" - const kind = String(comp?.kind || "").toLowerCase(); - const slot = String(v.slot || "").toLowerCase(); - if (kind === "weapon" && SLOT_KEYS.includes(slot)) slotsUsed[slot] += 1; + // mods liczą się tylko jeśli equipped + if (!equipped) continue; + const m = vs.mods || {}; + for (const k of Object.keys(mods)) { + const val = Number(m[k]); + if (Number.isFinite(val)) mods[k] += val; } } - const total = { - armour: base.armour + mods.armour, - integrity: base.integrity + mods.integrity, - manoeuvre: base.manoeuvre + mods.manoeuvre, - detection: base.detection + mods.detection, - speed: base.speed + mods.speed, - space: base.space + mods.space, - power: base.power + mods.power, - spaceFree: base.space + mods.space - usage.space, - powerFree: base.power + mods.power - usage.power - }; - dbg("computeDerived:", { base, mods, usage, total, slotsUsed }); - return { base, mods, usage, total, slotsUsed }; + return { mods, use: { space: useSpace, power: usePower }, slotsUsed }; } -} -/** helpers */ -Hooks.once("init", () => { - if (!Handlebars.helpers.signed) { - Handlebars.registerHelper("signed", v => { - const n = Number(v||0); if (!Number.isFinite(n) || n===0) return "±0"; - return (n>0?"+":"−")+Math.abs(n); - }); - } - // pretty-json (for debug blocks) - if (!Handlebars.helpers.tojson) { - Handlebars.registerHelper("tojson", v => JSON.stringify(v, null, 2)); - } -}); - -VoidshipSheet.prototype.getData = async function(options) { + // ---- data aggregation for template ---- + async getData(options) { const data = await super.getData(options); const actor = this.actor; + const VB_MOD = "wg-voidships-builder"; + // Flagowe źródła (przeżywają migracje W&G) const flags = actor.getFlag(VB_MOD, "") || {}; - const hull = flags.hull || { class: actor.name, size: "Cruiser", slots: { prow:0,dorsal:0,port:0,starboard:0,keel:0 } }; - const base = flags.base || { armour:0, integrity:0, manoeuvre:0, detection:0, speed:0, space:0, power:0 }; - const crew = flags.crew || { command:1,pilot:1,sensors:1,engineering:2,gunnery:2,security:2,flightDeck:0,passengers:0 }; - const rtRaw = flags["rtRaw"] || {}; - const rt = rtRaw.rt || {}; + const hull = flags.hull || { class: actor.name, size: "Cruiser", slots: { prow: 0, dorsal: 0, port: 0, starboard: 0, keel: 0 } }; + const base = flags.base || { armour: 0, integrity: 0, manoeuvre: 0, detection: 0, speed: 0, space: 0, power: 0 }; + const crew = flags.crew || { command: 0, pilot: 0, sensors: 0, engineering: 0, gunnery: 0, security: 0, flightDeck: 0, passengers: 0 }; + // RT snapshot (jak dotąd) + const rtRaw = actor.getFlag(VB_MOD, "rtRaw") || {}; + const rt = rtRaw.rt || {}; const rtCard = { speed: rt.speed ?? rtRaw.combat?.speed ?? 0, manoeuvrability: rt.manoeuvrability ?? rtRaw.mnvr ?? 0, @@ -135,172 +108,290 @@ VoidshipSheet.prototype.getData = async function(options) { }, turret: rt.turret ?? 0, notes: rtRaw.notes ?? "", - source: rt.source ?? "" + source: rt.source ?? rtRaw.source ?? "" }; - // components (only items having system.voidship) - const components = actor.items.contents - .filter(i => i.system?.voidship) - .map(i => { - const v = foundry.utils.deepClone(i.system.voidship || {}); - const comp = i.getFlag(VB_MOD, "component") || v.component || {}; - return { - itemId: i.id, - name: i.name, - equipped: (i.system?.equipped ?? true) === true, - slot: v.slot || "Internal", - use: Object.assign({ space:0, power:0 }, v.use), - mods: Object.assign({ armour:0, integrity:0, manoeuvre:0, detection:0, speed:0, space:0, power:0 }, v.mods), - component: { kind: String(comp.kind||"").toLowerCase(), tags: comp.tags || [], allowedSlots: comp.allowedSlots || [] } - }; + // ===== KOMPONENTY: czytamy Z FLAG ===== + const items = actor.items.contents; + const inferSlotFromTags = (tags=[]) => { + const low = (Array.isArray(tags)?tags:[]).map(t => String(t).toLowerCase()); + const pref = ["prow","dorsal","port","starboard","keel","aetherics","internal"]; + const hit = pref.find(p => low.includes(p)); + return hit ? (hit[0].toUpperCase()+hit.slice(1)) : "Internal"; + }; + + const components = []; + for (const i of items) { + const fmod = i.flags?.[VB_MOD] || {}; + const vflag = fmod.voidship || null; // <-- TU trzymamy liczby + const meta = fmod.component || {}; // kind/subtype/tags + // Dopuszczamy też stare itemy z system.voidship (jeśli coś przetrwa) + const vsys = i.system?.voidship || null; + + // komponent, jeśli ma vflag LUB meta.tags LUB vsys + const isComponent = !!(vflag || vsys || (Array.isArray(meta.tags) && meta.tags.length)); + if (!isComponent) continue; + + const vf = vflag || vsys || {}; + const use = { + space: Number(vf?.use?.space ?? 0), + power: Number(vf?.use?.power ?? 0) + }; + const mods = { + armour: Number(vf?.mods?.armour ?? 0), + integrity: Number(vf?.mods?.integrity ?? 0), + manoeuvre: Number(vf?.mods?.manoeuvre ?? 0), + detection: Number(vf?.mods?.detection ?? 0), + speed: Number(vf?.mods?.speed ?? 0), + space: Number(vf?.mods?.space ?? 0), + power: Number(vf?.mods?.power ?? 0) + }; + let slot = vf.slot || meta.slot || inferSlotFromTags(meta.tags); + const equipped = (i.system?.equipped ?? true) && (vf.disabled !== true); + + components.push({ + itemId: i.id, + name: i.name, + slot, + equipped, + use, mods, + tags: meta.tags || [] }); + } - // derived totals and slotsUsed (weapons only) - const { base:baseCalc, mods, usage, total, slotsUsed } = this._computeDerived(); + // Zliczanie slotów (tylko equipped) + const slotsUsed = components.reduce((acc, c) => { + if (!c.equipped) return acc; + const key = String(c.slot || "Internal").toLowerCase(); + if (["prow","dorsal","port","starboard","keel"].includes(key)) acc[key] = (acc[key] || 0) + 1; + return acc; + }, { prow: 0, dorsal: 0, port: 0, starboard: 0, keel: 0 }); - // Warnings: slots over-capacity (compare ONLY weapons vs hull slot caps) + // Capacity: bazowe + mody z komponentów (equipped) vs użycie (equipped) + const modsSum = components.reduce((acc, c) => { + if (!c.equipped) return acc; + for (const k of Object.keys(acc)) acc[k] += Number(c.mods[k] || 0); + return acc; + }, { armour:0, integrity:0, manoeuvre:0, detection:0, speed:0, space:0, power:0 }); + + const useSum = components.reduce((acc, c) => { + if (!c.equipped) return acc; + acc.space += Number(c.use.space || 0); + acc.power += Number(c.use.power || 0); + return acc; + }, { space: 0, power: 0 }); + + const totals = { + armour: (Number(base.armour)||0) + modsSum.armour, + integrity: (Number(base.integrity)||0) + modsSum.integrity, + manoeuvre: (Number(base.manoeuvre)||0) + modsSum.manoeuvre, + detection: (Number(base.detection)||0) + modsSum.detection, + speed: (Number(base.speed)||0) + modsSum.speed, + space: (Number(base.space)||0) + modsSum.space, + power: (Number(base.power)||0) + modsSum.power + }; + totals.spaceFree = totals.space - useSum.space; + totals.powerFree = totals.power - useSum.power; + + // Ostrzeżenia const warnings = {}; - if (components.length) { - const over = - (slotsUsed.prow > (hull.slots?.prow || 0)) || - (slotsUsed.dorsal > (hull.slots?.dorsal || 0)) || - (slotsUsed.port > (hull.slots?.port || 0)) || - (slotsUsed.starboard > (hull.slots?.starboard || 0)) || - (slotsUsed.keel > (hull.slots?.keel || 0)); - if (over) warnings.slots = "One or more weapon slot groups exceed hull limits."; - } - if (total.spaceFree < 0 || total.powerFree < 0) { + const overSlots = + (slotsUsed.prow > (hull.slots?.prow || 0)) || + (slotsUsed.dorsal > (hull.slots?.dorsal || 0)) || + (slotsUsed.port > (hull.slots?.port || 0)) || + (slotsUsed.starboard > (hull.slots?.starboard || 0)) || + (slotsUsed.keel > (hull.slots?.keel || 0)); + if (overSlots) warnings.slots = "One or more weapon slot groups exceed hull limits."; + + if (totals.spaceFree < 0 || totals.powerFree < 0) warnings.capacity = "Not enough Space/Power for installed components."; - } - // Validate allowedSlots for weapons (if provided) - const badMounts = components.filter(c => - c.equipped && - c.component?.kind === "weapon" && - Array.isArray(c.component.allowedSlots) && - c.component.allowedSlots.length && - !c.component.allowedSlots.map(s => String(s).toLowerCase()).includes(String(c.slot).toLowerCase()) - ); - if (badMounts.length) { - warnings.mounts = `Invalid weapon placement: ${badMounts.map(b=>`${b.name}→${b.slot}`).join(", ")}.`; - } - - // Requirements — gather tags from equipped components - const tagCounts = {}; - for (const c of components) { - if (!c.equipped) continue; - for (const t of (c.component?.tags || [])) { - const key = String(t).toLowerCase(); - tagCounts[key] = (tagCounts[key] || 0) + 1; - } - } - const reqs = (Array.isArray(hull.requirements) && hull.requirements.length) ? hull.requirements : DEFAULT_CORE_REQS; - const missing = []; - for (const r of reqs) { - const need = Number(r.min||0); - if (!need) continue; - const have = tagCounts[String(r.tag||"").toLowerCase()] || 0; - if (have < need) missing.push(`${r.label||r.tag}: ${have}/${need}`); - } - if (missing.length) warnings.requirements = `Missing required systems — ${missing.join("; ")}`; - - // expose to hbs + // wstrzyknij do template data.hull = hull; data.base = base; data.crew = crew; - data.mods = mods; - data.usage = usage; - data.totals = total; - data.slotsUsed = slotsUsed; data.rtCard = rtCard; data.components = components; + data.slotsUsed = slotsUsed; + data.totals = totals; data.warnings = warnings; - data.debug = { flags, tagCounts, reqs }; // handy raw blocks + dbg("sheet.getData", { base, hull, totals, slotsUsed, componentsCount: components.length }); return data; -}; +} -VoidshipSheet.prototype.activateListeners = function(html) { - super.activateListeners(html); + // ---- listeners & UI ---- + activateListeners(html) { + super.activateListeners(html); - // mark/unmark - html.find("[data-action='mark-voidship']").on("click", async () => { - await this.actor.setFlag(VB_MOD, "isVoidship", true); - ui.notifications.info("Marked as Voidship."); - this.render(true); - }); - html.find("[data-action='unmark-voidship']").on("click", async () => { - await this.actor.unsetFlag(VB_MOD, "isVoidship"); - ui.notifications.info("Unmarked Voidship."); - this.render(true); - }); - - // configure base - html.find("[data-action='configure-base']").on("click", async () => { - const cur = this._computeDerived().base; - const content = ` -
-
-
-
-
-
-
- `; - new Dialog({ - title: "Voidship — Base Stats", - content, buttons: { - ok: { label: "Save", callback: async (dlg) => { - const form = dlg[0].querySelector("form") || dlg[0]; - const get = (k) => Number(form.querySelector(`[name="${k}"]`)?.value || 0); - const patchBase = { - armour: get("armour"), - integrity: get("integrity"), - manoeuvre: get("manoeuvre"), - detection: get("detection"), - speed: get("speed"), - space: get("space"), - power: get("power") - }; - await this.actor.setFlag(VB_MOD, "base", patchBase); - this.render(true); - }}, - cancel: { label: "Cancel" } - }, default: "ok" - }, { jQuery: true }).render(true); - }); - - // toggle raw debug blocks - html.find("[data-action='toggle-raw']").on("click", (ev) => { - const el = html.find(".vb-raw")[0]; - if (el) el.style.display = (el.style.display === "none") ? "block" : "none"; - }); -}; - -// ACCEPT only items having system.voidship (and optionally flags[VB_MOD].component) -VoidshipSheet.prototype._onDropItem = async function(event, data) { - try { - const resolved = await Item.fromDropData(data); - if (!resolved) return ui.notifications.error("Drop failed: cannot resolve item (no UUID/DATA)."); - - const sys = resolved.system ?? {}; - if (!sys.voidship) return ui.notifications.warn("This item is not a voidship component."); - // optional hard guard: if not our 'voidOnly' flag, still allow — but warn - const vFlags = resolved.getFlag(VB_MOD, "component"); - if (!vFlags) dbg("Component missing flags; proceeding with system.voidship only."); - - // pass to Foundry to actually create the embedded item - const created = await this.actor.createEmbeddedDocuments("Item", [resolved.toObject()]); - if (created?.length) { - ui.notifications.info(`Installed component: ${created[0].name}`); + html.find("[data-action='mark-voidship']").on("click", async () => { + await this.actor.setFlag(VB_MOD, "isVoidship", true); + ui.notifications.info("Marked as Voidship."); this.render(true); - } - } catch (err) { - console.error(err); - ui.notifications.error("Drop failed: cannot resolve item data (no UUID/DATA)."); - } -}; + }); + html.find("[data-action='unmark-voidship']").on("click", async () => { + await this.actor.unsetFlag(VB_MOD, "isVoidship"); + ui.notifications.info("Unmarked Voidship."); + this.render(true); + }); + html.find("[data-action='configure-base']").on("click", async () => { + const cur = this.actor.getFlag(VB_MOD, "base") || {}; + const content = ` +
+
+
+
+
+
+
+
+
`; + new Dialog({ + title: "Voidship — Base Stats", + content, buttons: { + ok: { + label: "Save", + callback: async (dlg) => { + const form = dlg[0].querySelector("form"); + const num = (n) => Number(form.querySelector(`[name="${n}"]`)?.value || 0); + await this.actor.setFlag(VB_MOD, "base", { + armour: num("armour"), integrity: num("integrity"), + manoeuvre: num("manoeuvre"), detection: num("detection"), + speed: num("speed"), space: num("space"), power: num("power") + }); + this.render(true); + } + }, + cancel: { label: "Cancel" } + }, default: "ok" + }, { jQuery: true }).render(true); + }); + + // Components controls + html.find("[data-action='comp-toggle']").on("click", async (ev) => { + const row = ev.currentTarget.closest("tr"); + const id = row?.dataset?.itemId; + const item = this.actor.items.get(id); + if (!item) return; + const equipped = !(item.system?.equipped ?? true); + await item.update({ "system.equipped": equipped }); + this.render(true); + }); + + html.find("[data-action='comp-edit']").on("click", async (ev) => { + const row = ev.currentTarget.closest("tr"); + const id = row?.dataset?.itemId; + const item = this.actor.items.get(id); + if (item) item.sheet?.render(true); + }); + + html.find("[data-action='comp-remove']").on("click", async (ev) => { + const row = ev.currentTarget.closest("tr"); + const id = row?.dataset?.itemId; + if (!id) return; + await this.actor.deleteEmbeddedDocuments("Item", [id]); + this.render(true); + }); + } + +// --- robust drop handlers: flag-only storage (survives W&G) --- +async _onDrop(event) { + event.preventDefault(); + let raw = {}; + try { raw = JSON.parse(event.dataTransfer?.getData("text/plain") || "{}"); } + catch { ui.notifications.error("Drop failed: cannot parse drop payload."); return; } + if (raw?.type === "Item") return this._onDropItem(event, raw); + dbg("drop.ignored", raw); +} + +async _onDropItem(event, data) { + const VB_MOD = "wg-voidships-builder"; + dbg("drop.item.raw", foundry.utils.deepClone(data)); + + // 1) spróbuj fromUuid + let itemDoc = null; + if (data?.uuid) { + try { itemDoc = await fromUuid(data.uuid); } catch (e) { dbg("fromUuid.error", e); } + } + // 2) inline data + let itemData = itemDoc?.toObject?.() ?? data?.data ?? null; + // 3) ostatecznie spróbuj Foundry helpera + if (!itemData) { + try { + const i = await Item.implementation.fromDropData(data); + itemData = i?.toObject?.() ?? null; + } catch (e) { + ui.notifications.error("Drop failed: cannot resolve item data (no UUID/DATA)."); + dbg("fromDropData.error", e, data); return; + } + } + if (!itemData) { ui.notifications.error("Drop failed: no item data."); return; } + + // 4) Czy to komponent? – akceptujemy po flagach lub po system.voidship + const fmod = itemData.flags?.[VB_MOD] || {}; + const meta = fmod.component || {}; + const vflag = fmod.voidship || null; + const vsys = itemData.system?.voidship || null; + const tags = Array.isArray(meta.tags) ? meta.tags : []; + const isComponent = !!(vflag || vsys || tags.length); + if (!isComponent) { + ui.notifications.warn("This item is not a voidship component."); + dbg("notComponent", { name: itemData.name, flags: itemData.flags }); + return; + } + + // 5) wyznacz slot + liczby (preferuj to co już jest w flagach; jeśli było tylko w system.voidship – przenieś do flag) + const inferSlotFromTags = (tags=[]) => { + const low = (Array.isArray(tags)?tags:[]).map(t => String(t).toLowerCase()); + const pref = ["prow","dorsal","port","starboard","keel","aetherics","internal"]; + const hit = pref.find(p => low.includes(p)); + return hit ? (hit[0].toUpperCase()+hit.slice(1)) : "Internal"; + }; + + const vf = vflag || vsys || {}; + const slot = vf.slot || meta.slot || inferSlotFromTags(meta.tags); + const vfixed = { + slot, + use: { + space: Number(vf?.use?.space ?? 0), + power: Number(vf?.use?.power ?? 0) + }, + mods: { + armour: Number(vf?.mods?.armour ?? 0), + integrity: Number(vf?.mods?.integrity ?? 0), + manoeuvre: Number(vf?.mods?.manoeuvre ?? 0), + detection: Number(vf?.mods?.detection ?? 0), + speed: Number(vf?.mods?.speed ?? 0), + space: Number(vf?.mods?.space ?? 0), + power: Number(vf?.mods?.power ?? 0) + } + }; + + // 6) Nie dotykamy schema W&G – zapisujemy w FLAGS + itemData.flags = foundry.utils.mergeObject(itemData.flags || {}, { + [VB_MOD]: foundry.utils.mergeObject(fmod, { voidship: vfixed }, { inplace: false }) + }, { inplace: false }); + + // 7) dopnij equipped (żeby mody się naliczały od razu) + itemData.system = foundry.utils.mergeObject(itemData.system || {}, { equipped: true }, { inplace: false }); + + dbg("drop.finalized", { name: itemData.name, vfixed }); + + try { + const created = await this.actor.createEmbeddedDocuments("Item", [itemData]); + dbg("drop.created", created?.map(c => ({ id: c.id, name: c.name }))); + this.render(true); + } catch (e) { + ui.notifications.error("Failed to add component to this voidship (see console)."); + dbg("drop.create.error", e); + } +} + + +} + +// Register the sheet Hooks.once("init", () => { Actors.registerSheet(VB_MOD, VoidshipSheet, { types: ["vehicle"], diff --git a/wg-voidships-builder/templates/voidship-sheet.hbs b/wg-voidships-builder/templates/voidship-sheet.hbs index e4c9b11..d5e8453 100644 --- a/wg-voidships-builder/templates/voidship-sheet.hbs +++ b/wg-voidships-builder/templates/voidship-sheet.hbs @@ -5,7 +5,6 @@
- {{#if (eq actor.flags.wg-voidships-builder.isVoidship true)}} {{else}} @@ -22,35 +21,37 @@
+
-

Totals

+

Totals (Base + Mods)

  1. Armour: {{totals.armour}}
  2. Integrity: {{totals.integrity}}
  3. Manoeuvre: {{totals.manoeuvre}}
  4. Detection: {{totals.detection}}
  5. Speed: {{totals.speed}}
  6. -
  7. Space (free / total): {{totals.spaceFree}} / {{totals.space}}
  8. -
  9. Power (free / total): {{totals.powerFree}} / {{totals.power}}
  10. +
  11. Space (free/total): {{totals.spaceFree}} / {{totals.space}}
  12. +
  13. Power (free/total): {{totals.powerFree}} / {{totals.power}}
+ {{#if warnings.capacity}}

{{warnings.capacity}}

{{/if}}
+

Hull

  1. Class: {{hull.class}} ({{hull.size}})
  2. -
  3. Slots Allowed — Prow: {{hull.slots.prow}}, Dorsal: {{hull.slots.dorsal}}, Port: {{hull.slots.port}}, Starboard: {{hull.slots.starboard}}, Keel: {{hull.slots.keel}}
  4. +
  5. Slots — Prow: {{hull.slots.prow}}, Dorsal: {{hull.slots.dorsal}}, Port: {{hull.slots.port}}, Starboard: {{hull.slots.starboard}}, Keel: {{hull.slots.keel}}
+ {{#if warnings.slots}}

{{warnings.slots}}

{{/if}} + {{#if warnings.requirements}}

{{warnings.requirements}}

{{/if}}
- {{#if warnings.capacity}}

{{warnings.capacity}}

{{/if}} - {{#if warnings.slots}}

{{warnings.slots}}

{{/if}} - {{#if warnings.mounts}}

{{warnings.mounts}}

{{/if}} - {{#if warnings.requirements}}

{{warnings.requirements}}

{{/if}}
+

Base (flags)

@@ -64,6 +65,7 @@
  • Power: {{base.power}}
  • +

    Mods (items)

      @@ -75,11 +77,16 @@
    1. Space: {{mods.space}}
    2. Power: {{mods.power}}
    +

    * Mods dodawane są tylko z wyposażonych komponentów.

    + +
    Raw JSON +
    {{json this}}
    +
    - +
    @@ -108,6 +115,9 @@ {{#if rtCard.source}}

    Source: {{rtCard.source}}

    {{/if}}
    +
    Raw RT +
    {{json actor.flags.wg-voidships-builder.rtRaw}}
    +
    @@ -132,6 +142,9 @@
    +
    Raw Crew +
    {{json crew}}
    +
    @@ -143,8 +156,9 @@
  • Space (free / total): {{totals.spaceFree}} / {{totals.space}}
  • Power (free / total): {{totals.powerFree}} / {{totals.power}}
  • + {{#if warnings.capacity}}

    {{warnings.capacity}}

    {{/if}}
    -

    Weapon Slots Used

    +

    Slots Used

    1. Prow: {{slotsUsed.prow}} / {{hull.slots.prow}}
    2. Dorsal: {{slotsUsed.dorsal}} / {{hull.slots.dorsal}}
    3. @@ -152,9 +166,7 @@
    4. Starboard: {{slotsUsed.starboard}} / {{hull.slots.starboard}}
    5. Keel: {{slotsUsed.keel}} / {{hull.slots.keel}}
    - {{#if warnings.capacity}}

    {{warnings.capacity}}

    {{/if}} {{#if warnings.slots}}

    {{warnings.slots}}

    {{/if}} - {{#if warnings.mounts}}

    {{warnings.mounts}}

    {{/if}} {{#if warnings.requirements}}

    {{warnings.requirements}}

    {{/if}} @@ -168,46 +180,51 @@ Slot Use Mods + Actions {{#each components as |c|}} - + {{#if c.equipped}}{{else}}{{/if}} {{c.name}} {{c.slot}} - Space: {{c.use.space}}, Power: {{c.use.power}} - - {{#if c.mods.armour}}Armour {{signed c.mods.armour}} {{/if}} - {{#if c.mods.integrity}}Integrity {{signed c.mods.integrity}} {{/if}} - {{#if c.mods.manoeuvre}}Manoeuvre {{signed c.mods.manoeuvre}} {{/if}} - {{#if c.mods.detection}}Detection {{signed c.mods.detection}} {{/if}} - {{#if c.mods.speed}}Speed {{signed c.mods.speed}} {{/if}} - {{#if c.mods.space}}Space {{signed c.mods.space}} {{/if}} - {{#if c.mods.power}}Power {{signed c.mods.power}} {{/if}} - + + Space: {{c.use.space}}, Power: {{c.use.power}} + + + + {{#if c.mods.armour}}Armour {{signed c.mods.armour}} {{/if}} + {{#if c.mods.integrity}}Integrity {{signed c.mods.integrity}} {{/if}} + {{#if c.mods.manoeuvre}}Manoeuvre {{signed c.mods.manoeuvre}} {{/if}} + {{#if c.mods.detection}}Detection {{signed c.mods.detection}} {{/if}} + {{#if c.mods.speed}}Speed {{signed c.mods.speed}} {{/if}} + {{#if c.mods.space}}Space {{signed c.mods.space}} {{/if}} + {{#if c.mods.power}}Power {{signed c.mods.power}} {{/if}} + + + + + + + {{/each}} {{else}} -

    No components installed. Drop items with system.voidship.

    +

    No components installed. Drag items from the Components compendium here.

    {{/if}} - - +
    Raw Components & Use +
    {{json components}}
    +
    {{json use}}
    +
    + diff --git a/wg-voidships-builder/wg-voidships-builder.zip b/wg-voidships-builder/wg-voidships-builder.zip index c9a2863345017a0874afffe2dde96b3ce5a9807e..965a59930f9dab86f13c0142ef11272b2713f632 100644 GIT binary patch delta 10199 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