Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acf2c8ef07 | ||
|
|
b931d0634b | ||
|
|
99d6702fe1 | ||
|
|
96896ba92f | ||
|
|
6557ef82ad | ||
|
|
17c64ec0de | ||
|
|
64bef08fe0 | ||
|
|
d81034f6f4 | ||
|
|
f66ac84c0b | ||
|
|
24f513baf8 | ||
|
|
9269348bf4 | ||
|
|
2758be6096 | ||
|
|
b1cfb636df | ||
|
|
0d77741a41 | ||
|
|
6508a7e883 | ||
|
|
8cbea7c237 | ||
|
|
d89671e707 | ||
|
|
d0d907bd98 | ||
|
|
f3264d60e2 | ||
|
|
63da87f372 | ||
|
|
4a5561a82f | ||
|
|
9fb7867069 | ||
|
|
b64125e637 | ||
|
|
c728f7bb6d | ||
|
|
19b472de00 |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect x="14" y="12" width="36" height="40" rx="6" stroke="#F4F7FA" stroke-width="4"/>
|
||||
<circle cx="24" cy="27" r="5" stroke="#F4F7FA" stroke-width="4"/>
|
||||
<path d="M19 40c2-4 5-6 9-6s7 2 9 6M36 24h8M36 32h8M36 40h8" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 358 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M20 50V18l12-8 12 8v32" stroke="#F4F7FA" stroke-width="4" stroke-linejoin="round"/>
|
||||
<path d="M26 24h3M35 24h3M26 31h3M35 31h3M26 38h3M35 38h3" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
<path d="M16 50h32" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 376 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M39 10c-8 4-13 12-13 22 0 10 5 18 13 22-13-1.5-24-11.8-24-27S26 11.5 39 10Z" fill="#F4F7FA"/>
|
||||
<path d="m40 21 8 11-8 11" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 297 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M10 32c5.7-9 13.1-13.5 22-13.5S48.3 23 54 32c-5.7 9-13.1 13.5-22 13.5S15.7 41 10 32Z" stroke="#F4F7FA" stroke-width="4" stroke-linejoin="round"/>
|
||||
<circle cx="32" cy="32" r="7" stroke="#F4F7FA" stroke-width="4"/>
|
||||
<circle cx="32" cy="32" r="2.5" fill="#F4F7FA"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 356 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M23 18h18l5 8-3 15H21l-3-15 5-8Z" stroke="#F4F7FA" stroke-width="4" stroke-linejoin="round"/>
|
||||
<circle cx="26" cy="29" r="2.5" fill="#F4F7FA"/>
|
||||
<circle cx="38" cy="29" r="2.5" fill="#F4F7FA"/>
|
||||
<path d="M26 37c2 2 4 3 6 3s4-1 6-3" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 385 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M18 12h20l8 8v28a4 4 0 0 1-4 4H18a4 4 0 0 1-4-4V16a4 4 0 0 1 4-4Z" stroke="#F4F7FA" stroke-width="4" stroke-linejoin="round"/>
|
||||
<path d="M38 12v10h10M24 30h12M24 38h16" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 320 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M32 16v28M24 44h16" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
<path d="M22 22c2.5-3.5 6-5 10-5s7.5 1.5 10 5M16 16c4.3-5.3 9.6-8 16-8s11.7 2.7 16 8M16 28c4.3 5.3 9.6 8 16 8s11.7-2.7 16-8" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 356 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M18 48 28 16M30 50l8-26M42 48l6-18" stroke="#F4F7FA" stroke-width="5" stroke-linecap="round"/>
|
||||
<path d="M18 48c2-4 6-7 10-8M30 50c2-4 5-7 8-8M42 48c1.5-3 4-5.5 7-6.5" stroke="#F4F7FA" stroke-width="3.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 321 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M32 8 48 14v14c0 11-6.4 20.8-16 28-9.6-7.2-16-17-16-28V14L32 8Z" stroke="#F4F7FA" stroke-width="4" stroke-linejoin="round"/>
|
||||
<path d="M32 18v24M22 30h20" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 306 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<path d="M24 10h16l8 14-8 14H24l-8-14 8-14Z" stroke="#F4F7FA" stroke-width="4" stroke-linejoin="round"/>
|
||||
<circle cx="32" cy="24" r="4" fill="#F4F7FA"/>
|
||||
<path d="M32 28v18M32 38h10M32 46H22" stroke="#F4F7FA" stroke-width="4" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 335 B |
@@ -214,8 +214,8 @@
|
||||
},
|
||||
"hits": {
|
||||
"increase": {
|
||||
"android": "@UUID[Compendium.mosh.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Make a Wound Check}",
|
||||
"human": "@UUID[Compendium.mosh.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Make a Wound Check}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Make a Wound Check}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Make a Wound Check}"
|
||||
},
|
||||
"increaseHeader": {
|
||||
"android": "Damaged",
|
||||
@@ -226,12 +226,12 @@
|
||||
"human": "systems/sla-mothership/images/icons/ui/attributes/health.png"
|
||||
},
|
||||
"hitCeiling": {
|
||||
"android": "The end draws near . . .<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}",
|
||||
"human": "The end draws near . . .<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}"
|
||||
"android": "The end draws near . . .<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}",
|
||||
"human": "The end draws near . . .<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}"
|
||||
},
|
||||
"pastCeiling": {
|
||||
"android": "The end draws near . . .<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}",
|
||||
"human": "The end draws near . . .<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}"
|
||||
"android": "The end draws near . . .<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}",
|
||||
"human": "The end draws near . . .<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Make a Death Save}"
|
||||
},
|
||||
"decrease": {
|
||||
"android": "System resources free up and you feel energized.",
|
||||
@@ -823,64 +823,64 @@
|
||||
"macro": {
|
||||
"wound": {
|
||||
"bleeding": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Bleeding}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Bleeding}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Bleeding}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Bleeding}"
|
||||
},
|
||||
"bleeding_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Bleeding [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Bleeding [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Bleeding [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Bleeding [-]}"
|
||||
},
|
||||
"bleeding_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.tFcWNddtZvlv7tsg]{Bleeding [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.tFcWNddtZvlv7tsg]{Bleeding [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.tFcWNddtZvlv7tsg]{Bleeding [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.tFcWNddtZvlv7tsg]{Bleeding [+]}"
|
||||
},
|
||||
"blunt_force": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Blunt Force}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Blunt Force}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Blunt Force}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Blunt Force}"
|
||||
},
|
||||
"blunt_force_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.k0zf8ZGivRguc0wb]{Blunt Force [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.k0zf8ZGivRguc0wb]{Blunt Force [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.k0zf8ZGivRguc0wb]{Blunt Force [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.k0zf8ZGivRguc0wb]{Blunt Force [-]}"
|
||||
},
|
||||
"blunt_force_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Blunt Force [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Blunt Force [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Blunt Force [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Blunt Force [+]}"
|
||||
},
|
||||
"fire_explosives": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fire & Explosives}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fire & Explosives}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fire & Explosives}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fire & Explosives}"
|
||||
},
|
||||
"fire_explosives_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fire & Explosives [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fire & Explosives [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fire & Explosives [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fire & Explosives [-]}"
|
||||
},
|
||||
"fire_explosives_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fire & Explosives [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fire & Explosives [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fire & Explosives [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fire & Explosives [+]}"
|
||||
},
|
||||
"gore_massive": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Gore}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Gore}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Gore}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Gore}"
|
||||
},
|
||||
"gore_massive_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.eQPuDgwv8evetFIk]{Gore [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.eQPuDgwv8evetFIk]{Gore [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.eQPuDgwv8evetFIk]{Gore [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.eQPuDgwv8evetFIk]{Gore [-]}"
|
||||
},
|
||||
"gore_massive_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Gore [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Gore [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Gore [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Gore [+]}"
|
||||
},
|
||||
"gunshot": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.XgCOLv9UunBddUyW]{Gunshot}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.XgCOLv9UunBddUyW]{Gunshot}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.XgCOLv9UunBddUyW]{Gunshot}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.XgCOLv9UunBddUyW]{Gunshot}"
|
||||
},
|
||||
"gunshot_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Gunshot [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Gunshot [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Gunshot [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Gunshot [-]}"
|
||||
},
|
||||
"gunshot_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.fnVATRHYJEUlS3pR]{Gunshot [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.fnVATRHYJEUlS3pR]{Gunshot [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.fnVATRHYJEUlS3pR]{Gunshot [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.fnVATRHYJEUlS3pR]{Gunshot [+]}"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -214,8 +214,8 @@
|
||||
},
|
||||
"hits": {
|
||||
"increase": {
|
||||
"android": "@UUID[Compendium.mosh.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Faça um Teste de Ferimento}",
|
||||
"human": "@UUID[Compendium.mosh.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Faça um Teste de Ferimento}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Faça um Teste de Ferimento}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_hotbar_1e.ZzKgfEmRdvDfyBMS]{Faça um Teste de Ferimento}"
|
||||
},
|
||||
"increaseHeader": {
|
||||
"android": "Dano",
|
||||
@@ -226,12 +226,12 @@
|
||||
"human": "systems/sla-mothership/images/icons/ui/attributes/health.png"
|
||||
},
|
||||
"hitCeiling": {
|
||||
"android": "O fim está próximo...<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}",
|
||||
"human": "O fim está próximo...<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}"
|
||||
"android": "O fim está próximo...<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}",
|
||||
"human": "O fim está próximo...<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}"
|
||||
},
|
||||
"pastCeiling": {
|
||||
"android": "O fim está próximo...<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}",
|
||||
"human": "O fim está próximo...<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}"
|
||||
"android": "O fim está próximo...<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}",
|
||||
"human": "O fim está próximo...<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.NsRHfRuuNGPfkYVf]{Faça uma Salvaguarda de Morte}"
|
||||
},
|
||||
"decrease": {
|
||||
"android": "Os recursos do sistema se estabilizam e você se sente energizado.",
|
||||
@@ -823,64 +823,64 @@
|
||||
"macro": {
|
||||
"wound": {
|
||||
"bleeding": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Sangramento}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Sangramento}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Sangramento}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.1DD8i6eCS6nx2Ip0]{Sangramento}"
|
||||
},
|
||||
"bleeding_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Sangramento [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Sangramento [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Sangramento [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.xr2o2PU5vdrR6fxQ]{Sangramento [-]}"
|
||||
},
|
||||
"bleeding_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.tFcWNddtZvlv7tsg]{Sangramento [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.tFcWNddtZvlv7tsg]{Sangramento [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.tFcWNddtZvlv7tsg]{Sangramento [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.tFcWNddtZvlv7tsg]{Sangramento [+]}"
|
||||
},
|
||||
"blunt_force": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Força Contundente}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Força Contundente}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Força Contundente}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.TAjlQjA5AAy3qYL3]{Força Contundente}"
|
||||
},
|
||||
"blunt_force_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.k0zf8ZGivRguc0wb]{Força Contundente [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.k0zf8ZGivRguc0wb]{Força Contundente [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.k0zf8ZGivRguc0wb]{Força Contundente [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.k0zf8ZGivRguc0wb]{Força Contundente [-]}"
|
||||
},
|
||||
"blunt_force_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Força Contundente [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Força Contundente [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Força Contundente [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.oL3GH0HoEPlP8vzG]{Força Contundente [+]}"
|
||||
},
|
||||
"fire_explosives": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fogo & Explosivos}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fogo & Explosivos}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fogo & Explosivos}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.bZi1qKmcKLFvnhZ2]{Fogo & Explosivos}"
|
||||
},
|
||||
"fire_explosives_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fogo & Explosivos [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fogo & Explosivos [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fogo & Explosivos [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.7rYhbDAaFeok1Daq]{Fogo & Explosivos [-]}"
|
||||
},
|
||||
"fire_explosives_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fogo & Explosivos [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fogo & Explosivos [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fogo & Explosivos [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.dJnQKDf0AlwK27QD]{Fogo & Explosivos [+]}"
|
||||
},
|
||||
"gore_massive": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Carniça}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Carniça}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Carniça}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.S9nnHKWYGSQmjQdp]{Carniça}"
|
||||
},
|
||||
"gore_massive_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.eQPuDgwv8evetFIk]{Carniça [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.eQPuDgwv8evetFIk]{Carniça [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.eQPuDgwv8evetFIk]{Carniça [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.eQPuDgwv8evetFIk]{Carniça [-]}"
|
||||
},
|
||||
"gore_massive_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Carniça [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Carniça [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Carniça [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.DuVjNlE4lsnR7Emc]{Carniça [+]}"
|
||||
},
|
||||
"gunshot": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.XgCOLv9UunBddUyW]{Disparo de Arma}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.XgCOLv9UunBddUyW]{Disparo de Arma}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.XgCOLv9UunBddUyW]{Disparo de Arma}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.XgCOLv9UunBddUyW]{Disparo de Arma}"
|
||||
},
|
||||
"gunshot_dis": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Disparo de Arma [-]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Disparo de Arma [-]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Disparo de Arma [-]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.LTpa1ZYVZl4m9k6z]{Disparo de Arma [-]}"
|
||||
},
|
||||
"gunshot_adv": {
|
||||
"android": "@UUID[Compendium.mosh.macros_triggered_1e.fnVATRHYJEUlS3pR]{Disparo de Arma [+]}",
|
||||
"human": "@UUID[Compendium.mosh.macros_triggered_1e.fnVATRHYJEUlS3pR]{Disparo de Arma [+]}"
|
||||
"android": "@UUID[Compendium.sla-mothership.macros_triggered_1e.fnVATRHYJEUlS3pR]{Disparo de Arma [+]}",
|
||||
"human": "@UUID[Compendium.sla-mothership.macros_triggered_1e.fnVATRHYJEUlS3pR]{Disparo de Arma [+]}"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -141,6 +141,30 @@ function decorateSkillWithTraitPreview(skill, traitRows = []) {
|
||||
return skill;
|
||||
}
|
||||
|
||||
function getPurchasableItemTotalCost(itemData = {}) {
|
||||
const system = itemData?.system ?? itemData?.data ?? {};
|
||||
const unitCost = Number(system.cost ?? 0) || 0;
|
||||
const quantity = Math.max(1, Number(system.quantity ?? 1) || 1);
|
||||
return Math.round(unitCost * quantity * 100) / 100;
|
||||
}
|
||||
|
||||
function isAmmoPurchaseItem(itemData = {}) {
|
||||
const system = itemData?.system ?? itemData?.data ?? {};
|
||||
const sla = system?.sla ?? {};
|
||||
const name = String(itemData?.name ?? "").trim().toLowerCase();
|
||||
const category = String(sla.category ?? "").trim().toLowerCase();
|
||||
const calibre = String(sla.calibre ?? "").trim();
|
||||
const ammoTag = String(sla.ammoTag ?? "").trim();
|
||||
return category === "ammunition" || Boolean((calibre && ammoTag) || name.startsWith("ammo:"));
|
||||
}
|
||||
|
||||
function formatSlaTimestamp() {
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "short",
|
||||
timeStyle: "short"
|
||||
}).format(new Date());
|
||||
}
|
||||
|
||||
const SLA_SPECIES_RULES = {
|
||||
Human: [
|
||||
{ key: "adaptable", label: "Adaptable", summary: "Once per session, reroll one Stat check and take the better result.", optional: false, default: true }
|
||||
@@ -282,6 +306,19 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
data.data.vevaphonInstabilityElevated = instab >= 6;
|
||||
data.data.vevaphonInstabilityCritical = instab >= 10;
|
||||
data.data.vevaphonInstabilityClass = instab >= 10 ? "instability-critical" : instab >= 6 ? "instability-elevated" : "instability-nominal";
|
||||
data.data.vevaphonInstabilityDesc = instab >= 10
|
||||
? "Instability critical. Full reversion risk on every shift."
|
||||
: instab >= 6
|
||||
? "Instability elevated. Sanity saves required when morphing mid-scene."
|
||||
: "Instability nominal. Morphing is available without additional risk.";
|
||||
data.data.vevaphonMorphPanic = [
|
||||
{ roll: 1, label: "Cascade Shift", desc: "Random morph form, +1 Instability." },
|
||||
{ roll: 2, label: "Identity Bleed", desc: "Forgets name and callsign until end of scene." },
|
||||
{ roll: 3, label: "Partial Lock", desc: "One limb freezes. −10 physical rolls using that limb." },
|
||||
{ roll: 4, label: "Tissue Rejection", desc: "1d5 damage, armour does not apply." },
|
||||
{ roll: 5, label: "Threat Imprint", desc: "Locked on nearest visible target." },
|
||||
{ roll: 6, label: "Full Reversion", desc: "Base form, lose morph bonuses, −1 Instability." }
|
||||
];
|
||||
}
|
||||
data.data.slaSpeciesTraitList = String(superData.sla.speciesNotes?.value ?? "").split(/\n+/).map((entry) => entry.trim()).filter(Boolean);
|
||||
data.data.slaPackageSkillList = String(superData.sla.packageSkills?.value ?? "").split(/\s*,\s*/).map((entry) => entry.trim()).filter(Boolean);
|
||||
@@ -420,6 +457,7 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
const armors = [];
|
||||
const conditions = [];
|
||||
const abilities = [];
|
||||
const morphForms = [];
|
||||
const persTraits = [];
|
||||
|
||||
let curWeight = 0;
|
||||
@@ -526,7 +564,11 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
|
||||
conditions.push(i);
|
||||
} else if (i.type === 'ability') {
|
||||
abilities.push(i);
|
||||
if (i.system?.sla?.morphForm) {
|
||||
morphForms.push(i);
|
||||
} else {
|
||||
abilities.push(i);
|
||||
}
|
||||
} else if (i.type === 'persTrait') {
|
||||
persTraits.push(i);
|
||||
}
|
||||
@@ -563,6 +605,9 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
actorData.weapons = weapons;
|
||||
actorData.conditions = conditions;
|
||||
actorData.abilities = abilities;
|
||||
const activeMorphFormName = String(actorData.system?.sla?.morphForm?.value ?? "").trim();
|
||||
morphForms.forEach(f => { f.slaIsActiveMorphForm = f.name === activeMorphFormName; });
|
||||
actorData.slaMorphForms = morphForms;
|
||||
actorData.persTraits = persTraits.sort((left, right) => String(left?.name ?? "").localeCompare(String(right?.name ?? "")));
|
||||
|
||||
}
|
||||
@@ -677,19 +722,26 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
//Quantity adjuster
|
||||
html.on('mousedown', '.item-quantity', ev => {
|
||||
const li = ev.currentTarget.closest(".item");
|
||||
//const item = duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId))
|
||||
var item;
|
||||
item = foundry.utils.duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
|
||||
let amount = item.system.quantity;
|
||||
const sourceItem = this.actor.getEmbeddedDocument("Item", li.dataset.itemId);
|
||||
if (!sourceItem) return;
|
||||
const item = foundry.utils.duplicate(sourceItem);
|
||||
const amount = Math.max(0, Number(item.system?.quantity ?? 0) || 0);
|
||||
let delta = 0;
|
||||
|
||||
if (event.button == 0) {
|
||||
item.system.quantity = Number(amount) + 1;
|
||||
} else if (event.button == 2) {
|
||||
item.system.quantity = Number(amount) - 1;
|
||||
if (ev.button === 0) {
|
||||
delta = 1;
|
||||
} else if (ev.button === 2) {
|
||||
delta = -1;
|
||||
}
|
||||
|
||||
this.actor.updateEmbeddedDocuments('Item', [item]);
|
||||
if (!delta) return;
|
||||
item.system.quantity = Math.max(0, amount + delta);
|
||||
|
||||
this.actor.updateEmbeddedDocuments('Item', [item]).then(async () => {
|
||||
if (delta > 0) {
|
||||
await this._applySlaQuantityIncreaseDebit(sourceItem, delta);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//Severity adjuster
|
||||
@@ -774,7 +826,7 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
var item;
|
||||
item = foundry.utils.duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
|
||||
this.actor.rollCheck(null, null, null, item.name, item.system.bonus, null);
|
||||
this.actor.rollCheck(null, null, null, item.name, item.system.bonus, null, null, { promptModifier: true });
|
||||
});
|
||||
|
||||
html.find('.sla-ebb-skill-roll').click(ev => {
|
||||
@@ -806,7 +858,7 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
//const item = duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
var item;
|
||||
item = foundry.utils.duplicate(this.actor.getEmbeddedDocument("Item", li.dataset.itemId));
|
||||
this.actor.rollWeaponAttack(item);
|
||||
this.actor.rollWeaponAttack(item, { promptModifier: true });
|
||||
});
|
||||
|
||||
// Rollable Damage
|
||||
@@ -1197,6 +1249,91 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = TextEditor.getDragEventData(event);
|
||||
if (data?.type !== "Item") return super._onDrop(event);
|
||||
|
||||
const droppedItem = await Item.implementation.fromDropData(data).catch(() => null);
|
||||
if (!droppedItem) return super._onDrop(event);
|
||||
|
||||
if (droppedItem.parent?.uuid === this.actor.uuid) {
|
||||
return super._onDrop(event);
|
||||
}
|
||||
|
||||
const shouldDebitPurchase = !droppedItem.parent || droppedItem.parent.documentName !== "Actor";
|
||||
const itemData = droppedItem.toObject();
|
||||
delete itemData._id;
|
||||
delete itemData.folder;
|
||||
const created = await this.actor.createEmbeddedDocuments("Item", [itemData], {
|
||||
slaPurchaseDebit: true,
|
||||
slaPurchaseSource: data.uuid ?? droppedItem.uuid ?? ""
|
||||
});
|
||||
if (shouldDebitPurchase) {
|
||||
await this._applySlaPurchaseDebit(created);
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
async _applySlaPurchaseDebit(createdDocs = []) {
|
||||
const documents = Array.isArray(createdDocs) ? createdDocs : [createdDocs];
|
||||
const total = Math.round(documents.reduce((sum, doc) => sum + getPurchasableItemTotalCost(doc?.toObject?.() ?? doc), 0) * 100) / 100;
|
||||
if (!total) return;
|
||||
|
||||
const currentCredits = Number(this.actor.system?.credits?.value ?? 0) || 0;
|
||||
const newCredits = Math.round((currentCredits - total) * 100) / 100;
|
||||
const updateData = { "system.credits.value": newCredits };
|
||||
|
||||
const itemNames = documents.map((doc) => doc?.name).filter(Boolean).join(", ");
|
||||
const ammoDocs = documents
|
||||
.map((doc) => doc?.toObject?.() ?? doc)
|
||||
.filter((doc) => isAmmoPurchaseItem(doc));
|
||||
if (ammoDocs.length) {
|
||||
const stamp = formatSlaTimestamp();
|
||||
const currentLedger = String(this.actor.system?.sla?.ammoLedger?.value ?? "").trim();
|
||||
const purchaseEntries = ammoDocs.map((doc) => {
|
||||
const system = doc?.system ?? doc?.data ?? {};
|
||||
const quantity = Math.max(1, Number(system.quantity ?? 1) || 1);
|
||||
const unitCost = Number(system.cost ?? 0) || 0;
|
||||
const lineCost = Math.round(unitCost * quantity * 100) / 100;
|
||||
return `[${stamp}] PURCHASE | ${doc?.name ?? "Ammo"} | ${quantity} round${quantity === 1 ? "" : "s"} | -${lineCost} cR | balance ${newCredits} cR`;
|
||||
});
|
||||
const ledgerLines = [...purchaseEntries, ...currentLedger.split("\n").filter(Boolean)].slice(0, 60);
|
||||
updateData["system.sla.ammoLedger.value"] = ledgerLines.join("\n");
|
||||
}
|
||||
|
||||
await this.actor.update(updateData);
|
||||
|
||||
ui.notifications.info(`${this.actor.name}: deducted ${total} cR for ${itemNames || "purchased item"}. Credits now ${newCredits} cR.`);
|
||||
await this.actor.addSlaActivityLog?.(`Purchased ${itemNames || "item"} for ${total} cR. Credits now ${newCredits} cR.`);
|
||||
}
|
||||
|
||||
async _applySlaQuantityIncreaseDebit(itemDoc, increase = 0) {
|
||||
const added = Math.max(0, Number(increase ?? 0) || 0);
|
||||
if (!added || !itemDoc) return;
|
||||
|
||||
const unitCost = Number(itemDoc.system?.cost ?? 0) || 0;
|
||||
const total = Math.round(unitCost * added * 100) / 100;
|
||||
if (!total) return;
|
||||
|
||||
const currentCredits = Number(this.actor.system?.credits?.value ?? 0) || 0;
|
||||
const newCredits = Math.round((currentCredits - total) * 100) / 100;
|
||||
const updateData = { "system.credits.value": newCredits };
|
||||
|
||||
if (isAmmoPurchaseItem(itemDoc)) {
|
||||
const stamp = formatSlaTimestamp();
|
||||
const currentLedger = String(this.actor.system?.sla?.ammoLedger?.value ?? "").trim();
|
||||
const entry = `[${stamp}] PURCHASE | ${itemDoc.name ?? "Ammo"} | ${added} round${added === 1 ? "" : "s"} | -${total} cR | balance ${newCredits} cR`;
|
||||
const ledgerLines = [entry, ...currentLedger.split("\n").filter(Boolean)].slice(0, 60);
|
||||
updateData["system.sla.ammoLedger.value"] = ledgerLines.join("\n");
|
||||
}
|
||||
|
||||
await this.actor.update(updateData);
|
||||
ui.notifications.info(`${this.actor.name}: deducted ${total} cR for ${added} more ${itemDoc.name ?? "item"}. Credits now ${newCredits} cR.`);
|
||||
await this.actor.addSlaActivityLog?.(`Purchased +${added} ${itemDoc.name ?? "item"} for ${total} cR. Credits now ${newCredits} cR.`);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Handle creating a new Owned Item for the actor using initial data defined in the HTML dataset
|
||||
* @param {Event} event The originating click event
|
||||
|
||||
@@ -4,6 +4,21 @@ import { SLADrugSystem } from "../sla-drug-system.js";
|
||||
import { SLA_SPECIES_BALANCE_VERSION, getSlaSpeciesStatAdjustments } from "../sla-species-balance.js";
|
||||
import { buildSlaTraumaResponseText } from "../sla-trauma.js";
|
||||
|
||||
// Global event delegation to handle interactive range slider value updates
|
||||
// in a way that is fully compatible with Foundry VTT's HTML sanitization.
|
||||
if (typeof document !== "undefined") {
|
||||
document.addEventListener("input", (event) => {
|
||||
const target = event.target;
|
||||
if (target && target.tagName === "INPUT" && target.name === "rollModifier") {
|
||||
const value = Number(target.value) || 0;
|
||||
const label = target.closest(".resource")?.querySelector(".slider-value");
|
||||
if (label) {
|
||||
label.innerText = (value >= 0 ? "+" : "") + value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const SLA_AMMO_TYPES = {
|
||||
STD: { label: "Standard", multiplier: 1, damageBonus: "", woundEffect: "", summary: "Standard ammunition." },
|
||||
AP: { label: "AP", multiplier: 2, damageBonus: "-1", woundEffect: "Gunshot [-]", summary: "Armour-piercing ammunition. Treat target armour as halved and reduce damage by 1." },
|
||||
@@ -402,14 +417,6 @@ export class MothershipActor extends Actor {
|
||||
// Prepare Character type specific data
|
||||
_deriveCharacter() {
|
||||
const system = this.system;
|
||||
//clamp stress.value to stress.min so stale stored values never show below the floor
|
||||
if (system.other?.stress) {
|
||||
const stressMin = Number(system.other.stress.min ?? 0);
|
||||
const stressVal = Number(system.other.stress.value ?? 0);
|
||||
if (Number.isFinite(stressMin) && Number.isFinite(stressVal) && stressVal < stressMin) {
|
||||
system.other.stress.value = stressMin;
|
||||
}
|
||||
}
|
||||
//armor points + damage reduction
|
||||
//init vars
|
||||
let armorPoints = 0;
|
||||
@@ -497,44 +504,11 @@ export class MothershipActor extends Actor {
|
||||
}
|
||||
|
||||
async useSlaDrug(itemId) {
|
||||
const result = await SLADrugSystem.useDrug({ actor: this, itemId });
|
||||
if (result?.ok !== false) {
|
||||
const item = this.items.get(itemId);
|
||||
if (item) await this.addSlaActivityLog(`Drug used: ${item.name}.`);
|
||||
}
|
||||
return result;
|
||||
return SLADrugSystem.useDrug({ actor: this, itemId });
|
||||
}
|
||||
|
||||
async closeSlaDrug(itemId = "", drug = "") {
|
||||
const result = await SLADrugSystem.closeDrug({ actor: this, itemId, drug });
|
||||
if (result?.ok !== false) {
|
||||
const drugName = drug || (itemId ? (this.items.get(itemId)?.name ?? "Unknown drug") : "Unknown drug");
|
||||
await this.addSlaActivityLog(`Drug effect ended: ${drugName}.`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a timestamped line to the operative's activity log.
|
||||
* Keeps newest entries at the top and trims to ~10 KB.
|
||||
*/
|
||||
async addSlaActivityLog(entry) {
|
||||
try {
|
||||
const now = new Date();
|
||||
const ts = now.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" });
|
||||
const line = `[${ts}] ${entry}`;
|
||||
const current = String(this.system?.sla?.activityLog?.value ?? "");
|
||||
const combined = current ? `${line}\n${current}` : line;
|
||||
// Trim oldest lines until under 10 KB
|
||||
const MAX = 10240;
|
||||
if (combined.length > MAX) {
|
||||
const lines = combined.split("\n");
|
||||
while (lines.join("\n").length > MAX && lines.length > 1) lines.pop();
|
||||
await this.update({ "system.sla.activityLog.value": lines.join("\n") });
|
||||
} else {
|
||||
await this.update({ "system.sla.activityLog.value": combined });
|
||||
}
|
||||
} catch (_) { /* log failures are non-fatal */ }
|
||||
return SLADrugSystem.closeDrug({ actor: this, itemId, drug });
|
||||
}
|
||||
|
||||
//central flavor text library for all chat messages
|
||||
@@ -640,9 +614,123 @@ export class MothershipActor extends Actor {
|
||||
return rollStringParsed;
|
||||
}
|
||||
|
||||
clampSlaRollTarget(rollTarget, rollString = "") {
|
||||
const numericTarget = Number(rollTarget);
|
||||
if (!Number.isFinite(numericTarget)) return rollTarget;
|
||||
const usesD100 = String(rollString ?? "").includes("1d100");
|
||||
if (!usesD100) return numericTarget;
|
||||
return Math.min(98, numericTarget);
|
||||
}
|
||||
|
||||
isSlaAutomaticFailure(total, rollString = "") {
|
||||
const numericTotal = Number(total);
|
||||
if (!Number.isFinite(numericTotal)) return false;
|
||||
const usesD100 = String(rollString ?? "").includes("1d100");
|
||||
return usesD100 && numericTotal === 99;
|
||||
}
|
||||
|
||||
getSlaChatVariant(context = {}) {
|
||||
const actorClass = String(this.system?.class?.value ?? "").trim();
|
||||
const employer = String(this.system?.sla?.employer?.value ?? "").trim();
|
||||
const sector = String(this.system?.sla?.sector?.value ?? "").trim();
|
||||
const skill = String(context?.skill ?? "").trim();
|
||||
const skillCategory = String(context?.skillCategory ?? "").trim();
|
||||
const tableName = String(context?.tableName ?? "").trim();
|
||||
const header = String(context?.msgHeader ?? "").trim();
|
||||
const weaponName = String(context?.weapon?.name ?? "").trim();
|
||||
const itemName = String(context?.item?.name ?? "").trim();
|
||||
const extra = String(context?.extra ?? "").trim();
|
||||
|
||||
const haystack = [
|
||||
actorClass,
|
||||
employer,
|
||||
sector,
|
||||
skill,
|
||||
skillCategory,
|
||||
tableName,
|
||||
header,
|
||||
weaponName,
|
||||
itemName,
|
||||
extra
|
||||
].join(" ").toLowerCase();
|
||||
|
||||
if (context?.isSlaEbbSkill || /\bebb\b|ebon|brain\swaste|flux|telekinesis|blast|awareness/.test(haystack)) {
|
||||
return { key: "ebb", label: "Ebb", emblem: "EBB" };
|
||||
}
|
||||
if (/\bdark\s?night\b/.test(haystack)) {
|
||||
return { key: "darknight", label: "DarkNight", emblem: "DN" };
|
||||
}
|
||||
if (/\bshiver\b/.test(haystack)) {
|
||||
return { key: "shiver", label: "Shiver", emblem: "SV" };
|
||||
}
|
||||
if (/\bmort\b|mortuary|undertaker|corpse|cadaver/.test(haystack)) {
|
||||
return { key: "mort", label: "Mort", emblem: "MT" };
|
||||
}
|
||||
if (/\btek\b|technical|engineer|engineering|medic|medical|science|research/.test(haystack)) {
|
||||
return { key: "tek", label: "Tek", emblem: "TK" };
|
||||
}
|
||||
if (/\bops\b|operations|opscon|ops\scon|operative|squad/.test(haystack)) {
|
||||
return { key: "ops", label: "Ops", emblem: "OP" };
|
||||
}
|
||||
return { key: "sla", label: "SLA", emblem: "SLA" };
|
||||
}
|
||||
|
||||
getSlaSeverityMeta({ severity = null, tableName = "", specialRoll = "", tableResultNumber = null } = {}) {
|
||||
const rawSeverity = Number(severity);
|
||||
if (Number.isFinite(rawSeverity)) {
|
||||
if (rawSeverity >= 5) return { key: "critical", label: "Critical", cssClass: "sla-severity-critical" };
|
||||
if (rawSeverity >= 3) return { key: "severe", label: "Severe", cssClass: "sla-severity-severe" };
|
||||
return { key: "minor", label: "Minor", cssClass: "sla-severity-minor" };
|
||||
}
|
||||
|
||||
const name = String(tableName ?? "").toLowerCase();
|
||||
const special = String(specialRoll ?? "").toLowerCase();
|
||||
const numericResult = Number(tableResultNumber);
|
||||
|
||||
if (!Number.isFinite(numericResult)) {
|
||||
return { key: "minor", label: "Minor", cssClass: "sla-severity-minor" };
|
||||
}
|
||||
|
||||
const isPanic = special === "paniccheck" || name.includes("panic");
|
||||
const isWound = name.includes("wound");
|
||||
|
||||
if (isPanic) {
|
||||
if (numericResult >= 16) return { key: "critical", label: "Catastrophic", cssClass: "sla-severity-critical" };
|
||||
if (numericResult >= 9) return { key: "severe", label: "Severe", cssClass: "sla-severity-severe" };
|
||||
return { key: "minor", label: "Minor", cssClass: "sla-severity-minor" };
|
||||
}
|
||||
|
||||
if (isWound) {
|
||||
if (numericResult >= 8) return { key: "critical", label: "Critical", cssClass: "sla-severity-critical" };
|
||||
if (numericResult >= 4) return { key: "severe", label: "Severe", cssClass: "sla-severity-severe" };
|
||||
return { key: "minor", label: "Minor", cssClass: "sla-severity-minor" };
|
||||
}
|
||||
|
||||
return { key: "minor", label: "Minor", cssClass: "sla-severity-minor" };
|
||||
}
|
||||
|
||||
async addSlaActivityLog(entry, { maxEntries = 40 } = {}) {
|
||||
const text = String(entry ?? "").trim();
|
||||
if (!text || this.type !== "character") return null;
|
||||
|
||||
const timestamp = new Date().toLocaleString("en-GB", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit"
|
||||
});
|
||||
const currentLog = String(this.system?.sla?.activityLog?.value ?? "").trim();
|
||||
const existingLines = currentLog ? currentLog.split("\n").filter(Boolean) : [];
|
||||
const nextLines = [`[${timestamp}] ${text}`, ...existingLines].slice(0, Math.max(1, maxEntries));
|
||||
await this.update({ "system.sla.activityLog.value": nextLines.join("\n") });
|
||||
return nextLines[0];
|
||||
}
|
||||
|
||||
//central roll parsing function | TAKES '1d100',[Foundry roll object],true,true,41,'<' | RETURNS enriched Foundry roll object
|
||||
parseRollResult(rollString, rollResult, zeroBased, checkCrit, rollTarget, comparison, specialRoll) {
|
||||
//init vars
|
||||
rollTarget = this.clampSlaRollTarget(rollTarget, rollString);
|
||||
let doubles = new Set([0, 11, 22, 33, 44, 55, 66, 77, 88, 99]);
|
||||
let enrichedRollResult = rollResult;
|
||||
let rollFormula = enrichedRollResult.formula;
|
||||
@@ -711,29 +799,29 @@ export class MothershipActor extends Actor {
|
||||
if (rollString.includes("[")) {
|
||||
//set whether each die succeeded
|
||||
//die 0
|
||||
if (comparison === '<' && die0value < rollTarget && die0value < 90) {
|
||||
if (comparison === '<' && die0value < rollTarget && !this.isSlaAutomaticFailure(die0value, rollString)) {
|
||||
die0success = true;
|
||||
}
|
||||
if (comparison === '<=' && die0value <= rollTarget && die0value < 90) {
|
||||
if (comparison === '<=' && die0value <= rollTarget && !this.isSlaAutomaticFailure(die0value, rollString)) {
|
||||
die0success = true;
|
||||
}
|
||||
if (comparison === '>' && die0value > rollTarget && die0value < 90) {
|
||||
if (comparison === '>' && die0value > rollTarget && !this.isSlaAutomaticFailure(die0value, rollString)) {
|
||||
die0success = true;
|
||||
}
|
||||
if (comparison === '>=' && die0value >= rollTarget && die0value < 90) {
|
||||
if (comparison === '>=' && die0value >= rollTarget && !this.isSlaAutomaticFailure(die0value, rollString)) {
|
||||
die0success = true;
|
||||
}
|
||||
//die 1
|
||||
if (comparison === '<' && die1value < rollTarget && die1value < 90) {
|
||||
if (comparison === '<' && die1value < rollTarget && !this.isSlaAutomaticFailure(die1value, rollString)) {
|
||||
die1success = true;
|
||||
}
|
||||
if (comparison === '<=' && die1value <= rollTarget && die1value < 90) {
|
||||
if (comparison === '<=' && die1value <= rollTarget && !this.isSlaAutomaticFailure(die1value, rollString)) {
|
||||
die1success = true;
|
||||
}
|
||||
if (comparison === '>' && die1value > rollTarget && die1value < 90) {
|
||||
if (comparison === '>' && die1value > rollTarget && !this.isSlaAutomaticFailure(die1value, rollString)) {
|
||||
die1success = true;
|
||||
}
|
||||
if (comparison === '>=' && die1value >= rollTarget && die1value < 90) {
|
||||
if (comparison === '>=' && die1value >= rollTarget && !this.isSlaAutomaticFailure(die1value, rollString)) {
|
||||
die1success = true;
|
||||
}
|
||||
//set whether each die are a crit
|
||||
@@ -875,8 +963,8 @@ export class MothershipActor extends Actor {
|
||||
//add data point: detect success/failure
|
||||
if (rollTarget || rollTarget === 0) {
|
||||
//check for auto failure
|
||||
if (enrichedRollResult.total >= 90) {
|
||||
//result >= 90 is a failure
|
||||
if (this.isSlaAutomaticFailure(enrichedRollResult.total, rollString)) {
|
||||
// result 99 on d100 is always a failure
|
||||
enrichedRollResult.success = false;
|
||||
} else {
|
||||
//compare values based on compararison setting
|
||||
@@ -951,7 +1039,7 @@ export class MothershipActor extends Actor {
|
||||
compareIcon = '<i class="fas fa-greater-than-equal"></i>';
|
||||
}
|
||||
//prepare formula
|
||||
if (rollTarget) {
|
||||
if (rollTarget || rollTarget === 0) {
|
||||
//show dice against target
|
||||
diceFormula = rollString + ' ' + compareIcon + ' ' + rollTarget;
|
||||
} else {
|
||||
@@ -1344,27 +1432,27 @@ export class MothershipActor extends Actor {
|
||||
}
|
||||
//append Calm effects for Critical Panic Failure
|
||||
if (useCalm && !parsedRollResult.success && parsedRollResult.critical) {
|
||||
tableResultFooter = `<br><br>You lose 1d10 Calm because you critically failed.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.jHyqXb2yDFTNWxpy]{-1d10 Calm}`;
|
||||
tableResultFooter = `<br><br>You lose 1d10 Calm because you critically failed.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.jHyqXb2yDFTNWxpy]{-1d10 Calm}`;
|
||||
}
|
||||
//append effects for Stress + Maintenance Check Failure
|
||||
if (specialRoll === 'maintenanceCheck' && !useCalm && !parsedRollResult.success && !parsedRollResult.critical) {
|
||||
tableResultFooter = `<br><br>Everyone on board the ship takes 1 Stress.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.dvJR9DYXI2kV0BbR]{+1 Stress}`;
|
||||
tableResultFooter = `<br><br>Everyone on board the ship takes 1 Stress.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.dvJR9DYXI2kV0BbR]{+1 Stress}`;
|
||||
}
|
||||
//append effects for Stress + Critical Maintenance Check Failure
|
||||
if (specialRoll === 'maintenanceCheck' && !useCalm && !parsedRollResult.success && parsedRollResult.critical) {
|
||||
tableResultFooter = `<br><br>Everyone on board the ship takes 1 Stress. You must roll for another maintenance issue because you critically failed.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.dvJR9DYXI2kV0BbR]{+1 Stress}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.hRapiXGVW8WZQH12]{Roll for Maintenance Issue}`;
|
||||
tableResultFooter = `<br><br>Everyone on board the ship takes 1 Stress. You must roll for another maintenance issue because you critically failed.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.dvJR9DYXI2kV0BbR]{+1 Stress}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.hRapiXGVW8WZQH12]{Roll for Maintenance Issue}`;
|
||||
}
|
||||
//append effects for Calm + Maintenance Check Failure
|
||||
if (specialRoll === 'maintenanceCheck' && useCalm && !parsedRollResult.success && !parsedRollResult.critical) {
|
||||
tableResultFooter = `<br><br>Everyone on board the ship loses 1d10 Calm.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.jHyqXb2yDFTNWxpy]{-1d10 Calm}`;
|
||||
tableResultFooter = `<br><br>Everyone on board the ship loses 1d10 Calm.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.jHyqXb2yDFTNWxpy]{-1d10 Calm}`;
|
||||
}
|
||||
//append effects for Calm + Critical Maintenance Check Failure
|
||||
if (specialRoll === 'maintenanceCheck' && useCalm && !parsedRollResult.success && parsedRollResult.critical) {
|
||||
tableResultFooter = `<br><br>Everyone on board the ship loses 1d10 Calm. You must roll for another maintenance issue because you critically failed.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.jHyqXb2yDFTNWxpy]{-1d10 Calm}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.hRapiXGVW8WZQH12]{Roll for Maintenance Issue}`;
|
||||
tableResultFooter = `<br><br>Everyone on board the ship loses 1d10 Calm. You must roll for another maintenance issue because you critically failed.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.jHyqXb2yDFTNWxpy]{-1d10 Calm}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.hRapiXGVW8WZQH12]{Roll for Maintenance Issue}`;
|
||||
}
|
||||
//append effects for Calm + Critical Maintenance Check Success
|
||||
if (specialRoll === 'maintenanceCheck' && useCalm && parsedRollResult.success && parsedRollResult.critical) {
|
||||
flavorText = flavorText + ` Gain 1d10 Calm.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.k2TtLFOG9mGaWVx3]{+1d10 Calm}`;
|
||||
flavorText = flavorText + ` Gain 1d10 Calm.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.k2TtLFOG9mGaWVx3]{+1d10 Calm}`;
|
||||
}
|
||||
//set table result type (using first value)
|
||||
if (tableResult[0].type === 0 || tableResult[0].type === 'text') {
|
||||
@@ -1376,6 +1464,12 @@ export class MothershipActor extends Actor {
|
||||
}
|
||||
//generate chat message
|
||||
//prepare data
|
||||
const severityMeta = this.getSlaSeverityMeta({
|
||||
tableName,
|
||||
specialRoll,
|
||||
tableResultNumber
|
||||
});
|
||||
|
||||
let messageData = {
|
||||
actor: this,
|
||||
tableResult: tableResult,
|
||||
@@ -1390,7 +1484,14 @@ export class MothershipActor extends Actor {
|
||||
woundText: woundText,
|
||||
secondRoll: secondRoll,
|
||||
parsedRollResult2: parsedRollResult2,
|
||||
specialRoll: specialRoll
|
||||
specialRoll: specialRoll,
|
||||
severityMeta: severityMeta,
|
||||
chatStyle: this.getSlaChatVariant({
|
||||
tableName,
|
||||
msgHeader: tableName,
|
||||
isSlaEbbSkill: false,
|
||||
extra: specialRoll
|
||||
})
|
||||
};
|
||||
//prepare template
|
||||
messageTemplate = 'systems/sla-mothership/templates/chat/rollTable.html';
|
||||
@@ -1409,6 +1510,7 @@ export class MothershipActor extends Actor {
|
||||
}, {
|
||||
keepId: true
|
||||
});
|
||||
await this.addSlaActivityLog?.(`${tableName}: ${parsedRollResult.success ? "success" : "failure"} on ${rollString}${tableResultNumber !== null ? ` -> ${tableResultNumber}` : ""}.`);
|
||||
if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {
|
||||
//log what was done
|
||||
slaDebug(`Rolled on table ID: ${tableId}, with: rollString:${rollString}, aimFor:${aimFor}, zeroBased:${zeroBased}, checkCrit:${checkCrit}, rollAgainst:${rollAgainst}, comparison:${comparison}`);
|
||||
@@ -1642,8 +1744,6 @@ export class MothershipActor extends Actor {
|
||||
let skillList = ``;
|
||||
//create skill counter
|
||||
let skillCount = 0;
|
||||
//create dialog pixel counter
|
||||
let dialogHeight = 232;
|
||||
//loop through and create skill rows
|
||||
const filteredSkills = playerItems.filter((item) => item.type === "skill" && this.isSkillRelevantForContext(item, context));
|
||||
const skillSource = filteredSkills.length
|
||||
@@ -1671,13 +1771,9 @@ export class MothershipActor extends Actor {
|
||||
skillList = skillList + tempRow;
|
||||
//increment skill count
|
||||
skillCount++;
|
||||
//increment pixel counter
|
||||
dialogHeight = dialogHeight + 77;
|
||||
}
|
||||
//check if there are no skills, and adjust prompt height accordingly
|
||||
//check if there are no skills
|
||||
if (skillCount === 0) {
|
||||
//set window height
|
||||
dialogHeight = 170;
|
||||
skillList = `<div class="macro_window"><div class="macro_desc" style="padding: 12px 14px;">${requiresCombatSkills ? "No combat-tagged skills are available for this action." : "No matching skills are available for this action."}</div></div>`;
|
||||
}
|
||||
//create button header if needed
|
||||
@@ -1686,12 +1782,24 @@ export class MothershipActor extends Actor {
|
||||
} else {
|
||||
buttonDesc = ``;
|
||||
}
|
||||
//wrap skill list in a scrollable container so long lists don't push buttons off-screen
|
||||
const scrollableSkillList = `<div class="sla-skill-scroll-list" style="max-height: 340px; overflow-y: auto; padding-right: 4px; margin-bottom: 4px;">${skillList}</div>`;
|
||||
//create final dialog data
|
||||
const showModifier = !foundry.utils.hasProperty(context.attackContext ?? {}, "rollModifier");
|
||||
const modifierHtml = showModifier ? `
|
||||
<div class="resource" style="margin-top: 15px; margin-bottom: 10px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 10px; padding-left: 10px; padding-right: 10px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Roll Modifier</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;" oninput="this.previousElementSibling.querySelector('.slider-value').innerText = (this.value >= 0 ? '+' : '') + this.value">
|
||||
</div>
|
||||
` : "";
|
||||
const dialogData = {
|
||||
window: {title: dlgTitle},
|
||||
classes: ["macro-popup-dialog"],
|
||||
position: {width: 600},
|
||||
content: skillHeader + `<div class="skill-dialog-scroll">${skillList}</div>` + buttonDesc,
|
||||
content: skillHeader + scrollableSkillList + modifierHtml + buttonDesc,
|
||||
buttons: []
|
||||
};
|
||||
//add adv/normal/dis buttons if we need a rollString
|
||||
@@ -1705,8 +1813,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = `1d100 [+]`;
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-up`
|
||||
},
|
||||
@@ -1717,8 +1826,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = `1d100`;
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-minus`
|
||||
},
|
||||
@@ -1729,8 +1839,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = `1d100 [-]`;
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-down`
|
||||
}
|
||||
@@ -1744,8 +1855,9 @@ export class MothershipActor extends Actor {
|
||||
callback: (event, button, dialog) => {
|
||||
skill = button.form.querySelector("input[name='skill']:checked")?.getAttribute("id");
|
||||
skillValue = button.form.querySelector("input[name='skill']:checked")?.getAttribute("value");
|
||||
resolve([rollString, skill, skillValue]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}`);
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : (Number(context.attackContext?.rollModifier ?? 0) || 0);
|
||||
resolve([rollString, skill, skillValue, rollModifier]);
|
||||
slaDebug(`User left the chooseSkill dialog with: rollString:${rollString}, skill:${skill}, skillValue:${skillValue}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-chevron-circle-right`
|
||||
}
|
||||
@@ -1766,19 +1878,29 @@ export class MothershipActor extends Actor {
|
||||
let dieAdv = die + ` [+]`;
|
||||
let dieDis = die + ` [-]`;
|
||||
//create final dialog data
|
||||
const modifierHtml = `
|
||||
<div class="resource" style="margin-top: 15px; margin-bottom: 10px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 10px; padding-left: 10px; padding-right: 10px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Roll Modifier</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;" oninput="this.previousElementSibling.querySelector('.slider-value').innerText = (this.value >= 0 ? '+' : '') + this.value">
|
||||
</div>
|
||||
`;
|
||||
const dialogData = {
|
||||
window: {title: dlgTitle},
|
||||
classes: ["macro-popup-dialog"],
|
||||
position: {width: 600},
|
||||
content: `<div class="macro_prompt">` + game.i18n.localize("Mosh.SelectYourRollType") + `:</div>`,
|
||||
content: `<form style="padding: 5px 10px;"><div class="macro_prompt" style="margin-bottom:10px;">` + game.i18n.localize("Mosh.SelectYourRollType") + `:</div>` + modifierHtml + `</form>`,
|
||||
buttons: [
|
||||
{
|
||||
label: game.i18n.localize("Mosh.Advantage"),
|
||||
action: `action_advantage`,
|
||||
callback: (event, button, dialog) => {
|
||||
rollString = dieAdv;
|
||||
resolve([rollString]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}`);
|
||||
const rollModifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve([rollString, rollModifier]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-up`
|
||||
},
|
||||
@@ -1787,8 +1909,9 @@ export class MothershipActor extends Actor {
|
||||
action: `action_normal`,
|
||||
callback: (event, button, dialog) => {
|
||||
rollString = die;
|
||||
resolve([rollString]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}`);
|
||||
const rollModifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve([rollString, rollModifier]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-minus`
|
||||
},
|
||||
@@ -1797,8 +1920,9 @@ export class MothershipActor extends Actor {
|
||||
action: `action_disadvantage`,
|
||||
callback: (event, button, dialog) => {
|
||||
rollString = dieDis;
|
||||
resolve([rollString]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}`);
|
||||
const rollModifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve([rollString, rollModifier]);
|
||||
slaDebug(`User left the chooseAdvantage dialog with: rollString:${rollString}, modifier:${rollModifier}`);
|
||||
},
|
||||
icon: `fas fa-angle-double-down`
|
||||
}
|
||||
@@ -1907,19 +2031,29 @@ export class MothershipActor extends Actor {
|
||||
if (rawFormula === "Str/10") {
|
||||
rawFormula = `floor((${this.system.stats.strength.value} + ${(Number(this.system.stats.strength.mod) || 0)}) / 10)`;
|
||||
}
|
||||
const mult = Number(weapon?.system?.sla?.damageMultiplier ?? weapon?.system?.damageMultiplier ?? 1) || 1;
|
||||
if (mult > 1) {
|
||||
if (/^\d+d\d+/i.test(rawFormula)) {
|
||||
rawFormula = rawFormula.replace(/^(\d+)(d\d+)/i, (match, dice, rest) => {
|
||||
return `${Number(dice) * mult}${rest}`;
|
||||
});
|
||||
} else {
|
||||
rawFormula = `(${rawFormula}) * ${mult}`;
|
||||
}
|
||||
}
|
||||
const critDamageMode = game.settings.get('sla-mothership', 'critDamage');
|
||||
|
||||
if (isCritical) {
|
||||
if (critDamageMode === 'advantage') {
|
||||
rawFormula = `{${parsedDamageString},${parsedDamageString}}kh`;
|
||||
rawFormula = `{${rawFormula},${rawFormula}}kh`;
|
||||
} else if (critDamageMode === 'doubleDamage') {
|
||||
rawFormula = `(${parsedDamageString}) * 2`;
|
||||
rawFormula = `(${rawFormula}) * 2`;
|
||||
} else if (critDamageMode === 'doubleDice') {
|
||||
rawFormula = `${parsedDamageString} + ${parsedDamageString}`;
|
||||
rawFormula = `${rawFormula} + ${rawFormula}`;
|
||||
} else if (critDamageMode === 'maxDamage') {
|
||||
rawFormula = parsedDamageString.replaceAll('d', ' * ');
|
||||
rawFormula = rawFormula.replaceAll('d', ' * ');
|
||||
} else if (critDamageMode === 'weaponValue') {
|
||||
rawFormula = `${parsedDamageString} + ${weapon?.system?.critDmg || 0}`;
|
||||
rawFormula = `${rawFormula} + ${weapon?.system?.critDmg || 0}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2391,6 +2525,9 @@ export class MothershipActor extends Actor {
|
||||
rollString = chosenSkills[0];
|
||||
skill = chosenSkills[1];
|
||||
skillValue = chosenSkills[2];
|
||||
if (chosenSkills[3] !== undefined) {
|
||||
attackContext.rollModifier = chosenSkills[3];
|
||||
}
|
||||
}
|
||||
//if rollString is STILL blank, redirect player to choose the roll
|
||||
if (!rollString) {
|
||||
@@ -2398,6 +2535,9 @@ export class MothershipActor extends Actor {
|
||||
let chosenRollType = await this.chooseAdvantage(this.system.stats[attribute].rollLabel, '1d100');
|
||||
//set variables
|
||||
rollString = chosenRollType[0];
|
||||
if (chosenRollType[1] !== undefined) {
|
||||
attackContext.rollModifier = chosenRollType[1];
|
||||
}
|
||||
}
|
||||
//if this is a weapon roll
|
||||
if (weapon) {
|
||||
@@ -2457,7 +2597,15 @@ export class MothershipActor extends Actor {
|
||||
//if this is a damage roll
|
||||
if (specialRoll === 'damage') {
|
||||
//parse the roll string
|
||||
let damageRollString = weapon.system.damage
|
||||
let damageRollString = weapon.system.damage;
|
||||
if (weapon && !overrideDamagaRollString) {
|
||||
const mult = Number(weapon.system?.sla?.damageMultiplier ?? weapon.system?.damageMultiplier ?? 1) || 1;
|
||||
if (mult > 1) {
|
||||
damageRollString = damageRollString.replace(/^(\d+)(d\d+)/i, (match, dice, rest) => {
|
||||
return `${Number(dice) * mult}${rest}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
if(overrideDamagaRollString){
|
||||
damageRollString = overrideDamagaRollString;
|
||||
}
|
||||
@@ -2476,8 +2624,10 @@ export class MothershipActor extends Actor {
|
||||
}
|
||||
//prepare flavortext
|
||||
if (weapon.system.damage === "Str/10" && this.type === 'character') {
|
||||
const mult = Number(weapon.system?.sla?.damageMultiplier ?? weapon.system?.damageMultiplier ?? 1) || 1;
|
||||
const multStr = mult > 1 ? `${mult} * ` : '';
|
||||
//determine the damage string
|
||||
flavorText = 'You strike your target for <strong>[[floor((' + this.system.stats.strength.value + ' + ' + (Number(this.system.stats.strength.mod) || 0) + ')/10)]] damage</strong>.';
|
||||
flavorText = 'You strike your target for <strong>[[' + multStr + 'floor((' + this.system.stats.strength.value + ' + ' + (Number(this.system.stats.strength.mod) || 0) + ')/10)]] damage</strong>.';
|
||||
} else {
|
||||
flavorText = 'You inflict [[' + parsedDamageString + '[' + dsnTheme + ']' + critMod + ']] points of damage.';
|
||||
}
|
||||
@@ -2513,7 +2663,13 @@ export class MothershipActor extends Actor {
|
||||
targetingResult: targetingResult,
|
||||
needsDesc: needsDesc,
|
||||
woundEffect: woundEffect,
|
||||
specialRoll: specialRoll
|
||||
specialRoll: specialRoll,
|
||||
chatStyle: this.getSlaChatVariant({
|
||||
weapon,
|
||||
msgHeader,
|
||||
isSlaEbbSkill: false,
|
||||
extra: ammoContext?.label ?? ""
|
||||
})
|
||||
};
|
||||
let chatData = {
|
||||
user: game.user.id,
|
||||
@@ -2528,6 +2684,7 @@ export class MothershipActor extends Actor {
|
||||
const content = await foundry.applications.handlebars.renderTemplate(template, messageData);
|
||||
chatData.content = content;
|
||||
await ChatMessage.create(chatData);
|
||||
await this.addSlaActivityLog?.(`${weapon.name}: damage roll resolved.${targetingResult ? ` ${targetingResult.targetName} took ${targetingResult.finalDamage} damage.` : ""}`);
|
||||
//log what was done
|
||||
console.log(`Rolled damage on:${weapon.name}`);
|
||||
//return messageData
|
||||
@@ -2545,6 +2702,25 @@ export class MothershipActor extends Actor {
|
||||
} else {
|
||||
rollTarget = rollTargetOverride;
|
||||
}
|
||||
const modifier = Number(attackContext?.rollModifier ?? 0) || 0;
|
||||
if (modifier) {
|
||||
rollTarget += modifier;
|
||||
if (effectiveRollBreakdown) {
|
||||
effectiveRollBreakdown.parts.push({
|
||||
label: "Roll Modifier",
|
||||
value: modifier
|
||||
});
|
||||
effectiveRollBreakdown.total += modifier;
|
||||
effectiveRollBreakdown.formulaText += ` ${modifier >= 0 ? "+" : ""}${modifier}`;
|
||||
}
|
||||
}
|
||||
rollTarget = this.clampSlaRollTarget(rollTarget, rollString);
|
||||
if (effectiveRollBreakdown && (String(rollString ?? "").includes("1d100"))) {
|
||||
effectiveRollBreakdown = {
|
||||
...effectiveRollBreakdown,
|
||||
total: rollTarget
|
||||
};
|
||||
}
|
||||
//roll the dice
|
||||
//parse the roll string
|
||||
let parsedRollString = this.parseRollString(rollString, aimFor);
|
||||
@@ -2707,9 +2883,9 @@ export class MothershipActor extends Actor {
|
||||
}
|
||||
if (ammoUsage) {
|
||||
const roundLabel = ammoUsage.shots === 1 ? 'round' : 'rounds';
|
||||
const ammoPrefix = `<strong>${ammoUsage.label}</strong> fire with <strong>${ammoUsage.ammoLabel}</strong> spent <strong>${ammoUsage.shots}</strong> ${roundLabel}. Magazine <strong>${ammoUsage.loaded}/${weapon.system.shots}</strong>. Reserve <strong>${ammoUsage.reserve}</strong>. Ammo cost <strong>${ammoUsage.totalCost}</strong> cR. ${ammoUsage.ammoRule}`;
|
||||
const ammoPrefix = `<strong>${ammoUsage.label}</strong> fire with <strong>${ammoUsage.ammoLabel}</strong> spent <strong>${ammoUsage.shots}</strong> ${roundLabel}. Magazine <strong>${ammoUsage.loaded}/${weapon.system.shots}</strong>. Reserve <strong>${ammoUsage.reserve}</strong>. Firing spend <strong>${ammoUsage.totalCost}</strong> cR. ${ammoUsage.ammoRule}`;
|
||||
const accountingText = ammoAccounting
|
||||
? ` Credits now <strong>${ammoAccounting.newCredits}</strong> cR. Running ammo spend <strong>${ammoAccounting.spendTotal}</strong> cR.`
|
||||
? ` Credits now <strong>${ammoAccounting.newCredits}</strong> cR. Running firing spend <strong>${ammoAccounting.spendTotal}</strong> cR.`
|
||||
: "";
|
||||
flavorText = flavorText ? `${ammoPrefix}${accountingText}<br>${flavorText}` : `${ammoPrefix}${accountingText}`;
|
||||
}
|
||||
@@ -2999,7 +3175,14 @@ export class MothershipActor extends Actor {
|
||||
targetingResult: targetingResult,
|
||||
firstEdition: game.settings.get('sla-mothership', 'firstEdition'),
|
||||
useCalm: game.settings.get('sla-mothership', 'useCalm'),
|
||||
androidPanic: game.settings.get('sla-mothership', 'androidPanic')
|
||||
androidPanic: game.settings.get('sla-mothership', 'androidPanic'),
|
||||
chatStyle: this.getSlaChatVariant({
|
||||
weapon,
|
||||
skill,
|
||||
skillCategory: String(attackContext?.skillCategory ?? "").trim(),
|
||||
msgHeader,
|
||||
isSlaEbbSkill
|
||||
})
|
||||
};
|
||||
//prepare template
|
||||
messageTemplate = 'systems/sla-mothership/templates/chat/rollCheck.html';
|
||||
@@ -3018,6 +3201,11 @@ export class MothershipActor extends Actor {
|
||||
}, {
|
||||
keepId: true
|
||||
});
|
||||
const skillLabel = String(skill ?? "").trim();
|
||||
const actionLabel = weapon
|
||||
? weapon.name
|
||||
: (skillLabel ? `${attributeLabel} / ${skillLabel}` : attributeLabel);
|
||||
await this.addSlaActivityLog?.(`${actionLabel}: ${parsedRollResult.success ? "success" : "failure"} (${parsedRollResult.total} vs ${rollTarget}).`);
|
||||
//is DSN active?
|
||||
if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {
|
||||
//log what was done
|
||||
@@ -3040,18 +3228,6 @@ export class MothershipActor extends Actor {
|
||||
await this.rollTable("panicCheck", null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
// Activity log
|
||||
if (this.type === "character" && specialRoll !== "damage") {
|
||||
try {
|
||||
const rollLabel = skill && skill !== "none" ? skill : (attribute ? String(attribute).charAt(0).toUpperCase() + String(attribute).slice(1) : "Roll");
|
||||
const resultNum = Number(parsedRollResult?.total ?? 0);
|
||||
const outcome = parsedRollResult?.success
|
||||
? (parsedRollResult.critical ? "Critical success" : "Pass")
|
||||
: (parsedRollResult?.critical ? "Critical failure" : "Fail");
|
||||
const critTag = parsedRollResult?.critical ? " ★" : "";
|
||||
await this.addSlaActivityLog(`${rollLabel}: rolled ${resultNum} vs ${rollTarget} — ${outcome}${critTag}`);
|
||||
} catch (_) {}
|
||||
}
|
||||
return [messageData];
|
||||
}
|
||||
|
||||
@@ -3908,10 +4084,58 @@ export class MothershipActor extends Actor {
|
||||
return { total, parts };
|
||||
}
|
||||
|
||||
async chooseWeaponAttackOptions(weapon) {
|
||||
async promptRollModifier(title = "Roll Modifier") {
|
||||
return new Promise((resolve) => {
|
||||
const dialogData = {
|
||||
window: { title },
|
||||
content: `
|
||||
<form style="padding: 5px 10px;">
|
||||
<div class="resource" style="margin-bottom: 15px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Modifier Value</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;">
|
||||
<div class="slider-ticks" style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 0.85em; color: rgba(255,255,255,0.6); padding: 0 8px;">
|
||||
<span>-30</span>
|
||||
<span>-20</span>
|
||||
<span>-10</span>
|
||||
<span style="color: #cc2828; font-weight: bold;">0</span>
|
||||
<span>+10</span>
|
||||
<span>+20</span>
|
||||
<span>+30</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`,
|
||||
buttons: [
|
||||
{
|
||||
label: "Roll",
|
||||
action: "roll",
|
||||
icon: "fas fa-dice-d20",
|
||||
callback: (_event, button) => {
|
||||
const modifier = Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0;
|
||||
resolve(modifier);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Cancel",
|
||||
action: "cancel",
|
||||
icon: "fas fa-times",
|
||||
callback: () => resolve(null)
|
||||
}
|
||||
],
|
||||
close: () => resolve(null)
|
||||
};
|
||||
new foundry.applications.api.DialogV2(dialogData).render({ force: true });
|
||||
});
|
||||
}
|
||||
|
||||
async chooseWeaponAttackOptions(weapon, attackContext = {}) {
|
||||
const fireModes = this.getWeaponFireModes(weapon);
|
||||
const activeFireMode = this.getActiveWeaponFireMode(weapon);
|
||||
const ammoChoices = this.getWeaponAmmoChoices(weapon);
|
||||
const showModifier = Boolean(attackContext?.promptModifier);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const fireOptions = fireModes.map((mode) => `
|
||||
@@ -3921,20 +4145,40 @@ export class MothershipActor extends Actor {
|
||||
<option value="${choice.tag}" ${choice.selected ? "selected" : ""}>${choice.label}</option>
|
||||
`).join("");
|
||||
|
||||
const modifierHtml = showModifier ? `
|
||||
<div class="resource" style="margin-top: 15px; margin-bottom: 10px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 10px;">
|
||||
<label class="resource-label" style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 8px;">
|
||||
<span>Roll Modifier</span>
|
||||
<span class="slider-value" style="font-weight: bold; color: #cc2828;">0</span>
|
||||
</label>
|
||||
<input type="range" name="rollModifier" min="-30" max="30" step="10" value="0" style="width: 100%; cursor: pointer; accent-color: #cc2828;">
|
||||
<div class="slider-ticks" style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 0.85em; color: rgba(255,255,255,0.6); padding: 0 8px;">
|
||||
<span>-30</span>
|
||||
<span>-20</span>
|
||||
<span>-10</span>
|
||||
<span style="color: #cc2828; font-weight: bold;">0</span>
|
||||
<span>+10</span>
|
||||
<span>+20</span>
|
||||
<span>+30</span>
|
||||
</div>
|
||||
</div>
|
||||
` : "";
|
||||
|
||||
const dialogData = {
|
||||
window: {
|
||||
title: `${weapon.name} Attack Setup`
|
||||
},
|
||||
content: `
|
||||
<form>
|
||||
<form style="padding: 5px 10px;">
|
||||
<div class="resource" style="margin-bottom: 10px;">
|
||||
<label class="resource-label">Fire Mode</label>
|
||||
<select name="fireMode">${fireOptions}</select>
|
||||
<label class="resource-label" style="font-weight: bold; margin-bottom: 5px; display: block;">Fire Mode</label>
|
||||
<select name="fireMode" style="width: 100%;">${fireOptions}</select>
|
||||
</div>
|
||||
<div class="resource" style="margin-bottom: 10px;">
|
||||
<label class="resource-label">Ammo Type</label>
|
||||
<select name="ammoTag">${ammoOptions}</select>
|
||||
<label class="resource-label" style="font-weight: bold; margin-bottom: 5px; display: block;">Ammo Type</label>
|
||||
<select name="ammoTag" style="width: 100%;">${ammoOptions}</select>
|
||||
</div>
|
||||
${modifierHtml}
|
||||
</form>
|
||||
`,
|
||||
buttons: [
|
||||
@@ -3946,10 +4190,12 @@ export class MothershipActor extends Actor {
|
||||
const fireLabel = button.form.querySelector("select[name='fireMode']")?.value ?? activeFireMode.label;
|
||||
const fireMode = fireModes.find((mode) => mode.label === fireLabel) ?? activeFireMode;
|
||||
const ammoTag = button.form.querySelector("select[name='ammoTag']")?.value ?? ammoChoices[0]?.tag ?? "STD";
|
||||
const rollModifier = showModifier ? (Number(button.form.querySelector("input[name='rollModifier']")?.value ?? 0) || 0) : 0;
|
||||
resolve({
|
||||
fireMode: fireMode.label,
|
||||
shotsPerFire: fireMode.shots,
|
||||
ammoTag
|
||||
ammoTag,
|
||||
rollModifier
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -3966,10 +4212,20 @@ export class MothershipActor extends Actor {
|
||||
});
|
||||
}
|
||||
|
||||
async rollWeaponAttack(weapon) {
|
||||
const attackContext = weapon?.system?.useAmmo ? await this.chooseWeaponAttackOptions(weapon) : {};
|
||||
if (weapon?.system?.useAmmo && !attackContext) return;
|
||||
return this.rollCheck(null, 'low', 'combat', null, null, weapon, null, attackContext ?? {});
|
||||
async rollWeaponAttack(weapon, attackContext = {}) {
|
||||
let context = { ...attackContext };
|
||||
if (weapon?.system?.useAmmo) {
|
||||
const ammoContext = await this.chooseWeaponAttackOptions(weapon, context);
|
||||
if (!ammoContext) return null;
|
||||
context = { ...context, ...ammoContext };
|
||||
} else {
|
||||
if (context.promptModifier) {
|
||||
const rollMod = await this.promptRollModifier(`${weapon.name} Attack Roll`);
|
||||
if (rollMod === null) return null;
|
||||
context.rollModifier = rollMod;
|
||||
}
|
||||
}
|
||||
return this.rollCheck(null, 'low', 'combat', null, null, weapon, null, context);
|
||||
}
|
||||
|
||||
async cycleWeaponFireMode(itemId, direction = 1) {
|
||||
@@ -4812,57 +5068,12 @@ export class MothershipActor extends Actor {
|
||||
|
||||
getSlaSpeciesMinimumWounds() {
|
||||
const species = String(this.system?.sla?.species?.value ?? "").trim();
|
||||
if (["Frother", "Shaktar", "Stormer 313 Malice", "Stormer 711 Xeno", "Stormer Vevaphon"].includes(species)) {
|
||||
if (["Frother", "Shaktar", "Stormer 313 Malice", "Stormer 711 Xeno"].includes(species)) {
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
isSlaVevaphon() {
|
||||
const species = String(this.system?.sla?.species?.value ?? "").trim();
|
||||
return species === "Stormer Vevaphon";
|
||||
}
|
||||
|
||||
getSlaVevaphonInstability() {
|
||||
return Math.max(0, Math.min(12, Number(this.system?.sla?.vevaphonInstability?.value ?? 0) || 0));
|
||||
}
|
||||
|
||||
getSlaVevaphonMorphForm() {
|
||||
return String(this.system?.sla?.morphForm?.value ?? "").trim() || "Brute Form";
|
||||
}
|
||||
|
||||
async setSlaVevaphonMorphForm(formName) {
|
||||
if (!this.isSlaVevaphon()) return null;
|
||||
const validForms = ["Brute Form", "Stalker Form", "Raptor Form"];
|
||||
const resolved = validForms.find((entry) => entry === formName) ?? formName;
|
||||
const currentInstability = this.getSlaVevaphonInstability();
|
||||
const newInstability = Math.min(12, currentInstability + 1);
|
||||
await this.update({
|
||||
"system.sla.morphForm.value": resolved,
|
||||
"system.sla.vevaphonInstability.value": newInstability
|
||||
});
|
||||
const instabilityWarning = newInstability >= 10
|
||||
? " ⚠ Instability critical — Morph Panic risk on failed Sanity save."
|
||||
: newInstability >= 6
|
||||
? " Instability elevated — minor morph effects active."
|
||||
: "";
|
||||
ui.notifications.info(`${this.name} shifts to ${resolved}. Instability: ${newInstability}/12.${instabilityWarning}`);
|
||||
return { morphForm: resolved, instability: newInstability };
|
||||
}
|
||||
|
||||
async adjustSlaVevaphonInstability(delta = 1) {
|
||||
if (!this.isSlaVevaphon()) return null;
|
||||
const current = this.getSlaVevaphonInstability();
|
||||
const next = Math.max(0, Math.min(12, current + delta));
|
||||
await this.update({ "system.sla.vevaphonInstability.value": next });
|
||||
if (next >= 12) {
|
||||
ui.notifications.warn(`${this.name} has reached maximum Instability (12). The Vevaphon is lost — immediate retirement or death.`);
|
||||
} else if (next >= 10) {
|
||||
ui.notifications.warn(`${this.name} — Instability ${next}/12. Morph Panic risk: failed Sanity save triggers a Morph Panic event.`);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
async enforceSlaSpeciesWounds() {
|
||||
if (this.type !== "character") return null;
|
||||
const minimumWounds = this.getSlaSpeciesMinimumWounds();
|
||||
@@ -4957,16 +5168,31 @@ export class MothershipActor extends Actor {
|
||||
return ["Ebon", "Brain Waster"].includes(species);
|
||||
}
|
||||
|
||||
isSlaVevaphon() {
|
||||
return String(this.system?.sla?.species?.value ?? "").trim() === "Stormer Vevaphon";
|
||||
}
|
||||
|
||||
async setSlaVevaphonMorphForm(formName) {
|
||||
if (!formName) return;
|
||||
await this.update({ "system.sla.morphForm.value": String(formName) });
|
||||
}
|
||||
|
||||
async adjustSlaVevaphonInstability(delta) {
|
||||
const current = Math.max(0, Math.min(12, Number(this.system?.sla?.vevaphonInstability?.value ?? 0) || 0));
|
||||
const next = Math.max(0, Math.min(12, current + (Number(delta) || 0)));
|
||||
await this.update({ "system.sla.vevaphonInstability.value": next });
|
||||
}
|
||||
|
||||
getSlaRestrictedEbbItemIds() {
|
||||
return this.items
|
||||
.filter((item) => {
|
||||
const name = String(item.name ?? "").trim();
|
||||
const sla = item.system?.sla ?? {};
|
||||
if (item.type === "ability") {
|
||||
// Vevaphon morph form abilities are NOT Ebb items — exclude them
|
||||
if (item.system?.sla?.morphForm === true) return false;
|
||||
// Also exclude by name so hand-placed morph abilities are safe even without the flag
|
||||
const morphNames = ["Brute Form", "Stalker Form", "Raptor Form"];
|
||||
if (morphNames.includes(name)) return false;
|
||||
// Only flag abilities that are explicitly Ebb abilities.
|
||||
// Morph forms (Vevaphon) get abilityType "morph" from the generator and are never removed.
|
||||
// morphForm flag is a belt-and-suspenders guard in case abilityType is missing.
|
||||
if (sla.morphForm || String(sla.abilityType ?? "ebb").trim() !== "ebb") return false;
|
||||
return true;
|
||||
}
|
||||
if (item.type !== "skill") return false;
|
||||
@@ -4987,13 +5213,20 @@ export class MothershipActor extends Actor {
|
||||
"system.sla.ebbRating.value": 0
|
||||
};
|
||||
await this.update(updateData);
|
||||
if (restrictedIds.length) {
|
||||
await this.deleteEmbeddedDocuments("Item", restrictedIds);
|
||||
const validIds = restrictedIds.filter(id => this.items.get(id) !== undefined);
|
||||
let removed = 0;
|
||||
if (validIds.length) {
|
||||
try {
|
||||
await this.deleteEmbeddedDocuments("Item", validIds);
|
||||
removed = validIds.length;
|
||||
} catch (err) {
|
||||
// Concurrent enforcement calls may have already deleted these items — safe to ignore
|
||||
}
|
||||
}
|
||||
if (notify && restrictedIds.length) {
|
||||
if (notify && removed) {
|
||||
ui.notifications.warn(`${this.name} is not an Ebb user. Restricted Ebb skills and abilities were removed.`);
|
||||
}
|
||||
return { removed: restrictedIds.length };
|
||||
return { removed };
|
||||
}
|
||||
|
||||
const currentMax = Math.max(0, Number(this.system?.sla?.flux?.max ?? 0) || 0);
|
||||
@@ -5344,8 +5577,6 @@ export class MothershipActor extends Actor {
|
||||
if (shouldPanic) {
|
||||
await this.rollTable("panicCheck", null, null, null, null, null, null);
|
||||
}
|
||||
const saveOutcome = saveResult ? (saveResult.success ? "Pass" : "Fail") : "n/a";
|
||||
await this.addSlaActivityLog(`Flux ${forcePanic ? "Panic forced" : "Save"} — Fear save ${saveOutcome}. Flux ${this.system?.sla?.flux?.value ?? 0}/${this.system?.sla?.flux?.max ?? 0}.${shouldPanic ? " Panic triggered." : ""}`);
|
||||
return { saveResult, state, panicTriggered: shouldPanic };
|
||||
}
|
||||
|
||||
@@ -5531,7 +5762,8 @@ export class MothershipActor extends Actor {
|
||||
insert: rollInsert,
|
||||
onlyDesc: true,
|
||||
swapNameDesc,
|
||||
swapName
|
||||
swapName,
|
||||
severityMeta: this.getSlaSeverityMeta({ severity: item?.system?.severity })
|
||||
};
|
||||
|
||||
const chatData = {
|
||||
|
||||
@@ -79,6 +79,9 @@ export class MothershipCreatureSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
if (data.data.system.settings == null) {
|
||||
data.data.system.settings = {};
|
||||
}
|
||||
if (data.data.system.slaNpc == null) {
|
||||
data.data.system.slaNpc = {};
|
||||
}
|
||||
data.data.system.settings.useCalm = game.settings.get("sla-mothership", "useCalm");
|
||||
data.data.system.settings.hideWeight = game.settings.get("sla-mothership", "hideWeight");
|
||||
data.data.system.settings.firstEdition = game.settings.get("sla-mothership", "firstEdition");
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { MothershipCreatureSheet } from "./creature-sheet.js";
|
||||
|
||||
/**
|
||||
* Extend MothershipCreatureSheet for the streamlined NPC (creature) actor sheet.
|
||||
* Displays a single-page, tab-free dashboard with core stats and equipment.
|
||||
* @extends {MothershipCreatureSheet}
|
||||
*/
|
||||
export class MothershipNpcSheet extends MothershipCreatureSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
const options = {
|
||||
classes: ["mosh", "sheet", "actor", "creature", "npc-sheet"],
|
||||
template: "systems/sla-mothership/templates/actor/npc-sheet.html",
|
||||
width: 720,
|
||||
height: 680,
|
||||
tabs: [], // Disable tabs
|
||||
submitOnChange: true
|
||||
};
|
||||
|
||||
return foundry.utils.mergeObject(super.defaultOptions, options);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData() {
|
||||
const data = await super.getData();
|
||||
|
||||
// Limit the displayed skills to a maximum of 5
|
||||
if (data.skills) {
|
||||
data.skills = data.skills.slice(0, 5);
|
||||
}
|
||||
|
||||
// Flag to show/hide the "Add Skill" button based on 5-skill constraint
|
||||
data.showAddSkill = (!data.skills || data.skills.length < 5);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
// Custom Wound Roll Button Click
|
||||
html.find('.npc-wound-roll').click(async ev => {
|
||||
ev.preventDefault();
|
||||
await this.actor.chooseSlaWoundTable();
|
||||
});
|
||||
|
||||
// Custom Panic Roll Button Click
|
||||
html.find('.npc-panic-roll').click(async ev => {
|
||||
ev.preventDefault();
|
||||
await this.actor.rollTable("panicCheck", null, null, null, null, null, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,22 @@
|
||||
import { SLADrugSystem } from "../sla-drug-system.js";
|
||||
|
||||
function isAmmoPurchaseItem(itemData = {}) {
|
||||
const system = itemData?.system ?? {};
|
||||
const sla = system?.sla ?? {};
|
||||
const name = String(itemData?.name ?? "").trim().toLowerCase();
|
||||
const category = String(sla.category ?? "").trim().toLowerCase();
|
||||
const calibre = String(sla.calibre ?? "").trim();
|
||||
const ammoTag = String(sla.ammoTag ?? "").trim();
|
||||
return category === "ammunition" || Boolean((calibre && ammoTag) || name.startsWith("ammo:"));
|
||||
}
|
||||
|
||||
function formatSlaTimestamp() {
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "short",
|
||||
timeStyle: "short"
|
||||
}).format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the basic ItemSheet with some very simple modifications
|
||||
* @extends {ItemSheet}
|
||||
@@ -128,11 +145,38 @@ export class MothershipItemSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
|
||||
async _updateObject(event, formData) {
|
||||
const updateData = foundry.utils.expandObject(formData);
|
||||
const currentQty = Math.max(0, Number(this.item.system?.quantity ?? 0) || 0);
|
||||
if (Object.prototype.hasOwnProperty.call(updateData?.system ?? {}, "weight")) {
|
||||
const parsed = Number(updateData.system.weight ?? 0) || 0;
|
||||
updateData.system.weight = Math.round(parsed * 10) / 10;
|
||||
}
|
||||
await this.item.update(updateData, { diff: false });
|
||||
|
||||
const nextQtyRaw = updateData?.system?.quantity;
|
||||
const nextQty = nextQtyRaw === undefined ? currentQty : Math.max(0, Number(nextQtyRaw ?? 0) || 0);
|
||||
const increase = Math.max(0, nextQty - currentQty);
|
||||
const actor = this.item.parent;
|
||||
if (!increase || actor?.documentName !== "Actor") return;
|
||||
|
||||
const unitCost = Number(updateData?.system?.cost ?? this.item.system?.cost ?? 0) || 0;
|
||||
const total = Math.round(unitCost * increase * 100) / 100;
|
||||
if (!total) return;
|
||||
|
||||
const currentCredits = Number(actor.system?.credits?.value ?? 0) || 0;
|
||||
const newCredits = Math.round((currentCredits - total) * 100) / 100;
|
||||
const updateActorData = { "system.credits.value": newCredits };
|
||||
|
||||
if (isAmmoPurchaseItem(this.item.toObject())) {
|
||||
const stamp = formatSlaTimestamp();
|
||||
const currentLedger = String(actor.system?.sla?.ammoLedger?.value ?? "").trim();
|
||||
const entry = `[${stamp}] PURCHASE | ${this.item.name ?? "Ammo"} | ${increase} round${increase === 1 ? "" : "s"} | -${total} cR | balance ${newCredits} cR`;
|
||||
const ledgerLines = [entry, ...currentLedger.split("\n").filter(Boolean)].slice(0, 60);
|
||||
updateActorData["system.sla.ammoLedger.value"] = ledgerLines.join("\n");
|
||||
}
|
||||
|
||||
await actor.update(updateActorData);
|
||||
ui.notifications.info(`${actor.name}: deducted ${total} cR for ${increase} more ${this.item.name ?? "item"}. Credits now ${newCredits} cR.`);
|
||||
await actor.addSlaActivityLog?.(`Purchased +${increase} ${this.item.name ?? "item"} for ${total} cR. Credits now ${newCredits} cR.`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { MothershipActor } from "./actor/actor.js";
|
||||
import { MothershipActorSheet, MothershipActorSheetDossier } from "./actor/actor-sheet.js";
|
||||
import { MothershipCreatureSheet } from "./actor/creature-sheet.js";
|
||||
import { MothershipNpcSheet } from "./actor/npc-sheet.js";
|
||||
import { MothershipShipSheet } from "./actor/ship-sheet.js";
|
||||
import { MothershipShipSheetSBT } from "./actor/ship-sheet-sbt.js";
|
||||
|
||||
@@ -12,6 +13,7 @@ import { MothershipSkillSheet } from "./item/skill-sheet.js";
|
||||
import { SLADrugSystem } from "./sla-drug-system.js";
|
||||
import { slaDebug } from "./logger.js";
|
||||
import { SLAMothershipGenerator } from "./windows/sla-character-generator.js";
|
||||
import { SLANpcGeneratorApp, generateSlaNpc } from "./windows/sla-npc-generator.js";
|
||||
import { SLAWorldToolsApp, installSlaSidebarButtons } from "./windows/sla-world-tools.js";
|
||||
|
||||
import {
|
||||
@@ -50,6 +52,8 @@ Hooks.once('init', async function () {
|
||||
closeDrug: (actor, itemId, drug = "") => SLADrugSystem.closeDrug({ actor, itemId, drug }),
|
||||
restartDrugReminders: () => SLADrugSystem.startReminderLoop(),
|
||||
openGenerator: (actor = null, options = {}) => SLAMothershipGenerator.open(actor, options),
|
||||
openNpcDesk: (options = {}) => SLANpcGeneratorApp.open(options),
|
||||
createNpc: (state = {}) => generateSlaNpc(state),
|
||||
createRandomOperative: (options = {}) => SLAMothershipGenerator.createRandomOperative(options),
|
||||
createStarterSquad: (options = {}) => SLAMothershipGenerator.createStarterSquad(options),
|
||||
openTools: () => SLAWorldToolsApp.open(),
|
||||
@@ -78,7 +82,8 @@ Hooks.once('init', async function () {
|
||||
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipActorSheet, {types: ['character'], makeDefault: true});
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipActorSheetDossier, {types: ['character'], makeDefault: false, label: "SLA Dossier"});
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipCreatureSheet, {types: ['creature'], makeDefault: false});
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipNpcSheet, {types: ['creature'], makeDefault: true, label: "SLA Streamlined NPC Sheet"});
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipCreatureSheet, {types: ['creature'], makeDefault: false, label: "SLA Standard Creature Sheet"});
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipShipSheetSBT, {types: ['ship'], makeDefault: true});
|
||||
foundry.documents.collections.Actors.registerSheet("sla-mothership", MothershipShipSheet, {types: ['ship'], makeDefault: false});
|
||||
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
||||
@@ -144,11 +149,38 @@ Hooks.once('init', async function () {
|
||||
await SLADrugSystem.handleEffectDeleted(effect, options);
|
||||
});
|
||||
|
||||
Hooks.on("createItem", async (item) => {
|
||||
// Debounce map: actorId → pending timeout handle.
|
||||
// Prevents enforceSlaEbbEligibility from being called once per item when the
|
||||
// character generator creates many items in rapid succession (each createItem
|
||||
// hook call would otherwise race to delete the same Ebb items concurrently).
|
||||
const _pendingEbbEnforcement = new Map();
|
||||
Hooks.on("createItem", async (item, options, userId) => {
|
||||
// ── Unarmed Combat Auto-Skill Drop ──
|
||||
const actor = item.parent;
|
||||
if (actor && actor.documentName === "Actor" && item.type === "weapon" && String(item.name).trim().toLowerCase() === "unarmed combat") {
|
||||
const hasSkill = actor.items.some(i => i.type === "skill" && String(i.name).trim().toLowerCase() === "unarmed combat");
|
||||
if (!hasSkill) {
|
||||
await actor.createEmbeddedDocuments("Item", [{
|
||||
name: "Unarmed Combat",
|
||||
type: "skill",
|
||||
img: "icons/svg/fist.svg",
|
||||
system: {
|
||||
rank: "Trained",
|
||||
bonus: 10,
|
||||
sla: { category: "combat", skillFamily: "", source: "Unarmed Item Drop" }
|
||||
}
|
||||
}]);
|
||||
ui.notifications.info(`Added 'Unarmed Combat' skill to ${actor.name}.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!actor || actor.type !== "character" || typeof actor.enforceSlaEbbEligibility !== "function") return;
|
||||
if (actor.isSlaEbbUser?.()) return;
|
||||
await actor.enforceSlaEbbEligibility({ notify: true, refillFlux: false });
|
||||
if (_pendingEbbEnforcement.has(actor.id)) clearTimeout(_pendingEbbEnforcement.get(actor.id));
|
||||
_pendingEbbEnforcement.set(actor.id, setTimeout(async () => {
|
||||
_pendingEbbEnforcement.delete(actor.id);
|
||||
await actor.enforceSlaEbbEligibility({ notify: true, refillFlux: false });
|
||||
}, 300));
|
||||
});
|
||||
|
||||
Hooks.on("updateActor", async (actor, changes, options) => {
|
||||
@@ -175,16 +207,37 @@ Hooks.once('init', async function () {
|
||||
|
||||
Hooks.on("renderActorDirectory", (app, html) => {
|
||||
installSlaSidebarButtons(app, html);
|
||||
if (!game.user?.isGM) enforceSlaPlayerDirectoryRestrictions("actors", html);
|
||||
});
|
||||
|
||||
Hooks.on("renderSidebarTab", (app, html) => {
|
||||
const isActorsTab = app?.tabName === "actors" || app?.options?.id === "actors";
|
||||
if (!isActorsTab) return;
|
||||
installSlaSidebarButtons(app, html);
|
||||
if (isActorsTab) installSlaSidebarButtons(app, html);
|
||||
if (!game.user?.isGM) {
|
||||
hideSlaRestrictedSidebarTabs();
|
||||
enforceSlaPlayerSidebarTabRestrictions(app, html);
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.on("renderSceneDirectory", (_app, html) => {
|
||||
if (!game.user?.isGM) enforceSlaPlayerDirectoryRestrictions("scenes", html);
|
||||
});
|
||||
|
||||
Hooks.on("renderJournalDirectory", (_app, html) => {
|
||||
if (!game.user?.isGM) enforceSlaPlayerDirectoryRestrictions("journal", html);
|
||||
});
|
||||
|
||||
Hooks.on("renderRollTableDirectory", (_app, html) => {
|
||||
if (!game.user?.isGM) enforceSlaPlayerDirectoryRestrictions("tables", html);
|
||||
});
|
||||
|
||||
Hooks.on("renderCompendiumDirectory", (_app, html) => {
|
||||
if (!game.user?.isGM) enforceSlaPlayerDirectoryRestrictions("compendium", html);
|
||||
});
|
||||
|
||||
Hooks.on("renderCombatTracker", (app, html) => {
|
||||
installSlaCombatTrackerControls(app, html);
|
||||
if (!game.user?.isGM) enforceSlaPlayerDirectoryRestrictions("combat", html);
|
||||
});
|
||||
|
||||
Hooks.on("updateCombat", async (combat, changed) => {
|
||||
@@ -247,9 +300,62 @@ Hooks.once("ready", async function () {
|
||||
}
|
||||
|
||||
patchSlaInitiativeSystem();
|
||||
if (!game.user?.isGM) hideSlaRestrictedSidebarTabs();
|
||||
|
||||
// GM Conditions Summary — whisper to all GMs every 30 minutes
|
||||
if (game.user?.isGM) {
|
||||
setInterval(_sendGMConditionsSummary, 30 * 60 * 1000);
|
||||
console.log("SLA MOTHERSHIP | GM conditions summary timer started (every 30 minutes).");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Scans all actors for active condition items and whispers a summary to GM(s).
|
||||
* Fires every 30 minutes when logged in as GM.
|
||||
*/
|
||||
function _sendGMConditionsSummary() {
|
||||
if (!game.user?.isGM) return;
|
||||
|
||||
const rows = [];
|
||||
for (const actor of game.actors) {
|
||||
const conditions = actor.items?.filter(i => i.type === "condition") ?? [];
|
||||
if (conditions.length === 0) continue;
|
||||
const conditionList = conditions.map(c => {
|
||||
const sev = c.system?.severity ?? "";
|
||||
return `<span style="color:#ff4444;font-weight:bold;">${c.name}${sev ? ` (${sev})` : ""}</span>`;
|
||||
}).join(", ");
|
||||
rows.push(`<tr><td style="padding:2px 8px;font-weight:bold;color:#eee;">${actor.name}</td><td style="padding:2px 8px;">${conditionList}</td></tr>`);
|
||||
}
|
||||
|
||||
let content;
|
||||
if (rows.length === 0) {
|
||||
content = `<div style="font-family:monospace;color:#888;padding:4px 8px;">
|
||||
<strong style="color:#ff4444;">⚕ CONDITIONS REPORT</strong> — No active conditions.
|
||||
</div>`;
|
||||
} else {
|
||||
content = `<div style="font-family:monospace;padding:4px 0;">
|
||||
<div style="background:#1a0000;border:1px solid #8b0000;border-radius:4px;padding:4px 8px;margin-bottom:6px;">
|
||||
<strong style="color:#ff4444;font-size:1em;">⚕ CONDITIONS REPORT</strong>
|
||||
<span style="color:#888;font-size:0.8em;margin-left:8px;">${new Date().toLocaleTimeString()}</span>
|
||||
</div>
|
||||
<table style="width:100%;border-collapse:collapse;">
|
||||
<thead><tr style="border-bottom:1px solid #8b0000;">
|
||||
<th style="padding:2px 8px;color:#aaa;text-align:left;font-size:0.8em;">ACTOR</th>
|
||||
<th style="padding:2px 8px;color:#aaa;text-align:left;font-size:0.8em;">CONDITIONS</th>
|
||||
</tr></thead>
|
||||
<tbody>${rows.join("")}</tbody>
|
||||
</table>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
ChatMessage.create({
|
||||
content,
|
||||
whisper: ChatMessage.getWhisperRecipients("GM"),
|
||||
speaker: { alias: "SLA System" }
|
||||
});
|
||||
}
|
||||
|
||||
Hooks.on("renderChatMessageHTML", (app, html) => {
|
||||
const root = html?.[0] ?? html;
|
||||
if (!root?.querySelectorAll) return;
|
||||
@@ -272,6 +378,129 @@ Hooks.on("renderChatMessageHTML", (app, html) => {
|
||||
await actor.rollSlaWoundEffect(effectKey, modifier);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Critical Hit? Button Handler ──
|
||||
root.querySelectorAll(".sla-crit-hit-btn").forEach((button) => {
|
||||
button.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const actorId = button.dataset.actorId;
|
||||
const itemId = button.dataset.itemId;
|
||||
const actor = actorId ? game.actors?.get(actorId) : null;
|
||||
if (!actor) {
|
||||
ui.notifications.warn("The actor for this critical hit could not be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
const weapon = itemId ? actor.items.get(itemId) : null;
|
||||
|
||||
// Determine wound setting key based on weapon and damage type
|
||||
let settingKey = 'table1eWoundBluntForce';
|
||||
let tableLabel = 'Blunt Force';
|
||||
|
||||
if (weapon) {
|
||||
const name = String(weapon.name ?? "").toLowerCase();
|
||||
const damageType = String(weapon.system?.sla?.damageType ?? "").toLowerCase();
|
||||
|
||||
if (damageType.includes("blunt") || damageType.includes("impact")) {
|
||||
settingKey = 'table1eWoundBluntForce';
|
||||
tableLabel = 'Blunt Force';
|
||||
} else if (damageType.includes("penetrating") || damageType.includes("pierce") || damageType.includes("stab") || damageType.includes("bullet") || damageType.includes("shot")) {
|
||||
settingKey = 'table1eWoundGunshot';
|
||||
tableLabel = 'Gunshot';
|
||||
} else if (damageType.includes("slash") || damageType.includes("rend") || damageType.includes("bleed") || damageType.includes("cut")) {
|
||||
settingKey = 'table1eWoundBleeding';
|
||||
tableLabel = 'Bleeding';
|
||||
} else if (damageType.includes("fire") || damageType.includes("explos") || damageType.includes("acid") || damageType.includes("burn")) {
|
||||
settingKey = 'table1eWoundFireExplosives';
|
||||
tableLabel = 'Fire & Explosives';
|
||||
} else if (name.includes("pistol") || name.includes("smg") || name.includes("rifle") || name.includes("shotgun") || name.includes("blunderbuss") || name.includes("gun") || name.includes("harpoon") || name.includes("bullet") || name.includes("projectile") || name.includes("crossbow")) {
|
||||
settingKey = 'table1eWoundGunshot';
|
||||
tableLabel = 'Gunshot';
|
||||
} else if (name.includes("machete") || name.includes("cleaver") || name.includes("whip") || name.includes("blade") || name.includes("knife") || name.includes("sword") || name.includes("claws") || name.includes("bite") || name.includes("razor") || name.includes("teeth")) {
|
||||
settingKey = 'table1eWoundBleeding';
|
||||
tableLabel = 'Bleeding';
|
||||
} else if (name.includes("club") || name.includes("pipe") || name.includes("hammer") || name.includes("prod") || name.includes("unarmed") || name.includes("fist") || name.includes("strike") || name.includes("blunt") || name.includes("brawl") || name.includes("cuff")) {
|
||||
settingKey = 'table1eWoundBluntForce';
|
||||
tableLabel = 'Blunt Force';
|
||||
} else if (name.includes("bomb") || name.includes("acid") || name.includes("spit") || name.includes("fire") || name.includes("flame") || name.includes("grenade") || name.includes("explosive")) {
|
||||
settingKey = 'table1eWoundFireExplosives';
|
||||
tableLabel = 'Fire & Explosives';
|
||||
}
|
||||
}
|
||||
|
||||
const tableId = game.settings.get('sla-mothership', settingKey);
|
||||
if (!tableId) {
|
||||
ui.notifications.warn(`No wound table is configured for ${tableLabel}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve the table
|
||||
let resolved = game.tables.get(tableId) || game.tables.getName(tableId);
|
||||
if (!resolved) {
|
||||
for (const pack of game.packs) {
|
||||
if (pack.metadata.type === "RollTable") {
|
||||
const index = await pack.getIndex();
|
||||
const entry = index.find(e => e.id === tableId || e.name === tableId || e.name === `${tableLabel} Wound` || e.name === tableLabel.replace(/&/g, "and"));
|
||||
if (entry) {
|
||||
resolved = await pack.getDocument(entry._id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!resolved) {
|
||||
ui.notifications.warn(`The ${tableLabel} wound table could not be found.`);
|
||||
return;
|
||||
}
|
||||
|
||||
await actor.rollTable(resolved.uuid ?? resolved.id ?? tableId, resolved.formula ?? "1d10", "low", true, false, null, null);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Critical Success Option Button Handler ──
|
||||
root.querySelectorAll(".sla-crit-option-btn").forEach((button) => {
|
||||
button.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const actorId = button.dataset.actorId;
|
||||
const optionText = button.dataset.optionText;
|
||||
const actor = actorId ? game.actors?.get(actorId) : null;
|
||||
const actorName = actor ? actor.name : "An operative";
|
||||
|
||||
const chatContent = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/sla-mothership/templates/chat/sla-critical-selection.html',
|
||||
{
|
||||
actorName: actorName,
|
||||
img: actor?.img ?? 'icons/svg/mystery-man.svg',
|
||||
optionText: optionText
|
||||
}
|
||||
);
|
||||
|
||||
await ChatMessage.create({
|
||||
user: game.user.id,
|
||||
content: chatContent,
|
||||
speaker: ChatMessage.getSpeaker({ actor: actor })
|
||||
});
|
||||
|
||||
// Disable all options in the card
|
||||
const container = button.closest(".sla-crit-success-options");
|
||||
if (container) {
|
||||
container.querySelectorAll(".sla-crit-option-btn").forEach(btn => {
|
||||
btn.disabled = true;
|
||||
btn.style.opacity = 0.6;
|
||||
btn.style.cursor = "default";
|
||||
if (btn === button) {
|
||||
btn.style.background = "#0f300f";
|
||||
btn.style.border = "1px solid #1ebd1e";
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//add custom damage dice for MOSH
|
||||
@@ -1254,33 +1483,19 @@ export function formatCreditsNumber(num) {
|
||||
// SLA Industries Pause Screen Animation
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
let slaPauseRefreshHandle = null;
|
||||
|
||||
function injectSlaPauseAnimation() {
|
||||
const pauseEl = document.querySelector('#pause');
|
||||
if (!pauseEl) return;
|
||||
|
||||
// Don't inject twice
|
||||
if (pauseEl.querySelector('.sla-pause-root')) return;
|
||||
|
||||
// Aggressively hide ALL of Foundry's default pause content
|
||||
// Hide every direct child that isn't our injected element
|
||||
Array.from(pauseEl.children).forEach(child => {
|
||||
child.style.setProperty('display', 'none', 'important');
|
||||
});
|
||||
// Also kill any descendant with animation or image content
|
||||
pauseEl.querySelectorAll('figure, img, svg, h3, p, .fas, .fa-cog, canvas').forEach(el => {
|
||||
el.style.setProperty('display', 'none', 'important');
|
||||
});
|
||||
document.body?.classList.add("sla-pause-active");
|
||||
if (document.querySelector('.sla-pause-root')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const svgHTML = `
|
||||
<div class="sla-pause-root" aria-label="SLA Industries – Game Paused">
|
||||
<svg
|
||||
class="sla-pause-svg"
|
||||
viewBox="-120 -120 240 260"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
role="img"
|
||||
>
|
||||
<div class="sla-pause-stage">
|
||||
<svg class="sla-pause-svg" viewBox="-120 -120 240 260" xmlns="http://www.w3.org/2000/svg" role="img">
|
||||
<defs>
|
||||
<!-- Red glow filter for the logo and satellites -->
|
||||
<filter id="sla-glow-red" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur stdDeviation="3.5" result="blur"/>
|
||||
<feMerge>
|
||||
@@ -1288,7 +1503,6 @@ function injectSlaPauseAnimation() {
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<!-- Subtle glow for rings -->
|
||||
<filter id="sla-glow-ring" x="-30%" y="-30%" width="160%" height="160%">
|
||||
<feGaussianBlur stdDeviation="1.5" result="blur"/>
|
||||
<feMerge>
|
||||
@@ -1296,23 +1510,17 @@ function injectSlaPauseAnimation() {
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<!-- Radial gradient for background disc -->
|
||||
<radialGradient id="sla-bg-grad" cx="50%" cy="50%" r="50%">
|
||||
<stop offset="0%" stop-color="#1a0000" stop-opacity="0.95"/>
|
||||
<stop offset="100%" stop-color="#000000" stop-opacity="0.0"/>
|
||||
</radialGradient>
|
||||
<!-- Clip for the inner content -->
|
||||
<clipPath id="sla-clip-outer">
|
||||
<circle cx="0" cy="0" r="108"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<!-- Ambient background disc -->
|
||||
<circle cx="0" cy="0" r="108" fill="url(#sla-bg-grad)"/>
|
||||
|
||||
<!-- ── Outer ring (clockwise) ── -->
|
||||
<circle cx="0" cy="0" r="108" fill="url(#sla-bg-grad)" class="sla-pause-core-glow"/>
|
||||
<g class="sla-ring-outer">
|
||||
<!-- Dashed orbit path -->
|
||||
<animateTransform attributeName="transform" type="rotate" from="0 0 0" to="360 0 0" dur="18s" repeatCount="indefinite"/>
|
||||
<circle cx="0" cy="0" r="90"
|
||||
fill="none"
|
||||
stroke="#8b1a1a"
|
||||
@@ -1321,11 +1529,9 @@ function injectSlaPauseAnimation() {
|
||||
opacity="0.7"
|
||||
filter="url(#sla-glow-ring)"
|
||||
/>
|
||||
<!-- 3 red satellite dots at 0°, 120°, 240° -->
|
||||
<circle cx="0" cy="-90" r="5" fill="#cc2222" filter="url(#sla-glow-red)" class="sla-sat"/>
|
||||
<circle cx="77.9" cy="45" r="5" fill="#cc2222" filter="url(#sla-glow-red)" class="sla-sat"/>
|
||||
<circle cx="-77.9" cy="45" r="5" fill="#cc2222" filter="url(#sla-glow-red)" class="sla-sat"/>
|
||||
<!-- Thin tick marks every 30° on outer ring -->
|
||||
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(0)"/>
|
||||
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(30)"/>
|
||||
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(60)"/>
|
||||
@@ -1339,9 +1545,8 @@ function injectSlaPauseAnimation() {
|
||||
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(300)"/>
|
||||
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(330)"/>
|
||||
</g>
|
||||
|
||||
<!-- ── Inner ring (counter-clockwise) ── -->
|
||||
<g class="sla-ring-inner">
|
||||
<animateTransform attributeName="transform" type="rotate" from="360 0 0" to="0 0 0" dur="13s" repeatCount="indefinite"/>
|
||||
<circle cx="0" cy="0" r="62"
|
||||
fill="none"
|
||||
stroke="#6b1010"
|
||||
@@ -1350,15 +1555,11 @@ function injectSlaPauseAnimation() {
|
||||
opacity="0.6"
|
||||
filter="url(#sla-glow-ring)"
|
||||
/>
|
||||
<!-- 3 smaller orange-red dots at 60°, 180°, 300° offset for variety -->
|
||||
<circle cx="53.7" cy="-31" r="3.5" fill="#dd4422" filter="url(#sla-glow-red)" class="sla-sat-inner"/>
|
||||
<circle cx="-53.7" cy="-31" r="3.5" fill="#dd4422" filter="url(#sla-glow-red)" class="sla-sat-inner"/>
|
||||
<circle cx="0" cy="62" r="3.5" fill="#dd4422" filter="url(#sla-glow-red)" class="sla-sat-inner"/>
|
||||
</g>
|
||||
|
||||
<!-- ── Central "SLA" logotype ── -->
|
||||
<g filter="url(#sla-glow-red)">
|
||||
<!-- Hexagonal backing plate -->
|
||||
<g filter="url(#sla-glow-red)" class="sla-pause-logo-core">
|
||||
<polygon
|
||||
points="0,-38 33,-19 33,19 0,38 -33,19 -33,-19"
|
||||
fill="#1a0000"
|
||||
@@ -1366,7 +1567,6 @@ function injectSlaPauseAnimation() {
|
||||
stroke-width="1.2"
|
||||
opacity="0.9"
|
||||
/>
|
||||
<!-- SLA text -->
|
||||
<text
|
||||
x="0" y="14"
|
||||
text-anchor="middle"
|
||||
@@ -1378,35 +1578,27 @@ function injectSlaPauseAnimation() {
|
||||
class="sla-pause-logo-text"
|
||||
>SLA</text>
|
||||
</g>
|
||||
|
||||
<!-- ── Thin separator lines ── -->
|
||||
<line x1="-70" y1="48" x2="70" y2="48" stroke="#8b1a1a" stroke-width="0.5" opacity="0.7"/>
|
||||
|
||||
<!-- ── "STAND BY" label ── -->
|
||||
<text
|
||||
x="0" y="70"
|
||||
x="0" y="68"
|
||||
text-anchor="middle"
|
||||
font-family="'Oswald', 'Courier New', monospace"
|
||||
font-size="13"
|
||||
font-weight="400"
|
||||
letter-spacing="5"
|
||||
fill="#cc4444"
|
||||
font-size="11.5"
|
||||
font-weight="500"
|
||||
letter-spacing="3.2"
|
||||
fill="#ff7b7b"
|
||||
class="sla-pause-standby"
|
||||
>STAND BY</text>
|
||||
|
||||
<!-- ── "SLA INDUSTRIES" footer text ── -->
|
||||
>PLEASE STAND BY</text>
|
||||
<text
|
||||
x="0" y="95"
|
||||
x="0" y="94"
|
||||
text-anchor="middle"
|
||||
font-family="'Oswald', 'Arial Narrow', sans-serif"
|
||||
font-size="7"
|
||||
font-size="8"
|
||||
font-weight="300"
|
||||
letter-spacing="3"
|
||||
fill="#661111"
|
||||
opacity="0.85"
|
||||
fill="#b13b3b"
|
||||
opacity="0.92"
|
||||
>SLA INDUSTRIES</text>
|
||||
|
||||
<!-- ── Scanning line sweep ── -->
|
||||
<line
|
||||
x1="0" y1="-90" x2="0" y2="0"
|
||||
stroke="#ff2222"
|
||||
@@ -1415,37 +1607,138 @@ function injectSlaPauseAnimation() {
|
||||
class="sla-pause-scan"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>`;
|
||||
document.body?.insertAdjacentHTML('beforeend', svgHTML);
|
||||
}
|
||||
|
||||
// Inject directly into the pause element (not into figure, which we hid)
|
||||
pauseEl.insertAdjacentHTML('beforeend', svgHTML);
|
||||
function removeSlaPauseAnimation() {
|
||||
document.querySelector(".sla-pause-root")?.remove();
|
||||
document.body?.classList.remove("sla-pause-active");
|
||||
}
|
||||
|
||||
function queueSlaPauseRefresh(delay = 0) {
|
||||
window.clearTimeout(slaPauseRefreshHandle);
|
||||
slaPauseRefreshHandle = window.setTimeout(() => {
|
||||
if (!game?.paused) return;
|
||||
injectSlaPauseAnimation();
|
||||
}, delay);
|
||||
}
|
||||
|
||||
Hooks.once('ready', () => {
|
||||
// Inject if game is already paused on load
|
||||
if (game.paused) injectSlaPauseAnimation();
|
||||
});
|
||||
|
||||
// Use the pauseGame hook exclusively — don't use a MutationObserver
|
||||
// which could fight Foundry's own show/hide logic on the #pause element.
|
||||
Hooks.on('pauseGame', (paused) => {
|
||||
if (paused) {
|
||||
// Two-frame delay — Foundry renders the pause figure asynchronously
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => injectSlaPauseAnimation()));
|
||||
} else {
|
||||
// On unpause: remove our injected content so it can be re-injected cleanly next time
|
||||
const slaRoot = document.querySelector('#pause .sla-pause-root');
|
||||
if (slaRoot) slaRoot.remove();
|
||||
// Restore Foundry's original pause children (they were hidden inline, unhide them)
|
||||
const pauseEl = document.querySelector('#pause');
|
||||
if (pauseEl) {
|
||||
pauseEl.querySelectorAll(':scope > *:not(.sla-pause-root)').forEach(child => {
|
||||
child.style.removeProperty('display');
|
||||
});
|
||||
}
|
||||
if (game.paused) {
|
||||
queueSlaPauseRefresh(0);
|
||||
queueSlaPauseRefresh(60);
|
||||
queueSlaPauseRefresh(180);
|
||||
}
|
||||
});
|
||||
|
||||
Hooks.on('pauseGame', (paused) => {
|
||||
if (paused) {
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => injectSlaPauseAnimation()));
|
||||
queueSlaPauseRefresh(0);
|
||||
queueSlaPauseRefresh(60);
|
||||
queueSlaPauseRefresh(180);
|
||||
queueSlaPauseRefresh(360);
|
||||
} else {
|
||||
removeSlaPauseAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
function getSlaHtmlRoot(html) {
|
||||
return html instanceof HTMLElement ? html : html?.[0] ?? null;
|
||||
}
|
||||
|
||||
function hideSlaRestrictedSidebarTabs() {
|
||||
[
|
||||
"#sidebar-tabs [data-tab='tables']",
|
||||
"#sidebar-tabs [aria-controls='tables']",
|
||||
"#sidebar-tabs [data-tab='compendium']",
|
||||
"#sidebar-tabs [aria-controls='compendium']"
|
||||
].forEach((selector) => {
|
||||
document.querySelectorAll(selector).forEach((el) => {
|
||||
el.closest("li")?.remove();
|
||||
if (el instanceof HTMLElement) el.remove();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeSlaElements(root, selectors = []) {
|
||||
selectors.forEach((selector) => {
|
||||
root.querySelectorAll(selector).forEach((el) => el.remove());
|
||||
});
|
||||
}
|
||||
|
||||
function pruneEmptySlaFolders(root) {
|
||||
const folders = Array.from(root.querySelectorAll(".directory-item.folder"));
|
||||
folders.reverse().forEach((folder) => {
|
||||
const visibleDocuments = Array.from(folder.querySelectorAll(".directory-item.document, li.document")).filter((node) => node.offsetParent !== null);
|
||||
const visibleFolders = Array.from(folder.querySelectorAll(":scope > .directory-list > .directory-item.folder, :scope > ol > li.folder")).filter((node) => node.offsetParent !== null);
|
||||
if (!visibleDocuments.length && !visibleFolders.length) folder.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function shouldShowSlaPlayerJournal(entry) {
|
||||
if (!entry) return false;
|
||||
const name = String(entry.name ?? "").trim();
|
||||
if (/^operative handbook$/i.test(name)) return true;
|
||||
if (entry.getFlag?.("sla-mothership", "playerVisible") === true) return true;
|
||||
return entry.testUserPermission?.(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) ?? false;
|
||||
}
|
||||
|
||||
function filterSlaJournalDirectory(root) {
|
||||
const rows = Array.from(root.querySelectorAll("[data-entry-id], [data-document-id]"));
|
||||
rows.forEach((row) => {
|
||||
const id = row.dataset.entryId ?? row.dataset.documentId;
|
||||
if (!id) return;
|
||||
const entry = game.journal?.get?.(id);
|
||||
if (!shouldShowSlaPlayerJournal(entry)) row.remove();
|
||||
});
|
||||
pruneEmptySlaFolders(root);
|
||||
}
|
||||
|
||||
function enforceSlaPlayerDirectoryRestrictions(kind, html) {
|
||||
const root = getSlaHtmlRoot(html);
|
||||
if (!root || game.user?.isGM) return;
|
||||
|
||||
removeSlaElements(root, [
|
||||
".directory-header .header-actions",
|
||||
".directory-header .action-buttons",
|
||||
".sla-sidebar-actions",
|
||||
".qbm-scene-directory-actions",
|
||||
".qbm-launch",
|
||||
".sla-world-tools-launch",
|
||||
".sla-create-operative",
|
||||
".sla-create-random-operative",
|
||||
".sla-refresh-content",
|
||||
".sla-gear-cache-open",
|
||||
".sla-briefing-desk-open",
|
||||
".sla-bpn-dispatch-open",
|
||||
".sla-npc-director-open",
|
||||
".sla-npc-director-actor-open",
|
||||
".sla-ops-clock-open",
|
||||
".npp-generate-sidebar-btn"
|
||||
]);
|
||||
|
||||
if (kind === "journal") {
|
||||
filterSlaJournalDirectory(root);
|
||||
}
|
||||
|
||||
if (kind === "tables" || kind === "compendium") {
|
||||
root.innerHTML = "";
|
||||
}
|
||||
}
|
||||
|
||||
function enforceSlaPlayerSidebarTabRestrictions(app, html) {
|
||||
const tabName = app?.tabName ?? app?.options?.id ?? "";
|
||||
if (tabName === "actors") return enforceSlaPlayerDirectoryRestrictions("actors", html);
|
||||
if (tabName === "scenes") return enforceSlaPlayerDirectoryRestrictions("scenes", html);
|
||||
if (tabName === "journal") return enforceSlaPlayerDirectoryRestrictions("journal", html);
|
||||
if (tabName === "tables") return enforceSlaPlayerDirectoryRestrictions("tables", html);
|
||||
if (tabName === "compendium") return enforceSlaPlayerDirectoryRestrictions("compendium", html);
|
||||
if (tabName === "combat") return enforceSlaPlayerDirectoryRestrictions("combat", html);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SLA Industries — UI Icon Injection
|
||||
// Replaces Foundry's Font Awesome icons in the sidebar and scene controls
|
||||
|
||||
@@ -904,6 +904,13 @@ export class SLAMothershipGenerator extends FormApplication {
|
||||
const worldItem = findWorldItem(morph.name, "ability");
|
||||
if (worldItem) {
|
||||
const embedded = toEmbeddedData(worldItem);
|
||||
// abilityType "morph" is schema-defined and guaranteed to be stored —
|
||||
// this prevents the Ebb enforcement sweep from ever deleting morph forms.
|
||||
embedded.system ??= {};
|
||||
embedded.system.sla ??= {};
|
||||
embedded.system.sla.abilityType = "morph";
|
||||
embedded.system.sla.morphForm = true;
|
||||
embedded.system.sla.isStartingForm = morph.name === startingMorphForm;
|
||||
items.push(embedded);
|
||||
} else {
|
||||
// Build a minimal ability document so the character isn't empty-handed.
|
||||
@@ -916,6 +923,7 @@ export class SLAMothershipGenerator extends FormApplication {
|
||||
summary: morph.summary,
|
||||
special: morph.special,
|
||||
sla: {
|
||||
abilityType: "morph",
|
||||
morphForm: true,
|
||||
instabilityCost: morph.instabilityCost,
|
||||
statMods: morph.statMods ?? {},
|
||||
|
||||
@@ -0,0 +1,853 @@
|
||||
import { SLAMothershipGenerator } from "./sla-character-generator.js";
|
||||
|
||||
const SYSTEM_ID = "sla-mothership";
|
||||
const ROOT_ACTOR_FOLDER = "SLA Mothership";
|
||||
const NPC_FOLDER = "NPCs";
|
||||
|
||||
const NPC_ARCHETYPES = {
|
||||
"Civilian Witness": {
|
||||
summary: "Clerks, residents, dock workers, minor officials, and bystanders with enough identity to question or endanger.",
|
||||
stats: { combat: 18, instinct: 32, speed: 24, loyalty: 46, sanity: 36, armor: 0, damageReduction: 0, health: 8, hits: 1 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: false },
|
||||
skills: [
|
||||
{ name: "Persuade", bonus: 20 },
|
||||
{ name: "Spot Hidden", bonus: 25 },
|
||||
{ name: "Drive (Civilian)", bonus: 20 },
|
||||
{ name: "Bureaucracy", bonus: 15 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Civilian: ["Street Clothes / Leather Jacket", "UV / Multi-Spectrum Torch", "Oyster Card (ITB Card)"]
|
||||
},
|
||||
defaultLoadout: "Civilian",
|
||||
defaultRole: "Witness / Local",
|
||||
defaultAffiliation: "Mort Civilian",
|
||||
defaultDepartment: "Local District"
|
||||
},
|
||||
"Street Ganger": {
|
||||
summary: "Street muscle, lookouts, turf enforcers, and volatile crew members from Mort's lower tiers.",
|
||||
stats: { combat: 34, instinct: 34, speed: 30, loyalty: 24, sanity: 24, armor: 0, damageReduction: 0, health: 10, hits: 2 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: false, armor: false },
|
||||
skills: [
|
||||
{ name: "Brawl", bonus: 25 },
|
||||
{ name: "Streetwise", bonus: 25 },
|
||||
{ name: "Intimidate", bonus: 20 },
|
||||
{ name: "Dodge", bonus: 20 },
|
||||
{ name: "Firearm (Pistol)", bonus: 20 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
"Street Melee": ["Collapsible Baton", "Standard Combat Knife", "Street Clothes / Leather Jacket"],
|
||||
Sidearm: ["FEN 603 Auto-Pistol", "Standard Combat Knife", "Street Clothes / Leather Jacket"]
|
||||
},
|
||||
defaultLoadout: "Sidearm",
|
||||
defaultRole: "Street Gang Enforcer",
|
||||
defaultAffiliation: "Local Street Gang",
|
||||
defaultDepartment: "Turf Crew"
|
||||
},
|
||||
"Shiver Patrol": {
|
||||
summary: "Street cops, precinct enforcers, and cordon teams good for patrol scenes, arrests, and fast escalation.",
|
||||
stats: { combat: 44, instinct: 38, speed: 34, loyalty: 58, sanity: 36, armor: 3, damageReduction: 1, health: 12, hits: 2 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: true },
|
||||
skills: [
|
||||
{ name: "Firearm (Pistol)", bonus: 30 },
|
||||
{ name: "Firearm (SMG)", bonus: 25 },
|
||||
{ name: "Athletics", bonus: 20 },
|
||||
{ name: "Command", bonus: 20 },
|
||||
{ name: "Spot Hidden", bonus: 25 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Patrol: ["FEN 401 Shiver Pistol", "Collapsible Baton", "Shiver Flak Vest"],
|
||||
"SMG Team": ["FEN 209 Machine Pistol", "Collapsible Baton", "Full Shiver Armour"]
|
||||
},
|
||||
defaultLoadout: "Patrol",
|
||||
defaultRole: "Shiver Patrol Officer",
|
||||
defaultAffiliation: "SLA Industries",
|
||||
defaultDepartment: "Shiver Precinct"
|
||||
},
|
||||
"Corp Operative": {
|
||||
summary: "Standard corporate assets, contract staff, or in-house operatives for Mort departments and sponsor interests.",
|
||||
stats: { combat: 40, instinct: 40, speed: 32, loyalty: 50, sanity: 40, armor: 2, damageReduction: 0, health: 11, hits: 2 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: true },
|
||||
skills: [
|
||||
{ name: "Firearm (Pistol)", bonus: 25 },
|
||||
{ name: "Command", bonus: 20 },
|
||||
{ name: "Spot Hidden", bonus: 20 },
|
||||
{ name: "Bureaucracy", bonus: 20 },
|
||||
{ name: "Persuade", bonus: 15 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Sidearm: ["FEN 603 Auto-Pistol", "Street Clothes / Leather Jacket"],
|
||||
"Field Agent": ["FEN 209 Machine Pistol", "Shiver Flak Vest", "Klippo Multi-Band Communicator"]
|
||||
},
|
||||
defaultLoadout: "Field Agent",
|
||||
defaultAffiliationType: "Corporation",
|
||||
defaultRole: "Corporate Operative",
|
||||
defaultAffiliation: "SLA Industries",
|
||||
defaultDepartment: "Operations",
|
||||
defaultSector: "Mort City"
|
||||
},
|
||||
Media: {
|
||||
summary: "Reporters, propaganda staff, image handlers, and camera teams who shape the public story while staying very close to the danger.",
|
||||
stats: { combat: 20, instinct: 42, speed: 28, loyalty: 44, sanity: 42, armor: 1, damageReduction: 0, health: 9, hits: 1 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: true },
|
||||
skills: [
|
||||
{ name: "Persuade", bonus: 30 },
|
||||
{ name: "Fast Talk", bonus: 25 },
|
||||
{ name: "SLA Info", bonus: 25 },
|
||||
{ name: "Spot Hidden", bonus: 20 },
|
||||
{ name: "Intimidate", bonus: 15 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Press: ["Klippo Multi-Band Communicator", "UV / Multi-Spectrum Torch", "Street Clothes / Leather Jacket"],
|
||||
"Embedded Crew": ["FEN 603 Auto-Pistol", "Klippo Multi-Band Communicator", "Street Clothes / Leather Jacket"]
|
||||
},
|
||||
defaultLoadout: "Press",
|
||||
defaultAffiliationType: "Corporation",
|
||||
defaultRole: "Media Correspondent",
|
||||
defaultAffiliation: "SLA Media",
|
||||
defaultDepartment: "Editorial / Field Unit",
|
||||
defaultSector: "Downtown Mort"
|
||||
},
|
||||
"Internal Affairs": {
|
||||
summary: "Cold, suspicious investigators and auditors used for leak hunts, corruption probes, and quiet pressure on operatives or departments.",
|
||||
stats: { combat: 34, instinct: 48, speed: 28, loyalty: 56, sanity: 44, armor: 2, damageReduction: 0, health: 10, hits: 2 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: true },
|
||||
skills: [
|
||||
{ name: "Bureaucracy", bonus: 30 },
|
||||
{ name: "Psychology", bonus: 25 },
|
||||
{ name: "Intimidate", bonus: 25 },
|
||||
{ name: "Command", bonus: 20 },
|
||||
{ name: "Firearm (Pistol)", bonus: 20 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Audit: ["FEN 603 Auto-Pistol", "Klippo Multi-Band Communicator", "Street Clothes / Leather Jacket"],
|
||||
Pressure: ["FEN 401 Shiver Pistol", "Shiver Flak Vest", "Klippo Multi-Band Communicator"]
|
||||
},
|
||||
defaultLoadout: "Audit",
|
||||
defaultAffiliationType: "Department",
|
||||
defaultRole: "Internal Affairs Investigator",
|
||||
defaultAffiliation: "SLA Industries",
|
||||
defaultDepartment: "Internal Affairs",
|
||||
defaultSector: "Cannibal Sectors"
|
||||
},
|
||||
"DarkNight Agent": {
|
||||
summary: "Hard, covert, and unpleasant professionals for pressure scenes, black-bag work, and very bad conversations.",
|
||||
stats: { combat: 52, instinct: 48, speed: 42, loyalty: 42, sanity: 44, armor: 4, damageReduction: 2, health: 13, hits: 2 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: true },
|
||||
skills: [
|
||||
{ name: "Stealth", bonus: 30 },
|
||||
{ name: "Dodge", bonus: 25 },
|
||||
{ name: "Spot Hidden", bonus: 30 },
|
||||
{ name: "Firearm (SMG)", bonus: 30 },
|
||||
{ name: "Intimidate", bonus: 25 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
"Strike Agent": ["FEN 209 Machine Pistol", "Standard Combat Knife", "Stealth Suit"],
|
||||
Breach: ["FEN AR Assault Rifle", "Fragmentation Grenade", "Crackshot Armour"]
|
||||
},
|
||||
defaultLoadout: "Strike Agent",
|
||||
defaultAffiliationType: "Squad",
|
||||
defaultRole: "DarkNight Agent",
|
||||
defaultAffiliation: "DarkNight",
|
||||
defaultDepartment: "Black Unit",
|
||||
defaultSector: "Cannibal Sectors"
|
||||
},
|
||||
"Tek Specialist": {
|
||||
summary: "Engineers, locks-and-systems staff, data handlers, and machine-facing support assets.",
|
||||
stats: { combat: 26, instinct: 42, speed: 28, loyalty: 46, sanity: 40, armor: 1, damageReduction: 0, health: 9, hits: 1 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: true, sanity: true, armor: true },
|
||||
skills: [
|
||||
{ name: "Computer Systems", bonus: 30 },
|
||||
{ name: "Tech (Computers & AI)", bonus: 25 },
|
||||
{ name: "Tech (Electronics)", bonus: 25 },
|
||||
{ name: "Spot Hidden", bonus: 20 },
|
||||
{ name: "Firearm (Pistol)", bonus: 15 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Utility: ["FEN 603 Auto-Pistol", "Klippo Multi-Band Communicator", "UV / Multi-Spectrum Torch"],
|
||||
"Field Tek": ["FEN 603 Auto-Pistol", "BOOPA Medical Kit (Standard)", "Klippo Multi-Band Communicator"]
|
||||
},
|
||||
defaultLoadout: "Utility",
|
||||
defaultAffiliationType: "Department",
|
||||
defaultRole: "Tek Specialist",
|
||||
defaultAffiliation: "Tek Division",
|
||||
defaultDepartment: "Systems",
|
||||
defaultSector: "Industrial Edge"
|
||||
},
|
||||
"Ebb Operative": {
|
||||
summary: "Psychic intervention assets, occult handlers, and dangerous minds kept near the edge of tolerable doctrine.",
|
||||
stats: { combat: 30, instinct: 46, speed: 24, loyalty: 30, sanity: 46, armor: 0, damageReduction: 0, health: 9, hits: 2 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: false, sanity: true, armor: false },
|
||||
skills: [
|
||||
{ name: "Biofeedback", bonus: 25 },
|
||||
{ name: "Formulate", bonus: 25 },
|
||||
{ name: "Ebb (Core)", bonus: 25 },
|
||||
{ name: "Spot Hidden", bonus: 20 },
|
||||
{ name: "Firearm (Pistol)", bonus: 15 }
|
||||
],
|
||||
loadouts: {
|
||||
None: [],
|
||||
Focus: ["FEN 603 Auto-Pistol", "BOOPA Medical Kit (Standard)", "Klippo Multi-Band Communicator"]
|
||||
},
|
||||
defaultLoadout: "Focus",
|
||||
defaultAffiliationType: "Department",
|
||||
defaultRole: "Ebb Handler",
|
||||
defaultAffiliation: "SLA Industries",
|
||||
defaultDepartment: "Ebb / Black",
|
||||
defaultSector: "Mort City"
|
||||
},
|
||||
"Predator / Beast": {
|
||||
summary: "Mutants, monsters, feral biogen threats, or engineered horrors that need only enough structure to fight and stalk.",
|
||||
stats: { combat: 46, instinct: 56, speed: 40, loyalty: 12, sanity: 10, armor: 2, damageReduction: 1, health: 14, hits: 3 },
|
||||
enabled: { combat: true, instinct: true, speed: true, loyalty: false, sanity: false, armor: true },
|
||||
skills: [
|
||||
{ name: "Brawl", bonus: 30 },
|
||||
{ name: "Athletics", bonus: 25 },
|
||||
{ name: "Dodge", bonus: 20 },
|
||||
{ name: "Spot Hidden", bonus: 25 }
|
||||
],
|
||||
loadouts: {
|
||||
None: []
|
||||
},
|
||||
defaultLoadout: "None",
|
||||
defaultAffiliationType: "Independent",
|
||||
defaultRole: "Hunting Threat",
|
||||
defaultAffiliation: "Hostile Specimen",
|
||||
defaultDepartment: "Wild / Uncontrolled",
|
||||
defaultSector: "Waste District"
|
||||
}
|
||||
};
|
||||
|
||||
const QUALITY_MODS = {
|
||||
Rabble: { stat: -8, skill: -10, health: -2, hits: 0 },
|
||||
Standard: { stat: 0, skill: 0, health: 0, hits: 0 },
|
||||
Veteran: { stat: 6, skill: 5, health: 1, hits: 0 },
|
||||
Elite: { stat: 10, skill: 10, health: 2, hits: 1 },
|
||||
Boss: { stat: 14, skill: 15, health: 4, hits: 1 }
|
||||
};
|
||||
|
||||
const DISPOSITIONS = ["Neutral", "Professional", "Hostile", "Nervous", "Fanatical", "Cornered", "Corrupt", "Helpful"];
|
||||
const THREAT_TIERS = ["Low", "Moderate", "High", "Extreme"];
|
||||
const AFFILIATION_TYPES = ["Department", "Gang", "Corporation", "Cult", "Squad", "Civic", "Independent"];
|
||||
|
||||
const ROLE_SNIPPETS = {
|
||||
"Civilian Witness": ["Transit clerk", "Dock handler", "Apartment resident", "Witness under pressure", "Small trader"],
|
||||
"Street Ganger": ["Lookout", "Enforcer", "Runner", "Debt collector", "Back-alley bruiser"],
|
||||
"Shiver Patrol": ["Patrol officer", "Checkpoint lead", "Riot response cop", "Beat sergeant", "Scene controller"],
|
||||
"Corp Operative": ["Case handler", "Recovery agent", "Sponsor fixer", "Quiet escort", "Internal security operative"],
|
||||
Media: ["Field correspondent", "Embedded camera lead", "Image handler", "Narrative producer", "Live scene reporter"],
|
||||
"Internal Affairs": ["Audit investigator", "Leak hunter", "Corruption examiner", "Interrogation lead", "Compliance agent"],
|
||||
"DarkNight Agent": ["Pressure asset", "Black-bag specialist", "Interdiction hunter", "Silent breach lead", "Cleanup professional"],
|
||||
"Tek Specialist": ["Systems breach tech", "Maintenance lead", "Field engineer", "Data recovery tech", "Signals operator"],
|
||||
"Ebb Operative": ["Control asset", "Psi observer", "Occult investigator", "Flux-sensitive handler", "Discreet interventionist"],
|
||||
"Predator / Beast": ["Tunnel stalker", "Waste-zone hunter", "Escaped specimen", "Territory alpha", "Feral ambusher"]
|
||||
};
|
||||
|
||||
const AFFILIATION_SNIPPETS = {
|
||||
Department: ["Mort Department", "Ops Con", "Shiver Precinct", "Tek Division", "Cannibal Sector Authority"],
|
||||
Gang: ["Chrome Jacks", "Sump Dogs", "Red Wire Crew", "Murder Mile Kings", "Ash-Sector Runners"],
|
||||
Corporation: ["SLA Industries", "FEN", "Wraithen Security", "MediCore", "Tek Division"],
|
||||
Cult: ["The True Noise", "Church of White Fire", "The Bent Halo", "The Last Broadcast", "Ash Choir"],
|
||||
Squad: ["Blue BPN Hold Team", "Black Transit Unit", "Sweep Detail", "Strike Cell Seven", "Special Recovery Team"],
|
||||
Civic: ["Transit Maintenance", "Block Committee", "Waste Processing", "Public Utility", "Relocation Office"],
|
||||
Independent: ["Freelance crew", "Mercenary pair", "Broker network", "Private fixer", "Unaffiliated contact"]
|
||||
};
|
||||
|
||||
const DEPARTMENT_SNIPPETS = {
|
||||
"Civilian Witness": ["Hab Block", "Transit", "Utility", "Street Market", "Dock Quarter"],
|
||||
"Street Ganger": ["East Cut", "Underline", "Recycling Stack", "Canal Row", "Tunnel Nine"],
|
||||
"Shiver Patrol": ["Precinct 88", "Riot Control", "Street Division", "Transit Policing", "Evidence Escort"],
|
||||
"Corp Operative": ["Internal Security", "Investigations", "Sponsor Liaison", "Logistics Recovery", "Operations"],
|
||||
Media: ["Editorial Desk", "Live Scene Unit", "Mort Broadcast", "Image Control", "Public Feed Team"],
|
||||
"Internal Affairs": ["Compliance Review", "Leak Office", "Audit Section", "Disciplinary Unit", "Special Oversight"],
|
||||
"DarkNight Agent": ["Silent Entry", "Black Archive", "Pressure Cell", "Removal Team", "Interdiction"],
|
||||
"Tek Specialist": ["Signals", "Maintenance", "Surveillance", "Field Systems", "Machine Control"],
|
||||
"Ebb Operative": ["Occult Oversight", "Black Psi", "Flux Watch", "Intervention Cell", "Containment"],
|
||||
"Predator / Beast": ["Den", "Nest", "Territory", "Spore Cluster", "Hunting Ground"]
|
||||
};
|
||||
|
||||
export class SLANpcGeneratorApp extends FormApplication {
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
this.formState = null;
|
||||
}
|
||||
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
id: "sla-npc-generator",
|
||||
classes: ["mosh", "sheet", "sla-generator", "sla-npc-generator"],
|
||||
template: "systems/sla-mothership/templates/dialogs/sla-npc-generator.html",
|
||||
width: 780,
|
||||
height: "auto",
|
||||
submitOnChange: false,
|
||||
closeOnSubmit: false
|
||||
});
|
||||
}
|
||||
|
||||
get title() {
|
||||
return "SLA NPC Desk";
|
||||
}
|
||||
|
||||
async getData() {
|
||||
await SLAMothershipGenerator.ensureSeedData();
|
||||
const seed = await SLAMothershipGenerator.loadSeedData();
|
||||
const speciesOptions = seed.species.species.map((entry) => entry.name);
|
||||
const state = this.formState ?? this.defaultState(speciesOptions);
|
||||
this.formState = state;
|
||||
|
||||
const archetype = NPC_ARCHETYPES[state.archetype] ?? NPC_ARCHETYPES["Street Ganger"];
|
||||
const loadoutOptions = Object.keys(archetype.loadouts ?? { None: [] });
|
||||
|
||||
return {
|
||||
state,
|
||||
accentKey: getArchetypeAccentKey(state.archetype),
|
||||
archetypes: Object.entries(NPC_ARCHETYPES).map(([name, entry]) => ({ name, summary: entry.summary })),
|
||||
speciesOptions,
|
||||
qualityOptions: Object.keys(QUALITY_MODS),
|
||||
dispositionOptions: DISPOSITIONS,
|
||||
threatOptions: THREAT_TIERS,
|
||||
affiliationTypes: AFFILIATION_TYPES,
|
||||
loadoutOptions,
|
||||
summary: archetype.summary,
|
||||
preview: buildNpcPreview(state, archetype)
|
||||
};
|
||||
}
|
||||
|
||||
defaultState(speciesOptions = []) {
|
||||
const archetype = "Street Ganger";
|
||||
const config = NPC_ARCHETYPES[archetype];
|
||||
return {
|
||||
name: SLAMothershipGenerator.randomName(),
|
||||
archetype,
|
||||
quality: "Standard",
|
||||
species: speciesOptions.includes("Human") ? "Human" : (speciesOptions[0] ?? "Human"),
|
||||
affiliationType: config.defaultAffiliationType ?? "Gang",
|
||||
affiliation: config.defaultAffiliation,
|
||||
department: config.defaultDepartment,
|
||||
role: config.defaultRole,
|
||||
sector: config.defaultSector ?? "Mort City",
|
||||
disposition: "Hostile",
|
||||
threat: "Moderate",
|
||||
loadout: config.defaultLoadout ?? "None",
|
||||
assignPortrait: true,
|
||||
openSheet: true,
|
||||
notes: ""
|
||||
};
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
html.find(".sla-npc-random-name").on("click", () => {
|
||||
html.find("[name='name']").val(SLAMothershipGenerator.randomName());
|
||||
});
|
||||
|
||||
html.find(".sla-npc-randomize").on("click", async () => {
|
||||
const state = this.collectState(html);
|
||||
const randomized = this.randomizeState(state);
|
||||
this.formState = randomized;
|
||||
await this.render(false);
|
||||
});
|
||||
|
||||
html.find("[name='archetype']").on("change", async () => {
|
||||
const current = this.collectState(html);
|
||||
this.formState = this.rethemeStateForArchetype(current, current.archetype);
|
||||
await this.render(false);
|
||||
});
|
||||
|
||||
const rerenderSelectors = [
|
||||
"[name='quality']",
|
||||
"[name='species']",
|
||||
"[name='disposition']",
|
||||
"[name='threat']",
|
||||
"[name='loadout']",
|
||||
"[name='affiliationType']"
|
||||
];
|
||||
|
||||
for (const selector of rerenderSelectors) {
|
||||
html.find(selector).on("change", async () => {
|
||||
this.formState = this.collectState(html);
|
||||
await this.render(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
collectState(html) {
|
||||
return {
|
||||
name: String(html.find("[name='name']").val() ?? "").trim(),
|
||||
archetype: String(html.find("[name='archetype']").val() ?? "Street Ganger"),
|
||||
quality: String(html.find("[name='quality']").val() ?? "Standard"),
|
||||
species: String(html.find("[name='species']").val() ?? "Human"),
|
||||
affiliationType: String(html.find("[name='affiliationType']").val() ?? "Department"),
|
||||
affiliation: String(html.find("[name='affiliation']").val() ?? "").trim(),
|
||||
department: String(html.find("[name='department']").val() ?? "").trim(),
|
||||
role: String(html.find("[name='role']").val() ?? "").trim(),
|
||||
sector: String(html.find("[name='sector']").val() ?? "").trim(),
|
||||
disposition: String(html.find("[name='disposition']").val() ?? "Neutral"),
|
||||
threat: String(html.find("[name='threat']").val() ?? "Moderate"),
|
||||
loadout: String(html.find("[name='loadout']").val() ?? "None"),
|
||||
assignPortrait: Boolean(html.find("[name='assignPortrait']").prop("checked")),
|
||||
openSheet: Boolean(html.find("[name='openSheet']").prop("checked")),
|
||||
notes: String(html.find("[name='notes']").val() ?? "").trim()
|
||||
};
|
||||
}
|
||||
|
||||
randomizeState(current) {
|
||||
const state = { ...current };
|
||||
const archetypeName = state.archetype || randomFrom(Object.keys(NPC_ARCHETYPES)) || "Street Ganger";
|
||||
const archetype = NPC_ARCHETYPES[archetypeName] ?? NPC_ARCHETYPES["Street Ganger"];
|
||||
const themed = this.rethemeStateForArchetype(state, archetypeName);
|
||||
themed.affiliation = randomFrom(AFFILIATION_SNIPPETS[themed.affiliationType] ?? [archetype.defaultAffiliation]) ?? archetype.defaultAffiliation;
|
||||
themed.department = randomFrom(DEPARTMENT_SNIPPETS[archetypeName] ?? [archetype.defaultDepartment]) ?? archetype.defaultDepartment;
|
||||
themed.role = randomFrom(ROLE_SNIPPETS[archetypeName] ?? [archetype.defaultRole]) ?? archetype.defaultRole;
|
||||
themed.sector = randomFrom(getSectorOptionsForArchetype(archetypeName, archetype.defaultSector)) ?? (archetype.defaultSector ?? "Mort City");
|
||||
themed.disposition = randomFrom(DISPOSITIONS) ?? "Neutral";
|
||||
themed.threat = randomFrom(THREAT_TIERS) ?? "Moderate";
|
||||
themed.loadout = randomFrom(Object.keys(archetype.loadouts ?? { None: [] })) ?? "None";
|
||||
themed.name = SLAMothershipGenerator.randomName();
|
||||
return themed;
|
||||
}
|
||||
|
||||
rethemeStateForArchetype(current, archetypeName) {
|
||||
const archetype = NPC_ARCHETYPES[archetypeName] ?? NPC_ARCHETYPES["Street Ganger"];
|
||||
const next = { ...current, archetype: archetypeName };
|
||||
next.affiliationType = archetype.defaultAffiliationType ?? current.affiliationType ?? "Department";
|
||||
next.affiliation = archetype.defaultAffiliation ?? "";
|
||||
next.department = archetype.defaultDepartment ?? "";
|
||||
next.role = archetype.defaultRole ?? "";
|
||||
next.sector = archetype.defaultSector ?? "Mort City";
|
||||
next.loadout = archetype.defaultLoadout ?? "None";
|
||||
next.disposition = getDefaultDispositionForArchetype(archetypeName);
|
||||
next.threat = getDefaultThreatForArchetype(archetypeName);
|
||||
next.species = getDefaultSpeciesForArchetype(archetypeName, current.species);
|
||||
return next;
|
||||
}
|
||||
|
||||
async _updateObject(_event, formData) {
|
||||
const expanded = foundry.utils.expandObject(formData);
|
||||
const state = {
|
||||
name: String(expanded.name ?? "").trim(),
|
||||
archetype: String(expanded.archetype ?? "Street Ganger"),
|
||||
quality: String(expanded.quality ?? "Standard"),
|
||||
species: String(expanded.species ?? "Human"),
|
||||
affiliationType: String(expanded.affiliationType ?? "Department"),
|
||||
affiliation: String(expanded.affiliation ?? "").trim(),
|
||||
department: String(expanded.department ?? "").trim(),
|
||||
role: String(expanded.role ?? "").trim(),
|
||||
sector: String(expanded.sector ?? "").trim(),
|
||||
disposition: String(expanded.disposition ?? "Neutral"),
|
||||
threat: String(expanded.threat ?? "Moderate"),
|
||||
loadout: String(expanded.loadout ?? "None"),
|
||||
assignPortrait: Boolean(expanded.assignPortrait),
|
||||
openSheet: Boolean(expanded.openSheet),
|
||||
notes: String(expanded.notes ?? "").trim()
|
||||
};
|
||||
|
||||
this.formState = state;
|
||||
const result = await generateSlaNpc(state);
|
||||
if (result?.actor && state.openSheet) {
|
||||
result.actor.sheet?.render(true);
|
||||
}
|
||||
ui.notifications.info(`SLA NPC ready: ${result.actor.name}`);
|
||||
this.render(false);
|
||||
}
|
||||
|
||||
static open(options = {}) {
|
||||
return new SLANpcGeneratorApp(options).render({ force: true });
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateSlaNpc(state = {}) {
|
||||
await SLAMothershipGenerator.ensureSeedData();
|
||||
const seed = await SLAMothershipGenerator.loadSeedData();
|
||||
|
||||
const archetype = NPC_ARCHETYPES[state.archetype] ?? NPC_ARCHETYPES["Street Ganger"];
|
||||
const quality = QUALITY_MODS[state.quality] ?? QUALITY_MODS.Standard;
|
||||
const speciesName = String(state.species ?? "Human").trim() || "Human";
|
||||
const resolvedName = String(state.name ?? "").trim() || SLAMothershipGenerator.randomName();
|
||||
const folder = await ensureNpcFolder();
|
||||
|
||||
const actor = await Actor.create({
|
||||
name: resolvedName,
|
||||
type: "creature",
|
||||
folder: folder.id
|
||||
});
|
||||
|
||||
const stats = applyQualityToStats(archetype.stats, quality);
|
||||
const enabled = archetype.enabled ?? {};
|
||||
const description = buildNpcDescription({ state, archetype, speciesName });
|
||||
const biography = buildNpcBiography({ state, archetype, speciesName });
|
||||
|
||||
await actor.update({
|
||||
img: SLAMothershipGenerator.resolveSpeciesImage(speciesName),
|
||||
"system.description": description,
|
||||
"system.biography": biography,
|
||||
"system.notes": String(state.notes ?? "").trim(),
|
||||
"system.health.value": stats.health,
|
||||
"system.health.max": stats.health,
|
||||
"system.hits.value": 0,
|
||||
"system.hits.max": stats.hits,
|
||||
"system.stats.combat.value": stats.combat,
|
||||
"system.stats.instinct.value": stats.instinct,
|
||||
"system.stats.speed.value": stats.speed,
|
||||
"system.stats.loyalty.value": stats.loyalty,
|
||||
"system.stats.sanity.value": stats.sanity,
|
||||
"system.stats.armor.mod": stats.armor,
|
||||
"system.stats.armor.damageReduction": stats.damageReduction,
|
||||
"system.stats.combat.enabled": Boolean(enabled.combat),
|
||||
"system.stats.instinct.enabled": Boolean(enabled.instinct),
|
||||
"system.stats.speed.enabled": Boolean(enabled.speed),
|
||||
"system.stats.loyalty.enabled": Boolean(enabled.loyalty),
|
||||
"system.stats.sanity.enabled": Boolean(enabled.sanity),
|
||||
"system.stats.armor.enabled": Boolean(enabled.armor),
|
||||
"system.slaNpc.archetype.value": state.archetype,
|
||||
"system.slaNpc.species.value": speciesName,
|
||||
"system.slaNpc.affiliationType.value": state.affiliationType,
|
||||
"system.slaNpc.affiliation.value": String(state.affiliation ?? "").trim(),
|
||||
"system.slaNpc.department.value": String(state.department ?? "").trim(),
|
||||
"system.slaNpc.role.value": String(state.role ?? "").trim(),
|
||||
"system.slaNpc.sector.value": String(state.sector ?? "").trim(),
|
||||
"system.slaNpc.disposition.value": String(state.disposition ?? "").trim(),
|
||||
"system.slaNpc.threat.value": String(state.threat ?? "").trim(),
|
||||
"system.slaNpc.summary.value": archetype.summary
|
||||
});
|
||||
|
||||
const itemPayloads = [];
|
||||
itemPayloads.push(...buildNpcSkillItems(archetype.skills ?? [], quality, seed.skills.skills));
|
||||
itemPayloads.push(...buildLoadoutItems(archetype, state.loadout));
|
||||
|
||||
if (state.archetype === "Ebb Operative" && SLAMothershipGenerator.isEbbSpecies(speciesName)) {
|
||||
itemPayloads.push(...SLAMothershipGenerator.buildEbbSkillItems(speciesName));
|
||||
itemPayloads.push(...SLAMothershipGenerator.buildEbbItems(speciesName));
|
||||
}
|
||||
|
||||
if (state.archetype === "Predator / Beast") {
|
||||
itemPayloads.push(...SLAMothershipGenerator.buildSpeciesItems(speciesName));
|
||||
}
|
||||
|
||||
const uniquePayloads = uniqueEmbeddedItems(itemPayloads);
|
||||
if (uniquePayloads.length) {
|
||||
await actor.createEmbeddedDocuments("Item", uniquePayloads);
|
||||
}
|
||||
|
||||
if (state.assignPortrait && game.npcPortraitPack?.assignPortraitToActor) {
|
||||
await game.npcPortraitPack.assignPortraitToActor(actor);
|
||||
}
|
||||
|
||||
return { actor };
|
||||
}
|
||||
|
||||
async function ensureNpcFolder() {
|
||||
let root = game.folders.find((folder) => folder.type === "Actor" && folder.name === ROOT_ACTOR_FOLDER && !folder.folder);
|
||||
if (!root) {
|
||||
root = await Folder.create({ name: ROOT_ACTOR_FOLDER, type: "Actor", color: "#163447" });
|
||||
}
|
||||
|
||||
let folder = game.folders.find((entry) => entry.type === "Actor" && entry.name === NPC_FOLDER && entry.folder?.id === root.id);
|
||||
if (!folder) {
|
||||
folder = await Folder.create({ name: NPC_FOLDER, type: "Actor", folder: root.id, color: "#5b3349" });
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
function applyQualityToStats(baseStats, quality) {
|
||||
return {
|
||||
combat: clamp98((baseStats.combat ?? 10) + (quality.stat ?? 0)),
|
||||
instinct: clamp98((baseStats.instinct ?? 10) + (quality.stat ?? 0)),
|
||||
speed: clamp98((baseStats.speed ?? 10) + (quality.stat ?? 0)),
|
||||
loyalty: clamp98((baseStats.loyalty ?? 10) + (quality.stat ?? 0)),
|
||||
sanity: clamp98((baseStats.sanity ?? 10) + (quality.stat ?? 0)),
|
||||
armor: Math.max(0, Number(baseStats.armor ?? 0)),
|
||||
damageReduction: Math.max(0, Number(baseStats.damageReduction ?? 0)),
|
||||
health: Math.max(1, Number(baseStats.health ?? 8) + Number(quality.health ?? 0)),
|
||||
hits: Math.max(1, Number(baseStats.hits ?? 1) + Number(quality.hits ?? 0))
|
||||
};
|
||||
}
|
||||
|
||||
function buildNpcSkillItems(skillDefs, quality, allSkillData = []) {
|
||||
return (skillDefs ?? [])
|
||||
.map((entry) => {
|
||||
const baseBonus = Number(entry.bonus ?? 10) + Number(quality.skill ?? 0);
|
||||
const worldItem = findWorldItem(entry.name, "skill");
|
||||
if (worldItem) {
|
||||
const embedded = toEmbeddedData(worldItem);
|
||||
embedded.system.bonus = clamp98(baseBonus);
|
||||
embedded.system.rank = rankFromBonus(embedded.system.bonus);
|
||||
embedded.system.sla ??= {};
|
||||
embedded.system.sla.baseBonus = Number(worldItem.system?.bonus ?? 0) || 0;
|
||||
embedded.system.sla.packageBonus = Math.max(0, embedded.system.bonus - Number(embedded.system.sla.baseBonus ?? 0));
|
||||
return embedded;
|
||||
}
|
||||
|
||||
const data = allSkillData.find((skill) => normalizeText(skill.name) === normalizeText(entry.name)) ?? {};
|
||||
return {
|
||||
name: entry.name,
|
||||
type: "skill",
|
||||
img: "icons/svg/upgrade.svg",
|
||||
system: {
|
||||
description: "",
|
||||
rank: rankFromBonus(baseBonus),
|
||||
bonus: clamp98(baseBonus),
|
||||
prerequisite_ids: [],
|
||||
sla: {
|
||||
category: data.categoryRef ?? "",
|
||||
skillFamily: data.categoryRef ?? "",
|
||||
source: "SLA NPC Desk"
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function buildLoadoutItems(archetype, loadoutName) {
|
||||
const loadout = archetype.loadouts?.[loadoutName] ?? [];
|
||||
return loadout
|
||||
.map((name) => findWorldItem(name))
|
||||
.filter(Boolean)
|
||||
.map((item) => toEmbeddedData(item));
|
||||
}
|
||||
|
||||
function buildNpcDescription({ state, archetype, speciesName }) {
|
||||
return [
|
||||
`${state.role || archetype.defaultRole}.`,
|
||||
`${state.affiliation || archetype.defaultAffiliation}${state.department ? ` / ${state.department}` : ""}.`,
|
||||
`${state.disposition || "Neutral"} presence with ${state.threat || "Moderate"} threat pressure.`,
|
||||
`${speciesName} profile.`
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
function buildNpcBiography({ state, archetype, speciesName }) {
|
||||
return `
|
||||
<p><strong>Role:</strong> ${escapeHtml(state.role || archetype.defaultRole)}</p>
|
||||
<p><strong>Affiliation:</strong> ${escapeHtml(state.affiliation || archetype.defaultAffiliation)}</p>
|
||||
<p><strong>Department / Cell:</strong> ${escapeHtml(state.department || archetype.defaultDepartment)}</p>
|
||||
<p><strong>Species:</strong> ${escapeHtml(speciesName)}</p>
|
||||
<p><strong>Disposition:</strong> ${escapeHtml(state.disposition || "Neutral")} | <strong>Threat:</strong> ${escapeHtml(state.threat || "Moderate")}</p>
|
||||
<p><strong>Sector:</strong> ${escapeHtml(state.sector || "Mort City")}</p>
|
||||
<p>${escapeHtml(archetype.summary)}</p>
|
||||
`.trim();
|
||||
}
|
||||
|
||||
function buildNpcPreview(state, archetype) {
|
||||
const quality = QUALITY_MODS[state.quality] ?? QUALITY_MODS.Standard;
|
||||
const loadoutNames = archetype.loadouts?.[state.loadout] ?? [];
|
||||
const statline = applyQualityToStats(archetype.stats, quality);
|
||||
return {
|
||||
iconPath: getArchetypeIconPath(state.archetype),
|
||||
iconLabel: getArchetypeBadgeShort(state.archetype),
|
||||
badge: getArchetypeBadge(state.archetype),
|
||||
strap: getArchetypeStrapline(state.archetype),
|
||||
identity: `${state.role || archetype.defaultRole} / ${state.species}`,
|
||||
brief: `${state.affiliation || archetype.defaultAffiliation}${state.department ? ` / ${state.department}` : ""} operating in ${state.sector || archetype.defaultSector || "Mort City"}.`,
|
||||
posture: `${state.disposition || "Neutral"} disposition with ${state.threat || "Moderate"} threat expectations.`,
|
||||
statline: [
|
||||
`Combat ${statline.combat}`,
|
||||
`Instinct ${statline.instinct}`,
|
||||
`Speed ${statline.speed}`,
|
||||
`Health ${statline.health}`,
|
||||
`Wounds ${statline.hits}`
|
||||
],
|
||||
loadout: loadoutNames.length ? loadoutNames : ["No preset issue kit selected."],
|
||||
notes: archetype.summary
|
||||
};
|
||||
}
|
||||
|
||||
function clamp98(value) {
|
||||
return Math.max(1, Math.min(98, Number(value ?? 0) || 0));
|
||||
}
|
||||
|
||||
function rankFromBonus(bonus) {
|
||||
if (bonus >= 40) return "Master";
|
||||
if (bonus >= 25) return "Expert";
|
||||
return "Trained";
|
||||
}
|
||||
|
||||
function findWorldItem(name, type = null) {
|
||||
return game.items.find((item) => normalizeText(item.name) === normalizeText(name) && (!type || item.type === type)) ?? null;
|
||||
}
|
||||
|
||||
function toEmbeddedData(document) {
|
||||
return foundry.utils.duplicate(document.toObject());
|
||||
}
|
||||
|
||||
function uniqueEmbeddedItems(items = []) {
|
||||
const seen = new Set();
|
||||
const out = [];
|
||||
for (const item of items) {
|
||||
const key = `${item.type}::${normalizeText(item.name)}`;
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
out.push(item);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function normalizeText(value) {
|
||||
return String(value ?? "").trim().toLowerCase();
|
||||
}
|
||||
|
||||
function randomFrom(list = []) {
|
||||
if (!list.length) return null;
|
||||
return list[Math.floor(Math.random() * list.length)] ?? null;
|
||||
}
|
||||
|
||||
function getDefaultSpeciesForArchetype(archetypeName, currentSpecies = "Human") {
|
||||
if (archetypeName === "Ebb Operative") return "Ebon";
|
||||
if (archetypeName === "Predator / Beast") return "Advanced Carrien";
|
||||
return currentSpecies || "Human";
|
||||
}
|
||||
|
||||
function getDefaultDispositionForArchetype(archetypeName) {
|
||||
switch (archetypeName) {
|
||||
case "Civilian Witness": return "Nervous";
|
||||
case "Street Ganger": return "Hostile";
|
||||
case "Shiver Patrol": return "Professional";
|
||||
case "Corp Operative": return "Professional";
|
||||
case "Media": return "Corrupt";
|
||||
case "Internal Affairs": return "Professional";
|
||||
case "DarkNight Agent": return "Hostile";
|
||||
case "Tek Specialist": return "Professional";
|
||||
case "Ebb Operative": return "Cornered";
|
||||
case "Predator / Beast": return "Fanatical";
|
||||
default: return "Neutral";
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultThreatForArchetype(archetypeName) {
|
||||
switch (archetypeName) {
|
||||
case "Civilian Witness": return "Low";
|
||||
case "Street Ganger": return "Moderate";
|
||||
case "Shiver Patrol": return "Moderate";
|
||||
case "Corp Operative": return "Moderate";
|
||||
case "Media": return "Low";
|
||||
case "Internal Affairs": return "Moderate";
|
||||
case "DarkNight Agent": return "High";
|
||||
case "Tek Specialist": return "Moderate";
|
||||
case "Ebb Operative": return "High";
|
||||
case "Predator / Beast": return "Extreme";
|
||||
default: return "Moderate";
|
||||
}
|
||||
}
|
||||
|
||||
function getSectorOptionsForArchetype(archetypeName, fallback = "Mort City") {
|
||||
switch (archetypeName) {
|
||||
case "Street Ganger":
|
||||
return ["Cannibal Sectors", "Transit Underlevels", "Waste District", "Mort City"];
|
||||
case "Shiver Patrol":
|
||||
return ["Mort City", "Downtown Mort", "Transit Underlevels", "Cannibal Sectors"];
|
||||
case "Corp Operative":
|
||||
return ["Mort City", "Downtown Mort", "Industrial Edge", "Cannibal Sectors"];
|
||||
case "Media":
|
||||
return ["Downtown Mort", "Mort City", "Cannibal Sectors", "Transit Underlevels"];
|
||||
case "Internal Affairs":
|
||||
return ["Cannibal Sectors", "Mort City", "Downtown Mort", "Industrial Edge"];
|
||||
case "DarkNight Agent":
|
||||
return ["Cannibal Sectors", "Transit Underlevels", "Mort City", "Waste District"];
|
||||
case "Tek Specialist":
|
||||
return ["Industrial Edge", "Mort City", "Transit Underlevels", "Downtown Mort"];
|
||||
case "Ebb Operative":
|
||||
return ["Mort City", "Cannibal Sectors", "Downtown Mort"];
|
||||
case "Predator / Beast":
|
||||
return ["Waste District", "Cannibal Sectors", "Transit Underlevels", "Industrial Edge"];
|
||||
default:
|
||||
return [fallback, "Mort City", "Downtown Mort"];
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value ?? "")
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll('"', """)
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
|
||||
function getArchetypeAccentKey(archetypeName) {
|
||||
switch (archetypeName) {
|
||||
case "Shiver Patrol": return "shiver";
|
||||
case "DarkNight Agent": return "darknight";
|
||||
case "Tek Specialist": return "tek";
|
||||
case "Ebb Operative": return "ebb";
|
||||
case "Media": return "media";
|
||||
case "Internal Affairs": return "internal";
|
||||
case "Street Ganger": return "gang";
|
||||
case "Predator / Beast": return "predator";
|
||||
case "Civilian Witness": return "civilian";
|
||||
case "Corp Operative": return "corp";
|
||||
default: return "corp";
|
||||
}
|
||||
}
|
||||
|
||||
function getArchetypeBadge(archetypeName) {
|
||||
switch (archetypeName) {
|
||||
case "Shiver Patrol": return "Shiver Patrol";
|
||||
case "DarkNight Agent": return "DarkNight";
|
||||
case "Tek Specialist": return "Tek Division";
|
||||
case "Ebb Operative": return "Ebb Control";
|
||||
case "Media": return "Media Feed";
|
||||
case "Internal Affairs": return "Internal Affairs";
|
||||
case "Street Ganger": return "Street Threat";
|
||||
case "Predator / Beast": return "Hostile Specimen";
|
||||
case "Civilian Witness": return "Civilian Contact";
|
||||
case "Corp Operative": return "Corporate Asset";
|
||||
default: return archetypeName;
|
||||
}
|
||||
}
|
||||
|
||||
function getArchetypeBadgeShort(archetypeName) {
|
||||
switch (archetypeName) {
|
||||
case "Shiver Patrol": return "SV";
|
||||
case "DarkNight Agent": return "DN";
|
||||
case "Tek Specialist": return "TK";
|
||||
case "Ebb Operative": return "EB";
|
||||
case "Media": return "MD";
|
||||
case "Internal Affairs": return "IA";
|
||||
case "Street Ganger": return "SG";
|
||||
case "Predator / Beast": return "HX";
|
||||
case "Civilian Witness": return "CV";
|
||||
case "Corp Operative": return "CO";
|
||||
default: return "NPC";
|
||||
}
|
||||
}
|
||||
|
||||
function getArchetypeIconPath(archetypeName) {
|
||||
const root = "systems/sla-mothership/icons/ui/npc-badges";
|
||||
switch (archetypeName) {
|
||||
case "Shiver Patrol": return `${root}/shiver.svg`;
|
||||
case "DarkNight Agent": return `${root}/darknight.svg`;
|
||||
case "Tek Specialist": return `${root}/tek.svg`;
|
||||
case "Ebb Operative": return `${root}/ebb.svg`;
|
||||
case "Media": return `${root}/media.svg`;
|
||||
case "Internal Affairs": return `${root}/internal.svg`;
|
||||
case "Street Ganger": return `${root}/gang.svg`;
|
||||
case "Predator / Beast": return `${root}/predator.svg`;
|
||||
case "Civilian Witness": return `${root}/civilian.svg`;
|
||||
case "Corp Operative": return `${root}/corp.svg`;
|
||||
default: return `${root}/corp.svg`;
|
||||
}
|
||||
}
|
||||
|
||||
function getArchetypeStrapline(archetypeName) {
|
||||
switch (archetypeName) {
|
||||
case "Shiver Patrol": return "Precinct issue / patrol doctrine / fast response";
|
||||
case "DarkNight Agent": return "Black operations / pressure asset / covert response";
|
||||
case "Tek Specialist": return "Systems breach / maintenance / machine-facing support";
|
||||
case "Ebb Operative": return "Occult intervention / flux risk / psychic control";
|
||||
case "Media": return "Image control / live coverage / narrative pressure";
|
||||
case "Internal Affairs": return "Audit pressure / disciplinary review / quiet threat";
|
||||
case "Street Ganger": return "Turf violence / local intimidation / disposable muscle";
|
||||
case "Predator / Beast": return "Ferality / pursuit / close-quarters threat";
|
||||
case "Civilian Witness": return "Collateral witness / local knowledge / brittle pressure";
|
||||
case "Corp Operative": return "Corporate recovery / sponsor discipline / field oversight";
|
||||
default: return "Operational contact / generated dossier";
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SLAMothershipGenerator } from "./sla-character-generator.js";
|
||||
import { SLANpcGeneratorApp } from "./sla-npc-generator.js";
|
||||
|
||||
const SYSTEM_ID = "sla-mothership";
|
||||
|
||||
@@ -22,6 +23,7 @@ export class SLAWorldToolsApp extends FormApplication {
|
||||
async getData() {
|
||||
const seededItems = game.items.filter((item) => item.flags?.[SYSTEM_ID]?.slaSeed?.key);
|
||||
const actors = game.actors.filter((actor) => actor.type === "character");
|
||||
const creatures = game.actors.filter((actor) => actor.type === "creature");
|
||||
const ebbActors = actors.filter((actor) => ["Ebon", "Brain Waster"].includes(String(actor.system?.sla?.species?.value ?? "").trim()));
|
||||
|
||||
return {
|
||||
@@ -30,6 +32,7 @@ export class SLAWorldToolsApp extends FormApplication {
|
||||
weaponCount: seededItems.filter((item) => item.type === "weapon").length,
|
||||
gearCount: seededItems.filter((item) => item.flags?.[SYSTEM_ID]?.slaSeed?.kind === "gear").length,
|
||||
actorCount: actors.length,
|
||||
creatureCount: creatures.length,
|
||||
starterCount: actors.filter((actor) => actor.flags?.[SYSTEM_ID]?.slaStarter).length,
|
||||
ebbActorCount: ebbActors.length,
|
||||
quickBattleMapBuilderReady: Boolean(game.modules?.get("quick-battlemap-builder")?.active && game.quickBattleMapBuilder?.open)
|
||||
@@ -53,6 +56,10 @@ export class SLAWorldToolsApp extends FormApplication {
|
||||
game.slaMothership.openGenerator();
|
||||
});
|
||||
|
||||
html.find(".open-npc-desk").on("click", () => {
|
||||
game.slaMothership.openNpcDesk();
|
||||
});
|
||||
|
||||
html.find(".generate-random").on("click", async () => {
|
||||
await game.slaMothership.createRandomOperative({ openSheet: true });
|
||||
this.render(false);
|
||||
@@ -127,7 +134,14 @@ export function installSlaSidebarButtons(app, html) {
|
||||
await game.slaMothership.seedWorldContent({ overwrite: true, notify: true });
|
||||
});
|
||||
|
||||
toolContainer.append(randomButton, createButton, toolsButton, refreshButton);
|
||||
const npcButton = $(`
|
||||
<button type="button" class="sla-open-npc-desk">
|
||||
<i class="fas fa-id-badge"></i> NPC Desk
|
||||
</button>
|
||||
`);
|
||||
npcButton.on("click", () => SLANpcGeneratorApp.open());
|
||||
|
||||
toolContainer.append(randomButton, createButton, npcButton, toolsButton, refreshButton);
|
||||
}
|
||||
|
||||
function findToolContainer(root) {
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
{"_id":"2D3zgP8KtRTAqlfS","name":"Addiction","type":"condition","img":"systems/mosh/images/icons/ui/conditions/addicted.png","system":{"description":"<p>Excessive use of Pain Pills or Stimpaks requires a <strong>Body Save to prevent addiction</strong>. Once addicted, make a daily Body Save or gain 1d10 Stress every day you go without. If used once per day for a week you’ll need to take twice the amount of pills to gain the same effect.<br><br>Whenever you take more than one pill at a time roll 1d10. If you roll equal to or under the number taken make a Body Save. Failure means you fall unconscious and the Warden rolls a Death Save. You can cure an addiction through in-game treatment or leveling up.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"QEVnimwq5o0DxmZz","name":"Anhedonia","type":"condition","img":"systems/mosh/images/icons/ui/conditions/exhausted.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much Calm instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"23qE7TnIHxtw1E9y","name":"Bit Rot","type":"condition","img":"systems/mosh/images/icons/ui/conditions/data_loss.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZzvKo0yTqOcRP5Xo","name":"Broken","type":"condition","img":"systems/mosh/images/icons/ui/conditions/deflated.png","system":{"description":"<p>Make a Panic Check whenever a nearby crew member fails a Save.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Qnv6ZDPsbOXLi9go","name":"Cowardice","type":"condition","img":"systems/mosh/images/icons/ui/conditions/coward.png","system":{"description":"<p>You must make a Fear Save to engage in combat or else flee.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uoeVaOy5a6BIAGAi","name":"Death Drive","type":"condition","img":"systems/mosh/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>Whenever you encounter a stranger or known enemy you must make a Sanity Save or else immediately attack them.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PiMuPeHR5EobSPBP","name":"Deviant Logic Core","type":"condition","img":"systems/mosh/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dAJRV7JG0Wh1shcJ","name":"Emotional Detachment","type":"condition","img":"systems/mosh/images/icons/ui/conditions/detached.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you gain the Panic Effect of an Android, in addition to that of your own class. If you are an Android, gain the Panic Effect of a Marine.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"6vExNGxZiXcC3RFy","name":"Escapism","type":"condition","img":"systems/mosh/images/icons/ui/conditions/addicted.png","system":{"description":"<p>You always have Disadvantage on Body Saves to prevent Addiction.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kI2Yxt0Eo2mEywpZ","name":"Ethical Directive Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you now have the Panic Effect of a Marine, in addition to that of an Android.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5E3FGlNzi05S792f","name":"Ethical Directive Misread","type":"condition","img":"systems/mosh/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>Loses any expressiveness. Discusses the irrationality of Phobias, seeks to trigger them in others.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8D9ZtBYScCKjcBH3","name":"Faulty Heuristics","type":"condition","img":"systems/mosh/images/icons/ui/conditions/faulty_heuristics.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"B8vRorrFy3c2cOf5","name":"Fried Logic Core","type":"condition","img":"systems/mosh/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Frenzied nonsensical behaviour. Whenever you lose Calm, everyone else nearby loses the same amount of Calm.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"RZ5X3UuiM0Wzg3pQ","name":"Hallucinations","type":"condition","img":"systems/mosh/images/icons/ui/conditions/loss_of_confidence.png","system":{"description":"<p>You have trouble distinguishing between reality and fantasy.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"A3qRm3Gs36Nbfs29","name":"Hypervigilance","type":"condition","img":"systems/mosh/images/icons/ui/conditions/hypervigilance.png","system":{"description":"<p>Gain Advantage on all surprise rolls but lose 1d10 Calm every day.<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.5jMEd9JjJPIJBKHr]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"9vveNoR1VA9Bx0Wo","name":"Insane","type":"condition","img":"systems/mosh/images/icons/ui/conditions/spiraling.png","system":{"description":"<p>You become permanently, irreparably insane. Your character is now played by the Warden.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"hAfwbHxZih4Xb0qi","name":"Killswitch Engaged","type":"condition","img":"systems/mosh/images/icons/ui/conditions/killswitch.png","system":{"description":"<p>Go berserk, will not withdraw from combat regardless of situation, will not adhere to tactics.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1r6ruvSdxn2bHHIk","name":"Losing Your Grip","type":"condition","img":"systems/mosh/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"AXxmouWPp6Tx1JbK","name":"Panicky","type":"condition","img":"systems/mosh/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"lxIZLdg2IkwOC2b9","name":"Paranoid","type":"condition","img":"systems/mosh/images/icons/ui/conditions/suspicious.png","system":{"description":"<p>Whenever a character joins your group <em>(even if they only left for a short period of time)</em>, make a Fear Save or gain 1 Stress.<><>@UUID[Compendium.mosh.macros_triggered_0e.Macro.Er4ULzvdn2urxuet]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"lf1QZaUHSy82w7SR","name":"Phobia","type":"condition","img":"systems/mosh/images/icons/ui/conditions/frightened.png","system":{"description":"<p>Gain a new permanent phobia. Whenever you encounter this phobia make a Fear Save at Disadvantage.<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.RdJ2nh41wDUT4ZTP]{Fear Save [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Gm2XrTqVMbECVPan","name":"Psychotic Episodes","type":"condition","img":"systems/mosh/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"GbDO8pRNdPA5tQXE","name":"Rampancy","type":"condition","img":"systems/mosh/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round. These episodes double in duration <em>(or become twice as frequent)</em> each session.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"zbKI2RCl5h3vowoy","name":"Recurring Nightmares","type":"condition","img":"systems/mosh/images/icons/ui/conditions/nightmares.png","system":{"description":"<p>Every time you rest, make a Fear save. If you fail, lose 1d10 Calm and do not heal. The Warden will describe your nightmare.<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.5jMEd9JjJPIJBKHr]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"H4UUQsZOSaYGRPSY","name":"Severe Anxiety","type":"condition","img":"systems/mosh/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"xVW5zbK05EqQmaA4","name":"Social Anxiety","type":"condition","img":"systems/mosh/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose 1d10 Calm whenever you converse with someone new.<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.5jMEd9JjJPIJBKHr]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1rUlQJ5iwD29X4oT","name":"Software Bloat","type":"condition","img":"systems/mosh/images/icons/ui/conditions/software_bloat.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"XxjONzW7H4tIIAkN","name":"Starving","type":"condition","img":"systems/mosh/images/icons/ui/conditions/starving.png","system":{"description":"<p>Humans can survive roughly 3 weeks without food. <strong>After 24 hours without food you’re at Disadvantage to all rolls.</strong><br><br>The bare minimum to survive: you’ll need <strong>1 liter of water a day</strong>. However, at this level any strenuous activity (like running, Combat, or making mechanical repairs) will force you to make a Body Save or pass out. When water is scarce and you’re tracking it this closely you’re at Disadvantage to all Checks.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uOPcbqhk5sQHB8A2","name":"Suffocating","type":"condition","img":"systems/mosh/images/icons/ui/conditions/suffocating.png","system":{"description":"<p>In space you can last 15 seconds without oxygen before you fall unconscious. After passing out you can survive for 3-5 minutes before dying.<br><br><ul><li>If less than half of the original oxygen remains every roll is made at Disadvantage. All crew suffer headaches, fatigue, anxiety and general clumsiness.</li><li>If less than a quarter of the original oxygen amount remains players must make a Body Save once per day (and after every strenuous activity) or fall unconscious. All crew suffer panting, dizziness, severe headaches and impaired vision and tinnitus.</li><li>If a player runs out of oxygen they must make a Body Save. Failure means they die. Success means they fall unconscious and leach oxygen from a random player every day.</li></ul></p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"JV43ilZwsikj75j1","name":"The Shakes","type":"condition","img":"systems/mosh/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>You can’t keep your hands steady any more. Disadvantage on ranged attacks and all tasks requiring fine motor skills. Drugs may be able to help with this.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"xlKWL5nZm3SJPhrf","name":"Threat Assessment Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>You lose the ability to discern friend from foe, treating all vaguely-humanoid entities as you would members of your crew.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"iZzcfZ26I2svoonl","name":"Turing Test Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/turing_test_failure.png","system":{"description":"<p>Have difficulty expressing humanity. Party members make a Fear Save whenever you show up.<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.Er4ULzvdn2urxuet]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"qsOHsbKMonl9tiaq","name":"Twitchy","type":"condition","img":"systems/mosh/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>Your manual tasks have Disadvantage.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"x0YRvBbVoHPILD6x","name":"Vocalization Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/vocalization_failure.png","system":{"description":"<p>Intermittently shrieks like a fax machine under duress. Lapses into morse code, cannot communicate or sneak.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZIYe2ULX7AKP5MVI","name":"Worship Danger","type":"condition","img":"systems/mosh/images/icons/ui/conditions/worship_danger.png","system":{"description":"<p>Becomes Nihilistically Worshipful of the Source of Danger. Everyone else has Disadvantage on rolls against it. Everyone else takes a Fear save when failing to act against danger or gains a Phobia.<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.Er4ULzvdn2urxuet]{Fear Save}<br><br>@UUID[Compendium.mosh.macros_triggered_0e.Macro.qwmJTfTgmjNEApfX]{+1 Phobia}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8Ypj7tMZqoMYsqVJ","name":"The Bends","type":"condition","img":"systems/mosh/images/icons/ui/conditions/the_bends.png","system":{"description":"<p>You doubt the true nature of your identity. If you are human, you have started to believe you may be an android with implanted memories. If you are an android, you have started to believe you are a real person.<br><br>The severity of this condition starts at 5 unless you still have your <strong>Trinket</strong> from character creation, in which case it starts at 0. The Bends can never be decreased below 5, unless you never lose control of your Trinket. So you should never lose it. <strong>Ever.</strong></p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"2D3zgP8KtRTAqlfS","name":"Addiction","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/addicted.png","system":{"description":"<p>Excessive use of Pain Pills or Stimpaks requires a <strong>Body Save to prevent addiction</strong>. Once addicted, make a daily Body Save or gain 1d10 Stress every day you go without. If used once per day for a week you’ll need to take twice the amount of pills to gain the same effect.<br><br>Whenever you take more than one pill at a time roll 1d10. If you roll equal to or under the number taken make a Body Save. Failure means you fall unconscious and the Warden rolls a Death Save. You can cure an addiction through in-game treatment or leveling up.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"QEVnimwq5o0DxmZz","name":"Anhedonia","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/exhausted.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much Calm instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"23qE7TnIHxtw1E9y","name":"Bit Rot","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/data_loss.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZzvKo0yTqOcRP5Xo","name":"Broken","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/deflated.png","system":{"description":"<p>Make a Panic Check whenever a nearby crew member fails a Save.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Qnv6ZDPsbOXLi9go","name":"Cowardice","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/coward.png","system":{"description":"<p>You must make a Fear Save to engage in combat or else flee.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uoeVaOy5a6BIAGAi","name":"Death Drive","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>Whenever you encounter a stranger or known enemy you must make a Sanity Save or else immediately attack them.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PiMuPeHR5EobSPBP","name":"Deviant Logic Core","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dAJRV7JG0Wh1shcJ","name":"Emotional Detachment","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/detached.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you gain the Panic Effect of an Android, in addition to that of your own class. If you are an Android, gain the Panic Effect of a Marine.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"6vExNGxZiXcC3RFy","name":"Escapism","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/addicted.png","system":{"description":"<p>You always have Disadvantage on Body Saves to prevent Addiction.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kI2Yxt0Eo2mEywpZ","name":"Ethical Directive Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you now have the Panic Effect of a Marine, in addition to that of an Android.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5E3FGlNzi05S792f","name":"Ethical Directive Misread","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>Loses any expressiveness. Discusses the irrationality of Phobias, seeks to trigger them in others.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8D9ZtBYScCKjcBH3","name":"Faulty Heuristics","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/faulty_heuristics.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"B8vRorrFy3c2cOf5","name":"Fried Logic Core","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Frenzied nonsensical behaviour. Whenever you lose Calm, everyone else nearby loses the same amount of Calm.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"RZ5X3UuiM0Wzg3pQ","name":"Hallucinations","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/loss_of_confidence.png","system":{"description":"<p>You have trouble distinguishing between reality and fantasy.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"A3qRm3Gs36Nbfs29","name":"Hypervigilance","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/hypervigilance.png","system":{"description":"<p>Gain Advantage on all surprise rolls but lose 1d10 Calm every day.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.5jMEd9JjJPIJBKHr]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"9vveNoR1VA9Bx0Wo","name":"Insane","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/spiraling.png","system":{"description":"<p>You become permanently, irreparably insane. Your character is now played by the Warden.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"hAfwbHxZih4Xb0qi","name":"Killswitch Engaged","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/killswitch.png","system":{"description":"<p>Go berserk, will not withdraw from combat regardless of situation, will not adhere to tactics.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1r6ruvSdxn2bHHIk","name":"Losing Your Grip","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"AXxmouWPp6Tx1JbK","name":"Panicky","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"lxIZLdg2IkwOC2b9","name":"Paranoid","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/suspicious.png","system":{"description":"<p>Whenever a character joins your group <em>(even if they only left for a short period of time)</em>, make a Fear Save or gain 1 Stress.<><>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.Er4ULzvdn2urxuet]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"lf1QZaUHSy82w7SR","name":"Phobia","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/frightened.png","system":{"description":"<p>Gain a new permanent phobia. Whenever you encounter this phobia make a Fear Save at Disadvantage.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.RdJ2nh41wDUT4ZTP]{Fear Save [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Gm2XrTqVMbECVPan","name":"Psychotic Episodes","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"GbDO8pRNdPA5tQXE","name":"Rampancy","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round. These episodes double in duration <em>(or become twice as frequent)</em> each session.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"zbKI2RCl5h3vowoy","name":"Recurring Nightmares","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/nightmares.png","system":{"description":"<p>Every time you rest, make a Fear save. If you fail, lose 1d10 Calm and do not heal. The Warden will describe your nightmare.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.5jMEd9JjJPIJBKHr]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"H4UUQsZOSaYGRPSY","name":"Severe Anxiety","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"xVW5zbK05EqQmaA4","name":"Social Anxiety","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose 1d10 Calm whenever you converse with someone new.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.5jMEd9JjJPIJBKHr]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1rUlQJ5iwD29X4oT","name":"Software Bloat","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/software_bloat.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"XxjONzW7H4tIIAkN","name":"Starving","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/starving.png","system":{"description":"<p>Humans can survive roughly 3 weeks without food. <strong>After 24 hours without food you’re at Disadvantage to all rolls.</strong><br><br>The bare minimum to survive: you’ll need <strong>1 liter of water a day</strong>. However, at this level any strenuous activity (like running, Combat, or making mechanical repairs) will force you to make a Body Save or pass out. When water is scarce and you’re tracking it this closely you’re at Disadvantage to all Checks.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uOPcbqhk5sQHB8A2","name":"Suffocating","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/suffocating.png","system":{"description":"<p>In space you can last 15 seconds without oxygen before you fall unconscious. After passing out you can survive for 3-5 minutes before dying.<br><br><ul><li>If less than half of the original oxygen remains every roll is made at Disadvantage. All crew suffer headaches, fatigue, anxiety and general clumsiness.</li><li>If less than a quarter of the original oxygen amount remains players must make a Body Save once per day (and after every strenuous activity) or fall unconscious. All crew suffer panting, dizziness, severe headaches and impaired vision and tinnitus.</li><li>If a player runs out of oxygen they must make a Body Save. Failure means they die. Success means they fall unconscious and leach oxygen from a random player every day.</li></ul></p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"JV43ilZwsikj75j1","name":"The Shakes","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>You can’t keep your hands steady any more. Disadvantage on ranged attacks and all tasks requiring fine motor skills. Drugs may be able to help with this.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"xlKWL5nZm3SJPhrf","name":"Threat Assessment Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>You lose the ability to discern friend from foe, treating all vaguely-humanoid entities as you would members of your crew.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"iZzcfZ26I2svoonl","name":"Turing Test Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/turing_test_failure.png","system":{"description":"<p>Have difficulty expressing humanity. Party members make a Fear Save whenever you show up.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.Er4ULzvdn2urxuet]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"qsOHsbKMonl9tiaq","name":"Twitchy","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>Your manual tasks have Disadvantage.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"x0YRvBbVoHPILD6x","name":"Vocalization Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/vocalization_failure.png","system":{"description":"<p>Intermittently shrieks like a fax machine under duress. Lapses into morse code, cannot communicate or sneak.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZIYe2ULX7AKP5MVI","name":"Worship Danger","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/worship_danger.png","system":{"description":"<p>Becomes Nihilistically Worshipful of the Source of Danger. Everyone else has Disadvantage on rolls against it. Everyone else takes a Fear save when failing to act against danger or gains a Phobia.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.Er4ULzvdn2urxuet]{Fear Save}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_0e.Macro.qwmJTfTgmjNEApfX]{+1 Phobia}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8Ypj7tMZqoMYsqVJ","name":"The Bends","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/the_bends.png","system":{"description":"<p>You doubt the true nature of your identity. If you are human, you have started to believe you may be an android with implanted memories. If you are an android, you have started to believe you are a real person.<br><br>The severity of this condition starts at 5 unless you still have your <strong>Trinket</strong> from character creation, in which case it starts at 0. The Bends can never be decreased below 5, unless you never lose control of your Trinket. So you should never lose it. <strong>Ever.</strong></p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.814878 16f8db000 Recovering log #60
|
||||
2026/04/10-15:21:30.815292 16f8db000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.815311 16f8db000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.477917 16f81f000 Recovering log #86
|
||||
2026/05/27-23:54:37.483947 16f81f000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.484290 16f81f000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.939578 17164b000 Recovering log #58
|
||||
2026/04/10-15:15:40.939865 17164b000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.939883 17164b000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.611150 173b87000 Recovering log #84
|
||||
2026/05/19-23:19:40.611608 173b87000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.611656 173b87000 Delete type=0 #84
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
{"_id":"JM9PnNw2HVWcAfOX","name":"Anhedonia","type":"condition","img":"systems/mosh/images/icons/ui/conditions/exhausted.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much Calm instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"H1dqOrGg0voG2DmC","name":"Bit Rot","type":"condition","img":"systems/mosh/images/icons/ui/conditions/data_loss.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pxtF1NfletmoFFGV","name":"Bleeding","type":"condition","img":"systems/mosh/images/icons/ui/conditions/bleeding.png","system":{"description":"<p>Some weapons or Wounds cause you to <strong>Bleed</strong>. This means you take <strong>1 Damage every round until the bleeding is stopped.</strong> This is cumulative. If a character is bleeding 1 Damage per round and gains <strong>Bleeding +1,</strong> they now take 2 Damage per round. Bleeding damage ignores armor and damage reduction.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.aur5HWqZJNspwdCd]{Take Bleeding Damage}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZXyoVuMAsEDmU5Qi","name":"Broken","type":"condition","img":"systems/mosh/images/icons/ui/conditions/deflated.png","system":{"description":"<p>Make a Panic Check whenever a nearby crew member fails a Save.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"acxtiC0oGwQloAwj","name":"Corrosive Atmosphere","type":"condition","img":"systems/mosh/images/icons/ui/conditions/corrosive_atmosphere.png","system":{"description":"<p>Planets with Corrosive atmospheres require special gear to explore, otherwise there is the risk of harm or even death.<br><br>The planet’s atmosphere is deadly and destructive. It deals Damage every round while on it. <strong>This ranges from 1 DMG / round <em>(Mildly Corrosive)</em> to 10 DMG / round <em>(Highly Corrosive)</em>.</strong> Anything higher is simply impossible to safely traverse without specialized equipment and armor.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.vwpxRBbMwjfDCQVG]{-1 Health}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.C9iTlPOpROuuYi2F]{-10 Health}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"YIF9QkUlexxauSCE","name":"Coward","type":"condition","img":"systems/mosh/images/icons/ui/conditions/coward.png","system":{"description":"<p>You must make a Fear Save to engage in violence, otherwise you flee.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"j26FZQ2gYuNfMKkc","name":"Cryosickness","type":"condition","img":"systems/mosh/images/icons/ui/conditions/cryosickness.png","system":{"description":"<p>To endure long space journeys or hyperspace jumps, crews use cryopods, which are coffinlike capsules that freeze them in a suspended animation called cryosleep. While in cryosleep, vitals are preserved and aging slows down. However, upon awakening, you experience a hangover-like feeling called cryosickness, which causes sluggishness and slow reflexes. <strong>While cryosick you suffer [-] on all rolls for 1 week.</strong> Upgraded cryochambers can help mitigate these effects, and a stimpak can cure them instantly.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"srws3n4rpl4oCj83","name":"Death Wish","type":"condition","img":"systems/mosh/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>For the next 24 hours, whenever you encounter a stranger or known enemy, make a Sanity Save or immediately attack them.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.TkMfT4RIczQb56j2]{Sanity Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"waimTU6LXaADcJrT","name":"Deflated","type":"condition","img":"systems/mosh/images/icons/ui/conditions/deflated.png","system":{"description":"<p>Whenever a Close crewmember fails a Save, gain 1 Stress.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.dvJR9DYXI2kV0BbR]{+1 Stress}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PTK6ds7eJvJDonbp","name":"Deviant Logic Core","type":"condition","img":"systems/mosh/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"x41AwiI03h7wNjaM","name":"Doomed","type":"condition","img":"systems/mosh/images/icons/ui/conditions/doomed.png","system":{"description":"<p>You feel cursed and unlucky. All Critical Successes are instead Critical Failures.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"iiiAIZvpfUUNai74","name":"Emotional Detachment","type":"condition","img":"systems/mosh/images/icons/ui/conditions/detached.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you gain the Panic Effect of an Android, in addition to that of your own class. If you are an Android, gain the Panic Effect of a Marine.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"qejBMjd8niz1y3Zi","name":"Escapism","type":"condition","img":"systems/mosh/images/icons/ui/conditions/addicted.png","system":{"description":"<p>You always have Disadvantage on Body Saves to prevent Addiction.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pe7ChrErjX6N57VP","name":"Ethical Directive Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you now have the Panic Effect of a Marine, in addition to that of an Android.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"OBpJQ7uYIj3KezNc","name":"Ethical Directive Misread","type":"condition","img":"systems/mosh/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>Loses any expressiveness. Discusses the irrationality of Phobias, seeks to trigger them in others.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"jfcpnfM3bSHvMJlG","name":"Exhausted","type":"condition","img":"systems/mosh/images/icons/ui/conditions/exhausted.png","system":{"description":"<p>Long grueling treks on undiscovered planets can easily grind you down. If it becomes relevant, track exhaustion by making a Body Save every hour after 12 hours of activity. On a failure gain 1 Stress and take 1 Damage. <strong>After 24 hours of exhaustion, roll at Disadvantage on all rolls until you can rest for 8 hours.</strong><br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.vwpxRBbMwjfDCQVG]{-1 Health}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uco5QbXZ6ZTKxx9g","name":"Extreme Cold","type":"condition","img":"systems/mosh/images/icons/ui/conditions/extreme_cold.png","system":{"description":"<p>In most cases, a cold climate has no notable effects. However, in places of extreme cold, you should make Body Saves every hour or succumb to the Extreme Cold.<br><br>In sub-zero temperatures hypothermia and frostbite can set in within 10-30 min for those not dressed appropriately. To survive you must bring your body up to its normal temperature. Hypothermia can kill within 30 min to 6 hours.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"9DsSQajDLqPGpK2i","name":"Extreme Heat","type":"condition","img":"systems/mosh/images/icons/ui/conditions/extreme_heat.png","system":{"description":"<p>In most cases, a hot climate has no notable effects. However, in places of extreme heat, you should make Body Saves every hour or succumb to the Extreme Heat.<br><br>Extreme heat over 100ºF/40ºC can cause heat stroke and kill within hours. Victims must move to a cooler location immediately to get their temperature down.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uPVp78kHmvMSYx2F","name":"Faulty Heuristics","type":"condition","img":"systems/mosh/images/icons/ui/conditions/faulty_heuristics.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kYdj6XJlPvJAhBEN","name":"Fried Logic Core","type":"condition","img":"systems/mosh/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Frenzied nonsensical behaviour. Whenever you lose Calm, everyone else nearby loses the same amount of Calm.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"z0avrplKe6M0RcXk","name":"Frightened","type":"condition","img":"systems/mosh/images/icons/ui/conditions/frightened.png","system":{"description":"<p>When encountering what frightened you make a Fear Save [-] or gain 1d5 Stress.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.wVhApjRP5MXue2kh]{Fear Save -}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.luNKvwmm2tjUJhT6]{+1d5 Stress}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"oTafwWjoNOE7nBrj","name":"Hallucinations","type":"condition","img":"systems/mosh/images/icons/ui/conditions/loss_of_confidence.png","system":{"description":"<p>You have trouble distinguishing between reality and fantasy.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"olC4JytslvUrQN8g","name":"Haunted","type":"condition","img":"systems/mosh/images/icons/ui/conditions/haunted.png","system":{"description":"<p>Something starts visiting you at night. In your dreams. Out of the corner of your eye. And soon it will start making demands.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"tGYYK71q2QxnPtpL","name":"Hypervigilance","type":"condition","img":"systems/mosh/images/icons/ui/conditions/hypervigilance.png","system":{"description":"<p>Gain Advantage on all surprise rolls but lose 1d10 Calm every day.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.jHyqXb2yDFTNWxpy]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"0ZAwhewvLBwX3opf","name":"Insane","type":"condition","img":"systems/mosh/images/icons/ui/conditions/spiraling.png","system":{"description":"<p>You become permanently, irreparably insane. Your character is now played by the Warden.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"gSTHeVqpynRxoQEy","name":"Irradiated","type":"condition","img":"systems/mosh/images/icons/ui/conditions/irradiated.png","system":{"description":"<p>Whether it’s cosmic rays, an engine leak, or some previously undiscovered asteroid ore, radiation can kill you if you’re not careful.<br><br><ul><li><strong>Level 1 - Trace Radiation</strong><br>Normal, everyday radiation, cosmic rays. Damage: None immediately. Possible longterm side effects <em>(cancer, etc.).</em></li><li><strong>Level 2 - Acute Radiation</strong><br>Unshielded reactors/Warp Cores. Damage: Reduce all Stats and Saves by 1 every round.</li><li><strong>Level 3 - Lethal Radiation</strong><br>Atomic weapons, direct handling of Warp Cores. Damage: Every round: Body Save or lethal dose <em>(death in [[/r 1d5]] days).</em></li></ul><br>Armor with <strong>Radiation Shielding</strong> <em>(e.g., the Hazard Suit).</em> blocks all three levels of radiation.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.V1PPeCwryXNQAkUe]{-1 All Stats/Saves}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"g6CuxCqbyRnNa57N","name":"Killswitch Engaged","type":"condition","img":"systems/mosh/images/icons/ui/conditions/killswitch.png","system":{"description":"<p>Go berserk, will not withdraw from combat regardless of situation, will not adhere to tactics.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kNjz3I0yAYkt9CV0","name":"Losing Your Grip","type":"condition","img":"systems/mosh/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kbbVOYgjwzoODs7N","name":"Loss of Confidence","type":"condition","img":"systems/mosh/images/icons/ui/conditions/loss_of_confidence.png","system":{"description":"<p>Choose one Skill and lose that Skill’s bonus.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"MLPSYfWrwY6R7JDy","name":"Nightmares","type":"condition","img":"systems/mosh/images/icons/ui/conditions/nightmares.png","system":{"description":"<p>Sleep is difficult, gain [-] on Rest Saves.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.AM9nIK5l7mC5Ho8C]{Rest Save [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EW7X6FfetwxmZDzf","name":"Panicky","type":"condition","img":"systems/mosh/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"NuzL7Yi7PvUOeWsj","name":"Phobia","type":"condition","img":"systems/mosh/images/icons/ui/conditions/frightened.png","system":{"description":"<p>Gain a new permanent phobia. Whenever you encounter this phobia make a Fear Save at Disadvantage.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.wVhApjRP5MXue2kh]{Fear Save [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"og4lXN03vH5pwSDC","name":"Psychotic Episodes","type":"condition","img":"systems/mosh/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"lXoBqGW2eCK0b1tX","name":"Rampancy","type":"condition","img":"systems/mosh/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round. These episodes double in duration <em>(or become twice as frequent)</em> each session.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"S2kZpUl3nNPS4wNS","name":"Recurring Nightmares","type":"condition","img":"systems/mosh/images/icons/ui/conditions/nightmares.png","system":{"description":"<p>Every time you rest, make a Fear save. If you fail, lose 1d10 Calm and do not heal. The Warden will describe your nightmare.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.jHyqXb2yDFTNWxpy]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"CPRLqpW9inXDLYjS","name":"Severe Anxiety","type":"condition","img":"systems/mosh/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"hskhRKLEAJN7huAk","name":"Social Anxiety","type":"condition","img":"systems/mosh/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose 1d10 Calm whenever you converse with someone new.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.jHyqXb2yDFTNWxpy]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dA6COSDLbpmKdOkm","name":"Software Bloat","type":"condition","img":"systems/mosh/images/icons/ui/conditions/software_bloat.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Bt2rl2c5jGyt3QAr","name":"Spiraling","type":"condition","img":"systems/mosh/images/icons/ui/conditions/spiraling.png","system":{"description":"<p>Panic Checks are at [-].<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.EwZbGIwHB3JuRvx5]{Panic Check [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"6zDq1nvEr3AYLcLn","name":"Starving","type":"condition","img":"systems/mosh/images/icons/ui/conditions/starving.png","system":{"description":"<p>Humans can survive roughly 3 weeks without food. <strong>After 24 hours without food, you’re at Disadvantage to all rolls.</strong><br><br>For the bare minimum of survival you need 1 liter of water a day. However, at this level, any strenuous activity <em>(e.g., running, combat, making mechanical repairs)</em> forces you to make a Body Save or pass out. <strong>When water is scarce and you’re tracking it this closely, you’re at Disadvantage on all rolls.</strong><br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"VCgpc7OwyMU23Clv","name":"Suffocating","type":"condition","img":"systems/mosh/images/icons/ui/conditions/suffocating.png","system":{"description":"<p>In space you can last 15 seconds without oxygen before falling unconscious. After passing out, you can survive for [[/r 1d5]] minutes before dying.<br><br>If all of a ship’s Life Support system goes offline, roll [[/r 1d10]] and multiply it by the maximum crew capacity. This is the remaining oxygen supply.<br><br><strong>Every 24 hours, subtract the total number of breathing crewmembers from the remaining oxygen supply.</strong> Any crewmembers engaging in strenous activity <em>(e.g., running, combat, mechanical repairs, etc.)</em> further reduce the oxygen supply by 2 each.<br><br><strong>Whenever the oxygen supply is less than twice the amount of breathing passengers,</strong> all rolls are at Disadvantage as the crew suffers headaches, fatigue, anxiety, and general clumsiness.<br><br><strong>Whenever the oxygen supply is less than the total amount of breathing passengers,</strong> every breathing passenger must make a Body Save or else make a <strong>Death Save</strong> as they suffer panting, dizziness, severe headaches, impaired vision and tinnitus.<br><br><strong>Once the oxygen supply runs out,</strong> you can survive for 15 seconds before you fall unconscious. After falling unconscious, <strong>you can survive for [[/r 1d5]] minutes without oxygen before dying.</strong><br><br>Androids do not consume oxygen from the oxygen supply. Those in cryosleep do not reduce the Oxygen supply.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.Macro.NsRHfRuuNGPfkYVf]{Death Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8lOkseRbg09YFvv7","name":"Suspicious","type":"condition","img":"systems/mosh/images/icons/ui/conditions/suspicious.png","system":{"description":"<p>For the next week, whenever someone joins the crew <em>(even if they only left for a short period of time),</em> make a Fear Save or gain 1 Stress.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"d3KlY4zMdD1j3CTW","name":"The Shakes","type":"condition","img":"systems/mosh/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>You can’t keep your hands steady any more. Disadvantage on ranged attacks and all tasks requiring fine motor skills. Drugs may be able to help with this.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"HZBI88iwvtQVWKOR","name":"Threat Assessment Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>You lose the ability to discern friend from foe, treating all vaguely-humanoid entities as you would members of your crew.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"TCB5GnuGt45WbPsw","name":"Toxic Atmosphere","type":"condition","img":"systems/mosh/images/icons/ui/conditions/toxic_atmosphere.png","system":{"description":"<p>Planets with Toxic atmospheres require special gear to explore, otherwise there is the risk of harm or even death.<br><br>The planet’s atmosphere is not fit to breathe, but is otherwise safe. A rebreather or armor with its own oxygen supply is required. Without these, <strong>characters take 1d10 DMG per round, Body Save for half.</strong><br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.w3ttEaXP7yp25M5Q]{-1d10 Health}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"a87x3Hk72ymOx5rf","name":"Turing Test Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/turing_test_failure.png","system":{"description":"<p>Have difficulty expressing humanity. Party members make a Fear Save whenever you show up.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kiJyYYxzy5TdjTfS","name":"Twitchy","type":"condition","img":"systems/mosh/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>Your manual tasks have Disadvantage.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZO4f9gvaiVSKDmRC","name":"Vocalization Failure","type":"condition","img":"systems/mosh/images/icons/ui/conditions/vocalization_failure.png","system":{"description":"<p>Intermittently shrieks like a fax machine under duress. Lapses into morse code, cannot communicate or sneak.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"LDoAzwiELtLjgxrf","name":"Worship Danger","type":"condition","img":"systems/mosh/images/icons/ui/conditions/worship_danger.png","system":{"description":"<p>Becomes Nihilistically Worshipful of the Source of Danger. Everyone else has Disadvantage on rolls against it. Everyone else takes a Fear save when failing to act against danger or gains a Phobia.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.RTL29CqdaAriGSTS]{+1 Phobia}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PCPGYzzFaFjws1LL","name":"The Bends","type":"condition","img":"systems/mosh/images/icons/ui/conditions/the_bends.png","system":{"description":"<p>You doubt the true nature of your identity. If you are human, you have started to believe you may be an android with implanted memories. If you are an android, you have started to believe you are a real person.<br><br>The severity of this condition starts at 5 unless you still have your <strong>Trinket</strong> from character creation, in which case it starts at 0. The Bends can never be decreased below 5, unless you never lose control of your Trinket. So you should never lose it. <strong>Ever.</strong></p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"JM9PnNw2HVWcAfOX","name":"Anhedonia","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/exhausted.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much Calm instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"H1dqOrGg0voG2DmC","name":"Bit Rot","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/data_loss.png","system":{"description":"<p>Whenever you would recover Calm, recover half as much instead.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pxtF1NfletmoFFGV","name":"Bleeding","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/bleeding.png","system":{"description":"<p>Some weapons or Wounds cause you to <strong>Bleed</strong>. This means you take <strong>1 Damage every round until the bleeding is stopped.</strong> This is cumulative. If a character is bleeding 1 Damage per round and gains <strong>Bleeding +1,</strong> they now take 2 Damage per round. Bleeding damage ignores armor and damage reduction.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.aur5HWqZJNspwdCd]{Take Bleeding Damage}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZXyoVuMAsEDmU5Qi","name":"Broken","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/deflated.png","system":{"description":"<p>Make a Panic Check whenever a nearby crew member fails a Save.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"acxtiC0oGwQloAwj","name":"Corrosive Atmosphere","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/corrosive_atmosphere.png","system":{"description":"<p>Planets with Corrosive atmospheres require special gear to explore, otherwise there is the risk of harm or even death.<br><br>The planet’s atmosphere is deadly and destructive. It deals Damage every round while on it. <strong>This ranges from 1 DMG / round <em>(Mildly Corrosive)</em> to 10 DMG / round <em>(Highly Corrosive)</em>.</strong> Anything higher is simply impossible to safely traverse without specialized equipment and armor.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.vwpxRBbMwjfDCQVG]{-1 Health}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.C9iTlPOpROuuYi2F]{-10 Health}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"YIF9QkUlexxauSCE","name":"Coward","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/coward.png","system":{"description":"<p>You must make a Fear Save to engage in violence, otherwise you flee.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"j26FZQ2gYuNfMKkc","name":"Cryosickness","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/cryosickness.png","system":{"description":"<p>To endure long space journeys or hyperspace jumps, crews use cryopods, which are coffinlike capsules that freeze them in a suspended animation called cryosleep. While in cryosleep, vitals are preserved and aging slows down. However, upon awakening, you experience a hangover-like feeling called cryosickness, which causes sluggishness and slow reflexes. <strong>While cryosick you suffer [-] on all rolls for 1 week.</strong> Upgraded cryochambers can help mitigate these effects, and a stimpak can cure them instantly.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"srws3n4rpl4oCj83","name":"Death Wish","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>For the next 24 hours, whenever you encounter a stranger or known enemy, make a Sanity Save or immediately attack them.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.TkMfT4RIczQb56j2]{Sanity Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"waimTU6LXaADcJrT","name":"Deflated","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/deflated.png","system":{"description":"<p>Whenever a Close crewmember fails a Save, gain 1 Stress.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.dvJR9DYXI2kV0BbR]{+1 Stress}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PTK6ds7eJvJDonbp","name":"Deviant Logic Core","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"x41AwiI03h7wNjaM","name":"Doomed","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/doomed.png","system":{"description":"<p>You feel cursed and unlucky. All Critical Successes are instead Critical Failures.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"iiiAIZvpfUUNai74","name":"Emotional Detachment","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/detached.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you gain the Panic Effect of an Android, in addition to that of your own class. If you are an Android, gain the Panic Effect of a Marine.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"qejBMjd8niz1y3Zi","name":"Escapism","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/addicted.png","system":{"description":"<p>You always have Disadvantage on Body Saves to prevent Addiction.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pe7ChrErjX6N57VP","name":"Ethical Directive Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>You now lose half the Calm <em>(rounded up)</em> you normally would from all sources but you now have the Panic Effect of a Marine, in addition to that of an Android.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"OBpJQ7uYIj3KezNc","name":"Ethical Directive Misread","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/moral_compass.png","system":{"description":"<p>Loses any expressiveness. Discusses the irrationality of Phobias, seeks to trigger them in others.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"jfcpnfM3bSHvMJlG","name":"Exhausted","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/exhausted.png","system":{"description":"<p>Long grueling treks on undiscovered planets can easily grind you down. If it becomes relevant, track exhaustion by making a Body Save every hour after 12 hours of activity. On a failure gain 1 Stress and take 1 Damage. <strong>After 24 hours of exhaustion, roll at Disadvantage on all rolls until you can rest for 8 hours.</strong><br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.vwpxRBbMwjfDCQVG]{-1 Health}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uco5QbXZ6ZTKxx9g","name":"Extreme Cold","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/extreme_cold.png","system":{"description":"<p>In most cases, a cold climate has no notable effects. However, in places of extreme cold, you should make Body Saves every hour or succumb to the Extreme Cold.<br><br>In sub-zero temperatures hypothermia and frostbite can set in within 10-30 min for those not dressed appropriately. To survive you must bring your body up to its normal temperature. Hypothermia can kill within 30 min to 6 hours.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"9DsSQajDLqPGpK2i","name":"Extreme Heat","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/extreme_heat.png","system":{"description":"<p>In most cases, a hot climate has no notable effects. However, in places of extreme heat, you should make Body Saves every hour or succumb to the Extreme Heat.<br><br>Extreme heat over 100ºF/40ºC can cause heat stroke and kill within hours. Victims must move to a cooler location immediately to get their temperature down.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"uPVp78kHmvMSYx2F","name":"Faulty Heuristics","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/faulty_heuristics.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kYdj6XJlPvJAhBEN","name":"Fried Logic Core","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/logic_core.png","system":{"description":"<p>Frenzied nonsensical behaviour. Whenever you lose Calm, everyone else nearby loses the same amount of Calm.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"z0avrplKe6M0RcXk","name":"Frightened","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/frightened.png","system":{"description":"<p>When encountering what frightened you make a Fear Save [-] or gain 1d5 Stress.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.wVhApjRP5MXue2kh]{Fear Save -}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.luNKvwmm2tjUJhT6]{+1d5 Stress}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"oTafwWjoNOE7nBrj","name":"Hallucinations","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/loss_of_confidence.png","system":{"description":"<p>You have trouble distinguishing between reality and fantasy.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"olC4JytslvUrQN8g","name":"Haunted","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/haunted.png","system":{"description":"<p>Something starts visiting you at night. In your dreams. Out of the corner of your eye. And soon it will start making demands.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"tGYYK71q2QxnPtpL","name":"Hypervigilance","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/hypervigilance.png","system":{"description":"<p>Gain Advantage on all surprise rolls but lose 1d10 Calm every day.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.jHyqXb2yDFTNWxpy]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"0ZAwhewvLBwX3opf","name":"Insane","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/spiraling.png","system":{"description":"<p>You become permanently, irreparably insane. Your character is now played by the Warden.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"gSTHeVqpynRxoQEy","name":"Irradiated","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/irradiated.png","system":{"description":"<p>Whether it’s cosmic rays, an engine leak, or some previously undiscovered asteroid ore, radiation can kill you if you’re not careful.<br><br><ul><li><strong>Level 1 - Trace Radiation</strong><br>Normal, everyday radiation, cosmic rays. Damage: None immediately. Possible longterm side effects <em>(cancer, etc.).</em></li><li><strong>Level 2 - Acute Radiation</strong><br>Unshielded reactors/Warp Cores. Damage: Reduce all Stats and Saves by 1 every round.</li><li><strong>Level 3 - Lethal Radiation</strong><br>Atomic weapons, direct handling of Warp Cores. Damage: Every round: Body Save or lethal dose <em>(death in [[/r 1d5]] days).</em></li></ul><br>Armor with <strong>Radiation Shielding</strong> <em>(e.g., the Hazard Suit).</em> blocks all three levels of radiation.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.V1PPeCwryXNQAkUe]{-1 All Stats/Saves}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"g6CuxCqbyRnNa57N","name":"Killswitch Engaged","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/killswitch.png","system":{"description":"<p>Go berserk, will not withdraw from combat regardless of situation, will not adhere to tactics.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kNjz3I0yAYkt9CV0","name":"Losing Your Grip","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Sanity save, roll under your Sanity or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kbbVOYgjwzoODs7N","name":"Loss of Confidence","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/loss_of_confidence.png","system":{"description":"<p>Choose one Skill and lose that Skill’s bonus.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"MLPSYfWrwY6R7JDy","name":"Nightmares","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/nightmares.png","system":{"description":"<p>Sleep is difficult, gain [-] on Rest Saves.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.AM9nIK5l7mC5Ho8C]{Rest Save [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EW7X6FfetwxmZDzf","name":"Panicky","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/distress.png","system":{"description":"<p>Whenever you make a Fear save, roll under your Fear or your Calm, whichever is lower.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"NuzL7Yi7PvUOeWsj","name":"Phobia","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/frightened.png","system":{"description":"<p>Gain a new permanent phobia. Whenever you encounter this phobia make a Fear Save at Disadvantage.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.wVhApjRP5MXue2kh]{Fear Save [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"og4lXN03vH5pwSDC","name":"Psychotic Episodes","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"lXoBqGW2eCK0b1tX","name":"Rampancy","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/confused.png","system":{"description":"<p>Once per session, the Warden may take over your character for one round. These episodes double in duration <em>(or become twice as frequent)</em> each session.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"S2kZpUl3nNPS4wNS","name":"Recurring Nightmares","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/nightmares.png","system":{"description":"<p>Every time you rest, make a Fear save. If you fail, lose 1d10 Calm and do not heal. The Warden will describe your nightmare.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.jHyqXb2yDFTNWxpy]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"CPRLqpW9inXDLYjS","name":"Severe Anxiety","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"hskhRKLEAJN7huAk","name":"Social Anxiety","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/anxiety.png","system":{"description":"<p>Lose 1d10 Calm whenever you converse with someone new.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.jHyqXb2yDFTNWxpy]{-1d10 Calm}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dA6COSDLbpmKdOkm","name":"Software Bloat","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/software_bloat.png","system":{"description":"<p>Lose double Calm from all sources.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Bt2rl2c5jGyt3QAr","name":"Spiraling","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/spiraling.png","system":{"description":"<p>Panic Checks are at [-].<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.EwZbGIwHB3JuRvx5]{Panic Check [-]}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"6zDq1nvEr3AYLcLn","name":"Starving","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/starving.png","system":{"description":"<p>Humans can survive roughly 3 weeks without food. <strong>After 24 hours without food, you’re at Disadvantage to all rolls.</strong><br><br>For the bare minimum of survival you need 1 liter of water a day. However, at this level, any strenuous activity <em>(e.g., running, combat, making mechanical repairs)</em> forces you to make a Body Save or pass out. <strong>When water is scarce and you’re tracking it this closely, you’re at Disadvantage on all rolls.</strong><br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"VCgpc7OwyMU23Clv","name":"Suffocating","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/suffocating.png","system":{"description":"<p>In space you can last 15 seconds without oxygen before falling unconscious. After passing out, you can survive for [[/r 1d5]] minutes before dying.<br><br>If all of a ship’s Life Support system goes offline, roll [[/r 1d10]] and multiply it by the maximum crew capacity. This is the remaining oxygen supply.<br><br><strong>Every 24 hours, subtract the total number of breathing crewmembers from the remaining oxygen supply.</strong> Any crewmembers engaging in strenous activity <em>(e.g., running, combat, mechanical repairs, etc.)</em> further reduce the oxygen supply by 2 each.<br><br><strong>Whenever the oxygen supply is less than twice the amount of breathing passengers,</strong> all rolls are at Disadvantage as the crew suffers headaches, fatigue, anxiety, and general clumsiness.<br><br><strong>Whenever the oxygen supply is less than the total amount of breathing passengers,</strong> every breathing passenger must make a Body Save or else make a <strong>Death Save</strong> as they suffer panting, dizziness, severe headaches, impaired vision and tinnitus.<br><br><strong>Once the oxygen supply runs out,</strong> you can survive for 15 seconds before you fall unconscious. After falling unconscious, <strong>you can survive for [[/r 1d5]] minutes without oxygen before dying.</strong><br><br>Androids do not consume oxygen from the oxygen supply. Those in cryosleep do not reduce the Oxygen supply.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}<br><br>@UUID[Compendium.sla-mothership.macros_hotbar_1e.Macro.NsRHfRuuNGPfkYVf]{Death Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8lOkseRbg09YFvv7","name":"Suspicious","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/suspicious.png","system":{"description":"<p>For the next week, whenever someone joins the crew <em>(even if they only left for a short period of time),</em> make a Fear Save or gain 1 Stress.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"d3KlY4zMdD1j3CTW","name":"The Shakes","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>You can’t keep your hands steady any more. Disadvantage on ranged attacks and all tasks requiring fine motor skills. Drugs may be able to help with this.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"HZBI88iwvtQVWKOR","name":"Threat Assessment Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/death_wish.png","system":{"description":"<p>You lose the ability to discern friend from foe, treating all vaguely-humanoid entities as you would members of your crew.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"TCB5GnuGt45WbPsw","name":"Toxic Atmosphere","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/toxic_atmosphere.png","system":{"description":"<p>Planets with Toxic atmospheres require special gear to explore, otherwise there is the risk of harm or even death.<br><br>The planet’s atmosphere is not fit to breathe, but is otherwise safe. A rebreather or armor with its own oxygen supply is required. Without these, <strong>characters take 1d10 DMG per round, Body Save for half.</strong><br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3gqTFFwMe7AudiS]{Body Save}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.w3ttEaXP7yp25M5Q]{-1d10 Health}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"a87x3Hk72ymOx5rf","name":"Turing Test Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/turing_test_failure.png","system":{"description":"<p>Have difficulty expressing humanity. Party members make a Fear Save whenever you show up.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kiJyYYxzy5TdjTfS","name":"Twitchy","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/the_shakes.png","system":{"description":"<p>Your manual tasks have Disadvantage.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZO4f9gvaiVSKDmRC","name":"Vocalization Failure","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/vocalization_failure.png","system":{"description":"<p>Intermittently shrieks like a fax machine under duress. Lapses into morse code, cannot communicate or sneak.</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"LDoAzwiELtLjgxrf","name":"Worship Danger","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/worship_danger.png","system":{"description":"<p>Becomes Nihilistically Worshipful of the Source of Danger. Everyone else has Disadvantage on rolls against it. Everyone else takes a Fear save when failing to act against danger or gains a Phobia.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.R2KizR1soAhFYDZm]{Fear Save}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.RTL29CqdaAriGSTS]{+1 Phobia}</p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PCPGYzzFaFjws1LL","name":"The Bends","type":"condition","img":"systems/sla-mothership/images/icons/ui/conditions/the_bends.png","system":{"description":"<p>You doubt the true nature of your identity. If you are human, you have started to believe you may be an android with implanted memories. If you are an android, you have started to believe you are a real person.<br><br>The severity of this condition starts at 5 unless you still have your <strong>Trinket</strong> from character creation, in which case it starts at 0. The Bends can never be decreased below 5, unless you never lose control of your Trinket. So you should never lose it. <strong>Ever.</strong></p>","treatment":{"value":0,"html":""}},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.816908 16e0b7000 Recovering log #60
|
||||
2026/04/10-15:21:30.817298 16e0b7000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.817326 16e0b7000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.489334 16f013000 Recovering log #86
|
||||
2026/05/27-23:54:37.490810 16f013000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.491215 16f013000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.941390 170e3f000 Recovering log #58
|
||||
2026/04/10-15:15:40.941631 170e3f000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.941649 170e3f000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.613309 172363000 Recovering log #84
|
||||
2026/05/19-23:19:40.613576 172363000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.613610 172363000 Delete type=0 #84
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
{"_id":"ciAkQXkxSXTG8MV1","name":"Rancid smell permeates cabins.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pLleYaFjcIuAm4Pp","name":"Huge mess everywhere.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dReCCsfiV7it4lsm","name":"Staticky comms.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"4JRD71mvWNtFUDL7","name":"Faulty electrical system.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"59cXdcrZlmjUcJpV","name":"Loose couplings.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"CLvIvoNryBARtU7T","name":"Hidden (highly illegal) contraband.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vip6FxWcX4ReJD3b","name":"Autopilot systems down.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"AQt9nXy6S0Ev50r7","name":"Leaking hydraulic systems.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"QUyfvbFhCqb9d7Lu","name":"Creaking hull.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"SW5kVSjiFbBxIeiu","name":"Damaged bulkheads.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"wNm669fzbdZGwr0g","name":"Misaligned docking clamps.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"3l0LUZpjizvZmHWs","name":"Viewports blocked.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"c8SXxPHMsG7uycas","name":"Jammed exterior airlocks.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"9kS8VjGuSMpghdCk","name":"Dysfunctional gravity plating.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Low2X1z7m1iB3rkA","name":"Out of code compliance.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"BicB3xA1h978ZevJ","name":"Controls sticking.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"C9dQYp7gcjtq5QRz","name":"Coolant leak.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1HNvL7XEUcMQbLps","name":"Miscalibrated Thruster Gimbal System.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"xa9MPzfrPglkSJjg","name":"Bevvy of OSHA violations.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZbAFemnvHB1YTHBK","name":"Blocked air vents.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"wjyAZnOOafvv4xzB","name":"Emergency lighting only.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"l1OGQ0IXZHjnO4Ys","name":"Internal networking issues.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vleMoz5bbkZ5w28o","name":"Inaccurate data collection.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"T4wAR08WyT3g9C6D","name":"Oxygen leak. If ship is low on O2, lose 1d5 extra per day.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.u7TchSo3qutnzaKF]{-1d5 Oxygen}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"fbrN7sbgPjIwkk7I","name":"Throttled Afterburners. -2d10 Thrusters.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.jmOh8n2ps0YIeBC0]{-2d10 Thrusters}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"7GqbGIOzA9vYOPiI","name":"Lemon. Maintenance Checks at [-].<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.C04VbNoj8LgfY8QK]{Maintenance Check [-]}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dgisAPnBbrIOiisk","name":"Slow acceleration. +1 Week to travel.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"d94uF9rpmeP60Kl4","name":"Inaccurate navigation.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"3Ptitg8HBZfl2CXN","name":"Miscalibrated Targeting Sensors. -1d10 Battle.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.X3cL9eS2HOPxhLH5]{-1d10 Battle}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"mK1Acfk5NAgs1MHC","name":"Faulty Cryopods. Nightmares. Cryosickness lasts an additional week.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IR1sWnYXniMg9TdP","name":"Malfunctioning escape pods.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"FIqSHePAeLJywerx","name":"Unable to send distress signals.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"4kmMuAbW1jnfVMYP","name":"Sabotaged coolant system.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ALplRgZtneMRdloo","name":"Death trap. [-] on all rolls.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"2pxf4O2NrLdwYRtO","name":"Worn landing struts.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"64AQJ3zQDOb7NOR1","name":"Out-of-date air filters.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PKBXKvgWZwafKWJ3","name":"Corroded pipes.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"NgKPVhRkD8Gteo5Z","name":"Innaccurate orbital transfer navigation.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5d220ZzrEV3qx6Fy","name":"Worn out fuel injection nozzles.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IGx8nQrwfz07r6TR","name":"Inoperative exterior lighting system.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pW1FUDxp2N0M0D1y","name":"Defective intercom system.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"UPAxtEOrSF3Il4uA","name":"Inadequate waste recycling.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"m04JdXL1xGQOkDyp","name":"Faulty altitude control thrusters.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"OWkfB73RTSLDMlsU","name":"Insufficient Life Support redundancy.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"hNJYqetiMKUlZzYH","name":"Delayed communication relays.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"rlW0LUlsK7vDGZEh","name":"Damaged fuel lines.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IDiwAbD8DTbec7S1","name":"Corroded exhaust manifolds.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EteEoBrlnzcySppN","name":"Terminal displays non-functional.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"guvCGNRa75AB2Avg","name":"Check engine light won’t turn off.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"cbXMdd4ugxSOT5TU","name":"Failed backup systems.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kftgvuQoefQ7pl28","name":"Faulty door locks.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Odpb5coSTST7kCkc","name":"Buggy communications.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vMRVXZxu6ozj0iw2","name":"Infected food storage facilities.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"4Lqg0lqjjTlNlr0j","name":"Corrupted data banks.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Ka8elMGKtcakUIxx","name":"Jammed cargo bay doors.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"TAerNMqv19pANCxq","name":"Flickering interior lights.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vv1VykTwiQmgEj6N","name":"Failed airlock seals.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"GW1KGmYdxYYf4ZWT","name":"Fuel Leak. Burn +1 Fuel everytime you spend fuel.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"FLaPtHcegheN7wHw","name":"Jump Bug. 10% chance Jump takes 2d10 months, not 2d10 days.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"g9Z7He5zPHNrxYe1","name":"Fragile. Always take +1 MDMG.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IiPryFS9MOGZXeuG","name":"Cracked heat shields.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"FmPqHYH3UoGpaWYL","name":"Outdated software. -1d10 Systems.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.oDftFxRKkCQRNY2O]{-1d10 Systems}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"NLwybTzXJ1bndki3","name":"Inadequate Water Filtration. Parasites in the water supply.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"oySXnFIbRW0WRoeF","name":"Malfunctioning waste management system.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"RiHvRQ9nZDygwvvB","name":"Fusion Reactors overheating.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"wCYGQrI9qonhWy8F","name":"Failed radiation filter.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5J4r3yw4xDj890yZ","name":"Radiation leak. Entire ship is at Radiation Level 2.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"XmIcQgho4un7hYki","name":"Miscalibrated guidance system.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"KhlrUaPjVIoyhnaL","name":"Overloaded power storage.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"LRumIQdUBzD0Jc0X","name":"Malfunctioning sensor arrays.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"e144cIdUEyTJgN1G","name":"Failed Water Recovery System.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"b2b3j5JtanbyWlNd","name":"Micrometoroid hull damage.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5OBjTojgrp5N9mEw","name":"Faulty Carbon Dioxide Removal Assembly.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8s1eBY5bEcQQTCz0","name":"Solar panel degradation.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5UiJy739gvGHkRYp","name":"Computer failure from cosmic radiation.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"yJY9CzP1KA15aMqV","name":"Overloaded circuitry.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"nHac0gkEcCNew7RX","name":"Malfunctioning plasma thruster.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"DYHuVA4CQlmK2MJy","name":"Thermal management system failure.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"QIcoFYoC0hxW84qD","name":"Intermittent electrical outages.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"AuTERG3m7ECQKrKs","name":"Fire suppression system out of code.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1iOSKp82goZGJZch","name":"Damaged floor pannelling.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZBUtxiX72udqLzIk","name":"Broken light fixture in remote corridor.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"iwFmPpAth3VbRRL8","name":"Damaged coolant pump.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Eo0l4WMxcS62GCMP","name":"Cracked viewports.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"miRqXNzkW0biml1I","name":"Systems overloaded with malware.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"cOLcJ3Dnecbe6ZIU","name":"Leaky fuel valve.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"zRzb3Laiuw4ac6p0","name":"Jammed exhaust vent.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EZzGAO6DneH1qmQM","name":"Stuck waste disposal chute.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Tp6k1gPwhQmT6hCo","name":"Lifts non-functioning.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"2Ht7fg78511Hd49u","name":"Damaged communications antenna.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"XLEhMV9SnSfeEE7E","name":"Clogged Air Filtration. Crew capacity cut in half.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.DUuRY7kHKd7n5luv]{-50% Crew Capacity}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Z8raruNDvfNASFQi","name":"Malfunctioning climate control. 85º at all times.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"3rulbOVhyRlTizT0","name":"No emergency power.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ulWxa2UtTOQihTyz","name":"Weak Frame. -1 Hull, -1 Upgrade.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.uPY19Y49bGCLGK3N]{-1 Hull}<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.06NSvDYTtmkeUtLq]{-1 Upgrade}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EnogUslNNusSfVFy","name":"Toxic chemical spill.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ElXLL32uNYiPmE4G","name":"Poor scanners. Ship has to be one range band closer than normal.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"b081FxEAclRKji3q","name":"Counterfit papers. Ship is stolen. There is a bounty on it.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"zHsnShUX37Zvyi2O","name":"Corrupted A.I.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"58KhhfMQ9p0XJZHc","name":"Warp Cores fail 10% of the time.","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"60QSsxrVOt83OU9p","name":"Rust bucket. Everything that can go wrong, does. +1 Minimum Stress to crew.<br><br>@UUID[Compendium.mosh.macros_triggered_1e.Macro.BmEHWH7YxV9qb21p]{+1 Minimum Stress}","type":"repair","img":"systems/mosh/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ciAkQXkxSXTG8MV1","name":"Rancid smell permeates cabins.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pLleYaFjcIuAm4Pp","name":"Huge mess everywhere.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dReCCsfiV7it4lsm","name":"Staticky comms.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"4JRD71mvWNtFUDL7","name":"Faulty electrical system.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"59cXdcrZlmjUcJpV","name":"Loose couplings.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"CLvIvoNryBARtU7T","name":"Hidden (highly illegal) contraband.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vip6FxWcX4ReJD3b","name":"Autopilot systems down.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"AQt9nXy6S0Ev50r7","name":"Leaking hydraulic systems.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"QUyfvbFhCqb9d7Lu","name":"Creaking hull.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"SW5kVSjiFbBxIeiu","name":"Damaged bulkheads.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"wNm669fzbdZGwr0g","name":"Misaligned docking clamps.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"3l0LUZpjizvZmHWs","name":"Viewports blocked.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"c8SXxPHMsG7uycas","name":"Jammed exterior airlocks.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"9kS8VjGuSMpghdCk","name":"Dysfunctional gravity plating.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Low2X1z7m1iB3rkA","name":"Out of code compliance.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"BicB3xA1h978ZevJ","name":"Controls sticking.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"C9dQYp7gcjtq5QRz","name":"Coolant leak.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1HNvL7XEUcMQbLps","name":"Miscalibrated Thruster Gimbal System.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"xa9MPzfrPglkSJjg","name":"Bevvy of OSHA violations.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZbAFemnvHB1YTHBK","name":"Blocked air vents.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"wjyAZnOOafvv4xzB","name":"Emergency lighting only.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"l1OGQ0IXZHjnO4Ys","name":"Internal networking issues.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vleMoz5bbkZ5w28o","name":"Inaccurate data collection.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"T4wAR08WyT3g9C6D","name":"Oxygen leak. If ship is low on O2, lose 1d5 extra per day.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.u7TchSo3qutnzaKF]{-1d5 Oxygen}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"fbrN7sbgPjIwkk7I","name":"Throttled Afterburners. -2d10 Thrusters.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.jmOh8n2ps0YIeBC0]{-2d10 Thrusters}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"7GqbGIOzA9vYOPiI","name":"Lemon. Maintenance Checks at [-].<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.C04VbNoj8LgfY8QK]{Maintenance Check [-]}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"dgisAPnBbrIOiisk","name":"Slow acceleration. +1 Week to travel.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"d94uF9rpmeP60Kl4","name":"Inaccurate navigation.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"3Ptitg8HBZfl2CXN","name":"Miscalibrated Targeting Sensors. -1d10 Battle.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.X3cL9eS2HOPxhLH5]{-1d10 Battle}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"mK1Acfk5NAgs1MHC","name":"Faulty Cryopods. Nightmares. Cryosickness lasts an additional week.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IR1sWnYXniMg9TdP","name":"Malfunctioning escape pods.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"FIqSHePAeLJywerx","name":"Unable to send distress signals.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"4kmMuAbW1jnfVMYP","name":"Sabotaged coolant system.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ALplRgZtneMRdloo","name":"Death trap. [-] on all rolls.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"2pxf4O2NrLdwYRtO","name":"Worn landing struts.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"64AQJ3zQDOb7NOR1","name":"Out-of-date air filters.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"PKBXKvgWZwafKWJ3","name":"Corroded pipes.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"NgKPVhRkD8Gteo5Z","name":"Innaccurate orbital transfer navigation.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5d220ZzrEV3qx6Fy","name":"Worn out fuel injection nozzles.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IGx8nQrwfz07r6TR","name":"Inoperative exterior lighting system.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"pW1FUDxp2N0M0D1y","name":"Defective intercom system.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"UPAxtEOrSF3Il4uA","name":"Inadequate waste recycling.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"m04JdXL1xGQOkDyp","name":"Faulty altitude control thrusters.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"OWkfB73RTSLDMlsU","name":"Insufficient Life Support redundancy.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"hNJYqetiMKUlZzYH","name":"Delayed communication relays.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"rlW0LUlsK7vDGZEh","name":"Damaged fuel lines.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IDiwAbD8DTbec7S1","name":"Corroded exhaust manifolds.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EteEoBrlnzcySppN","name":"Terminal displays non-functional.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"guvCGNRa75AB2Avg","name":"Check engine light won’t turn off.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"cbXMdd4ugxSOT5TU","name":"Failed backup systems.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"kftgvuQoefQ7pl28","name":"Faulty door locks.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Odpb5coSTST7kCkc","name":"Buggy communications.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vMRVXZxu6ozj0iw2","name":"Infected food storage facilities.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"4Lqg0lqjjTlNlr0j","name":"Corrupted data banks.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Ka8elMGKtcakUIxx","name":"Jammed cargo bay doors.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"TAerNMqv19pANCxq","name":"Flickering interior lights.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"vv1VykTwiQmgEj6N","name":"Failed airlock seals.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"GW1KGmYdxYYf4ZWT","name":"Fuel Leak. Burn +1 Fuel everytime you spend fuel.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"FLaPtHcegheN7wHw","name":"Jump Bug. 10% chance Jump takes 2d10 months, not 2d10 days.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"g9Z7He5zPHNrxYe1","name":"Fragile. Always take +1 MDMG.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"IiPryFS9MOGZXeuG","name":"Cracked heat shields.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"FmPqHYH3UoGpaWYL","name":"Outdated software. -1d10 Systems.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.oDftFxRKkCQRNY2O]{-1d10 Systems}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"NLwybTzXJ1bndki3","name":"Inadequate Water Filtration. Parasites in the water supply.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"oySXnFIbRW0WRoeF","name":"Malfunctioning waste management system.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"RiHvRQ9nZDygwvvB","name":"Fusion Reactors overheating.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"wCYGQrI9qonhWy8F","name":"Failed radiation filter.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5J4r3yw4xDj890yZ","name":"Radiation leak. Entire ship is at Radiation Level 2.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"XmIcQgho4un7hYki","name":"Miscalibrated guidance system.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"KhlrUaPjVIoyhnaL","name":"Overloaded power storage.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"LRumIQdUBzD0Jc0X","name":"Malfunctioning sensor arrays.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"e144cIdUEyTJgN1G","name":"Failed Water Recovery System.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"b2b3j5JtanbyWlNd","name":"Micrometoroid hull damage.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5OBjTojgrp5N9mEw","name":"Faulty Carbon Dioxide Removal Assembly.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"8s1eBY5bEcQQTCz0","name":"Solar panel degradation.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"5UiJy739gvGHkRYp","name":"Computer failure from cosmic radiation.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"yJY9CzP1KA15aMqV","name":"Overloaded circuitry.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"nHac0gkEcCNew7RX","name":"Malfunctioning plasma thruster.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"DYHuVA4CQlmK2MJy","name":"Thermal management system failure.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"QIcoFYoC0hxW84qD","name":"Intermittent electrical outages.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"AuTERG3m7ECQKrKs","name":"Fire suppression system out of code.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"1iOSKp82goZGJZch","name":"Damaged floor pannelling.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ZBUtxiX72udqLzIk","name":"Broken light fixture in remote corridor.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"iwFmPpAth3VbRRL8","name":"Damaged coolant pump.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Eo0l4WMxcS62GCMP","name":"Cracked viewports.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"miRqXNzkW0biml1I","name":"Systems overloaded with malware.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"cOLcJ3Dnecbe6ZIU","name":"Leaky fuel valve.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"zRzb3Laiuw4ac6p0","name":"Jammed exhaust vent.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EZzGAO6DneH1qmQM","name":"Stuck waste disposal chute.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Tp6k1gPwhQmT6hCo","name":"Lifts non-functioning.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"2Ht7fg78511Hd49u","name":"Damaged communications antenna.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":false,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"XLEhMV9SnSfeEE7E","name":"Clogged Air Filtration. Crew capacity cut in half.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.DUuRY7kHKd7n5luv]{-50% Crew Capacity}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"Z8raruNDvfNASFQi","name":"Malfunctioning climate control. 85º at all times.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"3rulbOVhyRlTizT0","name":"No emergency power.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ulWxa2UtTOQihTyz","name":"Weak Frame. -1 Hull, -1 Upgrade.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.uPY19Y49bGCLGK3N]{-1 Hull}<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.06NSvDYTtmkeUtLq]{-1 Upgrade}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"EnogUslNNusSfVFy","name":"Toxic chemical spill.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"ElXLL32uNYiPmE4G","name":"Poor scanners. Ship has to be one range band closer than normal.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"b081FxEAclRKji3q","name":"Counterfit papers. Ship is stolen. There is a bounty on it.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"zHsnShUX37Zvyi2O","name":"Corrupted A.I.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"58KhhfMQ9p0XJZHc","name":"Warp Cores fail 10% of the time.","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
{"_id":"60QSsxrVOt83OU9p","name":"Rust bucket. Everything that can go wrong, does. +1 Minimum Stress to crew.<br><br>@UUID[Compendium.sla-mothership.macros_triggered_1e.Macro.BmEHWH7YxV9qb21p]{+1 Minimum Stress}","type":"repair","img":"systems/sla-mothership/images/icons/ui/rolltables/maintenance_issues.png","system":{"description":"<p>Maintenance Issue</p>","major":true,"quantity":1},"effects":[],"flags":{},"folder":null,"sort":0,"_stats":{"systemId":"mosh","systemVersion":"0.4.0","coreVersion":"11.308","createdTime":1685936572185,"modifiedTime":1693515520278,"lastModifiedBy":"6EeM38DJkcBWNAmw"}}
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.818908 16f0cf000 Recovering log #60
|
||||
2026/04/10-15:21:30.819298 16f0cf000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.819316 16f0cf000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.496572 17002b000 Recovering log #86
|
||||
2026/05/27-23:54:37.499483 17002b000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.499712 17002b000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.942933 17164b000 Recovering log #58
|
||||
2026/04/10-15:15:40.943347 17164b000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.943366 17164b000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.614698 172b6f000 Recovering log #84
|
||||
2026/05/19-23:19:40.614916 172b6f000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.614942 172b6f000 Delete type=0 #84
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.820489 16f0cf000 Recovering log #60
|
||||
2026/04/10-15:21:30.820764 16f0cf000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.820786 16f0cf000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.510817 16e807000 Recovering log #86
|
||||
2026/05/27-23:54:37.513089 16e807000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.513609 16e807000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.944425 171e57000 Recovering log #58
|
||||
2026/04/10-15:15:40.944787 171e57000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.944804 171e57000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.615928 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.616184 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.616214 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.821825 16e0b7000 Recovering log #60
|
||||
2026/04/10-15:21:30.822206 16e0b7000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.822238 16e0b7000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.515976 16e807000 Recovering log #86
|
||||
2026/05/27-23:54:37.516904 16e807000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.517115 16e807000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.946179 170e3f000 Recovering log #58
|
||||
2026/04/10-15:15:40.946914 170e3f000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.946937 170e3f000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.617145 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.617442 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.617486 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.988603 16f8db000 Recovering log #60
|
||||
2026/04/10-15:21:30.989459 16f8db000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.989517 16f8db000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.521319 16f81f000 Recovering log #86
|
||||
2026/05/27-23:54:37.522931 16f81f000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.523174 16f81f000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.964061 17164b000 Recovering log #58
|
||||
2026/04/10-15:15:40.964631 17164b000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.964657 17164b000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.618390 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.618663 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.618694 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000063
|
||||
MANIFEST-000089
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.992926 16f8db000 Recovering log #62
|
||||
2026/04/10-15:21:30.993656 16f8db000 Delete type=0 #62
|
||||
2026/04/10-15:21:30.993730 16f8db000 Delete type=3 #61
|
||||
2026/05/27-23:54:37.526390 17002b000 Recovering log #88
|
||||
2026/05/27-23:54:37.527569 17002b000 Delete type=0 #88
|
||||
2026/05/27-23:54:37.527659 17002b000 Delete type=3 #87
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.966053 17164b000 Recovering log #60
|
||||
2026/04/10-15:15:40.967356 17164b000 Delete type=0 #60
|
||||
2026/04/10-15:15:40.967388 17164b000 Delete type=3 #59
|
||||
2026/05/19-23:19:40.619688 17337b000 Recovering log #86
|
||||
2026/05/19-23:19:40.620003 17337b000 Delete type=3 #85
|
||||
2026/05/19-23:19:40.620026 17337b000 Delete type=0 #86
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000087
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.995778 16e8c3000 Recovering log #60
|
||||
2026/04/10-15:21:30.996525 16e8c3000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.996566 16e8c3000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.533375 16f81f000 Recovering log #86
|
||||
2026/05/27-23:54:37.534489 16f81f000 Delete type=3 #85
|
||||
2026/05/27-23:54:37.534725 16f81f000 Delete type=0 #86
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.968762 17164b000 Recovering log #58
|
||||
2026/04/10-15:15:40.968983 17164b000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.969099 17164b000 Delete type=3 #57
|
||||
2026/05/19-23:19:40.621197 17337b000 Recovering log #84
|
||||
2026/05/19-23:19:40.621497 17337b000 Delete type=3 #83
|
||||
2026/05/19-23:19:40.621534 17337b000 Delete type=0 #84
|
||||
|
||||
@@ -1 +1 @@
|
||||
MANIFEST-000061
|
||||
MANIFEST-000089
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:21:30.998700 16e8c3000 Recovering log #60
|
||||
2026/04/10-15:21:30.999246 16e8c3000 Delete type=0 #60
|
||||
2026/04/10-15:21:30.999287 16e8c3000 Delete type=3 #59
|
||||
2026/05/27-23:54:37.542562 16e807000 Recovering log #88
|
||||
2026/05/27-23:54:37.542994 16e807000 Delete type=0 #88
|
||||
2026/05/27-23:54:37.543060 16e807000 Delete type=3 #87
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/04/10-15:15:40.970322 172663000 Recovering log #58
|
||||
2026/04/10-15:15:40.970657 172663000 Delete type=0 #58
|
||||
2026/04/10-15:15:40.970680 172663000 Delete type=3 #57
|
||||
2026/05/27-23:54:24.293733 173d43000 Recovering log #86
|
||||
2026/05/27-23:54:24.295953 173d43000 Delete type=3 #85
|
||||
2026/05/27-23:54:24.296285 173d43000 Delete type=0 #86
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"id": "sla-mothership",
|
||||
"title": "SLA Mothership",
|
||||
"description": "An SLA Industries conversion built on the unofficial Mothership system for Foundry VTT, preserving Mothership's core mechanics while adding SLA flux, Ebb, BPN, and equipment support.",
|
||||
"version": "0.6.1",
|
||||
"version": "0.6.12",
|
||||
"esmodules": [
|
||||
"module/mosh.js"
|
||||
],
|
||||
@@ -160,7 +160,7 @@
|
||||
},
|
||||
"compatibility": {
|
||||
"minimum": "13",
|
||||
"maximum": "13",
|
||||
"verified": "13"
|
||||
"verified": "14",
|
||||
"maximum": "14"
|
||||
}
|
||||
}
|
||||
@@ -246,6 +246,38 @@
|
||||
"value": 1,
|
||||
"html": ""
|
||||
},
|
||||
"slaNpc": {
|
||||
"archetype": {
|
||||
"value": ""
|
||||
},
|
||||
"species": {
|
||||
"value": ""
|
||||
},
|
||||
"affiliationType": {
|
||||
"value": ""
|
||||
},
|
||||
"affiliation": {
|
||||
"value": ""
|
||||
},
|
||||
"department": {
|
||||
"value": ""
|
||||
},
|
||||
"role": {
|
||||
"value": ""
|
||||
},
|
||||
"sector": {
|
||||
"value": ""
|
||||
},
|
||||
"disposition": {
|
||||
"value": ""
|
||||
},
|
||||
"threat": {
|
||||
"value": ""
|
||||
},
|
||||
"summary": {
|
||||
"value": ""
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"combat": {
|
||||
"value": 10,
|
||||
@@ -717,4 +749,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,31 +12,24 @@
|
||||
from 1 to 12 and will create that number of columns. --}}
|
||||
|
||||
<div class="header">
|
||||
<img class="profile sla-portrait-static" src="{{img}}" data-edit="img" title="{{name}}" height="150"
|
||||
<img class="profile" src="{{img}}" data-edit="img" title="{{name}}" height="150"
|
||||
width="150" />
|
||||
|
||||
<div class="headergrid">
|
||||
<div class="sla-sheet-wordmark">SLA Industries</div>
|
||||
<!-- <img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" height="150" width="150"/> -->
|
||||
|
||||
{{!-- REST button — top-right, above Race --}}
|
||||
<div class="header-field header-field-rest">
|
||||
<button type="button" class="sla-sheet-action sla-rest-button sla-header-rest-pill" title="Take a short or long rest">REST</button>
|
||||
</div>
|
||||
|
||||
{{!-- ROW 2: Name / Class / Race --}}
|
||||
<!-- PLAYER NAME -->
|
||||
<div class="headernamegrid header-field header-field-name">
|
||||
<div class="headerinputtext">{{ localize 'Mosh.Name' }}</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="name" class="noborder" type="text"
|
||||
value="{{name}}" placeholder="{{ localize 'Mosh.Name' }}" /></div>
|
||||
</div>
|
||||
<div class="header-field header-field-lad">
|
||||
<div class="headerinputtext">L.A.D.</div>
|
||||
<label class="sla-header-checkbox" title="Life After Death">
|
||||
<input type="checkbox" name="system.sla.lad" data-dtype="Boolean" {{checked system.sla.lad}} />
|
||||
<span>L.A.D.</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-field header-field-credits">
|
||||
<div class="headerinputtext">{{ localize 'Mosh.Credits' }}</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.credits.value" class="noborder" type="text"
|
||||
value="{{system.credits.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
|
||||
<!-- CLASS -->
|
||||
<div class="header-field header-field-class">
|
||||
@@ -45,34 +38,43 @@
|
||||
value="{{system.class.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
|
||||
<!-- RANK -->
|
||||
<!-- RACE -->
|
||||
<div class="header-field header-field-race">
|
||||
<div class="headerinputtext">Race</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.rank.value" class="noborder" type="text"
|
||||
value="{{system.rank.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
|
||||
<div class="header-field header-field-sla-rank">
|
||||
<div class="headerinputtext">S.C.L</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.attributes.level.value" class="noborder"
|
||||
type="text" value="{{system.attributes.level.value}}" placeholder="" /></div>
|
||||
{{!-- ROW 3: Bottom row — all equal width, same font --}}
|
||||
<div class="sla-header-bottom-row">
|
||||
<div class="header-field header-field-lad">
|
||||
<div class="headerinputtext">L.A.D.</div>
|
||||
<label class="sla-header-checkbox" title="Life After Death">
|
||||
<input type="checkbox" name="system.sla.lad" data-dtype="Boolean" {{checked system.sla.lad}} />
|
||||
<span>L.A.D.</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-field header-field-credits">
|
||||
<div class="headerinputtext">{{ localize 'Mosh.Credits' }}</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.credits.value" class="noborder" type="text"
|
||||
value="{{system.credits.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
<div class="header-field header-field-sla-rank">
|
||||
<div class="headerinputtext">S.C.L.</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.attributes.level.value" class="noborder"
|
||||
type="text" value="{{system.attributes.level.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
<div class="header-field header-field-height">
|
||||
<div class="headerinputtext">Height</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.sla.height.value" class="noborder" type="text"
|
||||
value="{{system.sla.height.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
<div class="header-field header-field-weight">
|
||||
<div class="headerinputtext">Weight</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.sla.weightText.value" class="noborder" type="text"
|
||||
value="{{system.sla.weightText.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-field header-field-height">
|
||||
<div class="headerinputtext">Height</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.sla.height.value" class="noborder" type="text"
|
||||
value="{{system.sla.height.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
<div class="header-field header-field-weight">
|
||||
<div class="headerinputtext">Weight</div>
|
||||
<div class="headerinputfield sla-header-input charname"><input name="system.sla.weightText.value" class="noborder" type="text"
|
||||
value="{{system.sla.weightText.value}}" placeholder="" /></div>
|
||||
</div>
|
||||
<div class="header-field header-field-rest">
|
||||
<div class="headerinputtext"> </div>
|
||||
<button type="button" class="sla-sheet-action sla-rest-button sla-header-rest-pill" title="Take a short or long rest">Rest</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -206,16 +208,14 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
<!-- Trauma Response -->
|
||||
<div class="" style="margin-left: 6px; margin-right: 0px; flex: 0; grid-column-start: 1; grid-column-end: 3;">
|
||||
<div class="sla-trauma-header-row">
|
||||
<div class="resource-label sla-stat-heading sla-trauma-heading">{{ localize 'Mosh.TraumaResponse' }}</div>
|
||||
<div class="sla-session-ability-row">
|
||||
<label class="sla-session-ability-label" title="Check when the session trauma ability has been used">
|
||||
<input type="checkbox" class="sla-session-ability-used" {{#if system.sla.sessionAbilityUsed}}checked{{/if}} />
|
||||
<span>Session ability used</span>
|
||||
</label>
|
||||
<button type="button" class="sla-new-session" title="Start a new session — resets session ability">New Session</button>
|
||||
</div>
|
||||
<div class="sla-trauma-panel" style="margin-left: 6px; margin-right: 0px; flex: 0; grid-column-start: 1; grid-column-end: 3;">
|
||||
<div class="resource-label sla-stat-heading sla-trauma-heading">{{ localize 'Mosh.TraumaResponse' }}</div>
|
||||
<div class="sla-trauma-controls">
|
||||
<label class="sla-trauma-toggle" title="Mark the trauma response as used this session">
|
||||
<input type="checkbox" class="sla-session-ability-used" {{checked system.sla.sessionAbilityUsed}} />
|
||||
<span>Used This Session</span>
|
||||
</label>
|
||||
<button type="button" class="sla-inline-mini-button sla-new-session" title="Reset trauma response use for a new session">New Session</button>
|
||||
</div>
|
||||
<textarea name="system.other.stressdesc.value" rows="4" class="textarea-input trauma-response-box" type="text"
|
||||
data-target="system.other.stressdesc.value" placeholder="Trauma response">{{system.other.stressdesc.value}}</textarea>
|
||||
@@ -318,6 +318,14 @@
|
||||
<div class="sla-mainstat-action-strip">
|
||||
<button type="button" class="sla-sheet-action sla-wound-button">Wound</button>
|
||||
</div>
|
||||
{{#if conditions.length}}
|
||||
<div class="sla-active-conditions-summary">
|
||||
<span class="sla-conditions-label">CONDITIONS:</span>
|
||||
{{#each conditions as |condition|}}
|
||||
<span class="sla-active-condition">{{condition.name}}{{#if condition.system.severity}} {{condition.system.severity}}{{/if}}</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<!-- SAVES -->
|
||||
{{#if system.settings.firstEdition}}
|
||||
@@ -390,12 +398,12 @@
|
||||
<a class="tab-select" data-tab="skills">{{ localize 'Mosh.Skills' }}</a>
|
||||
<a class="tab-select" data-tab="weapons">{{ localize 'Mosh.Weapons' }}</a>
|
||||
<a class="tab-select" data-tab="items">{{ localize 'Mosh.Items' }}</a>
|
||||
<a class="tab-select" data-tab="drugs">Drugs</a>
|
||||
<a class="tab-select" data-tab="sla">SLA</a>
|
||||
<a class="tab-select" data-tab="traits">Traits</a>
|
||||
<a class="tab-select" data-tab="special-rules">Special Rules</a>
|
||||
{{#if isEbbUser}}<a class="tab-select" data-tab="ebb">Ebb</a>{{/if}}
|
||||
{{#if isVevaphon}}<a class="tab-select" data-tab="morph">Morph</a>{{/if}}
|
||||
<a class="tab-select" data-tab="contacts">Contacts</a>
|
||||
{{#if isEbbUser}}<a class="tab-select" data-tab="ebb">Ebb</a>{{/if}}
|
||||
<a class="tab-select" data-tab="description">{{ localize 'Mosh.Bio' }}</a>
|
||||
<a class="tab-select" data-tab="notes">{{ localize 'Mosh.Notes' }}</a>
|
||||
</nav>
|
||||
@@ -403,48 +411,6 @@
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
|
||||
{{!-- Contacts Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="contacts">
|
||||
<div class="sla-panel">
|
||||
<div class="sla-banner">
|
||||
<div>
|
||||
<div class="sla-kicker">Operative Network</div>
|
||||
<div class="sla-title">Contacts & Associates</div>
|
||||
</div>
|
||||
<div class="sla-tags">
|
||||
<span class="sla-tag">{{slaContactCount}} contact{{#unless (compare 'int' slaContactCount '===' 1)}}s{{/unless}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sla-contacts-toolbar">
|
||||
<button type="button" class="sla-sheet-action sla-contact-add"><i class="fas fa-plus"></i> Add Contact</button>
|
||||
</div>
|
||||
|
||||
{{#if slaContacts.length}}
|
||||
<div class="sla-contacts-list">
|
||||
{{#each slaContacts as |contact|}}
|
||||
<div class="sla-contact-card" data-contact-id="{{contact.id}}">
|
||||
<div class="sla-contact-header">
|
||||
<div class="sla-contact-disposition sla-contact-disposition-{{contact.disposition}}"></div>
|
||||
<div class="sla-contact-name">{{contact.name}}</div>
|
||||
<div class="sla-contact-role">{{contact.role}}</div>
|
||||
<div class="sla-contact-controls">
|
||||
<button type="button" class="sla-contact-edit" data-contact-id="{{contact.id}}" title="Edit contact"><i class="fas fa-edit"></i></button>
|
||||
<button type="button" class="sla-contact-delete" data-contact-id="{{contact.id}}" title="Delete contact"><i class="fas fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{{#if contact.notes}}
|
||||
<div class="sla-contact-notes">{{contact.notes}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="sla-note-pill sla-note-pill-wide">No contacts yet. Add allies, fixers, squad members, and other NPCs the operative knows.</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Biography Tab --}}
|
||||
<div class="tab biography" data-group="primary" data-tab="description">
|
||||
{{editor enriched.biography target="system.biography" button=true editable=true}}
|
||||
@@ -452,14 +418,14 @@
|
||||
{{!-- Notes Tab --}}
|
||||
<div class="tab biography" data-group="primary" data-tab="notes">
|
||||
<div class="sla-card" style="margin-bottom: 12px;">
|
||||
<div class="sla-card-label">Ammo Spend Ledger</div>
|
||||
<div class="sla-card-copy">Total spent: {{system.sla.ammoSpendTotal.value}} cR</div>
|
||||
<textarea readonly rows="6" class="textarea-input">{{system.sla.ammoLedger.value}}</textarea>
|
||||
<div class="sla-card-label">Operation Log</div>
|
||||
<div class="sla-card-copy">Recent rolls, outcomes, and field actions for this operative.</div>
|
||||
<textarea readonly rows="10" class="textarea-input">{{system.sla.activityLog.value}}</textarea>
|
||||
</div>
|
||||
<div class="sla-card sla-activity-log-card" style="margin-bottom: 12px;">
|
||||
<div class="sla-card-label">Operative Activity Log</div>
|
||||
<div class="sla-card-copy">Rolls, rests, drug use, panic — automatically recorded. Newest first.</div>
|
||||
<textarea readonly rows="8" class="textarea-input sla-activity-log-textarea">{{system.sla.activityLog.value}}</textarea>
|
||||
<div class="sla-card" style="margin-bottom: 12px;">
|
||||
<div class="sla-card-label">Ammo Economy Ledger</div>
|
||||
<div class="sla-card-copy">Firing spend total: {{system.sla.ammoSpendTotal.value}} cR. Purchases are logged below as separate entries.</div>
|
||||
<textarea readonly rows="6" class="textarea-input">{{system.sla.ammoLedger.value}}</textarea>
|
||||
</div>
|
||||
{{editor enriched.notes target="system.notes" button=true editable=true}}
|
||||
</div>
|
||||
@@ -474,7 +440,6 @@
|
||||
<span class="sla-tag">{{system.sla.bpn.value}}</span>
|
||||
<span class="sla-tag">SCL {{system.sla.scl.value}}</span>
|
||||
{{#if isEbbUser}}<span class="sla-tag">Ebb {{system.sla.ebbRating.value}}</span>{{/if}}
|
||||
{{#if isVevaphon}}<span class="sla-tag sla-instability-tag {{vevaphonInstabilityClass}}">Instability {{system.sla.vevaphonInstability.value}}/12</span>{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -539,15 +504,7 @@
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">SCL</label>
|
||||
<div class="sla-scl-control">
|
||||
<input type="text" name="system.sla.scl.value" value="{{system.sla.scl.value}}" data-dtype="String" class="sla-scl-input" />
|
||||
<div class="sla-scl-buttons">
|
||||
<button type="button" class="sla-scl-adjust" data-delta="1" title="+1 SCL">+1</button>
|
||||
<button type="button" class="sla-scl-adjust" data-delta="-1" title="-1 SCL">-1</button>
|
||||
<button type="button" class="sla-scl-adjust" data-delta="0.5" title="+0.5 SCL">+½</button>
|
||||
<button type="button" class="sla-scl-adjust" data-delta="-0.5" title="-0.5 SCL">-½</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" name="system.sla.scl.value" value="{{system.sla.scl.value}}" data-dtype="String" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Employer / Squad</label>
|
||||
@@ -779,8 +736,76 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{#if isVevaphon}}
|
||||
<div class="tab items" data-group="primary" data-tab="morph">
|
||||
<div class="sla-panel">
|
||||
<div class="sla-banner">
|
||||
<div>
|
||||
<div class="sla-kicker">Stormer Vevaphon</div>
|
||||
<div class="sla-title">Polymorphic Form Control</div>
|
||||
</div>
|
||||
<div class="sla-tags">
|
||||
<span class="sla-tag">Form: {{system.sla.morphForm.value}}</span>
|
||||
<span class="sla-tag {{vevaphonInstabilityClass}}">Instability {{system.sla.vevaphonInstability.value}} / 12</span>
|
||||
<span class="sla-tag">Sanity {{system.stats.sanity.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2col sla-card-grid">
|
||||
{{!-- Instability Track --}}
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Instability Track</div>
|
||||
<div class="sla-morph-track-bar">
|
||||
<div class="sla-morph-track-fill {{vevaphonInstabilityClass}}" style="width: {{vevaphonInstabilityPercent}}%;"></div>
|
||||
<span class="sla-morph-track-label">{{data.sla.vevaphonInstability.value}} / 12</span>
|
||||
</div>
|
||||
<div class="sla-card-copy">{{vevaphonInstabilityDesc}}</div>
|
||||
<div class="sla-action-row" style="margin-top: 10px;">
|
||||
<button type="button" class="sla-instability-increase sla-morph-btn-instab">+1 Instability</button>
|
||||
<button type="button" class="sla-instability-decrease sla-morph-btn-instab sla-morph-btn-instab-down">−1 Instability</button>
|
||||
</div>
|
||||
<div class="sla-card-copy" style="margin-top: 12px; font-style: italic;">At 12, the Vevaphon is lost — immediate retirement or death.</div>
|
||||
</div>
|
||||
|
||||
{{!-- Active Morph Form --}}
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Active Morph Form</div>
|
||||
<div class="sla-card-copy" style="margin-bottom: 10px;">Each morph shift costs 1 Instability. Changing form mid-scene requires a Sanity save at Instability 6+.</div>
|
||||
{{#each slaMorphForms as |form|}}
|
||||
<button type="button"
|
||||
class="sla-morph-shift sla-morph-form-btn {{#if form.slaIsActiveMorphForm}}sla-morph-active{{/if}}"
|
||||
data-form="{{form.name}}">
|
||||
<strong class="sla-morph-form-name">{{form.name}}</strong>
|
||||
{{#if form.system.summary}}<div class="sla-morph-form-summary">{{form.system.summary}}</div>{{/if}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2col sla-card-grid" style="margin-top: 12px;">
|
||||
{{!-- Morph Panic Reference --}}
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Morph Panic Reference</div>
|
||||
<div class="sla-card-copy">Triggered at Instability 10+ on a failed Sanity save. Roll 1d6:</div>
|
||||
<div class="sla-note-list" style="margin-top: 8px;">
|
||||
{{#each vevaphonMorphPanic as |entry|}}
|
||||
<div class="sla-note-pill sla-note-pill-wide">{{entry.roll}}. {{entry.label}} — {{entry.desc}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Morph Notes --}}
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Morph Notes</div>
|
||||
<textarea name="system.sla.morphNotes.value" rows="10" class="textarea-input" data-target="system.sla.morphNotes.value">{{system.sla.morphNotes.value}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if isEbbUser}}
|
||||
<div class="tab items" data-group="primary" data-tab="ebb">
|
||||
<div class="sla-panel">
|
||||
@@ -885,112 +910,19 @@
|
||||
</ol>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if isVevaphon}}
|
||||
<div class="tab items" data-group="primary" data-tab="morph">
|
||||
<div class="sla-panel">
|
||||
<div class="sla-banner">
|
||||
<div>
|
||||
<div class="sla-kicker">Stormer Vevaphon</div>
|
||||
<div class="sla-title">Polymorphic Form Control</div>
|
||||
</div>
|
||||
<div class="sla-tags">
|
||||
<span class="sla-tag">Form: {{system.sla.morphForm.value}}</span>
|
||||
<span class="sla-tag sla-instability-tag {{vevaphonInstabilityClass}}">Instability {{system.sla.vevaphonInstability.value}} / 12</span>
|
||||
<span class="sla-tag">Sanity {{system.stats.sanity.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2col sla-card-grid">
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Instability Track</div>
|
||||
<div class="sla-instability-bar-wrap">
|
||||
<div class="sla-instability-bar {{vevaphonInstabilityClass}}" style="width: {{vevaphonInstabilityPercent}}%;"></div>
|
||||
<div class="sla-instability-bar-label {{vevaphonInstabilityClass}}">{{system.sla.vevaphonInstability.value}} / 12</div>
|
||||
</div>
|
||||
<div class="sla-card-copy">
|
||||
{{#if vevaphonInstabilityCritical}}⚠ CRITICAL — Morph Panic risk on every failed Sanity save.{{/if}}
|
||||
{{#if vevaphonInstabilityElevated}}Instability elevated — minor morph effects trigger each scene.{{/if}}
|
||||
{{#unless vevaphonInstabilityElevated}}Instability nominal. Morphing is available without additional risk.{{/unless}}
|
||||
</div>
|
||||
<div class="sla-action-row" style="gap: 6px; flex-wrap: wrap;">
|
||||
<button type="button" class="sla-instability-increase">+1 Instability</button>
|
||||
<button type="button" class="sla-instability-decrease">-1 Instability</button>
|
||||
</div>
|
||||
<div class="sla-card-copy" style="margin-top: 8px;">At 12, the Vevaphon is lost — immediate retirement or death.</div>
|
||||
</div>
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Active Morph Form</div>
|
||||
<div class="sla-card-title">{{system.sla.morphForm.value}}</div>
|
||||
<div class="sla-card-copy">Each morph shift costs 1 Instability. Changing form mid-scene requires a Sanity save at Instability 6+.</div>
|
||||
<div class="sla-morph-form-buttons">
|
||||
<button type="button" class="sla-morph-shift" data-form="Brute Form" {{#if (compare 'str' system.sla.morphForm.value '===' 'Brute Form')}}disabled{{/if}}>
|
||||
<span class="sla-morph-btn-name">Brute Form</span>
|
||||
<span class="sla-morph-btn-meta">STR+10, BODY+10 | Knockdown Immune</span>
|
||||
</button>
|
||||
<button type="button" class="sla-morph-shift" data-form="Stalker Form" {{#if (compare 'str' system.sla.morphForm.value '===' 'Stalker Form')}}disabled{{/if}}>
|
||||
<span class="sla-morph-btn-name">Stalker Form</span>
|
||||
<span class="sla-morph-btn-meta">SPD+10, Stealth+20 | Armour Incompatible</span>
|
||||
</button>
|
||||
<button type="button" class="sla-morph-shift" data-form="Raptor Form" {{#if (compare 'str' system.sla.morphForm.value '===' 'Raptor Form')}}disabled{{/if}}>
|
||||
<span class="sla-morph-btn-name">Raptor Form</span>
|
||||
<span class="sla-morph-btn-meta">COM+10, SPD+5 | Critical Wound Bonus</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2col sla-card-grid">
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Morph Panic Reference</div>
|
||||
<div class="sla-card-copy">Triggered at Instability 10+ on a failed Sanity save. Roll 1d6:</div>
|
||||
<div class="sla-note-list">
|
||||
<div class="sla-note-pill sla-note-pill-wide">1. Cascade Shift — random morph form, +1 Instability.</div>
|
||||
<div class="sla-note-pill sla-note-pill-wide">2. Identity Bleed — forgets name and callsign until end of scene.</div>
|
||||
<div class="sla-note-pill sla-note-pill-wide">3. Partial Lock — one limb freezes. -10 physical rolls using that limb.</div>
|
||||
<div class="sla-note-pill sla-note-pill-wide">4. Tissue Rejection — 1d5 damage, armour does not apply.</div>
|
||||
<div class="sla-note-pill sla-note-pill-wide">5. Threat Imprint — locked on nearest visible target.</div>
|
||||
<div class="sla-note-pill sla-note-pill-wide">6. Full Reversion — base form, lose morph bonuses, -1 Instability.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-card">
|
||||
<div class="sla-card-label">Morph Notes</div>
|
||||
<textarea name="system.sla.morphNotes.value" rows="10" class="textarea-input" data-target="system.sla.morphNotes.value">{{system.sla.morphNotes.value}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{!-- Owned Items Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="items">
|
||||
{{#if drugAlerts.length}}
|
||||
<div class="sla-drug-alerts">
|
||||
{{#each drugAlerts as |alert id|}}
|
||||
<div class="sla-drug-alert {{alert.state}}">
|
||||
<div class="sla-drug-alert-main">
|
||||
<div class="sla-drug-alert-name">{{alert.name}}</div>
|
||||
<div class="sla-drug-alert-meta">
|
||||
<span class="sla-drug-alert-state">{{alert.stateLabel}}</span>
|
||||
{{#if alert.duration}}<span class="sla-drug-alert-duration">{{alert.duration}}</span>{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-drug-alert-summary">{{alert.summary}}</div>
|
||||
<button type="button" class="drug-close-btn drug-close" data-item-id="{{alert.itemId}}" data-drug-id="{{alert.drugId}}">Close</button>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if system.settings.firstEdition}}
|
||||
<!-- ARMOR -->
|
||||
<ol class="items-list" role="table">
|
||||
<li class="item flexrow item-header" role="rowgroup">
|
||||
<div class="item-image" role="cell"></div>
|
||||
<div class="skill-stat" style="flex-grow: 2.5;" role="cell">{{ localize 'Mosh.ArmorName' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Armour Protection — reduces incoming damage before it reaches your wounds. Higher is better.">{{ localize 'Mosh.AP' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Damage Reduction — subtracts directly from wound damage after AP is applied. Each point absorbed is one less point of damage taken.">{{ localize 'Mosh.DR' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Speed penalty — how much this armour slows movement. Expressed as a % penalty to physical speed checks.">{{ localize 'Mosh.Speed' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Oxygen supply — current / maximum charges for sealed suits and vacuum armour. N/A means the suit is not airtight.">{{ localize 'Mosh.Oxygen' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Carry state — Eqp means wearing it now (weight counts against your equipped load). Stow means packed away (counts as stowed weight).">Carry</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.AP' }}</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.DR' }}</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.Speed' }}</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.Oxygen' }}</div>
|
||||
<div class="skill-stat" role="cell">Carry</div>
|
||||
<div class="item-controls" role="cell">
|
||||
<a class="item-control item-create" title="{{ localize 'Mosh.CreateArmor' }}" data-type="armor"><i class="fas fa-plus"></i> {{ localize 'Mosh.Add' }}</a>
|
||||
</div>
|
||||
@@ -1027,10 +959,10 @@
|
||||
<li class="item flexrow item-header" role="rowgroup">
|
||||
<div class="item-image" role="cell"></div>
|
||||
<div class="skill-stat" style="flex-grow: 2.5;" role="cell">{{ localize 'Mosh.ArmorName' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Save Bonus — this value is added to your Body save when checking to resist physical damage while wearing this armour.">{{ localize 'Mosh.SaveBonus' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Speed penalty — how much this armour slows movement. Expressed as a % penalty to physical speed checks.">{{ localize 'Mosh.Speed' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Oxygen supply — current / maximum charges for sealed suits and vacuum armour. N/A means the suit is not airtight.">{{ localize 'Mosh.Oxygen' }}</div>
|
||||
<div class="skill-stat" role="cell" title="Carry state — Eqp means wearing it now (weight counts against your equipped load). Stow means packed away (counts as stowed weight).">Carry</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.SaveBonus' }}</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.Speed' }}</div>
|
||||
<div class="skill-stat" role="cell">{{ localize 'Mosh.Oxygen' }}</div>
|
||||
<div class="skill-stat" role="cell">Carry</div>
|
||||
<div class="item-controls" role="cell">
|
||||
<a class="item-control item-create" title="{{ localize 'Mosh.CreateArmor' }}" data-type="armor"><i class="fas fa-plus"></i> {{ localize 'Mosh.Add' }}</a>
|
||||
</div>
|
||||
@@ -1062,57 +994,15 @@
|
||||
</ol>
|
||||
{{/if}}
|
||||
|
||||
<!-- DRUGS -->
|
||||
<ol class="items-list sla-drug-list">
|
||||
<li class="item flexrow item-header">
|
||||
<div class="item-image"></div>
|
||||
<div class="skill-stat" style="flex-grow: 1.6;">Drug</div>
|
||||
<div class="skill-stat" title="Quantity — number of doses currently carried.">Qty</div>
|
||||
<div class="skill-stat" title="Rating — the potency tier of this drug. Higher ratings mean stronger effects and harder addiction saves.">Rating</div>
|
||||
<div class="skill-stat" title="Value — street price per dose in credits (cR).">Value</div>
|
||||
<div class="skill-stat" title="Weight — total carry weight for all doses of this drug.">Weight</div>
|
||||
<div class="skill-stat" title="Carry state — Eqp means on your person and immediately accessible. Stow means packed away in your kit.">Carry</div>
|
||||
<div class="skill-stat" title="State — current drug status. Ready means unused. Active means the drug is currently in effect. Crashed means the effect has ended and the character may be experiencing comedown penalties.">State</div>
|
||||
<div class="skill-stat" title="Duration — how many rounds or minutes of effect remain. Blank or 0 means the drug is not currently active.">Duration</div>
|
||||
<div class="item-controls">
|
||||
<a class="item-control item-create" title="Create Drug" data-type="drug"><i class="fas fa-plus"></i> Add</a>
|
||||
</div>
|
||||
</li>
|
||||
{{#each drugRows as |drug id|}}
|
||||
<li class="item flexrow dropitem" data-item-id="{{drug.itemId}}" data-drug-id="{{drug.drugId}}">
|
||||
<div class="item-image"><img src="{{drug.img}}" title="{{drug.name}}" width="24" height="24" /></div>
|
||||
<div class="skill-name list-roll description-roll drug-item-summary" style="flex-grow: 1.6;">{{drug.name}}<span>{{drug.summary}}</span></div>
|
||||
<div class="skill-stat item-quantity">{{drug.quantity}}</div>
|
||||
<div class="skill-stat">{{drug.rating}}</div>
|
||||
<div class="skill-stat">{{drug.cost}}</div>
|
||||
<div class="skill-stat">{{drug.slaCarry.totalWeight}} kg</div>
|
||||
<div class="skill-stat">
|
||||
<div class="sla-carry-toggle-row">
|
||||
<button type="button" class="sla-carry-toggle {{#if (compare 'str' drug.slaCarry.state '===' 'equipped')}}active{{/if}}" data-state="equipped">Eqp</button>
|
||||
<button type="button" class="sla-carry-toggle {{#if (compare 'str' drug.slaCarry.state '===' 'stowed')}}active{{/if}}" data-state="stowed">Stow</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="skill-stat">{{drug.statusLabel}}</div>
|
||||
<div class="skill-stat">{{drug.duration}}</div>
|
||||
<div class="item-controls">
|
||||
<button type="button" class="drug-use-btn drug-use" {{#unless drug.canUse}}disabled{{/unless}}>Use</button>
|
||||
<button type="button" class="drug-close-btn drug-close" {{#unless drug.canClose}}disabled{{/unless}}>Close</button>
|
||||
<a class="item-control item-edit" title="Edit Drug"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Drug"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
|
||||
<!-- ITEMS -->
|
||||
<ol class="items-list">
|
||||
<li class="item flexrow item-header">
|
||||
<div class="item-image"></div>
|
||||
<div class="skill-stat" style="flex-grow: 1.5;" title="Hover over any item name to see its description.">{{ localize 'Mosh.ItemName' }}</div>
|
||||
<div class="skill-stat" title="Quantity — how many of this item you are carrying.">{{ localize 'Mosh.Quantity' }}</div>
|
||||
<div class="skill-stat" title="Weight — total carry weight for all units of this item (kg).">{{ localize 'Mosh.Weight' }}</div>
|
||||
<div class="skill-stat" title="Carry state — Eqp means on your person and ready to use. Stow means packed away. Equipped items count against your active carry limit; stowed items count against your total carry limit.">Carry</div>
|
||||
<div class="skill-stat" title="Value — purchase price in credits (cR). Sell price is typically half.">{{ localize 'Mosh.Value' }}</div>
|
||||
<div class="skill-stat" style="flex-grow: 1.5;">{{ localize 'Mosh.ItemName' }}</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Quantity' }}</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Weight' }}</div>
|
||||
<div class="skill-stat">Carry</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Value' }}</div>
|
||||
<div class="item-controls">
|
||||
<a class="item-control item-create" title="{{ localize 'Mosh.CreateItem' }}" data-type="item"><i class="fas fa-plus"></i> Add</a>
|
||||
</div>
|
||||
@@ -1144,6 +1034,66 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="tab items" data-group="primary" data-tab="drugs">
|
||||
{{#if drugAlerts.length}}
|
||||
<div class="sla-drug-alerts">
|
||||
{{#each drugAlerts as |alert id|}}
|
||||
<div class="sla-drug-alert {{alert.state}}">
|
||||
<div class="sla-drug-alert-main">
|
||||
<div class="sla-drug-alert-name">{{alert.name}}</div>
|
||||
<div class="sla-drug-alert-meta">
|
||||
<span class="sla-drug-alert-state">{{alert.stateLabel}}</span>
|
||||
{{#if alert.duration}}<span class="sla-drug-alert-duration">{{alert.duration}}</span>{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-drug-alert-summary">{{alert.summary}}</div>
|
||||
<button type="button" class="drug-close-btn drug-close" data-item-id="{{alert.itemId}}" data-drug-id="{{alert.drugId}}">Close</button>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<ol class="items-list sla-drug-list">
|
||||
<li class="item flexrow item-header">
|
||||
<div class="item-image"></div>
|
||||
<div class="skill-stat" style="flex-grow: 1.6;">Drug</div>
|
||||
<div class="skill-stat">Qty</div>
|
||||
<div class="skill-stat">Rating</div>
|
||||
<div class="skill-stat">Value</div>
|
||||
<div class="skill-stat">Weight</div>
|
||||
<div class="skill-stat">Carry</div>
|
||||
<div class="skill-stat">State</div>
|
||||
<div class="skill-stat">Duration</div>
|
||||
<div class="item-controls">
|
||||
<a class="item-control item-create" title="Create Drug" data-type="drug"><i class="fas fa-plus"></i> Add</a>
|
||||
</div>
|
||||
</li>
|
||||
{{#each drugRows as |drug id|}}
|
||||
<li class="item flexrow dropitem" data-item-id="{{drug.itemId}}" data-drug-id="{{drug.drugId}}">
|
||||
<div class="item-image"><img src="{{drug.img}}" title="{{drug.name}}" width="24" height="24" /></div>
|
||||
<div class="skill-name list-roll description-roll drug-item-summary" style="flex-grow: 1.6;">{{drug.name}}<span>{{drug.summary}}</span></div>
|
||||
<div class="skill-stat item-quantity">{{drug.quantity}}</div>
|
||||
<div class="skill-stat">{{drug.rating}}</div>
|
||||
<div class="skill-stat">{{drug.cost}}</div>
|
||||
<div class="skill-stat">{{drug.slaCarry.totalWeight}} kg</div>
|
||||
<div class="skill-stat">
|
||||
<div class="sla-carry-toggle-row">
|
||||
<button type="button" class="sla-carry-toggle {{#if (compare 'str' drug.slaCarry.state '===' 'equipped')}}active{{/if}}" data-state="equipped">Eqp</button>
|
||||
<button type="button" class="sla-carry-toggle {{#if (compare 'str' drug.slaCarry.state '===' 'stowed')}}active{{/if}}" data-state="stowed">Stow</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="skill-stat">{{drug.statusLabel}}</div>
|
||||
<div class="skill-stat">{{drug.duration}}</div>
|
||||
<div class="item-controls">
|
||||
<button type="button" class="drug-use-btn drug-use" {{#unless drug.canUse}}disabled{{/unless}}>Use</button>
|
||||
<button type="button" class="drug-close-btn drug-close" {{#unless drug.canClose}}disabled{{/unless}}>Close</button>
|
||||
<a class="item-control item-edit" title="Edit Drug"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Drug"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</div>
|
||||
{{!-- Owned Skills Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="skills">
|
||||
<div class="sla-card" style="margin-bottom: 12px;">
|
||||
@@ -1154,10 +1104,10 @@
|
||||
<ol class="items-list" style="margin-bottom : 10px;">
|
||||
<li class="item flexrow item-header">
|
||||
<div class="item-image"></div>
|
||||
<div class="skill-stat" style="flex-grow: 1.4;" title="Click a skill name to roll it against the relevant stat. Your bonus is added to a d100 roll — you succeed by rolling under the total.">{{ localize 'Mosh.SkillName' }}</div>
|
||||
<div class="skill-stat" title="Category — broad skill grouping (Combat, Technical, Social, etc.) used for package sorting and Ebb discipline filtering.">Category</div>
|
||||
<div class="skill-stat" title="Rank — your proficiency level in this skill. Untrained (no bonus), Basic (+1–9), Trained (+10–14), Expert (+15–19), Master (+20+).">{{ localize 'Mosh.SkillRank' }}</div>
|
||||
<div class="skill-stat" title="Bonus — total modifier added to d100 rolls with this skill. Breakdown shown in small text below the value. Higher is better — you need to roll under (stat + bonus).">{{ localize 'Mosh.SkillBonus' }}</div>
|
||||
<div class="skill-stat" style="flex-grow: 1.4;">{{ localize 'Mosh.SkillName' }}</div>
|
||||
<div class="skill-stat">Category</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.SkillRank' }}</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.SkillBonus' }}</div>
|
||||
<div class="item-controls">
|
||||
<a class="item-control skill-create" title="{{ localize 'Mosh.CreateSkill' }}" data-type="skill"><i class="fas fa-plus"></i> {{ localize 'Mosh.Add' }}</a>
|
||||
</div>
|
||||
@@ -1216,7 +1166,7 @@
|
||||
<li class="item flexrow dropitem" data-item-id="{{condition._id}}">
|
||||
<div class="item-image"><img src="{{condition.img}}" title="{{condition.name}}" width="24" height="24"/></div>
|
||||
<div class="skill-name description-roll list-roll">{{condition.name}}</div>
|
||||
<div class="skill-stat list-roll severity">{{condition.system.severity}}</div>
|
||||
<div class="skill-stat list-roll severity" data-severity="{{condition.system.severity}}">{{condition.system.severity}}</div>
|
||||
<div class="skill-stat">
|
||||
{{#if condition.system.treatment.html}}
|
||||
<div class="treatment-button list-roll flex" style="margin: 0; position: relative; top: 50%; -ms-transform: translateY(-50%); transform: translateY(-50%);" data-key="condition" data-label="condition" data-max="3" data-min="0">
|
||||
@@ -1244,7 +1194,7 @@
|
||||
<div class="tab items" data-group="primary" data-tab="weapons">
|
||||
<div class="sla-card" style="margin-bottom: 12px;">
|
||||
<div class="sla-card-label">Weapons Readiness</div>
|
||||
<div class="sla-card-copy">Ammo stacks: {{slaAmmoInventory.stackCount}} | Total loose rounds: {{slaAmmoInventory.roundCount}} | Running ammo spend: {{system.sla.ammoSpendTotal.value}} cR</div>
|
||||
<div class="sla-card-copy">Ammo stacks: {{slaAmmoInventory.stackCount}} | Total loose rounds: {{slaAmmoInventory.roundCount}} | Running firing spend: {{system.sla.ammoSpendTotal.value}} cR</div>
|
||||
<div class="sla-card-copy">Carry: {{slaCarry.current}} / {{slaCarry.capacity}} kg | {{slaCarry.state}}</div>
|
||||
<div class="sla-action-row" style="margin-top: 8px;">
|
||||
<button type="button" class="sla-sheet-action weapon-reload-all">Reload All</button>
|
||||
@@ -1254,13 +1204,13 @@
|
||||
<ol class="items-list">
|
||||
<li class="item flexrow item-header">
|
||||
<div class="item-image"></div>
|
||||
<div class="skill-stat" style="flex-grow: 2;" title="Click a weapon name to make an attack roll using your Combat stat. Calibre and current ammo state shown below the name.">{{ localize 'Mosh.WeaponName' }}</div>
|
||||
<div class="skill-stat" title="Damage — rolled on a successful hit. Melee weapons may add your Strength modifier. Anti-Armour (AA) weapons halve target armour before applying damage.">{{ localize 'Mosh.Damage' }}</div>
|
||||
<div class="skill-stat" title="Ammo — currently loaded type (STD / AP / HE / HEAP) and reserve count. STD is standard. AP is armour-piercing (halves target armour, -1 damage). HE is high explosive (+1d5 damage, explosive wounds). HEAP combines AP and HE effects.">{{ localize 'Mosh.Ammo' }}</div>
|
||||
<div class="skill-stat" title="Shots — current magazine / maximum magazine capacity. Click the reload icon to reload or swap ammo type.">{{ localize 'Mosh.Shots' }}</div>
|
||||
<div class="skill-stat" title="Fire Mode — click to cycle between available modes. Single fires one shot. Burst fires several rounds for bonus damage but uses more ammo. Auto lays down suppressing fire.">Mode</div>
|
||||
<div class="skill-stat" title="Carry state — Eqp means the weapon is drawn and ready. Stow means holstered or packed. Only equipped weapons can be used in combat without an action to draw.">Carry</div>
|
||||
<div class="skill-stat" title="Range — maximum effective distance. At short range you roll normally. At medium range you take a penalty. At long range the penalty increases significantly. Beyond max range the weapon cannot reach.">{{ localize 'Mosh.Range' }}</div>
|
||||
<div class="skill-stat" style="flex-grow: 2;">{{ localize 'Mosh.WeaponName' }}</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Damage' }}</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Ammo' }}</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Shots' }}</div>
|
||||
<div class="skill-stat">Mode</div>
|
||||
<div class="skill-stat">Carry</div>
|
||||
<div class="skill-stat">{{ localize 'Mosh.Range' }}</div>
|
||||
<div class="item-controls">
|
||||
<a class="item-control weapon-create" title="{{ localize 'Mosh.CreateWeapon' }}" data-type="weapon"><i class="fas fa-plus"></i> {{ localize 'Mosh.Add' }}</a>
|
||||
</div>
|
||||
|
||||
@@ -97,6 +97,46 @@
|
||||
</div>
|
||||
<div class="whiteline"></div>
|
||||
</header>
|
||||
<section class="sla-creature-dossier">
|
||||
<div class="sla-creature-dossier-grid">
|
||||
<div class="resource">
|
||||
<label class="resource-label">Role</label>
|
||||
<input type="text" name="system.slaNpc.role.value" value="{{system.slaNpc.role.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Archetype</label>
|
||||
<input type="text" name="system.slaNpc.archetype.value" value="{{system.slaNpc.archetype.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Species</label>
|
||||
<input type="text" name="system.slaNpc.species.value" value="{{system.slaNpc.species.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Affiliation</label>
|
||||
<input type="text" name="system.slaNpc.affiliation.value" value="{{system.slaNpc.affiliation.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Department / Cell</label>
|
||||
<input type="text" name="system.slaNpc.department.value" value="{{system.slaNpc.department.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Sector</label>
|
||||
<input type="text" name="system.slaNpc.sector.value" value="{{system.slaNpc.sector.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Disposition</label>
|
||||
<input type="text" name="system.slaNpc.disposition.value" value="{{system.slaNpc.disposition.value}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Threat</label>
|
||||
<input type="text" name="system.slaNpc.threat.value" value="{{system.slaNpc.threat.value}}" />
|
||||
</div>
|
||||
<div class="resource sla-creature-dossier-wide">
|
||||
<label class="resource-label">Snapshot</label>
|
||||
<input type="text" name="system.slaNpc.summary.value" value="{{system.slaNpc.summary.value}}" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="creature-description-grid">
|
||||
<div class="creaturedescription">
|
||||
<div class="grid grid-3col">
|
||||
@@ -391,7 +431,7 @@
|
||||
<li class="item flexrow dropitem" data-item-id="{{condition._id}}">
|
||||
<div class="item-image"><img src="{{condition.img}}" title="{{condition.name}}" width="24" height="24"/></div>
|
||||
<div class="skill-name description-roll list-roll">{{condition.name}}</div>
|
||||
<div class="skill-stat list-roll severity">{{condition.system.severity}}</div>
|
||||
<div class="skill-stat list-roll severity" data-severity="{{condition.system.severity}}">{{condition.system.severity}}</div>
|
||||
<div class="skill-stat">
|
||||
{{#if condition.system.treatment.html}}
|
||||
<div class="treatment-button list-roll flex" style="margin: 0; position: relative; top: 50%; -ms-transform: translateY(-50%); transform: translateY(-50%);" data-key="condition" data-label="condition" data-max="3" data-min="0">
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
<form class="{{cssClass}} npc-sheet-form" autocomplete="off">
|
||||
{{!-- NPC Header --}}
|
||||
<header class="npc-header-container">
|
||||
<div class="npc-header-title-row">
|
||||
<input name="name" class="noborder npc-name-input" type="text" value="{{name}}" placeholder="NPC / Creature Name" />
|
||||
</div>
|
||||
|
||||
<div class="npc-meta-row">
|
||||
<div class="npc-meta-item">
|
||||
<label>Species</label>
|
||||
<input type="text" name="system.slaNpc.species.value" value="{{system.slaNpc.species.value}}" placeholder="Unknown" />
|
||||
</div>
|
||||
<div class="npc-meta-item">
|
||||
<label>Role</label>
|
||||
<input type="text" name="system.slaNpc.role.value" value="{{system.slaNpc.role.value}}" placeholder="None" />
|
||||
</div>
|
||||
<div class="npc-meta-item">
|
||||
<label>Threat</label>
|
||||
<input type="text" name="system.slaNpc.threat.value" value="{{system.slaNpc.threat.value}}" placeholder="Low" />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{!-- Main NPC Dashboard --}}
|
||||
<div class="npc-sheet-dashboard">
|
||||
|
||||
{{!-- Left Column: Vitals, Actions, Stats, and Skills --}}
|
||||
<div class="npc-column-left">
|
||||
|
||||
{{!-- Vitals --}}
|
||||
<div class="npc-vitals-block">
|
||||
<div class="npc-vital-card health">
|
||||
<span class="npc-vital-label">{{ localize 'Mosh.Health' }}</span>
|
||||
<div class="npc-vital-inputs">
|
||||
<input type="text" name="system.health.value" value="{{system.health.value}}" data-dtype="Number" />
|
||||
<span class="divider">/</span>
|
||||
<input type="text" name="system.health.max" value="{{system.health.max}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="npc-vital-card wounds">
|
||||
<span class="npc-vital-label">
|
||||
{{#if system.settings.firstEdition}}{{ localize 'Mosh.Wounds' }}{{else}}{{ localize 'Mosh.Hits' }}{{/if}}
|
||||
</span>
|
||||
<div class="npc-vital-inputs">
|
||||
<input type="text" name="system.hits.value" value="{{system.hits.value}}" data-dtype="Number" />
|
||||
<span class="divider">/</span>
|
||||
<input type="text" name="system.hits.max" value="{{system.hits.max}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Glowing Quick Roll Buttons --}}
|
||||
<div class="npc-action-buttons">
|
||||
<button type="button" class="npc-action-btn npc-wound-roll" title="Roll Wound Table">
|
||||
<i class="fas fa-skull"></i> 💀 WOUND ROLL
|
||||
</button>
|
||||
<button type="button" class="npc-action-btn npc-panic-roll" title="Roll Panic Check">
|
||||
<i class="fas fa-brain"></i> 🧠 PANIC ROLL
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{!-- Stats Grid --}}
|
||||
<div class="npc-section-block">
|
||||
<div class="npc-section-header">
|
||||
<span><i class="fas fa-chart-bar"></i> Attributes</span>
|
||||
</div>
|
||||
<div class="npc-stats-grid">
|
||||
<!-- Combat -->
|
||||
<div class="npc-stat-box">
|
||||
<span class="npc-stat-label stat-roll clickable" data-key="combat" data-roll="d100" data-label="Combat">COMBAT</span>
|
||||
<input type="text" name="system.stats.combat.value" value="{{system.stats.combat.value}}" data-dtype="Number" />
|
||||
</div>
|
||||
<!-- Instinct -->
|
||||
<div class="npc-stat-box">
|
||||
<span class="npc-stat-label stat-roll clickable" data-key="instinct" data-roll="d100" data-label="Instinct">INSTINCT</span>
|
||||
<input type="text" name="system.stats.instinct.value" value="{{system.stats.instinct.value}}" data-dtype="Number" />
|
||||
</div>
|
||||
<!-- Speed -->
|
||||
<div class="npc-stat-box">
|
||||
<span class="npc-stat-label stat-roll clickable" data-key="speed" data-roll="d100" data-label="Speed">SPEED</span>
|
||||
<input type="text" name="system.stats.speed.value" value="{{system.stats.speed.value}}" data-dtype="Number" />
|
||||
</div>
|
||||
<!-- Loyalty -->
|
||||
<div class="npc-stat-box">
|
||||
<span class="npc-stat-label stat-roll clickable" data-key="loyalty" data-roll="d100" data-label="Loyalty">LOYALTY</span>
|
||||
<input type="text" name="system.stats.loyalty.value" value="{{system.stats.loyalty.value}}" data-dtype="Number" />
|
||||
</div>
|
||||
<!-- Armor -->
|
||||
<div class="npc-stat-box">
|
||||
<span class="npc-stat-label stat-roll clickable" data-key="armor" data-roll="d100" data-label="Armor Save">ARMOR</span>
|
||||
<input type="text" name="system.stats.armor.value" value="{{system.stats.armor.value}}" data-dtype="Number" />
|
||||
</div>
|
||||
<!-- Sanity -->
|
||||
<div class="npc-stat-box">
|
||||
<span class="npc-stat-label stat-roll clickable" data-key="sanity" data-roll="d100" data-label="Sanity">SANITY</span>
|
||||
<input type="text" name="system.stats.sanity.value" value="{{system.stats.sanity.value}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Skills (Max 5) --}}
|
||||
<div class="npc-section-block">
|
||||
<div class="npc-section-header">
|
||||
<span><i class="fas fa-graduation-cap"></i> Skills (Max 5)</span>
|
||||
{{#if showAddSkill}}
|
||||
<a class="item-control skill-create npc-add-btn" title="Create Skill" data-type="skill"><i class="fas fa-plus"></i> Add Skill</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="npc-skills-list">
|
||||
{{#each skills as |skill id|}}
|
||||
<div class="npc-skill-item item" data-item-id="{{skill._id}}">
|
||||
<span class="skill-name skill-roll clickable" title="Roll Skill Check">{{skill.name}}</span>
|
||||
<span class="skill-bonus">+{{skill.system.bonus}}%</span>
|
||||
<div class="skill-controls">
|
||||
<a class="item-control skill-edit" title="Edit Skill"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Skill"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="npc-empty-text">No skills added yet. Click 'Add Skill' to add one.</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{!-- Right Column: Image, Weapons, Armor Values, and Ebon Capabilities --}}
|
||||
<div class="npc-column-right">
|
||||
|
||||
{{!-- Profile Image --}}
|
||||
<div class="npc-profile-wrapper">
|
||||
<img class="img profile noborder npc-profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||
</div>
|
||||
|
||||
{{!-- Weapons --}}
|
||||
<div class="npc-section-block">
|
||||
<div class="npc-section-header">
|
||||
<span><i class="fas fa-crosshairs"></i> Weapons</span>
|
||||
<a class="item-control weapon-create npc-add-btn" title="Create Weapon" data-type="weapon"><i class="fas fa-plus"></i> Add Weapon</a>
|
||||
</div>
|
||||
<div class="npc-weapons-list">
|
||||
{{#each weapons as |weapon id|}}
|
||||
<div class="npc-weapon-item item" data-item-id="{{weapon._id}}">
|
||||
<div class="weapon-main">
|
||||
<span class="weapon-name weapon-roll clickable" title="Roll Attack Check">{{weapon.name}}</span>
|
||||
<span class="weapon-damage dmg-roll clickable" title="Roll Damage">{{weapon.system.damage}}</span>
|
||||
{{#if weapon.system.useAmmo}}
|
||||
<span class="weapon-ammo-count weapon-ammo clickable" title="Right/Left click to adjust ammo">{{weapon.system.ammo}} rnds</span>
|
||||
{{/if}}
|
||||
<div class="weapon-controls">
|
||||
<a class="item-control weapon-edit" title="Edit Weapon"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Weapon"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="npc-empty-text">No weapons added yet.</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Armor AP & DR --}}
|
||||
<div class="npc-section-block">
|
||||
<div class="npc-section-header">
|
||||
<span><i class="fas fa-shield-alt"></i> Protection Values</span>
|
||||
</div>
|
||||
<div class="npc-armor-grid">
|
||||
<div class="npc-armor-field">
|
||||
<label>Armor Points (AP)</label>
|
||||
<input type="text" name="system.stats.armor.mod" value="{{system.stats.armor.mod}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="npc-armor-field">
|
||||
<label>Damage Reduction (DR)</label>
|
||||
<input type="text" name="system.stats.armor.damageReduction" value="{{system.stats.armor.damageReduction}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Ebon (Ebb) Capabilities --}}
|
||||
<div class="npc-section-block">
|
||||
<div class="npc-section-header">
|
||||
<span><i class="fas fa-magic"></i> Ebon Capabilities</span>
|
||||
<a class="item-control weapon-create npc-add-btn" title="Create Ability" data-type="ability"><i class="fas fa-plus"></i> Add Ebb</a>
|
||||
</div>
|
||||
<div class="npc-abilities-list">
|
||||
{{#each abilities as |ability id|}}
|
||||
<div class="npc-ability-item item" data-item-id="{{ability._id}}">
|
||||
<div class="ability-main">
|
||||
<span class="ability-name description-roll clickable" title="Click to post description to chat">{{ability.name}}</span>
|
||||
<div class="ability-controls">
|
||||
<a class="item-control item-edit" title="Edit Ability"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Ability"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{#if ability.system.description}}
|
||||
<div class="ability-description">{{{ability.system.description}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="npc-empty-text">No Ebon abilities.</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,88 +1,97 @@
|
||||
<div class="mosh" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-item" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
{{#if item._id}}data-item-id="{{item._id}}" {{/if}} {{#if tokenId}}data-token-id="{{tokenId}}" {{/if}}>
|
||||
<div class="showinfo"></div>
|
||||
<div class="showlessinfo"></div>
|
||||
<div class="rollcontainer">
|
||||
<div class="flexrow">
|
||||
{{#if swapNameDesc}}
|
||||
<div class="rollweaponh1" >{{swapName}}</div>
|
||||
{{else}}
|
||||
{{#if (compare 'int' item.name.length '>=' 22)}}
|
||||
<div class="rollweaponh1" style="font-size: 0.75rem; padding-top: 7px;">{{item.name}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1" >{{item.name}}</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (compare 'str' item.type '===' 'ability')}}
|
||||
{{#if (compare 'str' actor.img '===' 'icons/svg/mystery-man.svg')}}
|
||||
<div style="text-align: right"><img class="roll-image" src="systems/sla-mothership/images/icons/ui/attributes/instinct.png" /></div>
|
||||
{{else}}
|
||||
<div style="text-align: right"><img class="roll-image" src="{{actor.img}}" /></div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div style="text-align: right"><img class="roll-image" src="{{item.img}}" /></div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sla-chat-hero">
|
||||
<div class="sla-chat-hero-main">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker">Item Detail</div>
|
||||
<div class="sla-chat-meta-row">
|
||||
{{#if (compare 'str' item.system.sla.impact '===' 'heal')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-heal">HLG</span>
|
||||
{{else if item.system.roll}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-attack">ATK</span>
|
||||
{{else if (compare 'str' item.type '===' 'ability')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-ebb">ABL</span>
|
||||
{{else}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-item">ITM</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if swapNameDesc}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{swapName}}</div>
|
||||
{{else}}
|
||||
{{#if (compare 'int' item.name.length '>=' 22)}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title sla-chat-hero-title-tight">{{item.name}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{item.name}}</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sla-chat-hero-media">
|
||||
{{#if (compare 'str' item.type '===' 'ability')}}
|
||||
{{#if (compare 'str' actor.img '===' 'icons/svg/mystery-man.svg')}}
|
||||
<img class="roll-image" src="systems/sla-mothership/images/icons/ui/attributes/instinct.png" />
|
||||
{{else}}
|
||||
<img class="roll-image" src="{{actor.img}}" />
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<img class="roll-image" src="{{item.img}}" />
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if item.system.roll}}
|
||||
<div class="description">
|
||||
<div class="description sla-chat-section {{#if (compare 'str' item.system.sla.impact '===' 'heal')}}sla-chat-section-heal{{else}}sla-chat-section-damage{{/if}}">
|
||||
{{#if (compare 'str' item.system.sla.impact '===' 'heal')}}
|
||||
<div class="body">You restore <strong>[[{{item.system.roll}}[damage]]]</strong> points of healing.</div>
|
||||
{{else}}
|
||||
<div class="body">You inflict <strong>[[{{item.system.roll}}[damage]]]</strong> points of damage.</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div style="margin-bottom : 10px;"></div>
|
||||
<div style="border-bottom: 1px solid #999; height: 0; width: 100%;"></div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
{{/if}}
|
||||
|
||||
{{#if item.system.severity}}
|
||||
<div class="description">
|
||||
<div class="body"><strong>{{ localize 'Mosh.Severity' }}: </strong>{{item.system.severity}}</div>
|
||||
<div class="description sla-chat-section {{severityMeta.cssClass}}" data-severity="{{item.system.severity}}">
|
||||
<div class="sla-chat-section-heading">
|
||||
<span class="sla-chat-severity-pill {{severityMeta.cssClass}}">{{severityMeta.label}}</span>
|
||||
</div>
|
||||
<div class="body"><strong>{{ localize 'Mosh.Severity' }}:</strong> {{item.system.severity}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
<div style="border-bottom: 1px solid #999; height: 0; width: 100%;"></div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
{{/if}}
|
||||
|
||||
{{#if item.system.armorPoints}}
|
||||
<div class="description">
|
||||
<div class="body"><strong>{{ localize 'Mosh.ArmorPoints' }}: </strong>{{item.system.armorPoints}}</div>
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body"><strong>{{ localize 'Mosh.ArmorPoints' }}:</strong> {{item.system.armorPoints}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
<div style="border-bottom: 1px solid #999; height: 0; width: 100%;"></div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
{{/if}}
|
||||
|
||||
{{#if item.system.damageReduction}}
|
||||
<div class="description">
|
||||
<div class="body"><strong>{{ localize 'Mosh.DMGReduction' }}: </strong>{{item.system.damageReduction}}</div>
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body"><strong>{{ localize 'Mosh.DMGReduction' }}:</strong> {{item.system.damageReduction}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
<div style="border-bottom: 1px solid #999; height: 0; width: 100%;"></div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
{{/if}}
|
||||
|
||||
{{#if swapNameDesc}}
|
||||
<div class="description">
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">{{{item.name}}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 16px;"></div>
|
||||
{{else if (compare 'str' item.system.type '===' 'repair')}}
|
||||
<div class="description">
|
||||
<div class="description sla-chat-section">
|
||||
{{#if item.system.major}}
|
||||
<div class="body"><strong>{{ localize 'Mosh.MajorRepair' }}</strong></div>
|
||||
{{else}}
|
||||
<div class="body"><strong>{{ localize 'Mosh.MinorRepair' }}</strong></div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
<div style="border-bottom: 1px solid #999; height: 0; width: 100%;"></div>
|
||||
<div style="margin-bottom : 5px;"></div>
|
||||
<div class="description">
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">{{{item.name}}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 16px;"></div>
|
||||
{{else}}
|
||||
<div class="description">
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">{{{item.system.description}}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 16px;"></div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
<div class="mosh" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-actor-update" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
{{#if item._id}}data-item-id="{{item._id}}" {{/if}} {{#if tokenId}}data-token-id="{{tokenId}}" {{/if}}>
|
||||
<div class="rollcontainer">
|
||||
<div class="flexrow" style="margin-bottom: 5px;">
|
||||
{{#if (compare 'int' msgHeader.length '>=' 22)}}
|
||||
<div class="rollweaponh1" style="font-size: 0.75rem; padding-top: 7px;">{{{msgHeader}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1" >{{{msgHeader}}}</div>
|
||||
{{/if}}
|
||||
<div style="text-align: right"><img class="roll-image" src="{{{msgImgPath}}}" /></div>
|
||||
<div class="sla-chat-hero">
|
||||
<div class="sla-chat-hero-main">
|
||||
<div class="sla-chat-kicker">Actor Update</div>
|
||||
{{#if (compare 'int' msgHeader.length '>=' 22)}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title sla-chat-hero-title-tight">{{{msgHeader}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{{msgHeader}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sla-chat-hero-media">
|
||||
<img class="roll-image" src="{{{msgImgPath}}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="description"" style="margin-bottom: 20px;">
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">
|
||||
{{{msgFlavor}}}
|
||||
{{#if modRollString}}
|
||||
<div class="description" style="margin-bottom: 10px;"></div>
|
||||
{{{parsedRollResult.rollHtml}}}
|
||||
{{else}}
|
||||
<br><br>
|
||||
<div class="sla-chat-rollframe">{{{parsedRollResult.rollHtml}}}</div>
|
||||
{{/if}}
|
||||
{{{msgOutcome}}}
|
||||
{{#if halfDamage}}
|
||||
<br><br>@UUID[Compendium.mosh.macros_hotbar_0e.eyGvbBi1BhWSgfUP]{Make a Panic Check}
|
||||
<div class="sla-chat-section sla-chat-section-danger">
|
||||
<div class="body">@UUID[Compendium.mosh.macros_hotbar_0e.eyGvbBi1BhWSgfUP]{Make a Panic Check}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
<div class="mosh" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-item-update" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
{{#if item._id}}data-item-id="{{item._id}}" {{/if}} {{#if tokenId}}data-token-id="{{tokenId}}" {{/if}}>
|
||||
<div class="rollcontainer">
|
||||
<div class="flexrow" style="margin-bottom : 5px;">
|
||||
{{#if (compare 'int' msgHeader.length '>=' 22)}}
|
||||
<div class="rollweaponh1" style="font-size: 0.75rem; padding-top: 7px;">{{{msgHeader}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1" >{{{msgHeader}}}</div>
|
||||
{{/if}}
|
||||
<div style="text-align: right"><img class="roll-image" src="{{{msgImgPath}}}" /></div>
|
||||
<div class="sla-chat-hero">
|
||||
<div class="sla-chat-hero-main">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker">Item Update</div>
|
||||
<div class="sla-chat-meta-row">
|
||||
<span class="sla-chat-type-badge sla-chat-type-item">UPD</span>
|
||||
</div>
|
||||
</div>
|
||||
{{#if (compare 'int' msgHeader.length '>=' 22)}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title sla-chat-hero-title-tight">{{{msgHeader}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{{msgHeader}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sla-chat-hero-media">
|
||||
<img class="roll-image" src="{{{msgImgPath}}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="description" style="margin-bottom: 10px;">
|
||||
<div class="description sla-chat-section sla-chat-section-target">
|
||||
<div class="body">{{{flavorText}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
<div class="mosh" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-reload" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
{{#if item._id}}data-item-id="{{item._id}}" {{/if}} {{#if tokenId}}data-token-id="{{tokenId}}" {{/if}}>
|
||||
<div class="rollcontainer">
|
||||
<div class="flexrow" style="margin-bottom : 5px;">
|
||||
{{#if (compare 'int' item.name.length '>=' 22)}}
|
||||
<div class="rollweaponh1" style="font-size: 0.75rem; padding-top: 7px;">{{{item.name}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1" >{{{item.name}}}</div>
|
||||
{{/if}}
|
||||
<div style="text-align: right"><img class="roll-image" src="systems/sla-mothership/images/icons/ui/macros/reload.png" /></div>
|
||||
<div class="sla-chat-hero">
|
||||
<div class="sla-chat-hero-main">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker">Reload Action</div>
|
||||
<div class="sla-chat-meta-row">
|
||||
<span class="sla-chat-type-badge sla-chat-type-reload">RLD</span>
|
||||
</div>
|
||||
</div>
|
||||
{{#if (compare 'int' item.name.length '>=' 22)}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title sla-chat-hero-title-tight">{{{item.name}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{{item.name}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sla-chat-hero-media">
|
||||
<img class="roll-image" src="systems/sla-mothership/images/icons/ui/macros/reload.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="description">
|
||||
<div class="description sla-chat-section sla-chat-section-target">
|
||||
<div class="body">{{{msgBody}}}</div>
|
||||
</div>
|
||||
<div style="margin-bottom : 16px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,38 +1,58 @@
|
||||
<div class="mosh{{#if isSlaEbbSkill}} sla-ebb-chat{{/if}}" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-check{{#if isSlaEbbSkill}} sla-chat-shell-ebb{{/if}} sla-chat-variant-{{chatStyle.key}}{{#if parsedRollResult.success}} sla-chat-shell-success{{else}} sla-chat-shell-failure{{/if}}{{#if parsedRollResult.critical}} sla-chat-shell-critical{{/if}}" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
{{#if weapon._id}}data-item-id="{{weapon._id}}" {{/if}} {{#if tokenId}}data-token-id="{{tokenId}}" {{/if}}>
|
||||
<div class="rollcontainer">
|
||||
<div class="flexrow" style="margin-bottom : 5px;">
|
||||
{{#if (compare 'int' msgHeader.length '>=' 22)}}
|
||||
<div class="rollweaponh1" style="font-size: 0.75rem; padding-top: 7px;">{{{msgHeader}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1" >{{{msgHeader}}}</div>
|
||||
{{/if}}
|
||||
<div style="text-align: right"><img class="roll-image" src="{{{msgImgPath}}}" /></div>
|
||||
<div class="sla-chat-hero">
|
||||
<div class="sla-chat-hero-main">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker">{{#if (compare 'str' specialRoll '===' 'damage')}}Attack Roll{{else if isSlaEbbSkill}}Ebb Check{{else}}Normal Roll{{/if}}</div>
|
||||
<div class="sla-chat-meta-row">
|
||||
{{#if (compare 'str' specialRoll '===' 'damage')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-attack">ATK</span>
|
||||
{{else if isSlaEbbSkill}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-ebb">EBB</span>
|
||||
{{else}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-normal">CHK</span>
|
||||
{{/if}}
|
||||
<div class="sla-chat-deptline"><span class="sla-chat-emblem">{{chatStyle.emblem}}</span><span class="sla-chat-dept">{{chatStyle.label}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if (compare 'int' msgHeader.length '>=' 22)}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title sla-chat-hero-title-tight">{{{msgHeader}}}</div>
|
||||
{{else}}
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{{msgHeader}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sla-chat-hero-media">
|
||||
<img class="roll-image" src="{{{msgImgPath}}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if (compare 'str' specialRoll '!==' 'damage')}}
|
||||
{{{parsedRollResult.outcomeHtml}}}
|
||||
<div class="description" style="margin-bottom: 10px;">
|
||||
<div class="body">
|
||||
{{#if (compare 'int' parsedRollResult.total '>=' 90)}}
|
||||
<span class="high-failure">{{ localize 'Mosh.YouRolled90OrHigher' }}</span>
|
||||
{{else}}
|
||||
{{#if isSlaEbbSkill}}
|
||||
<div class="sla-chat-summary">
|
||||
{{#if (compare 'int' parsedRollResult.total '>=' 90)}}
|
||||
<span class="high-failure">{{ localize 'Mosh.YouRolled90OrHigher' }}</span>
|
||||
{{else}}
|
||||
{{#if isSlaEbbSkill}}
|
||||
{{#if (compare 'int' skillValue '>' 0)}}
|
||||
You {{{outcomeVerb}}} {{{comparisonText}}} your <strong>{{{attribute}}}</strong> plus the <strong>{{{skill}}}</strong> discipline.
|
||||
{{else}}
|
||||
You {{{outcomeVerb}}} {{{comparisonText}}} your <strong>{{{attribute}}}</strong> while channeling <strong>{{{skill}}}</strong>.
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{else}}
|
||||
{{#if (compare 'int' skillValue '>' 0)}}
|
||||
You {{{outcomeVerb}}} {{{comparisonText}}} your <strong>{{{attribute}}}</strong> plus <strong>{{{skill}}}</strong> skill bonus.
|
||||
{{else}}
|
||||
You {{{outcomeVerb}}} {{{comparisonText}}} your <strong>{{{attribute}}}</strong>.
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{{parsedRollResult.rollHtml}}}
|
||||
|
||||
<div class="sla-chat-rollframe">
|
||||
{{{parsedRollResult.outcomeHtml}}}
|
||||
{{{parsedRollResult.rollHtml}}}
|
||||
</div>
|
||||
|
||||
{{#if isSlaEbbSkill}}
|
||||
<div class="sla-chat-section sla-chat-section-ebb-meta">
|
||||
<div class="sla-chat-section-title">Ebb Discipline</div>
|
||||
@@ -50,79 +70,73 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<div class="description" style="margin-bottom : 20px;">
|
||||
{{#if (compare 'str' specialRoll '===' 'damage')}}
|
||||
<div class="description sla-chat-section">{{{flavorText}}}</div>
|
||||
{{#if needsDesc}}
|
||||
<div style="margin-bottom : 10px;"></div>
|
||||
<div class="grid grid-2col" style="grid-template-columns: 10px 75px auto">
|
||||
<div style="border-bottom:1px solid #999; height: 50%;"></div>
|
||||
<div style= "font-size:0.65rem; text-align:center;">DESCRIPTION</div>
|
||||
<div style="border-bottom:1px solid #999; height: 50%;"></div>
|
||||
</div>
|
||||
<div style="margin-bottom : 10px;"></div>
|
||||
<div class="description">
|
||||
<div class="body">{{{weapon.system.description}}}</div>
|
||||
{{#if woundEffect}}
|
||||
<div class="body">
|
||||
<br><strong>{{ localize 'Mosh.WoundEffect' }}</strong>
|
||||
<div style="margin-bottom : 3px;"></div>
|
||||
{{{woundEffect}}}
|
||||
{{#unless isSlaEbbSkill}}
|
||||
{{#if rollBreakdown}}
|
||||
<div class="sla-chat-section sla-chat-section-meta" style="margin-top: 5px; border-top: 1px dashed rgba(255,255,255,0.15); padding-top: 5px;">
|
||||
<div class="body"><strong>Target Number:</strong> {{#each rollBreakdown.parts as |part index|}}{{#if index}} + {{/if}}{{part.label}} {{part.value}}{{/each}} = <strong>{{rollBreakdown.total}}</strong></div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (compare 'str' specialRoll '===' 'damage')}}
|
||||
<div class="sla-chat-section sla-chat-section-damage">{{{flavorText}}}</div>
|
||||
<div class="sla-chat-section sla-chat-section-crit-btn" style="margin-top: 6px;">
|
||||
<button class="sla-crit-hit-btn" data-actor-id="{{actor._id}}" data-item-id="{{weapon._id}}" style="background: linear-gradient(185deg, #a80000 0%, #5c0000 100%); color: #ffffff; border: 1px solid #ff4444; border-radius: 4px; padding: 6px 12px; cursor: pointer; font-family: 'Barlow Condensed', sans-serif; font-size: 11pt; font-weight: bold; width: 100%; text-shadow: 0 1px 2px #000; box-shadow: 0 0 6px rgba(255, 0, 0, 0.4); transition: all 0.2s ease;">
|
||||
<i class="fas fa-skull-crossbones"></i> CRITICAL HIT?
|
||||
</button>
|
||||
</div>
|
||||
<div style="margin-bottom : 16px;"></div>
|
||||
{{#if needsDesc}}
|
||||
<div class="sla-chat-divider">Description</div>
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">{{{weapon.system.description}}}</div>
|
||||
{{#if woundEffect}}
|
||||
<div class="body sla-chat-wound-block">
|
||||
<strong>{{ localize 'Mosh.WoundEffect' }}</strong>
|
||||
<div class="sla-chat-wound-link">{{{woundEffect}}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{#if parsedRollResult.success}}
|
||||
{{#if flavorText}}<div class="sla-chat-section sla-chat-section-success">{{{flavorText}}}</div>{{/if}}
|
||||
{{#if weapon}}
|
||||
<div class="description sla-chat-section">{{{flavorText}}}</div>
|
||||
{{#if criticalSuccessOptions.length}}
|
||||
<div class="sla-chat-section sla-chat-section-success">
|
||||
<div class="sla-chat-section-title">Critical Success Options</div>
|
||||
<ol class="sla-chat-list">
|
||||
{{#each criticalSuccessOptions as |option|}}
|
||||
<li>{{option}}</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
<div class="sla-chat-section sla-chat-section-crit-btn" style="margin-top: 6px; margin-bottom: 6px;">
|
||||
<button class="sla-crit-hit-btn" data-actor-id="{{actor._id}}" data-item-id="{{weapon._id}}" style="background: linear-gradient(185deg, #a80000 0%, #5c0000 100%); color: #ffffff; border: 1px solid #ff4444; border-radius: 4px; padding: 6px 12px; cursor: pointer; font-family: 'Barlow Condensed', sans-serif; font-size: 11pt; font-weight: bold; width: 100%; text-shadow: 0 1px 2px #000; box-shadow: 0 0 6px rgba(255, 0, 0, 0.4); transition: all 0.2s ease;">
|
||||
<i class="fas fa-skull-crossbones"></i> CRITICAL HIT?
|
||||
</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if criticalSuccessOptions.length}}
|
||||
<div class="sla-chat-section sla-chat-section-success">
|
||||
<div class="sla-chat-section-title"><i class="fas fa-crown"></i> Critical Success Options</div>
|
||||
<div class="sla-crit-success-options" style="margin-top: 5px;">
|
||||
{{#each criticalSuccessOptions as |option|}}
|
||||
<button class="sla-crit-option-btn" data-actor-id="{{../actor._id}}" data-option-text="{{option}}" style="background: linear-gradient(180deg, #1f421f 0%, #0c260c 100%); color: #bdf2bd; border: 1px solid #3fa63f; border-radius: 4px; padding: 8px 10px; margin-bottom: 8px; cursor: pointer; font-family: 'Barlow Condensed', sans-serif; font-size: 10.5pt; text-align: left; width: 100%; transition: all 0.2s ease; display: flex !important; align-items: flex-start !important; gap: 6px; text-shadow: 0 1px 2px #000; height: auto !important; min-height: fit-content !important; line-height: 1.3 !important; overflow: visible !important; white-space: normal !important;">
|
||||
<i class="fas fa-chevron-right" style="margin-top: 3px; font-size: 8pt; color: #2ebd2e;"></i>
|
||||
<span>{{option}}</span>
|
||||
</button>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if weapon}}
|
||||
{{#if needsDesc}}
|
||||
<div style="margin-bottom : 10px;"></div>
|
||||
<div class="grid grid-2col" style="grid-template-columns: 10px 75px auto">
|
||||
<div style="border-bottom:1px solid #999; height: 50%;"></div>
|
||||
<div style= "font-size:0.65rem; text-align:center;">{{ localize 'Mosh.Description' }}</div>
|
||||
<div style="border-bottom:1px solid #999; height: 50%;"></div>
|
||||
</div>
|
||||
<div style="margin-bottom : 10px;"></div>
|
||||
<div class="description">
|
||||
<div class="sla-chat-divider">{{ localize 'Mosh.Description' }}</div>
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">{{{weapon.system.description}}}</div>
|
||||
{{#if woundEffect}}
|
||||
<div class="body">
|
||||
<br><strong>{{ localize 'Mosh.WoundEffect' }}</strong>
|
||||
<div style="margin-bottom : 3px;"></div>
|
||||
{{{woundEffect}}}
|
||||
<div class="body sla-chat-wound-block">
|
||||
<strong>{{ localize 'Mosh.WoundEffect' }}</strong>
|
||||
<div class="sla-chat-wound-link">{{{woundEffect}}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div style="margin-bottom : 16px;"></div>
|
||||
{{else}}
|
||||
<div class="sla-chat-section">{{{flavorText}}}</div>
|
||||
{{#if criticalSuccessOptions.length}}
|
||||
<div class="sla-chat-section sla-chat-section-success">
|
||||
<div class="sla-chat-section-title">Critical Success Options</div>
|
||||
<ol class="sla-chat-list">
|
||||
{{#each criticalSuccessOptions as |option|}}
|
||||
<li>{{option}}</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{#if flavorText}}<div class="sla-chat-section">{{{flavorText}}}</div>{{/if}}
|
||||
{{#if flavorText}}<div class="sla-chat-section sla-chat-section-danger">{{{flavorText}}}</div>{{/if}}
|
||||
{{#if criticalFailureTable}}
|
||||
<div class="sla-chat-section sla-chat-section-danger">
|
||||
<div class="sla-chat-section-title">{{criticalFailureTable.label}}</div>
|
||||
@@ -132,15 +146,18 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if critFail}}
|
||||
<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.IgWvaabVqzKDzLL4]{Make a Panic Check}
|
||||
<div class="sla-chat-section sla-chat-section-danger">
|
||||
<div class="body">@UUID[Compendium.mosh.macros_hotbar_1e.IgWvaabVqzKDzLL4]{Make a Panic Check}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if targetingResult}}
|
||||
<div class="sla-chat-section sla-chat-section-target">
|
||||
<div class="sla-chat-section-title">Target Resolution</div>
|
||||
<div class="body"><strong>{{targetingResult.targetName}}</strong> took <strong>{{targetingResult.finalDamage}}</strong> damage.</div>
|
||||
<div class="body">Rolled {{targetingResult.rawDamage}}. Armour reduced {{targetingResult.armourReduced}}{{#if targetingResult.armourPiercing}} after AP/anti-armour effects{{/if}}.</div>
|
||||
<div class="body">Rolled {{targetingResult.rawDamage}}. Armour reduced {{targetingResult.armourReduced}}{{#if targetingResult.armourPiercing}} after AP or anti-armour effects{{/if}}.</div>
|
||||
{{#if targetingResult.additionalTargets}}
|
||||
<div class="body">{{targetingResult.additionalTargets}} additional targeted token(s) were ignored for this automatic application.</div>
|
||||
{{/if}}
|
||||
@@ -152,6 +169,5 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,45 @@
|
||||
<div class="mosh" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-table sla-chat-variant-{{chatStyle.key}}{{#if parsedRollResult.success}} sla-chat-shell-success{{else}} sla-chat-shell-failure{{/if}}" {{#if actor._id}}data-actor-id="{{actor._id}}" {{/if}}
|
||||
{{#if item._id}}data-item-id="{{item._id}}" {{/if}} {{#if tokenId}}data-token-id="{{tokenId}}" {{/if}}>
|
||||
<div class="rollcontainer">
|
||||
<div class="flexrow" style="margin-bottom : 5px;">
|
||||
<div class="rollweaponh1">{{{tableName}}}</div>
|
||||
<div style="text-align: right"><img class="roll-image" src="{{{tableImg}}}" /></div>
|
||||
<div class="sla-chat-hero">
|
||||
<div class="sla-chat-hero-main">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker">Table Roll</div>
|
||||
<div class="sla-chat-meta-row">
|
||||
{{#if (compare 'str' specialRoll '===' 'panicCheck')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-panic">PNC</span>
|
||||
{{else if (compare 'str' tableName '===' 'Gunshot Wound')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-wound">WND</span>
|
||||
{{else if (compare 'str' tableName '===' 'Bleeding Wound')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-wound">WND</span>
|
||||
{{else if (compare 'str' tableName '===' 'Fire & Explosives Wound')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-wound">WND</span>
|
||||
{{else if (compare 'str' tableName '===' 'Gore & Massive Wound')}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-wound">WND</span>
|
||||
{{else}}
|
||||
<span class="sla-chat-type-badge sla-chat-type-table">TBL</span>
|
||||
{{/if}}
|
||||
<div class="sla-chat-deptline"><span class="sla-chat-emblem">{{chatStyle.emblem}}</span><span class="sla-chat-dept">{{chatStyle.label}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rollweaponh1 sla-chat-hero-title">{{{tableName}}}</div>
|
||||
</div>
|
||||
<div class="sla-chat-hero-media">
|
||||
<img class="roll-image" src="{{{tableImg}}}" />
|
||||
</div>
|
||||
</div>
|
||||
{{{parsedRollResult.outcomeHtml}}}
|
||||
<div class="description sla-chat-section" style="margin-bottom: 10px;">
|
||||
|
||||
<div class="description sla-chat-section">
|
||||
<div class="body">{{{msgDesc}}}</div>
|
||||
</div>
|
||||
{{{parsedRollResult.rollHtml}}}
|
||||
|
||||
<div class="sla-chat-rollframe">
|
||||
{{{parsedRollResult.outcomeHtml}}}
|
||||
{{{parsedRollResult.rollHtml}}}
|
||||
</div>
|
||||
|
||||
{{#if secondRoll}}
|
||||
<div class="description sla-chat-section" style="margin-bottom: 10px;">
|
||||
<div class="description sla-chat-section">
|
||||
{{#if (compare 'str' specialRoll '===' 'panicCheck')}}
|
||||
<div class="body">{{ localize 'Mosh.RollingForPanicEffect' }}</div>
|
||||
{{/if}}
|
||||
@@ -19,34 +47,57 @@
|
||||
<div class="body">{{ localize 'Mosh.RollingForMaintenanceIssue' }}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{{parsedRollResult2.rollHtml}}}
|
||||
<div class="sla-chat-rollframe">
|
||||
{{{parsedRollResult2.rollHtml}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if parsedRollResult.success}}
|
||||
<div class="description sla-chat-section sla-chat-section-success" style="margin-bottom : 20px;">{{{flavorText}}}</div>
|
||||
<div class="description sla-chat-section sla-chat-section-success">{{{flavorText}}}</div>
|
||||
{{else}}
|
||||
{{#if woundText}}
|
||||
{{{woundText}}}<br><br>
|
||||
<div class="sla-chat-section sla-chat-section-danger {{severityMeta.cssClass}}">
|
||||
<div class="sla-chat-section-heading">
|
||||
<span class="sla-chat-severity-pill {{severityMeta.cssClass}}">{{severityMeta.label}}</span>
|
||||
</div>
|
||||
{{{woundText}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (compare 'str' tableResultType '===' 'document')}}
|
||||
<ol class="table-results">
|
||||
{{#each tableResult}}
|
||||
<li class="table-result flexrow" data-result-id="{{{this._id}}}">
|
||||
<img class="result-image" src="{{{this.img}}}">
|
||||
<div class="result-text"><a class="content-link broken" draggable="true" data-type="Item" data-uuid="undefined"><i class="fas fa-unlink"></i>{{{this.description}}}</a></div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
<div class="sla-chat-section sla-chat-section-target">
|
||||
<div class="sla-chat-section-title">Linked Results</div>
|
||||
<ol class="table-results">
|
||||
{{#each tableResult}}
|
||||
<li class="table-result flexrow" data-result-id="{{{this._id}}}">
|
||||
<img class="result-image" src="{{{this.img}}}">
|
||||
<div class="result-text"><a class="content-link broken" draggable="true" data-type="Item" data-uuid="undefined"><i class="fas fa-unlink"></i>{{{this.description}}}</a></div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (compare 'str' tableResultType '===' 'text')}}
|
||||
{{#if tableResultEdited}}
|
||||
<div class="description sla-chat-section sla-chat-section-danger" style="margin-bottom : 20px;">{{{tableResultEdited}}}{{{tableResultFooter}}}</div>
|
||||
<div class="description sla-chat-section sla-chat-section-danger {{severityMeta.cssClass}}">
|
||||
<div class="sla-chat-section-heading">
|
||||
<span class="sla-chat-severity-pill {{severityMeta.cssClass}}">{{severityMeta.label}}</span>
|
||||
</div>
|
||||
{{{tableResultEdited}}}{{{tableResultFooter}}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="description sla-chat-section sla-chat-section-danger" style="margin-bottom : 20px;">{{{tableResult.[0].description}}}{{{tableResultFooter}}}</div>
|
||||
<div class="description sla-chat-section sla-chat-section-danger {{severityMeta.cssClass}}">
|
||||
<div class="sla-chat-section-heading">
|
||||
<span class="sla-chat-severity-pill {{severityMeta.cssClass}}">{{severityMeta.label}}</span>
|
||||
</div>
|
||||
{{{tableResult.[0].description}}}{{{tableResultFooter}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (compare 'str' specialRoll '===' 'maintenanceCheck')}}
|
||||
{{#if critFail}}
|
||||
<br><br>@UUID[Compendium.mosh.macros_hotbar_1e.IgWvaabVqzKDzLL4]{Make a Panic Check}
|
||||
<div class="sla-chat-section sla-chat-section-danger">
|
||||
<div class="body">@UUID[Compendium.mosh.macros_hotbar_1e.IgWvaabVqzKDzLL4]{Make a Panic Check}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<div class="mosh sla-chat-shell sla-chat-shell-check sla-chat-shell-success" style="border-left: 4px solid #2ebd2e; padding-left: 8px;">
|
||||
<div class="rollcontainer">
|
||||
<div class="sla-chat-hero" style="background: rgba(46, 189, 46, 0.15); display: flex; align-items: center; padding: 6px; border-radius: 4px 4px 0 0;">
|
||||
<div class="sla-chat-hero-main" style="flex-grow: 1;">
|
||||
<div class="sla-chat-kicker-row">
|
||||
<div class="sla-chat-kicker" style="color: #85e085; font-size: 8pt; font-weight: bold; letter-spacing: 0.1em;">TACTICAL DECISION</div>
|
||||
</div>
|
||||
<div class="rollweaponh1 sla-chat-hero-title" style="font-size: 14pt; margin: 0; color: #ffffff;">{{{actorName}}}</div>
|
||||
</div>
|
||||
<div class="sla-chat-hero-media" style="width: 32px; height: 32px; border-radius: 4px; overflow: hidden; margin-left: 8px; flex-shrink: 0; border: 1px solid #2ebd2e;">
|
||||
<img class="roll-image" src="{{{img}}}" style="width: 100%; height: 100%; object-fit: cover;" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-chat-section sla-chat-section-success" style="padding: 10px; background: rgba(0,0,0,0.3); border-radius: 0 0 4px 4px; font-family: 'Cormorant Garamond', serif; font-size: 13pt; line-height: 1.3;">
|
||||
<i class="fas fa-check-circle" style="color: #2ebd2e; margin-right: 4px;"></i> <strong>Combat Critical Choice:</strong>
|
||||
<div style="margin-top: 6px; color: #e0fde0; font-style: italic;">"{{{optionText}}}"</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,154 @@
|
||||
<form class="{{cssClass}} sla-npc-generator sla-npc-accent-{{accentKey}}" autocomplete="off">
|
||||
<p>Create lightweight SLA NPCs with enough identity for play, then open the creature sheet to adjust portrait, items, weapons, skills, and notes.</p>
|
||||
|
||||
<div class="sla-card sla-npc-brief-card" style="padding: 12px; margin-bottom: 12px;">
|
||||
<div class="grid grid-2col" style="gap: 10px;">
|
||||
<div class="resource">
|
||||
<label class="resource-label">Name</label>
|
||||
<div class="flexrow" style="gap: 8px;">
|
||||
<input type="text" name="name" value="{{state.name}}" />
|
||||
<button type="button" class="sla-npc-random-name"><i class="fas fa-dice"></i> Name</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Archetype</label>
|
||||
<select name="archetype">
|
||||
{{#each archetypes}}
|
||||
<option value="{{this.name}}" {{#if (compare "str" ../state.archetype "===" this.name)}}selected{{/if}}>{{this.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Species</label>
|
||||
<select name="species">
|
||||
{{#each speciesOptions}}
|
||||
<option value="{{this}}" {{#if (compare "str" ../state.species "===" this)}}selected{{/if}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Quality</label>
|
||||
<select name="quality">
|
||||
{{#each qualityOptions}}
|
||||
<option value="{{this}}" {{#if (compare "str" ../state.quality "===" this)}}selected{{/if}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-card-copy" style="margin-top: 10px;">{{summary}}</div>
|
||||
</div>
|
||||
|
||||
<section class="sla-card sla-npc-preview-panel" style="margin-bottom: 12px;">
|
||||
<div class="sla-npc-preview-header">
|
||||
<div class="sla-npc-preview-heading">
|
||||
<div class="sla-npc-preview-badge" aria-hidden="true">
|
||||
<img class="sla-npc-preview-icon" src="{{preview.iconPath}}" alt="" />
|
||||
<span>{{preview.iconLabel}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="sla-kicker">{{preview.badge}}</div>
|
||||
<div class="sla-title">{{state.name}}</div>
|
||||
<div class="sla-card-copy">{{preview.strap}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-npc-preview-pill">{{state.quality}}</div>
|
||||
</div>
|
||||
<div class="sla-npc-preview-grid">
|
||||
<div class="sla-npc-preview-block">
|
||||
<div class="sla-card-label">Profile</div>
|
||||
<div class="sla-card-copy"><strong>{{preview.identity}}</strong></div>
|
||||
<div class="sla-card-copy">{{preview.brief}}</div>
|
||||
<div class="sla-card-copy">{{preview.posture}}</div>
|
||||
</div>
|
||||
<div class="sla-npc-preview-block">
|
||||
<div class="sla-card-label">Field Readout</div>
|
||||
<div class="sla-tags">
|
||||
{{#each preview.statline}}
|
||||
<span class="sla-tag">{{this}}</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="sla-npc-preview-block sla-npc-preview-wide">
|
||||
<div class="sla-card-label">Issue Kit</div>
|
||||
<div class="sla-note-list">
|
||||
{{#each preview.loadout}}
|
||||
<span class="sla-note-pill">{{this}}</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="grid grid-2col" style="gap: 10px;">
|
||||
<div class="resource">
|
||||
<label class="resource-label">Affiliation Type</label>
|
||||
<select name="affiliationType">
|
||||
{{#each affiliationTypes}}
|
||||
<option value="{{this}}" {{#if (compare "str" ../state.affiliationType "===" this)}}selected{{/if}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Affiliation</label>
|
||||
<input type="text" name="affiliation" value="{{state.affiliation}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Department / Cell / Turf</label>
|
||||
<input type="text" name="department" value="{{state.department}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Role / Title</label>
|
||||
<input type="text" name="role" value="{{state.role}}" />
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Sector / Location</label>
|
||||
<input type="text" name="sector" value="{{state.sector}}" />
|
||||
</div>
|
||||
<div class="grid grid-2col" style="gap: 10px;">
|
||||
<div class="resource">
|
||||
<label class="resource-label">Disposition</label>
|
||||
<select name="disposition">
|
||||
{{#each dispositionOptions}}
|
||||
<option value="{{this}}" {{#if (compare "str" ../state.disposition "===" this)}}selected{{/if}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Threat</label>
|
||||
<select name="threat">
|
||||
{{#each threatOptions}}
|
||||
<option value="{{this}}" {{#if (compare "str" ../state.threat "===" this)}}selected{{/if}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Loadout Preset</label>
|
||||
<select name="loadout">
|
||||
{{#each loadoutOptions}}
|
||||
<option value="{{this}}" {{#if (compare "str" ../state.loadout "===" this)}}selected{{/if}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Generator Notes</label>
|
||||
<textarea name="notes" rows="4">{{state.notes}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sla-action-row" style="margin-top: 12px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
|
||||
<label class="checkbox" style="display:inline-flex; gap:6px; align-items:center;">
|
||||
<input type="checkbox" name="assignPortrait" {{checked state.assignPortrait}} />
|
||||
Assign portrait if available
|
||||
</label>
|
||||
<label class="checkbox" style="display:inline-flex; gap:6px; align-items:center;">
|
||||
<input type="checkbox" name="openSheet" {{checked state.openSheet}} />
|
||||
Open sheet after creation
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="sla-action-row" style="margin-top: 12px; display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap;">
|
||||
<button type="button" class="sla-npc-randomize"><i class="fas fa-shuffle"></i> Randomize Brief</button>
|
||||
<button type="submit"><i class="fas fa-user-plus"></i> Create NPC</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -10,6 +10,10 @@
|
||||
<label class="resource-label">Character Actors</label>
|
||||
<div>{{actorCount}}</div>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Creature NPCs</label>
|
||||
<div>{{creatureCount}}</div>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<label class="resource-label">Skills / Weapons</label>
|
||||
<div>{{skillCount}} / {{weaponCount}}</div>
|
||||
@@ -28,6 +32,7 @@
|
||||
<button type="button" class="seed-world"><i class="fas fa-box-open"></i> Seed SLA Content</button>
|
||||
<button type="button" class="refresh-world"><i class="fas fa-sync"></i> Refresh Seeded Content</button>
|
||||
<button type="button" class="open-generator"><i class="fas fa-user-plus"></i> Open Generator</button>
|
||||
<button type="button" class="open-npc-desk"><i class="fas fa-id-badge"></i> Open NPC Desk</button>
|
||||
<button type="button" class="generate-random"><i class="fas fa-dice"></i> Create Random Operative</button>
|
||||
<button type="button" class="generate-random-standard"><i class="fas fa-user"></i> Create Standard Operative</button>
|
||||
<button type="button" class="generate-random-ebb"><i class="fas fa-brain"></i> Create Random Ebb User</button>
|
||||
|
||||