diff --git a/wg-voidships-foundry/packs/wg-voidship-items.db b/wg-voidships-foundry/packs/wg-voidship-items.db index 7e45d39..ea89e51 100644 --- a/wg-voidships-foundry/packs/wg-voidship-items.db +++ b/wg-voidships-foundry/packs/wg-voidship-items.db @@ -1,8 +1,8 @@ {"_id": "4c636b539f64cdb9", "name": "Mars-Pattern Macrocannon", "type": "weapon", "img": null, "system": {"category": "ranged", "damage": {"base": 12, "bonus": 0, "rank": 0, "ed": {"base": 3, "bonus": 0, "rank": 0}, "ap": {"base": -1, "bonus": 0, "rank": 0}, "enabled": false, "otherDamage": {"mortal": "0", "shock": "0", "wounds": "0"}}, "range": {"short": 30, "medium": 60, "long": 120, "melee": 1, "thrown": null}, "salvo": 3, "traits": {"list": [{"name": "brutal"}, {"name": "rapidFire", "rating": "2"}]}, "keywords": "VOIDSHIP, MACROBROADSIDES"}} {"_id": "ca475410c5c586ab", "name": "Sunsear Laser Battery", "type": "weapon", "img": null, "system": {"category": "ranged", "damage": {"base": 14, "bonus": 0, "rank": 0, "ed": {"base": 2, "bonus": 0, "rank": 0}, "ap": {"base": -2, "bonus": 0, "rank": 0}, "enabled": false, "otherDamage": {"mortal": "0", "shock": "0", "wounds": "0"}}, "range": {"short": 40, "medium": 80, "long": 160, "melee": 1, "thrown": null}, "salvo": 2, "traits": {"list": [{"name": "reliable"}, {"name": "volley", "rating": "2"}]}, "keywords": "VOIDSHIP, MACROLASERS"}} {"_id": "2e5ebcbd3f63b739", "name": "Lance Battery", "type": "weapon", "img": null, "system": {"category": "ranged", "damage": {"base": 16, "bonus": 0, "rank": 0, "ed": {"base": 1, "bonus": 0, "rank": 0}, "ap": {"base": -3, "bonus": 0, "rank": 0}, "enabled": false, "otherDamage": {"mortal": "0", "shock": "0", "wounds": "0"}}, "range": {"short": 50, "medium": 100, "long": 200, "melee": 1, "thrown": null}, "salvo": 2, "traits": {"list": [{"name": "precise"}, {"name": "volley", "rating": "2"}]}, "keywords": "VOIDSHIP, LANCE"}} -{"_id": "c0e76cf8e4a100c0","name":"Torpedo Tubes","type":"weapon","img":null,"system":{"category":"ranged","description":"Torpedowe wyrzutnie okrętowe. Test Gunnery (BS) vs DEF celu; statystyki trafienia (DMG/AP/ED, ewentualne efekty specjalne) wynikają z wybranej głowicy torpedy (payload). Cel może być broniony przez TUR (intercept). Zasięgi rozpatruj wg kategorii (Contact/Close/Medium/Long/Extreme).","keywords":"VOIDSHIP, ORDNANCE, TORPEDO, PAYLOAD-DEPENDENT","rarity":"uncommon","salvo":1,"damage":{"enabled":false,"base":0,"bonus":0,"rank":0,"ed":{"base":0,"bonus":0,"rank":0},"ap":{"base":0,"bonus":0,"rank":0},"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120,"melee":1,"thrown":null},"traits":{"list":[{"name":"payload","rating":"torpedo warhead"},{"name":"interceptable","rating":"TUR"},{"name":"ordnance","rating":"-"}]},"install":{"notes":"DMG/AP/ED wg wpisu głowicy (Standard/Plasma/Melta/Virus/Vortex/Guided)."}}} -{"_id": "60951ef378ddb44c","name":"Launch Bay","type":"weapon","img":null,"system":{"category":"ranged","description":"Zatoki startowe dla skrzydeł (Fury/Starhawk/Assault Boats). Test Gunnery (BS) vs DEF celu lub manewry CAP/Intercept/Bombing/Assault wg opisu skrzydła. Obrażenia/efekty zależne od składu skrzydła (payload). Interakcje z TUR przy przechwytywaniu.","keywords":"VOIDSHIP, CARRIER, CRAFT, PAYLOAD-DEPENDENT","rarity":"uncommon","salvo":1,"damage":{"enabled":false,"base":0,"bonus":0,"rank":0,"ed":{"base":0,"bonus":0,"rank":0},"ap":{"base":0,"bonus":0,"rank":0},"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120,"melee":1,"thrown":null},"traits":{"list":[{"name":"carrier","rating":"wings"},{"name":"payload","rating":"craft loadout"},{"name":"interceptable","rating":"TUR"}]},"install":{"notes":"Efekty zależne od skrzydła (CAP/Intercept/Bombing/Assault)."}}} +{"_id":"c0e76cf8e4a100c0","name":"Torpedo Tubes","type":"weapon","img":null,"system":{"category":"ranged","description":"Torpedowe wyrzutnie okrętowe. Test Gunnery (BS) vs DEF celu; statystyki trafienia (DMG/AP/ED, ewentualne efekty specjalne) wynikają z wybranej głowicy torpedy (payload). Cel może być broniony przez TUR (intercept). Zasięgi rozpatruj wg kategorii (Contact/Close/Medium/Long/Extreme).","keywords":"VOIDSHIP, ORDNANCE, TORPEDO, PAYLOAD-DEPENDENT","rarity":"uncommon","salvo":1,"damage":{"enabled":false,"base":0,"bonus":0,"rank":0,"ed":{"base":0,"bonus":0,"rank":0},"ap":{"base":0,"bonus":0,"rank":0},"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120,"melee":1,"thrown":null},"traits":{"list":[{"name":"payload","rating":"torpedo warhead"},{"name":"interceptable","rating":"TUR"},{"name":"ordnance","rating":"-"}]},"install":{"notes":"DMG/AP/ED wg wpisu głowicy (Standard/Plasma/Melta/Virus/Vortex/Guided)."}},"flags":{"wg-voidships-builder":{"mount":"torpedo"}}} +{"_id":"60951ef378ddb44c","name":"Launch Bay","type":"weapon","img":null,"system":{"category":"ranged","description":"Zatoki startowe dla skrzydeł (Fury/Starhawk/Assault Boats). Test Gunnery (BS) vs DEF celu lub manewry CAP/Intercept/Bombing/Assault wg opisu skrzydła. Obrażenia/efekty zależne od składu skrzydła (payload). Interakcje z TUR przy przechwytywaniu.","keywords":"VOIDSHIP, CARRIER, CRAFT, PAYLOAD-DEPENDENT","rarity":"uncommon","salvo":1,"damage":{"enabled":false,"base":0,"bonus":0,"rank":0,"ed":{"base":0,"bonus":0,"rank":0},"ap":{"base":0,"bonus":0,"rank":0},"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120,"melee":1,"thrown":null},"traits":{"list":[{"name":"carrier","rating":"wings"},{"name":"payload","rating":"craft loadout"},{"name":"interceptable","rating":"TUR"}]},"install":{"notes":"Efekty zależne od skrzydła (CAP/Intercept/Bombing/Assault)."}},"flags":{"wg-voidships-builder":{"mount":"launch-bay"}}} {"_id": "24c79e9c9ee464af","name":"Nova Cannon","type":"weapon","img":null,"system":{"category":"ranged","description":"Potężny strzał z przeładowaniem: można odpalić co 2 rundy (Recharge 1). Jeśli chybi, fala uderzeniowa rozrywa jednostki w promieniu 1 VU od punktu detonacji (rozproszenie). Każda 6 na ED przy trafieniu generuje dodatkowy krytyk.","keywords":"VOIDSHIP, SIEGE, NOVA","rarity":"rare","salvo":1,"damage":{"enabled":false,"base":0,"bonus":0,"rank":0,"ed":{"base":0,"bonus":0,"rank":0},"ap":{"base":0,"bonus":0,"rank":0},"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120,"melee":1,"thrown":null},"traits":{"list":[{"name":"recharge","rating":"1 (fires every 2 rounds)"},{"name":"blast","rating":"1 VU (shockwave on miss)"},{"name":"nova-scatter","rating":"miss: detonate area"},{"name":"ed6-extra-crit","rating":"ED=6 → +1 Crit"}]},"install":{"notes":"DMG/AP/ED i dokładny szablon efektu mogą być modulowane stołowo; core: Recharge 1, miss→fala 1 VU, ED=6→+1 Crit."}}} {"_id": "dce16e3acc436f41", "name": "Plasma Drive — Jovian Pattern", "type": "gear", "img": null, "system": {"description": "Essential Component: plasma drive (Jovian).", "value": 0, "rarity": "rare", "keywords": "VOIDSHIP, ESSENTIAL, DRIVE"}} {"_id": "501ff1a2bd541b7a", "name": "Plasma Drive — Lathe Pattern", "type": "gear", "img": null, "system": {"description": "Essential Component: plasma drive (Lathe).", "value": 0, "rarity": "veryRare", "keywords": "VOIDSHIP, ESSENTIAL, DRIVE"}} @@ -65,12 +65,12 @@ {"_id":"e121a1b2c3d4e5f1","name":"Sunhammer Lance (Weapon)","type":"weapon","img":null,"system":{"category":"ranged","damage":{"base":12,"bonus":0,"rank":0,"ed":{"base":2,"bonus":0,"rank":0},"ap":{"base":-1,"bonus":0,"rank":0},"enabled":false,"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120},"salvo":2,"traits":{"list":[{"name":"lance","rating":"-"}]},"description":"Wysokoenergetyczny emiter lancy do przebijania pancerzy i pasów opancerzenia.","keywords":"VOIDSHIP, LANCE","rarity":"uncommon","source":"Into the Storm, p. 163"}} {"_id":"e122a1b2c3d4e5f2","name":"Sunhammer Lance (Battery)","type":"weapon","img":null,"system":{"category":"ranged","damage":{"base":12,"bonus":0,"rank":0,"ed":{"base":2,"bonus":0,"rank":0},"ap":{"base":-1,"bonus":0,"rank":0},"enabled":false,"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120},"salvo":2,"traits":{"list":[{"name":"lance","rating":"-"},{"name":"battery","rating":"-"}]},"description":"Zespół sprzężonych emiterów Sunhammer – nasyca cel cięciem wiązek przy ogromnym poborze mocy.","keywords":"VOIDSHIP, LANCE","rarity":"uncommon","source":"Into the Storm, p. 163"}} {"_id":"e123a1b2c3d4e5f3","name":"Sunsear Las-broadside","type":"weapon","img":null,"system":{"category":"ranged","damage":{"base":12,"bonus":0,"rank":0,"ed":{"base":2,"bonus":0,"rank":0},"ap":{"base":-1,"bonus":0,"rank":0},"enabled":false,"otherDamage":{"mortal":"0","shock":"0","wounds":"0"}},"range":{"short":30,"medium":60,"long":120},"salvo":2,"traits":{"list":[{"name":"broadside","rating":"-"}]},"description":"Długozasięgowe zespoły Sunsear na burtach – celność i precyzja na dystansie.","keywords":"VOIDSHIP, MACROLASERS","rarity":"uncommon","source":"Into the Storm, p. 162–163"}} -{"_id":"a1b2c3d4e5f60123","name":"Torpedo Warhead — Standard","type":"gear","img":null,"system":{"description":"Standardowa głowica torpedy: zrównoważone obrażenia i przebicie. Interceptowalna przez TUR.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"Test Gunnery (BS) vs DEF; może być przechwycone przez TUR."},"damage":{"base":14,"ed":3,"ap":-2},"traits":["ordnance","interceptable:TUR"],"special":"Brak efektów dodatkowych."}}} -{"_id":"b2c3d4e5f6a70124","name":"Torpedo Warhead — Plasma","type":"gear","img":null,"system":{"description":"Plazmowa głowica: silna saturacja energią, dobra na tarcze.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, PLASMA","rarity":"rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"+1 ED przeciw celom z aktywnymi SHD."},"damage":{"base":12,"ed":5,"ap":-2},"traits":["ordnance","interceptable:TUR","anti-shield:+1ED"],"special":"+1 ED jeśli cel ma SHD>0."}}} -{"_id":"c3d4e5f6a7b80125","name":"Torpedo Warhead — Melta","type":"gear","img":null,"system":{"description":"Melta: ekstremalne przebicie pancerza i niszczące uderzenie z bliska.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, MELTA","rarity":"rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"W zasięgu Contact/Close: +2 ED."},"damage":{"base":18,"ed":2,"ap":-4},"traits":["ordnance","interceptable:TUR","melta:+2ED@Close"],"special":"+2 ED w Contact/Close; potężne AP."}}} -{"_id":"d4e5f6a7b8c90126","name":"Torpedo Warhead — Virus","type":"gear","img":null,"system":{"description":"Wirusowa: minimalne obrażenia kadłuba, za to dewastuje załogę i automaty okrętu.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, VIRUS","rarity":"very rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"Pełne efekty tylko na celach z wyłączonymi SHD lub po przebiciu SHD."},"damage":{"base":4,"ed":0,"ap":0},"traits":["ordnance","interceptable:TUR","crew-killer"],"special":"On Hit (bez SHD): cel traci 1 stopień CR; na 6 na Wrath die → dodatkowe -1 CR."}}} -{"_id":"e5f6a7b8c9d00127","name":"Torpedo Warhead — Vortex","type":"gear","img":null,"system":{"description":"Worteksowa: mikroszczelina Osnowy rozrywająca cel i przestrzeń wokół.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, VORTEX","rarity":"extremely rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":-1,"notes":"Trudniejszy strzał; niektóre MG mogą wymagać Lock-On."},"damage":{"base":20,"ed":6,"ap":-5},"traits":["ordnance","interceptable:TUR","blast:1VU"],"special":"On Crit: dodatkowy d66 Crit i Blast 1 VU wokół punktu trafienia."}}} -{"_id":"f6a7b8c9d0e10128","name":"Torpedo Warhead — Guided","type":"gear","img":null,"system":{"description":"Naprowadzana: inteligentna głowica o lepszej celności i mniejszej podatności na TUR.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, GUIDED","rarity":"rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":"+1k","notes":"Atak z +1k lub przerzut 1 nieudanego kości."},"damage":{"base":14,"ed":3,"ap":-2},"traits":["ordnance","guided","interceptable:TUR-1"],"special":"TUR przeciwnika ma -1 do testów przechwytu tej torpedy."}}} -{"_id":"a7b8c9d0e1f20129","name":"Wing Loadout — Fury Interceptors","type":"gear","img":null,"system":{"description":"Myśliwce przechwytujące: CAP/Intercept, osłona własnych jednostek i neutralizacja craftów/torped.","keywords":"VOIDSHIP, PAYLOAD, WING, FURY, INTERCEPT","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"launch-bay","role":"intercept","attack":{"bonus":0,"notes":"Przy Intercept przeciw craft/torpedom: +2 do testu i wymuś przeciwnikowi -1k."},"damage":{"base":8,"ed":2,"ap":-1},"traits":["carrier-wing","cap","intercept:+2"],"special":"Gdy pełnią CAP: sojuszniczy DEF +1 przeciwko craft/torpedom na 1 VU."}}} -{"_id":"b8c9d0e1f2a3012a","name":"Wing Loadout — Starhawk Bombers","type":"gear","img":null,"system":{"description":"Bombowce: klasyczne Bombing runy przeciw okrętom; wysokie ED i przebicie.","keywords":"VOIDSHIP, PAYLOAD, WING, STARHAWK, BOMBING","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"launch-bay","role":"bombing","attack":{"bonus":0,"notes":"Atak vs DEF; obrona: TUR Intercept. Przy udanym Intercept przeciwnika: -1 trafienie (min 0)."},"damage":{"base":12,"ed":4,"ap":-2},"traits":["carrier-wing","bombing","interceptable:TUR"],"special":"Jeśli cel ma SHD>0, dodaj +1 ED (ładunki EMP/penetrujące)." }}} -{"_id":"c9d0e1f2a3b4012b","name":"Wing Loadout — Assault Boats","type":"gear","img":null,"system":{"description":"Łodzie abordażowe: dostarczają zespoły szturmowe na pokład przeciwnika.","keywords":"VOIDSHIP, PAYLOAD, WING, ASSAULT, BOARDING","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"launch-bay","role":"assault","attack":{"bonus":0,"notes":"Zamiast DMG uruchamia procedurę Boarding (Close/Contact). +2 do pierwszej fazy Boarding, jeśli dotarły bez strat."},"damage":{"base":0,"ed":0,"ap":0},"traits":["carrier-wing","assault-boats","boarding"],"special":"On Success: w pierwszej rundzie abordażu drużyny atakujące mają +2 do testów (Leadership/Pilot/Combat wg systemu stołu)."}}} +{"_id":"a1b2c3d4e5f60123","name":"Torpedo Warhead — Standard","type":"gear","img":null,"system":{"description":"Standardowa głowica torpedy: zrównoważone obrażenia i przebicie. Interceptowalna przez TUR.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"Test Gunnery (BS) vs DEF; może być przechwycone przez TUR."},"damage":{"base":14,"ed":3,"ap":-2},"traits":["ordnance","interceptable:TUR"],"special":"Brak efektów dodatkowych."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"Test Gunnery (BS) vs DEF; może być przechwycone przez TUR."},"damage":{"base":14,"ed":3,"ap":-2},"traits":["ordnance","interceptable:TUR"],"special":"Brak efektów dodatkowych."}}}} +{"_id":"b2c3d4e5f6a70124","name":"Torpedo Warhead — Plasma","type":"gear","img":null,"system":{"description":"Plazmowa głowica: silna saturacja energią, dobra na tarcze.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, PLASMA","rarity":"rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"+1 ED przeciw celom z aktywnymi SHD."},"damage":{"base":12,"ed":5,"ap":-2},"traits":["ordnance","interceptable:TUR","anti-shield:+1ED"],"special":"+1 ED jeśli cel ma SHD>0."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"+1 ED przeciw celom z aktywnymi SHD."},"damage":{"base":12,"ed":5,"ap":-2},"traits":["ordnance","interceptable:TUR","anti-shield:+1ED"],"special":"+1 ED jeśli cel ma SHD>0."}}}} +{"_id":"c3d4e5f6a7b80125","name":"Torpedo Warhead — Melta","type":"gear","img":null,"system":{"description":"Melta: ekstremalne przebicie pancerza i niszczące uderzenie z bliska.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, MELTA","rarity":"rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"W zasięgu Contact/Close: +2 ED."},"damage":{"base":18,"ed":2,"ap":-4},"traits":["ordnance","interceptable:TUR","melta:+2ED@Close"],"special":"+2 ED w Contact/Close; potężne AP."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"W zasięgu Contact/Close: +2 ED."},"damage":{"base":18,"ed":2,"ap":-4},"traits":["ordnance","interceptable:TUR","melta:+2ED@Close"],"special":"+2 ED w Contact/Close; potężne AP."}}}} +{"_id":"d4e5f6a7b8c90126","name":"Torpedo Warhead — Virus","type":"gear","img":null,"system":{"description":"Wirusowa: minimalne obrażenia kadłuba, za to dewastuje załogę i automaty okrętu.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, VIRUS","rarity":"very rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"Pełne efekty tylko na celach z wyłączonymi SHD lub po przebiciu SHD."},"damage":{"base":4,"ed":0,"ap":0},"traits":["ordnance","interceptable:TUR","crew-killer"],"special":"On Hit (bez SHD): cel traci 1 stopień CR; na 6 na Wrath die → dodatkowe -1 CR."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"torpedo","attack":{"bonus":0,"notes":"Pełne efekty tylko na celach z wyłączonymi SHD lub po przebiciu SHD."},"damage":{"base":4,"ed":0,"ap":0},"traits":["ordnance","interceptable:TUR","crew-killer"],"special":"On Hit (bez SHD): cel traci 1 stopień CR; na 6 na Wrath die → dodatkowe -1 CR."}}}} +{"_id":"e5f6a7b8c9d00127","name":"Torpedo Warhead — Vortex","type":"gear","img":null,"system":{"description":"Worteksowa: mikroszczelina Osnowy rozrywająca cel i przestrzeń wokół.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, VORTEX","rarity":"extremely rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":-1,"notes":"Trudniejszy strzał; niektóre MG mogą wymagać Lock-On."},"damage":{"base":20,"ed":6,"ap":-5},"traits":["ordnance","interceptable:TUR","blast:1VU"],"special":"On Crit: dodatkowy d66 Crit i Blast 1 VU wokół punktu trafienia."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"torpedo","attack":{"bonus":-1,"notes":"Trudniejszy strzał; niektóre MG mogą wymagać Lock-On."},"damage":{"base":20,"ed":6,"ap":-5},"traits":["ordnance","interceptable:TUR","blast:1VU"],"special":"On Crit: dodatkowy d66 Crit i Blast 1 VU wokół punktu trafienia."}}}} +{"_id":"f6a7b8c9d0e10128","name":"Torpedo Warhead — Guided","type":"gear","img":null,"system":{"description":"Naprowadzana: inteligentna głowica o lepszej celności i mniejszej podatności na TUR.","keywords":"VOIDSHIP, PAYLOAD, TORPEDO, GUIDED","rarity":"rare","source":"Voidships W&G — payloads","payload":{"mount":"torpedo","attack":{"bonus":"+1k","notes":"Atak z +1k lub przerzut 1 nieudanego kości."},"damage":{"base":14,"ed":3,"ap":-2},"traits":["ordnance","guided","interceptable:TUR-1"],"special":"TUR przeciwnika ma -1 do testów przechwytu tej torpedy."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"torpedo","attack":{"bonus":"+1k","notes":"Atak z +1k lub przerzut 1 nieudanego kości."},"damage":{"base":14,"ed":3,"ap":-2},"traits":["ordnance","guided","interceptable:TUR-1"],"special":"TUR przeciwnika ma -1 do testów przechwytu tej torpedy."}}}} +{"_id":"a7b8c9d0e1f20129","name":"Wing Loadout — Fury Interceptors","type":"gear","img":null,"system":{"description":"Myśliwce przechwytujące: CAP/Intercept, osłona własnych jednostek i neutralizacja craftów/torped.","keywords":"VOIDSHIP, PAYLOAD, WING, FURY, INTERCEPT","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"launch-bay","role":"intercept","attack":{"bonus":0,"notes":"Przy Intercept przeciw craft/torpedom: +2 do testu i wymuś przeciwnikowi -1k."},"damage":{"base":8,"ed":2,"ap":-1},"traits":["carrier-wing","cap","intercept:+2"],"special":"Gdy pełnią CAP: sojuszniczy DEF +1 przeciwko craft/torpedom na 1 VU."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"launch-bay","role":"intercept","attack":{"bonus":0,"notes":"Przy Intercept przeciw craft/torpedom: +2 do testu i wymuś przeciwnikowi -1k."},"damage":{"base":8,"ed":2,"ap":-1},"traits":["carrier-wing","cap","intercept:+2"],"special":"Gdy pełnią CAP: sojuszniczy DEF +1 przeciwko craft/torpedom na 1 VU."}}}} +{"_id":"b8c9d0e1f2a3012a","name":"Wing Loadout — Starhawk Bombers","type":"gear","img":null,"system":{"description":"Bombowce: klasyczne Bombing runy przeciw okrętom; wysokie ED i przebicie.","keywords":"VOIDSHIP, PAYLOAD, WING, STARHAWK, BOMBING","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"launch-bay","role":"bombing","attack":{"bonus":0,"notes":"Atak vs DEF; obrona: TUR Intercept. Przy udanym Intercept przeciwnika: -1 trafienie (min 0)."},"damage":{"base":12,"ed":4,"ap":-2},"traits":["carrier-wing","bombing","interceptable:TUR"],"special":"Jeśli cel ma SHD>0, dodaj +1 ED (ładunki EMP/penetrujące)." }},"flags":{"wg-voidships-builder":{"payload":{"mount":"launch-bay","role":"bombing","attack":{"bonus":0,"notes":"Atak vs DEF; obrona: TUR Intercept. Przy udanym Intercept przeciwnika: -1 trafienie (min 0)."},"damage":{"base":12,"ed":4,"ap":-2},"traits":["carrier-wing","bombing","interceptable:TUR"],"special":"Jeśli cel ma SHD>0, dodaj +1 ED (ładunki EMP/penetrujące)." }}}} +{"_id":"c9d0e1f2a3b4012b","name":"Wing Loadout — Assault Boats","type":"gear","img":null,"system":{"description":"Łodzie abordażowe: dostarczają zespoły szturmowe na pokład przeciwnika.","keywords":"VOIDSHIP, PAYLOAD, WING, ASSAULT, BOARDING","rarity":"uncommon","source":"Voidships W&G — payloads","payload":{"mount":"launch-bay","role":"assault","attack":{"bonus":0,"notes":"Zamiast DMG uruchamia procedurę Boarding (Close/Contact). +2 do pierwszej fazy Boarding, jeśli dotarły bez strat."},"damage":{"base":0,"ed":0,"ap":0},"traits":["carrier-wing","assault-boats","boarding"],"special":"On Success: w pierwszej rundzie abordażu drużyny atakujące mają +2 do testów (Leadership/Pilot/Combat wg systemu stołu)."}},"flags":{"wg-voidships-builder":{"payload":{"mount":"launch-bay","role":"assault","attack":{"bonus":0,"notes":"Zamiast DMG uruchamia procedurę Boarding (Close/Contact). +2 do pierwszej fazy Boarding, jeśli dotarły bez strat."},"damage":{"base":0,"ed":0,"ap":0},"traits":["carrier-wing","assault-boats","boarding"],"special":"On Success: w pierwszej rundzie abordażu drużyny atakujące mają +2 do testów (Leadership/Pilot/Combat wg systemu stołu)."}}}} diff --git a/wg-voidships-foundry/packs/wg-voidship-macros.db b/wg-voidships-foundry/packs/wg-voidship-macros.db index f39e971..f921f6b 100644 --- a/wg-voidships-foundry/packs/wg-voidship-macros.db +++ b/wg-voidships-foundry/packs/wg-voidship-macros.db @@ -1,10 +1,8 @@ -{"_id":"4be25d217b8dd9de","name":"Add Gear to Selected Voidship","type":"script","img":"icons/svg/plus.svg","scope":"global","author":null,"ownership":{"default":2},"command":"(async ()=>{const a=canvas.tokens?.controlled[0]?.actor; if(!a) return ui.notifications.warn('Select a voidship token.'); const pack=game.packs.get('wg-voidships-builder.wg-voidship-items'); if(!pack) return ui.notifications.error('Items pack not found.'); // 1) Pobierz index z nazwami i ID\nconst index=await pack.getIndex({fields:['name']}); const names=[...index].map(e=>e.name); names.sort((x,y)=>x.localeCompare(y)); const opts=names.map(n=>``).join(''); const content=`
Choose items to add (Ctrl/Cmd+Click):
`; new Dialog({title:'Add Gear', content, buttons:{ok:{label:'Add',callback:async html=>{const sel=[...html[0].querySelector('#it').selectedOptions].map(o=>o.value); if(!sel.length) return; // 2) Zamień nazwy na ID z indexu\nconst idByName={}; for(const e of index) idByName[e.name]=e._id; const ids=sel.map(n=>idByName[n]).filter(Boolean); if(!ids.length){ui.notifications.warn('Nothing matched selection IDs.');return;} // 3) Pobierz dokumenty po ID i dodaj do aktora\nconst docs=await pack.getDocuments(ids); const data=docs.map(d=>d.toObject()); const created=await a.createEmbeddedDocuments('Item', data); ui.notifications.info(`Added ${created.length}/${sel.length} item(s) to ${a.name}.`);}}}}).render(true);})();"} -{"_id": "41ade68c839678fa", "name": "Remove All Gear (Selected)", "type": "script", "img": "icons/svg/trash.svg", "command": "(async()=>{const a=canvas.tokens.controlled[0]?.actor; if(!a) return ui.notifications.warn('Select a voidship token.'); const ids=a.items.filter(i=>['gear','weapon'].includes(i.type)).map(i=>i.id); if(!ids.length) return ui.notifications.info('No gear/weapon items to remove.'); await a.deleteEmbeddedDocuments('Item', ids); ui.notifications.info(`Removed ${ids.length} items from ${a.name}.`);})();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "5079989f359a3c3d", "name": "Toggle Geller (Primary/Reserve)", "type": "script", "img": "icons/svg/aura.svg", "command": "(async()=>{const a=canvas.tokens.controlled[0]?.actor; if(!a) return ui.notifications.warn('Select a voidship token.'); const g=a.getFlag('wg-voidships','geller')||{primaryActive:false,reserveActive:false}; const content=`Primary:
Reserve:
`; new Dialog({title:'Geller Fields',content,buttons:{ok:{label:'Set',callback:async html=>{const p=html[0].querySelector('#p').checked; const r=html[0].querySelector('#r').checked; await a.setFlag('wg-voidships','geller',{primaryActive:p,reserveActive:r}); ChatMessage.create({content:`${a.name}: Geller Primary ${p?'ON':'OFF'} / Reserve ${r?'ON':'OFF'}`});}}}}).render(true);})();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "6a4bc2349dda4733", "name": "Organize Builder Compendia Folders", "type": "script", "img": "icons/svg/folder.svg", "command": "(async ()=>{\n const moduleId = \"wg-voidships-builder\";\n const packs = {\n items: game.packs.get(`${moduleId}.wg-voidship-items`),\n hulls: game.packs.get(`${moduleId}.wg-voidship-hulls`)\n };\n async function ensureFolder(pack, name) {\n await pack.getIndex();\n const typeName = pack.documentName; // \"Item\" or \"Actor\"\n const existing = pack.folders.find(f => f.name === name);\n if (existing) return existing;\n return Folder.create({ name, type: typeName, sorting: \"a\" }, { pack: pack.collection });\n }\n // Items\n if (packs.items) {\n const fWeapons = await ensureFolder(packs.items, \"Weapons\");\n const fEssential = await ensureFolder(packs.items, \"Essential Components\");\n const fSupplemental = await ensureFolder(packs.items, \"Supplemental Components\");\n const fOrdnance = await ensureFolder(packs.items, \"Ordnance\");\n const docs = await packs.items.getDocuments();\n for (const d of docs) {\n const kw = String(d.system?.keywords ?? \"\").toUpperCase();\n let folder = fSupplemental;\n if (d.type === \"weapon\") folder = fWeapons;\n else if (kw.includes(\"ESSENTIAL\")) folder = fEssential;\n else if (kw.includes(\"ORDNANCE\")) folder = fOrdnance;\n if (!d.folder || d.folder.id !== folder.id) {\n await d.update({ folder: folder.id }, { pack: packs.items.collection });\n }\n }\n }\n // Hulls\n if (packs.hulls) {\n const fHulls = await ensureFolder(packs.hulls, \"Hulls\");\n const docs = await packs.hulls.getDocuments();\n for (const d of docs) {\n if (!d.folder || d.folder.id !== fHulls.id) {\n await d.update({ folder: fHulls.id }, { pack: packs.hulls.collection });\n }\n }\n }\n ui.notifications.info(\"Voidships Builder: Compendium folders organized.\");\n})();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "a68969a2ac5a2855", "name": "Import Voidships", "type": "script", "img": "icons/svg/sword.svg", "command": "game.wgVoidshipsMacros.importVoidships();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "72e2ff46870f2723", "name": "Create Voidship Crit Table (d66)", "type": "script", "img": "icons/svg/d20-black.svg", "command": "game.wgVoidshipsMacros.createCritTable();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "9c4931885b529b9c", "name": "Apply Voidship Hit", "type": "script", "img": "icons/svg/splash.svg", "command": "game.wgVoidshipsMacros.applyHit();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "473e9b2b97086116", "name": "Recharge Void Shields", "type": "script", "img": "icons/svg/regen.svg", "command": "game.wgVoidshipsMacros.rechargeShields();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id": "dfd9ef292fb3774f", "name": "Set Void Shields", "type": "script", "img": "icons/svg/aura.svg", "command": "game.wgVoidshipsMacros.setShields();", "scope": "global", "author": null, "ownership": {"default": 2}} -{"_id":"6f2a9b8c7d6e5f40","name":"Payload → Apply/Revert","type":"script","img":"icons/commodities/tech/cog-brass.webp","scope":"global","author":null,"ownership":{"default":2},"command":"(async()=>{function T(s){const t=String(s??\"\").split(\":\");return{name:t[0].trim(),rating:(t[1]||\"-\").trim()}};const actor=canvas.tokens?.controlled[0]?.actor??game.user?.character; if(!actor){ui.notifications.warn(\"Select a token or open an actor sheet.\");return;} const weapons=actor.items.filter(i=>i.type===\"weapon\"&&(((i.system?.traits?.list)||[]).some(t=>((t.name||\"\").toLowerCase()).includes(\"payload\"))||[\"torpedo tubes\",\"launch bay\"].includes((i.name||\"\").toLowerCase()))); if(!weapons.length){ui.notifications.warn(\"No payload-capable weapons on actor.\");return;} const packs=game.packs.filter(p=>p.documentName===\"Item\"&&/^wg-voidship-/.test(p.metadata?.name||p.metadata?.id||\"\")); const PL=[]; for(const p of packs){try{const docs=await p.getDocuments(); for(const d of docs){const pl=d.system?.payload; if(pl) PL.push({name:d.name,id:d.uuid,mount:pl.mount,data:d})}}catch(e){console.warn(e)}} for(const it of actor.items.filter(i=>i.type==='gear'&&i.system?.payload)){PL.push({name:`${it.name} (owned)`,id:it.uuid,mount:it.system.payload.mount,data:it})} const wOpts=weapons.map(w=>``).join(\"\"); function payloadOpts(m){const o=PL.filter(p=>p.mount===m).map(p=>``).join(\"\");return o||``} let mount='torpedo'; const dlg=new Dialog({title:\"Apply Payload to Weapon\",content:``,render:html=>{const $w=html.find(\"select[name='weapon']\"); const setList=()=>{const wid=$w.val(); const w=actor.items.get(wid); const nm=(w?.name||\"\").toLowerCase(); mount=nm.includes('torpedo')? 'torpedo' : (nm.includes('launch bay')? 'launch-bay' : (((w?.system?.traits?.list)||[]).some(t=>((t.name||\"\").toLowerCase()).includes(\"torpedo\"))? 'torpedo' : 'launch-bay')); html.find(\"select[name='payload']\").html(payloadOpts(mount))}; $w.on('change',setList); setList()},buttons:{apply:{label:\"Apply\",callback:async html=>{const wid=html.find(\"select[name='weapon']\").val(); const uuid=(html.find(\"input[name='uuid']\").val()||\"\").trim(); let pid=html.find(\"select[name='payload']\").val(); let doc=null; try{if(uuid) doc=await fromUuid(uuid)}catch(e){console.warn(e)} if(!doc&&pid) doc=await fromUuid(pid); if(!doc){ui.notifications.error(\"No valid payload selected.\");return;} const pl=doc.system?.payload; if(!pl||!['torpedo','launch-bay'].includes(pl.mount)){ui.notifications.error(\"Selected item has no compatible payload data.\");return;} const w=actor.items.get(wid); const backup={name:w.name,damage:w.system?.damage,traits:w.system?.traits,keywords:w.system?.keywords,description:w.system?.description}; await w.update({\"flags.wgvoid.payloadBackup\":backup,\"flags.wgvoid.payloadRef\":doc.uuid}); const base=Array.isArray(w.system?.traits?.list)?w.system.traits.list:[]; const kept=base.filter(t=>((t.name||\"\").toLowerCase()).indexOf(\"payload\")==-1); const newTraits=[...kept,...(pl.traits||[]).map(T),{name:\"payload-applied\",rating:doc.name}]; const dm=pl.damage||{}; const note=`Primary:
Reserve:
`; new Dialog({title:'Geller Fields',content,buttons:{ok:{label:'Set',callback:async html=>{const p=html[0].querySelector('#p').checked; const r=html[0].querySelector('#r').checked; await a.setFlag('wg-voidships','geller',{primaryActive:p,reserveActive:r}); ChatMessage.create({content:`${a.name}: Geller Primary ${p?'ON':'OFF'} / Reserve ${r?'ON':'OFF'}`});}}}}).render(true);}catch(e){console.error(e);ui.notifications.error('Toggle Geller error — check console');}})();"} +{"_id":"6f2a9b8c7d6e5f40","name":"Payload → Apply/Revert","type":"script","img":"icons/commodities/tech/cog-brass.webp","scope":"global","author":null,"ownership":{"default":2},"command":"(async()=>{const FLAG='wg-voidships-builder';const dbg=(...m)=>console.log('[WG Payload]',...m);function T(s){const t=String(s??'').split(':');return{name:t[0].trim(),rating:(t[1]||'-').trim()}};try{const actor=canvas.tokens?.controlled[0]?.actor??game.user?.character; if(!actor){ui.notifications.warn('Select a token or open an actor sheet.');return;} const weapons=actor.items.filter(i=>i.type==='weapon'&&(((i.system?.traits?.list)||[]).some(t=>((t.name||'').toLowerCase()).includes('payload'))||['torpedo tubes','launch bay'].includes((i.name||'').toLowerCase())||i.getFlag?.(FLAG,'mount'))); if(!weapons.length){ui.notifications.warn('No payload-capable weapons on actor.');return;} const packsWanted=new Set(['wg-voidships-builder.wg-voidship-items','wg-voidships-builder.wg-voidship-archeotech','wg-voidships-builder.wg-voidship-xenos']); const packs=game.packs.filter(p=>p.documentName==='Item'&&(packsWanted.has(p.collection)||/^wg-voidship-/.test(p.metadata?.name||p.metadata?.id||''))); const PL=[]; const clean=(s)=>String(s||'').replace(/\\s*\\(owned.*\\)$/i,'').trim(); const getPl=(d)=>{try{const byFlag=d.getFlag?.(FLAG,'payload'); if(byFlag) return byFlag;}catch(e){} // backwards-compat\n try{const old=d.getFlag?.('wgvoid','payload'); if(old) return old;}catch(e){} return d.system?.payload}; const add=(d,tag='')=>{const pl=getPl(d); if(pl) PL.push({name:`${d.name}${tag}`, id:d.uuid, mount:pl.mount, data:d})}; // z kompendiów\nfor(const p of packs){try{const docs=await p.getDocuments(); for(const d of docs) add(d,'');}catch(e){console.warn(e)}} // z aktora\nfor(const it of actor.items.filter(i=>i.type==='gear')){const has=getPl(it); if(has) add(it,' (owned)')} // fallback: po nazwie\nfor(const it of actor.items.filter(i=>i.type==='gear'&&!getPl(i))){const nm=clean(it.name); const m= nm.startsWith('Wing Loadout')? 'launch-bay' : (nm.startsWith('Torpedo Warhead')? 'torpedo' : null); const fromPack=PL.find(p=>clean(p.name)===nm); if(fromPack) PL.push({name:`${nm} (owned→pack)`, id:fromPack.id, mount:fromPack.mount, data:fromPack.data}); else if(m) PL.push({name:`${nm} (owned—name only)`, id:it.uuid, mount:m, data:it, nameOnly:true})} const wOpts=weapons.map(w=>``).join(''); function payloadOpts(m){const o=PL.filter(p=>p.mount===m).map(p=>``).join('');return o||``} let mount='torpedo'; const dlg=new Dialog({title:'Apply Payload to Weapon',content:``,render:html=>{const $w=html.find(\"select[name='weapon']\"); const setList=()=>{const wid=$w.val(); const w=actor.items.get(wid); const nm=(w?.name||'').toLowerCase(); const byFlag=w.getFlag?.(FLAG,'mount'); mount=byFlag|| (nm.includes('torpedo')? 'torpedo' : (nm.includes('launch bay')? 'launch-bay' : (((w?.system?.traits?.list)||[]).some(t=>((t.name||'').toLowerCase()).includes('torpedo'))? 'torpedo' : 'launch-bay'))); html.find(\"select[name='payload']\").html(payloadOpts(mount))}; $w.on('change',setList); setList()},buttons:{apply:{label:'Apply',callback:async html=>{try{const wid=html.find(\"select[name='weapon']\").val(); let val=(html.find(\"input[name='uuid']\").val()||'').trim(); if(!val) val=html.find(\"select[name='payload']\").val(); const resolveAny=async(v)=>{try{if(!v) return null; if(v.startsWith('.Item.')){const r=foundry.utils.parseUuid(v,{relative:actor}); if(r?.uuid) return await fromUuid(r.uuid);} if(/^[A-Za-z0-9]{16}$/.test(v)){const owned=actor.items.get(v); if(owned) return owned;} if(!v.includes('.')&&v.length){const m=PL.find(p=>clean(p.name)===v); if(m) return await fromUuid(m.id);} return await fromUuid(v)}catch(e){return null}}; let doc=await resolveAny(val); if(!doc){ui.notifications.error('No valid payload selected.');return;} if(!(doc instanceof Item)){try{const d=await fromUuid(doc?.uuid||''); if(d) doc=d;}catch(e){}} const pl=getPl(doc); if(!pl){const m=PL.find(p=>clean(p.name)===clean(doc.name)&&getPl(p.data)); if(m){doc=await fromUuid(m.id);} } const payload=getPl(doc); if(!payload){ui.notifications.warn('Selected item has no payload data (flags/system). Run the migration macro to add flags.'); return;} if(!['torpedo','launch-bay'].includes(payload.mount)){ui.notifications.error('Payload mount not compatible (expected torpedo/launch-bay).');return;} const w=actor.items.get(wid); const backup={name:w.name,damage:w.system?.damage,traits:w.system?.traits,keywords:w.system?.keywords,description:w.system?.description}; await w.update({[`flags.${FLAG}.payloadBackup`]:backup,[`flags.${FLAG}.payloadRef`]:doc.uuid}); const base=Array.isArray(w.system?.traits?.list)?w.system.traits.list:[]; const kept=base.filter(t=>((t.name||'').toLowerCase()).indexOf('payload')==-1); const newTraits=[...kept,...(payload.traits||[]).map(T),{name:'payload-applied',rating:doc.name}]; const dm=payload.damage||{}; const note=`