27 Commits
Author SHA1 Message Date
tevans acf2c8ef07 feat: implement streamlined single-page NPC actor sheet v0.6.12 2026-05-28 00:05:31 +01:00
tevans b931d0634b fix: migrate all compendium pack links and asset paths from mosh to sla-mothership 2026-05-27 23:54:49 +01:00
tevans 99d6702fe1 fix: make critical success option buttons wrap and expand elastically without overlapping 2026-05-27 23:51:38 +01:00
tevans 96896ba92f Fix critical button roll: pass explicit table formula to bypass modifier slider prompt and prevent roll out-of-bounds error 2026-05-27 19:17:39 +01:00
tevans 6557ef82ad Enhance combat: add Unarmed Combat item support, interactive Critical Hit chat buttons, clickable critical success options, and severity text contrast visual overhaul 2026-05-27 18:45:18 +01:00
tevans 17c64ec0de style: premium scene control and sidebar UI overhaul v0.6.5 2026-05-25 14:27:14 +01:00
tevans 64bef08fe0 chore: bump version to 0.6.4 2026-05-24 21:02:11 +01:00
tevans d81034f6f4 feat: add interactive combat roll modifier slider snappable UI and visual ticks 2026-05-24 21:01:06 +01:00
tevans f66ac84c0b Skill roll dialog: scrollable list replaces fixed pixel height
- Remove manual dialogHeight pixel counter (was error-prone)
- Wrap skill list in scrollable div (max-height 340px, overflow-y auto)
- Long skill lists no longer push action buttons off-screen
2026-05-19 22:20:00 +01:00
tevans 24f513baf8 NPC Desk: archetype accents, live preview card, badge icons, custom SVG emblems
- sla-npc-generator.js: archetype-specific accent styling for Shiver, DarkNight, Tek, Ebb, Media, Internal Affairs, gangs, civilians, predators, corp assets; live preview card (identity, strapline, disposition/threat posture, stat readout, loadout kit) updating on archetype/quality/species/disposition/threat/loadout/affiliation change; badge icon helper switched from Font Awesome classes to custom SVG path mapping
- sla-npc-generator.html: preview card markup with badge header; SVG badge renderer replacing icon-class approach
- mosh.css: archetype accent strip styles; preview card layout; image-based badge styling; badge set rules under npc-badges
- icons/ui/npc-badges/: 10 new custom SVGs — shiver, darknight, tek, ebb, internal, media, gang, predator, civilian, corp
2026-04-15 18:27:24 +01:00
tevans 9269348bf4 Fix NPC dossier layout: move block below header, proper responsive grid
- templates/actor/creature-sheet.html: moved dossier section out of the header into the sheet body so it no longer squashes the stat/HP area; switched inner grid to new sla-creature-dossier-grid class; Snapshot field now spans full width with sla-creature-dossier-wide
- css/mosh.css: added sla-creature-dossier-grid (3-col responsive grid collapsing to 2-col at 900px, 1-col at 640px); labels get display:block + bottom margin; inputs get width:100% and box-sizing; added sla-creature-dossier-wide span-3 helper; fixed dossier margin
2026-04-15 17:20:34 +01:00
tevans 2758be6096 Add NPC Desk: generator window, creature dossier, world tools integration
New files:
- module/windows/sla-npc-generator.js — NPC generator window; archetype, species, quality, affiliation, dept/cell, role, sector, disposition, threat, loadout preset; auto-creates creature actors into SLA Mothership/NPCs folder; auto-assigns portrait if portrait pack active; seeds basic skills, weapons, armor and gear
- templates/dialogs/sla-npc-generator.html — form template for the NPC Desk window

Updated files:
- template.json — extended creature actor data with NPC dossier fields (role, affiliation, department, sector, threat, summary)
- templates/actor/creature-sheet.html — editable NPC dossier block on creature sheet
- module/actor/creature-sheet.js — wired dossier fields into sheet data
- module/mosh.js — exposed generator via system API
- module/windows/sla-world-tools.js — sidebar button to open NPC Desk
- templates/dialogs/sla-world-tools.html — Open NPC Desk entry in world tools dialog
- css/mosh.css — styling for NPC Desk and dossier block
2026-04-15 17:12:46 +01:00
tevans b1cfb636df Add active conditions summary below stats + GM 30-min chat report
- templates/actor/actor-sheet.html: red conditions bar shown below Strength/Speed/Intellect/Combat stats whenever any condition items are active; displays condition name and severity
- module/mosh.js: GM-only 30-minute interval timer that whispers a formatted conditions report to all GMs listing every actor with active conditions and their severities
- css/mosh.css: styles for .sla-active-conditions-summary, .sla-conditions-label, .sla-active-condition (red text, dark red border/background)
2026-04-15 16:24:41 +01:00
tevans 0d77741a41 Header redesign: REST top-right above Race, bottom row all equal-width flex
- REST button moves to grid row 1, cols 7-8, right-aligned above Race field
- Wordmark narrows to cols 1-6 to give REST clear space
- LAD / Credits / SCL / Height / Weight wrapped in single flex row (equal width)
- Removed compact-field font overrides — all bottom fields now same size
- Removed inline styles from REST button
2026-04-15 14:11:59 +01:00
tevans 6508a7e883 Header layout: REST next to LAD, wider Credits, consistent compact field fonts
- REST button moves to col 2 (immediately right of LAD)
- LAD drops span-2, takes single col 1
- Credits field now spans 3 columns (much wider, value fully visible)
- SCL/HEIGHT/WEIGHT shift right to cols 6-7-8
- Compact field fonts match other header fields (0.95rem)
- SCL/HEIGHT/WEIGHT labels and inputs centered
2026-04-15 14:04:06 +01:00
tevans 8cbea7c237 Add full Vevaphon MORPH tab: instability track, form selector, panic reference, morph notes
- actor.js: Add isSlaVevaphon(), setSlaVevaphonMorphForm(), adjustSlaVevaphonInstability() methods
- actor.js: Fix getSlaRestrictedEbbItemIds() to skip morph-form abilities (abilityType !== 'ebb')
- actor.js: Fix enforceSlaEbbEligibility() with ID validation + try/catch for concurrent calls
- actor-sheet.js: Split morphForms into separate array, pre-compute slaIsActiveMorphForm flag
- actor-sheet.js: Add vevaphonInstabilityDesc and vevaphonMorphPanic to template data
- actor-sheet.html: Add MORPH tab with instability track, active form buttons, panic reference, notes
- actor-sheet.html: Remove ability-use-trigger class from morph form rows (Vevaphons are not Ebb users)
- mosh.css: Add morph tab CSS (track bar, instability colours, form buttons, active state, tags)
- mosh.css: Enlarge REST button pill (max-width 120px, padding/font overrides)
2026-04-15 13:50:12 +01:00
tevans d89671e707 Fix: remove Ebb trigger from morph form rows; widen REST button container to 120px 2026-04-15 13:43:35 +01:00
tevans d0d907bd98 Fix morph forms: use abilityType=morph (schema-defined) to survive Ebb enforcement; bigger REST button 2026-04-15 11:52:42 +01:00
tevans f3264d60e2 Add Vevaphon morph form display to Special Rules tab; fix morphForm flag on world items; enlarge REST button 2026-04-15 11:39:20 +01:00
tevans 63da87f372 Fix: exempt morphForm abilities from Ebb eligibility sweep — Vevaphons morph, they are not Ebb users 2026-04-15 11:19:04 +01:00
tevans 4a5561a82f Fix v14 Vevaphon: debounce createItem hook + try/catch guard on Ebb enforcement deletes 2026-04-15 11:14:45 +01:00
tevans 9fb7867069 Fix v14 compat: filter embedded item IDs before deleteEmbeddedDocuments in enforceSlaEbbEligibility 2026-04-15 11:10:00 +01:00
tevans b64125e637 chore: bump to v0.6.3 — Foundry v14 compatibility (min:13, max:14, verified:14) 2026-04-15 09:04:26 +01:00
tevans c728f7bb6d chore: bump version to 0.6.2 — player permissions, CSS overhaul, template updates 2026-04-14 23:29:08 +01:00
tevans 19b472de00 feat: player permissions enforcement, CSS overhaul, actor/chat template updates
- Enforce sidebar directory restrictions for non-GM players across actors,
  scenes, journal, tables, compendium, and combat
- Major CSS refactor in mosh.css (layout, sizing, colour passes)
- Actor sheet JS: extended item handling and sheet render logic
- Actor data model updates in actor.js
- Item sheet additions in item-sheet.js
- Updated chat templates: itemRoll, modifyActor, modifyItem, reload,
  rollCheck, rollTable for improved formatting and clarity
- Actor/creature sheet HTML restructured
- Compendium pack DB files rotated (LevelDB log/manifest housekeeping)

Co-authored-by: slaguru666 <timevans666@gmail.com>
2026-04-14 22:38:18 +01:00
tevans bf4e98a780 chore: bump version to 0.6.1 — UI overhaul, icons, pause animation fix 2026-04-10 23:36:06 +01:00
tevansandClaude Sonnet 4.6 3d21b8e466 feat: SLA Industries UI overhaul — icons, pause animation, actor sheet enhancements
- Custom SLA Industries pause-screen animation (orbital rings, SLA hex logo, radar sweep, STAND BY blink)
- Pause animation now correctly disappears on unpause (fixed display:flex !important conflict)
- 18 custom SLA Industries SVG icons for all sidebar tabs and scene controls (icons/ui/)
- JavaScript DOM injection for Foundry v13 icon replacement (button-based structure)
- SCL fractional controls (+1/-1/+½/-½ step buttons)
- Session ability tracking checkbox + New Session button
- Contacts tab with card-based CRUD
- Drug stacking warning dialog
- Rest button (Short/Long rest with condition clear + flux restore)
- Activity log in Notes tab (rolls, rests, drugs, panic — newest first, 10KB cap)
- Portrait static neon blue border
- Header restructured to 8-column grid (LAD, Credits, SCL, Height, Weight, Rest)
- S.C.L label rename

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 23:12:06 +01:00
114 changed files with 5888 additions and 1064 deletions
+1925 -167
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Badge shape -->
<path d="M6,2 H26 L30,6 V30 H2 V6 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<!-- Notch at top (lanyard hole) -->
<rect x="13" y="0" width="6" height="4" rx="1" fill="currentColor"/>
<!-- Head -->
<circle cx="16" cy="12" r="4" fill="currentColor"/>
<!-- Shoulders -->
<path d="M8,26 C8,20 24,20 24,26" fill="currentColor"/>
<!-- ID stripe at bottom -->
<rect x="5" y="26" width="22" height="2" fill="currentColor" opacity="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 575 B

+8
View File
@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Hexagonal speech bubble -->
<polygon points="4,4 28,4 28,22 20,22 16,28 12,22 4,22" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linejoin="round" fill-rule="evenodd"/>
<!-- Signal bars inside -->
<rect x="8" y="14" width="3" height="5" fill="currentColor"/>
<rect x="13" y="11" width="3" height="8" fill="currentColor"/>
<rect x="18" y="8" width="3" height="11" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 489 B

+16
View File
@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Outer ring -->
<circle cx="16" cy="16" r="13" fill="none" stroke="currentColor" stroke-width="2"/>
<!-- Inner ring -->
<circle cx="16" cy="16" r="5" fill="none" stroke="currentColor" stroke-width="1.5"/>
<!-- Crosshairs -->
<line x1="16" y1="3" x2="16" y2="9" stroke="currentColor" stroke-width="2"/>
<line x1="16" y1="23" x2="16" y2="29" stroke="currentColor" stroke-width="2"/>
<line x1="3" y1="16" x2="9" y2="16" stroke="currentColor" stroke-width="2"/>
<line x1="23" y1="16" x2="29" y2="16" stroke="currentColor" stroke-width="2"/>
<!-- Corner tick marks -->
<line x1="11" y1="5" x2="12.5" y2="5" stroke="currentColor" stroke-width="1.5"/>
<line x1="21" y1="5" x2="19.5" y2="5" stroke="currentColor" stroke-width="1.5"/>
<!-- Center dot -->
<circle cx="16" cy="16" r="2" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 897 B

+14
View File
@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Cylinder top ellipse -->
<ellipse cx="16" cy="6" rx="12" ry="4" fill="none" stroke="currentColor" stroke-width="2"/>
<!-- Cylinder body -->
<line x1="4" y1="6" x2="4" y2="24" stroke="currentColor" stroke-width="2"/>
<line x1="28" y1="6" x2="28" y2="24" stroke="currentColor" stroke-width="2"/>
<!-- Cylinder bottom ellipse -->
<ellipse cx="16" cy="24" rx="12" ry="4" fill="currentColor" stroke="currentColor" stroke-width="2"/>
<!-- Data bands -->
<ellipse cx="16" cy="12" rx="12" ry="4" fill="none" stroke="currentColor" stroke-width="1" stroke-dasharray="3 2"/>
<ellipse cx="16" cy="18" rx="12" ry="4" fill="none" stroke="currentColor" stroke-width="1" stroke-dasharray="3 2"/>
<!-- Access port -->
<rect x="13" y="4" width="6" height="4" rx="1" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 866 B

+10
View File
@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Stylus body -->
<polygon points="8,4 24,4 28,8 16,30 4,8" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<!-- Stylus grip band -->
<line x1="6" y1="10" x2="26" y2="10" stroke="currentColor" stroke-width="1.5"/>
<!-- Tip -->
<polygon points="16,25 13,29 19,29" fill="currentColor"/>
<!-- SLA insignia on stylus face -->
<text x="16" y="19" text-anchor="middle" font-family="sans-serif" font-size="7" font-weight="bold" fill="currentColor">SLA</text>
</svg>

After

Width:  |  Height:  |  Size: 567 B

+15
View File
@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Main crate -->
<rect x="3" y="8" width="26" height="20" fill="none" stroke="currentColor" stroke-width="2" rx="1"/>
<!-- Lid -->
<rect x="3" y="4" width="26" height="6" fill="currentColor" rx="1"/>
<!-- Center clasp -->
<rect x="13" y="6" width="6" height="4" rx="1" fill="currentColor" opacity="0.6"/>
<!-- Horizontal divider on crate -->
<line x1="3" y1="18" x2="29" y2="18" stroke="currentColor" stroke-width="1.5"/>
<!-- Corner brackets -->
<path d="M3,13 L3,10 L6,10" fill="none" stroke="currentColor" stroke-width="1.5"/>
<path d="M29,13 L29,10 L26,10" fill="none" stroke="currentColor" stroke-width="1.5"/>
<path d="M3,23 L3,26 L6,26" fill="none" stroke="currentColor" stroke-width="1.5"/>
<path d="M29,23 L29,26 L26,26" fill="none" stroke="currentColor" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 881 B

+13
View File
@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- File/tablet body -->
<path d="M5,2 H22 L28,8 V30 H5 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<!-- Folded corner -->
<path d="M22,2 L22,8 L28,8" fill="none" stroke="currentColor" stroke-width="1.5"/>
<!-- Text lines -->
<line x1="9" y1="13" x2="24" y2="13" stroke="currentColor" stroke-width="1.5"/>
<line x1="9" y1="17" x2="24" y2="17" stroke="currentColor" stroke-width="1.5"/>
<line x1="9" y1="21" x2="20" y2="21" stroke="currentColor" stroke-width="1.5"/>
<!-- Classified stamp -->
<rect x="7" y="24" width="10" height="4" rx="0.5" fill="none" stroke="currentColor" stroke-width="1.2" transform="rotate(-8 12 26)"/>
<line x1="8" y1="26" x2="16" y2="26" stroke="currentColor" stroke-width="1" transform="rotate(-8 12 26)"/>
</svg>

After

Width:  |  Height:  |  Size: 859 B

+14
View File
@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Emitter housing -->
<polygon points="12,6 20,6 22,12 10,12" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Lens circle -->
<circle cx="16" cy="9" r="3" fill="none" stroke="currentColor" stroke-width="1.5" opacity="0.7"/>
<!-- Beam spread (lower trapezoid) -->
<polygon points="10,12 22,12 28,28 4,28" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Beam rays -->
<line x1="16" y1="12" x2="16" y2="28" stroke="currentColor" stroke-width="1" opacity="0.5"/>
<line x1="13" y1="12" x2="8" y2="28" stroke="currentColor" stroke-width="1"/>
<line x1="19" y1="12" x2="24" y2="28" stroke="currentColor" stroke-width="1"/>
<!-- Mounting bracket -->
<rect x="14" y="2" width="4" height="5" rx="1" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 894 B

+17
View File
@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Ruler body -->
<rect x="2" y="12" width="28" height="8" rx="1" fill="none" stroke="currentColor" stroke-width="2"/>
<!-- Major tick marks -->
<line x1="9" y1="12" x2="9" y2="17" stroke="currentColor" stroke-width="1.5"/>
<line x1="16" y1="12" x2="16" y2="20" stroke="currentColor" stroke-width="2"/>
<line x1="23" y1="12" x2="23" y2="17" stroke="currentColor" stroke-width="1.5"/>
<!-- Minor ticks -->
<line x1="5" y1="12" x2="5" y2="15" stroke="currentColor" stroke-width="1"/>
<line x1="12" y1="12" x2="12" y2="15" stroke="currentColor" stroke-width="1"/>
<line x1="19" y1="12" x2="19" y2="15" stroke="currentColor" stroke-width="1"/>
<line x1="26" y1="12" x2="26" y2="15" stroke="currentColor" stroke-width="1"/>
<!-- Arrow / range indicator above -->
<line x1="4" y1="8" x2="28" y2="8" stroke="currentColor" stroke-width="1.5"/>
<polygon points="4,8 8,6 8,10" fill="currentColor"/>
<polygon points="28,8 24,6 24,10" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+11
View File
@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Map pin shape -->
<path d="M16,2 C10,2 6,7 6,12 C6,19 16,30 16,30 C16,30 26,19 26,12 C26,7 22,2 16,2 Z" fill="currentColor" stroke="currentColor" stroke-width="2"/>
<!-- Inner ring -->
<circle cx="16" cy="12" r="5" fill="none" stroke="currentColor" stroke-width="2"/>
<!-- Center dot -->
<circle cx="16" cy="12" r="2.5" fill="currentColor"/>
<!-- Angular bracket decorations -->
<path d="M10,5 L8,7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
<path d="M22,5 L24,7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 644 B

+5
View File
@@ -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

+5
View File
@@ -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

+4
View File
@@ -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

+5
View File
@@ -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

+6
View File
@@ -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

+4
View File
@@ -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

+4
View File
@@ -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

+4
View File
@@ -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

+4
View File
@@ -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

+5
View File
@@ -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

+11
View File
@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Waveform bars -->
<rect x="2" y="12" width="3" height="8" rx="1" fill="currentColor"/>
<rect x="7" y="7" width="3" height="18" rx="1" fill="currentColor"/>
<rect x="12" y="4" width="3" height="24" rx="1" fill="currentColor"/>
<rect x="17" y="9" width="3" height="14" rx="1" fill="currentColor"/>
<rect x="22" y="6" width="3" height="20" rx="1" fill="currentColor"/>
<rect x="27" y="13" width="3" height="6" rx="1" fill="currentColor"/>
<!-- Base line -->
<line x1="2" y1="29" x2="30" y2="29" stroke="currentColor" stroke-width="1"/>
</svg>

After

Width:  |  Height:  |  Size: 631 B

+16
View File
@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Outer border -->
<rect x="2" y="2" width="28" height="28" fill="none" stroke="currentColor" stroke-width="2" rx="1"/>
<!-- Grid lines -->
<line x1="11" y1="2" x2="11" y2="30" stroke="currentColor" stroke-width="1"/>
<line x1="21" y1="2" x2="21" y2="30" stroke="currentColor" stroke-width="1"/>
<line x1="2" y1="11" x2="30" y2="11" stroke="currentColor" stroke-width="1"/>
<line x1="2" y1="21" x2="30" y2="21" stroke="currentColor" stroke-width="1"/>
<!-- Sector fills — industrial blocks -->
<rect x="3" y="3" width="7" height="7" fill="currentColor"/>
<rect x="13" y="13" width="7" height="7" fill="currentColor" opacity="0.6"/>
<rect x="22" y="22" width="7" height="7" fill="currentColor"/>
<rect x="22" y="3" width="7" height="7" fill="currentColor"/>
<!-- Location marker -->
<polygon points="16,17 14,21 18,21" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 940 B

+16
View File
@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Hex gear outer -->
<polygon points="16,2 27,8 27,20 16,26 5,20 5,8" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linejoin="round"/>
<!-- Gear teeth on hex edges -->
<polygon points="16,1 18,4 14,4" fill="currentColor"/>
<polygon points="27.5,7.5 27,11 24.5,9.5" fill="currentColor"/>
<polygon points="27.5,20.5 24.5,22.5 27,19" fill="currentColor"/>
<polygon points="16,27 14,24 18,24" fill="currentColor"/>
<polygon points="4.5,20.5 5,19 7.5,22.5" fill="currentColor"/>
<polygon points="4.5,7.5 7.5,9.5 5,11" fill="currentColor"/>
<!-- Inner hex cutout -->
<polygon points="16,9 21,12 21,18 16,21 11,18 11,12" fill="currentColor"/>
<!-- Center circle -->
<circle cx="16" cy="15" r="3.5" fill="none" stroke="currentColor" stroke-width="2"/>
<circle cx="16" cy="15" r="1.5" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 910 B

+9
View File
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Speaker cone -->
<polygon points="4,11 12,11 20,5 20,27 12,21 4,21" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Sound wave arcs -->
<path d="M23,10 C26,12 26,20 23,22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M25,7 C30,11 30,21 25,25" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>
<!-- Base line -->
<rect x="4" y="21" width="8" height="5" rx="0.5" fill="currentColor" opacity="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 609 B

+15
View File
@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Outer frame -->
<rect x="2" y="3" width="28" height="26" fill="none" stroke="currentColor" stroke-width="2" rx="1"/>
<!-- Header row -->
<rect x="2" y="3" width="28" height="6" fill="currentColor" rx="1"/>
<!-- Row dividers -->
<line x1="2" y1="15" x2="30" y2="15" stroke="currentColor" stroke-width="1"/>
<line x1="2" y1="21" x2="30" y2="21" stroke="currentColor" stroke-width="1"/>
<!-- Column dividers -->
<line x1="10" y1="9" x2="10" y2="29" stroke="currentColor" stroke-width="1"/>
<line x1="21" y1="9" x2="21" y2="29" stroke="currentColor" stroke-width="1"/>
<!-- Die symbol in first col -->
<rect x="4" y="11" width="4" height="4" rx="0.5" fill="none" stroke="currentColor" stroke-width="1"/>
<circle cx="6" cy="13" r="0.8" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 851 B

+14
View File
@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- 2x2 tile grid with isometric feel -->
<!-- Top-left tile -->
<rect x="2" y="2" width="13" height="13" rx="1" fill="currentColor" stroke="currentColor" stroke-width="1.5"/>
<!-- Top-right tile -->
<rect x="17" y="2" width="13" height="13" rx="1" fill="currentColor" opacity="0.5" stroke="currentColor" stroke-width="1.5"/>
<!-- Bottom-left tile -->
<rect x="2" y="17" width="13" height="13" rx="1" fill="currentColor" opacity="0.5" stroke="currentColor" stroke-width="1.5"/>
<!-- Bottom-right tile -->
<rect x="17" y="17" width="13" height="13" rx="1" fill="currentColor" stroke="currentColor" stroke-width="1.5"/>
<!-- Corner brackets on tiles -->
<path d="M4,7 L4,4 L7,4" fill="none" stroke="currentColor" stroke-width="1.2"/>
<path d="M19,7 L19,4 L22,4" fill="none" stroke="currentColor" stroke-width="1.2"/>
</svg>

After

Width:  |  Height:  |  Size: 907 B

+10
View File
@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Hex base -->
<polygon points="16,3 28,10 28,22 16,29 4,22 4,10" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<!-- Inner ring -->
<polygon points="16,8 23,12 23,20 16,24 9,20 9,12" fill="none" stroke="currentColor" stroke-width="1"/>
<!-- Head silhouette -->
<circle cx="16" cy="14" r="3.5" fill="currentColor"/>
<!-- Shoulders -->
<path d="M10,23 C10,19 22,19 22,23" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 509 B

+14
View File
@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- Main wall line heavy -->
<line x1="4" y1="16" x2="28" y2="16" stroke="currentColor" stroke-width="4"/>
<!-- Wall battlements (top) -->
<rect x="5" y="10" width="4" height="6" fill="currentColor"/>
<rect x="13" y="10" width="4" height="6" fill="currentColor"/>
<rect x="21" y="10" width="4" height="6" fill="currentColor"/>
<!-- Wall base foundation -->
<rect x="3" y="20" width="26" height="4" rx="1" fill="currentColor" opacity="0.5"/>
<!-- Door gap indicator -->
<rect x="14" y="16" width="4" height="4" fill="currentColor" opacity="0"/>
<line x1="14" y1="16" x2="14" y2="24" stroke="currentColor" stroke-width="1" stroke-dasharray="2 2" opacity="0.7"/>
<line x1="18" y1="16" x2="18" y2="24" stroke="currentColor" stroke-width="1" stroke-dasharray="2 2" opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 869 B

+36 -36
View File
@@ -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 [+]}"
}
}
},
+36 -36
View File
@@ -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 [+]}"
}
}
},
+351 -15
View File
@@ -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 }
@@ -258,6 +282,9 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
superData.sla.fluxNotes ??= { value: "" };
superData.sla.ebbNotes ??= { value: "" };
superData.sla.speciesRules ??= {};
superData.sla.sessionAbilityUsed ??= false;
superData.sla.contacts ??= [];
superData.sla.activityLog ??= { value: "" };
const activeTheme = this.actor.getFlag("sla-mothership", "sheetTheme") || "modern";
data.slaSheetTheme = activeTheme;
data.data.slaSheetTheme = activeTheme;
@@ -279,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);
@@ -292,6 +332,17 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
disadvantage: String(this._slaTraitPickerSelection?.disadvantage ?? "").trim()
};
data.data.slaPrometheusStatus = this.actor.getSlaPrometheusStatus?.() ?? { enabled: false, inCombat: false, currentRound: 0, roundsUntilPulse: null, pulseThisRound: false };
// Contacts
const rawContacts = Array.isArray(superData.sla.contacts) ? superData.sla.contacts : [];
data.data.slaContacts = rawContacts.map((c) => ({
id: String(c.id ?? foundry.utils.randomID()),
name: String(c.name ?? "Unknown"),
role: String(c.role ?? ""),
notes: String(c.notes ?? ""),
disposition: ["ally", "neutral", "hostile", "unknown"].includes(c.disposition) ? c.disposition : "neutral"
}));
data.data.slaContactCount = data.data.slaContacts.length;
const traitRows = buildSlaTraitRows(data.data.persTraits ?? []);
data.data.persTraitsEnhanced = traitRows;
data.data.traitCount = traitRows.length;
@@ -406,6 +457,7 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
const armors = [];
const conditions = [];
const abilities = [];
const morphForms = [];
const persTraits = [];
let curWeight = 0;
@@ -512,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);
}
@@ -549,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 ?? "")));
}
@@ -663,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
@@ -760,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 => {
@@ -792,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
@@ -933,8 +999,123 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
this.render(false);
});
html.find('.sla-panic-button').click(ev => {
this.actor.rollTable("panicCheck", null, null, null, null, null, null);
// SCL fractional adjustment buttons
html.find('.sla-scl-adjust').click(async (ev) => {
ev.preventDefault();
const delta = parseFloat(ev.currentTarget.dataset.delta ?? 0);
if (!delta) return;
const current = parseFloat(String(this.actor.system?.sla?.scl?.value ?? "0").replace(",", ".")) || 0;
const next = Math.max(0, Math.round((current + delta) * 10) / 10);
const formatted = Number.isInteger(next) ? String(next) : next.toFixed(1);
await this.actor.update({ "system.sla.scl.value": formatted });
this.render(false);
});
// Session ability tracking — checkbox
html.find('.sla-session-ability-used').on('change', async (ev) => {
ev.stopPropagation();
await this.actor.update({ "system.sla.sessionAbilityUsed": ev.currentTarget.checked });
});
// New Session reset button
html.find('.sla-new-session').click(async (ev) => {
ev.preventDefault();
const confirmed = await Dialog.confirm({
title: "New Session",
content: "<p>Start a new session? This will reset the trauma response session ability for this operative.</p>",
defaultYes: true
});
if (!confirmed) return;
await this.actor.update({ "system.sla.sessionAbilityUsed": false });
ui.notifications.info(`${this.actor.name}: session ability reset for new session.`);
this.render(false);
});
// Rest button — short or long rest dialog
html.find('.sla-rest-button').click(async (ev) => {
ev.preventDefault();
const restType = await new Promise((resolve) => {
new Dialog({
title: "Take a Rest",
content: `
<p>What kind of rest is <strong>${this.actor.name}</strong> taking?</p>
<p><strong>Short Rest:</strong> Removes non-permanent conditions. No stat recovery.</p>
<p><strong>Long Rest:</strong> Removes non-permanent conditions and fully restores Flux (if Ebb user).</p>
`,
buttons: {
short: { icon: '<i class="fas fa-moon"></i>', label: "Short Rest", callback: () => resolve("short") },
long: { icon: '<i class="fas fa-bed"></i>', label: "Long Rest", callback: () => resolve("long") },
cancel: { icon: '<i class="fas fa-times"></i>', label: "Cancel", callback: () => resolve(null) }
},
default: "short"
}).render(true);
});
if (!restType) return;
const updates = {};
// Remove temporary conditions (items of type "condition")
const conditionIds = this.actor.items
.filter((item) => item.type === "condition")
.map((item) => item.id);
if (conditionIds.length > 0) {
await this.actor.deleteEmbeddedDocuments("Item", conditionIds);
}
if (restType === "long") {
// Restore Flux to max for Ebb users
const isEbb = this.actor.isSlaEbbUser?.() ?? false;
if (isEbb) {
const fluxMax = Math.max(0, Number(this.actor.system?.sla?.flux?.max ?? 0));
updates["system.sla.flux.value"] = fluxMax;
await this.actor.updateSlaFluxState?.(fluxMax, { save: true });
}
}
if (Object.keys(updates).length > 0) {
await this.actor.update(updates);
}
const condMsg = conditionIds.length > 0 ? ` Cleared ${conditionIds.length} condition(s).` : "";
const fluxMsg = restType === "long" && (this.actor.isSlaEbbUser?.() ?? false) ? " Flux restored." : "";
ui.notifications.info(`${this.actor.name}: ${restType === "long" ? "Long" : "Short"} rest complete.${condMsg}${fluxMsg}`);
await this.actor.addSlaActivityLog?.(`${restType === "long" ? "Long" : "Short"} rest.${condMsg}${fluxMsg}`);
this.render(false);
});
// Contact add button
html.find('.sla-contact-add').click(async (ev) => {
ev.preventDefault();
await this._slaContactDialog(null);
});
// Contact edit button
html.find('.sla-contact-edit').click(async (ev) => {
ev.preventDefault();
const contactId = String(ev.currentTarget.dataset.contactId ?? "").trim();
if (!contactId) return;
await this._slaContactDialog(contactId);
});
// Contact delete button
html.find('.sla-contact-delete').click(async (ev) => {
ev.preventDefault();
const contactId = String(ev.currentTarget.dataset.contactId ?? "").trim();
if (!contactId) return;
const confirmed = await Dialog.confirm({
title: "Delete Contact",
content: "<p>Remove this contact from the operative's network?</p>",
defaultYes: false
});
if (!confirmed) return;
const contacts = Array.isArray(this.actor.system?.sla?.contacts) ? [...this.actor.system.sla.contacts] : [];
const updated = contacts.filter((c) => c.id !== contactId);
await this.actor.update({ "system.sla.contacts": updated });
this.render(false);
});
html.find('.sla-panic-button').click(async ev => {
await this.actor.rollTable("panicCheck", null, null, null, null, null, null);
await this.actor.addSlaActivityLog?.("Panic check triggered.");
});
html.find('.sla-wound-button').click(ev => {
@@ -1068,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
@@ -1210,6 +1476,76 @@ export class MothershipActorSheet extends foundry.appv1.sheets.ActorSheet {
});
}
/**
* Show a dialog for adding or editing a contact
* @param {string|null} contactId null = add new, string = edit existing
*/
async _slaContactDialog(contactId) {
const contacts = Array.isArray(this.actor.system?.sla?.contacts) ? [...this.actor.system.sla.contacts] : [];
const existing = contactId ? contacts.find((c) => c.id === contactId) : null;
const isNew = !existing;
const name = existing?.name ?? "";
const role = existing?.role ?? "";
const notes = existing?.notes ?? "";
const disposition = existing?.disposition ?? "neutral";
const content = `
<div style="display:grid; gap:8px; padding:8px 0;">
<div>
<label style="font-size:0.8rem; font-weight:600; display:block; margin-bottom:4px;">Name</label>
<input type="text" id="sla-contact-name" value="${name}" placeholder="Contact name" style="width:100%;" />
</div>
<div>
<label style="font-size:0.8rem; font-weight:600; display:block; margin-bottom:4px;">Role / Occupation</label>
<input type="text" id="sla-contact-role" value="${role}" placeholder="e.g. Fixer, Fence, Squad medic" style="width:100%;" />
</div>
<div>
<label style="font-size:0.8rem; font-weight:600; display:block; margin-bottom:4px;">Disposition</label>
<select id="sla-contact-disposition" style="width:100%;">
<option value="ally" ${disposition === "ally" ? "selected" : ""}>Ally</option>
<option value="neutral" ${disposition === "neutral" ? "selected" : ""}>Neutral</option>
<option value="hostile" ${disposition === "hostile" ? "selected" : ""}>Hostile</option>
<option value="unknown" ${disposition === "unknown" ? "selected" : ""}>Unknown</option>
</select>
</div>
<div>
<label style="font-size:0.8rem; font-weight:600; display:block; margin-bottom:4px;">Notes</label>
<textarea id="sla-contact-notes" rows="3" placeholder="Sector, history, how they know the operative..." style="width:100%;">${notes}</textarea>
</div>
</div>
`;
const result = await Dialog.prompt({
title: isNew ? "Add Contact" : "Edit Contact",
content,
label: isNew ? "Add" : "Save",
callback: (html) => {
const nameVal = String(html.find("#sla-contact-name").val() ?? "").trim();
if (!nameVal) return null;
return {
id: existing?.id ?? foundry.utils.randomID(),
name: nameVal,
role: String(html.find("#sla-contact-role").val() ?? "").trim(),
disposition: String(html.find("#sla-contact-disposition").val() ?? "neutral"),
notes: String(html.find("#sla-contact-notes").val() ?? "").trim()
};
},
rejectClose: false
});
if (!result) return;
let updated;
if (isNew) {
updated = [...contacts, result];
} else {
updated = contacts.map((c) => c.id === contactId ? result : c);
}
await this.actor.update({ "system.sla.contacts": updated });
this.render(false);
}
/**
* Extend and override the sheet header buttons
* @override
+406 -127
View File
@@ -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;
@@ -607,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;
@@ -678,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
@@ -842,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
@@ -918,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 {
@@ -1311,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') {
@@ -1343,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,
@@ -1357,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';
@@ -1376,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}`);
@@ -1609,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
@@ -1638,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
@@ -1653,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
@@ -1672,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`
},
@@ -1684,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`
},
@@ -1696,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`
}
@@ -1711,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`
}
@@ -1733,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`
},
@@ -1754,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`
},
@@ -1764,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`
}
@@ -1874,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}`;
}
}
@@ -2358,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) {
@@ -2365,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) {
@@ -2424,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;
}
@@ -2443,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.';
}
@@ -2480,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,
@@ -2495,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
@@ -2512,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);
@@ -2674,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}`;
}
@@ -2966,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';
@@ -2985,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
@@ -3863,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) => `
@@ -3876,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: [
@@ -3901,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
});
}
},
@@ -3921,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) {
@@ -4767,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();
@@ -4912,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;
@@ -4942,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);
@@ -5484,7 +5762,8 @@ export class MothershipActor extends Actor {
insert: rollInsert,
onlyDesc: true,
swapNameDesc,
swapName
swapName,
severityMeta: this.getSlaSeverityMeta({ severity: item?.system?.severity })
};
const chatData = {
+3
View File
@@ -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");
+57
View File
@@ -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);
});
}
}
+44
View File
@@ -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.`);
}
}
+597 -5
View File
@@ -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
@@ -1249,3 +1478,366 @@ export function formatCreditsNumber(num) {
return num.toString() + 'cr';
}
}
// ─────────────────────────────────────────────────────────────────────────────
// SLA Industries Pause Screen Animation
// ─────────────────────────────────────────────────────────────────────────────
let slaPauseRefreshHandle = null;
function injectSlaPauseAnimation() {
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">
<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>
<filter id="sla-glow-red" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3.5" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="sla-glow-ring" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="1.5" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<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>
<clipPath id="sla-clip-outer">
<circle cx="0" cy="0" r="108"/>
</clipPath>
</defs>
<circle cx="0" cy="0" r="108" fill="url(#sla-bg-grad)" class="sla-pause-core-glow"/>
<g class="sla-ring-outer">
<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"
stroke-width="0.8"
stroke-dasharray="6 4"
opacity="0.7"
filter="url(#sla-glow-ring)"
/>
<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"/>
<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)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(90)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(120)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(150)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(180)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(210)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(240)"/>
<line x1="0" y1="-86" x2="0" y2="-94" stroke="#8b1a1a" stroke-width="1" transform="rotate(270)"/>
<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>
<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"
stroke-width="0.6"
stroke-dasharray="4 6"
opacity="0.6"
filter="url(#sla-glow-ring)"
/>
<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>
<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"
stroke="#cc2222"
stroke-width="1.2"
opacity="0.9"
/>
<text
x="0" y="14"
text-anchor="middle"
font-family="'Oswald', 'Impact', 'Arial Narrow', sans-serif"
font-size="38"
font-weight="700"
letter-spacing="3"
fill="#ff2222"
class="sla-pause-logo-text"
>SLA</text>
</g>
<line x1="-70" y1="48" x2="70" y2="48" stroke="#8b1a1a" stroke-width="0.5" opacity="0.7"/>
<text
x="0" y="68"
text-anchor="middle"
font-family="'Oswald', 'Courier New', monospace"
font-size="11.5"
font-weight="500"
letter-spacing="3.2"
fill="#ff7b7b"
class="sla-pause-standby"
>PLEASE STAND BY</text>
<text
x="0" y="94"
text-anchor="middle"
font-family="'Oswald', 'Arial Narrow', sans-serif"
font-size="8"
font-weight="300"
letter-spacing="3"
fill="#b13b3b"
opacity="0.92"
>SLA INDUSTRIES</text>
<line
x1="0" y1="-90" x2="0" y2="0"
stroke="#ff2222"
stroke-width="0.8"
opacity="0.18"
class="sla-pause-scan"
/>
</svg>
</div>
</div>`;
document.body?.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', () => {
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
// by walking the live DOM and applying inline CSS mask-image styles.
// ─────────────────────────────────────────────────────────────────────────────
const SLA_ICON_BASE = "systems/sla-mothership/icons/ui/";
const SLA_SIDEBAR_ICONS = {
chat: "chat",
combat: "combat",
scenes: "scenes",
actors: "actors",
items: "items",
journal: "journal",
tables: "tables",
playlists: "playlists",
compendium: "compendium",
settings: "settings",
};
const SLA_CONTROL_ICONS = {
token: "token",
measure: "measure",
tiles: "tiles",
drawings: "drawings",
walls: "walls",
lighting: "lighting",
sounds: "sounds",
notes: "notes",
};
function _slaApplyIconMask(el, iconFile) {
const url = `${SLA_ICON_BASE}${iconFile}.svg`;
// Measure font size BEFORE zeroing it — FA icons scale with font-size
const fs = parseFloat(getComputedStyle(el).fontSize) || 18;
const sz = Math.round(fs * 1.15) + "px";
// font-size:0 → collapses the ::before FA glyph to nothing
// currentColor → inherits the button's text colour (white/grey/active from Foundry)
// mask → cuts that fill into our SVG shape
el.style.setProperty("font-size", "0", "important");
el.style.setProperty("line-height", "0", "important");
el.style.setProperty("width", sz, "important");
el.style.setProperty("height", sz, "important");
el.style.setProperty("display", "inline-flex", "important");
el.style.setProperty("align-items", "center", "important");
el.style.setProperty("justify-content", "center", "important");
el.style.setProperty("background-color", "currentColor", "important");
el.style.setProperty("-webkit-mask", `url('${url}') center/contain no-repeat`, "important");
el.style.setProperty("mask", `url('${url}') center/contain no-repeat`, "important");
el.setAttribute("data-sla-icon", iconFile);
}
function injectSlaIcons() {
let found = 0;
// ── Sidebar tab icons ─────────────────────────────────────────────────
// Foundry v13 confirmed structure:
// <button class="ui-control plain icon fa-solid fa-comments" data-tab="chat" ...>
// The BUTTON itself is the icon — no child <i> element.
document.querySelectorAll(
"#sidebar-tabs button[data-tab], #sidebar-tabs [data-tab].icon"
).forEach(btn => {
const name = btn.dataset.tab;
const file = SLA_SIDEBAR_ICONS[name];
if (!file || btn.hasAttribute("data-sla-icon")) return;
_slaApplyIconMask(btn, file);
found++;
});
// ── Scene / layer control icons ───────────────────────────────────────
// Foundry v13 scene controls are also buttons — search the whole doc
// since we don't yet know the container ID.
document.querySelectorAll(
"button[data-control], [data-control].icon, [data-control].ui-control"
).forEach(btn => {
const name = btn.dataset.control;
const file = SLA_CONTROL_ICONS[name];
if (!file || btn.hasAttribute("data-sla-icon")) return;
_slaApplyIconMask(btn, file);
found++;
});
if (found > 0) {
console.log(`SLA Industries | Applied ${found} custom icons.`);
} else {
console.warn("SLA Industries | injectSlaIcons: no icons matched — dumping HTML:");
console.warn("sidebar:", document.querySelector("#sidebar-tabs")?.outerHTML?.slice(0, 1200));
const ctrlDump = document.querySelector("#ui-left, #scene-controls, #controls");
console.warn("controls:", ctrlDump?.outerHTML?.slice(0, 1200) ?? "(not found — try: " + [...document.querySelectorAll("[data-control]")].map(e=>e.tagName+'.'+e.className).join(', ') + ")");
}
}
// Run once on ready, then re-run whenever Foundry re-renders these components
Hooks.once("ready", () => {
requestAnimationFrame(() => requestAnimationFrame(() => injectSlaIcons()));
});
Hooks.on("renderSidebar", () => requestAnimationFrame(() => injectSlaIcons()));
Hooks.on("renderSidebarTab", () => requestAnimationFrame(() => injectSlaIcons()));
Hooks.on("changeSidebarTab", () => requestAnimationFrame(() => injectSlaIcons()));
Hooks.on("renderSceneControls", () => requestAnimationFrame(() => injectSlaIcons()));
+17
View File
@@ -487,6 +487,23 @@ export class SLADrugSystem {
await this.resolveExpiredEffects(actor);
// Drug stacking warning — check if any OTHER drug is already active
const allActiveDrugEffects = this.getActorDrugEffects(actor);
const otherActiveDrugs = allActiveDrugEffects.filter((effect) => {
const flag = this.getDrugEffectFlag(effect);
return flag?.stage === "active" && flag?.drugId && flag.drugId !== def.id;
});
if (otherActiveDrugs.length > 0) {
const activeNames = [...new Set(otherActiveDrugs.map((e) => this.getDrugEffectFlag(e)?.drugName ?? e.name))].join(", ");
const proceed = await Dialog.confirm({
title: "Drug Stacking Warning",
content: `<p><strong>${actor.name}</strong> already has active drug effects from: <strong>${activeNames}</strong>.</p>
<p>Combining drugs can cause unpredictable or lethal interactions. Do you want to proceed?</p>`,
defaultYes: false
});
if (!proceed) return { ok: false, reason: "stacking-cancelled" };
}
const quantity = Math.max(0, Number(item.system?.quantity ?? 0));
if (consume && quantity < 1) {
ui.notifications.warn(`${actor.name} has no ${def.name} doses remaining.`);
@@ -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 ?? {},
+853
View File
@@ -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("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#39;");
}
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";
}
}
+15 -1
View File
@@ -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) {
+36 -36
View File
@@ -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"}}
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.583476 17054f000 Recovering log #38
2026/03/31-15:50:48.583855 17054f000 Delete type=0 #38
2026/03/31-15:50:48.583882 17054f000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.556257 16ffc3000 Recovering log #34
2026/03/29-21:14:27.556633 16ffc3000 Delete type=3 #32
2026/03/29-21:14:27.556668 16ffc3000 Delete type=0 #34
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
+50 -50
View File
@@ -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"}}
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.585617 170d5b000 Recovering log #38
2026/03/31-15:50:48.585981 170d5b000 Delete type=0 #38
2026/03/31-15:50:48.586009 170d5b000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.559077 1717e7000 Recovering log #34
2026/03/29-21:14:27.559760 1717e7000 Delete type=3 #32
2026/03/29-21:14:27.559790 1717e7000 Delete type=0 #34
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
+100 -100
View File
@@ -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"}}
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.587337 171d73000 Recovering log #38
2026/03/31-15:50:48.587684 171d73000 Delete type=0 #38
2026/03/31-15:50:48.587707 171d73000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.561319 170fdb000 Recovering log #34
2026/03/29-21:14:27.561677 170fdb000 Delete type=3 #32
2026/03/29-21:14:27.561715 170fdb000 Delete type=0 #34
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
File diff suppressed because one or more lines are too long
View File
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.589215 17054f000 Recovering log #38
2026/03/31-15:50:48.589634 17054f000 Delete type=0 #38
2026/03/31-15:50:48.589656 17054f000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.563010 1707cf000 Recovering log #34
2026/03/29-21:14:27.563276 1707cf000 Delete type=3 #32
2026/03/29-21:14:27.563303 1707cf000 Delete type=0 #34
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
File diff suppressed because one or more lines are too long
View File
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.590832 171567000 Recovering log #38
2026/03/31-15:50:48.591262 171567000 Delete type=0 #38
2026/03/31-15:50:48.591291 171567000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.564411 1717e7000 Recovering log #34
2026/03/29-21:14:27.564754 1717e7000 Delete type=3 #32
2026/03/29-21:14:27.564784 1717e7000 Delete type=0 #34
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
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.592976 170d5b000 Recovering log #38
2026/03/31-15:50:48.593456 170d5b000 Delete type=0 #38
2026/03/31-15:50:48.593476 170d5b000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.565839 1707cf000 Recovering log #34
2026/03/29-21:14:27.566214 1707cf000 Delete type=3 #32
2026/03/29-21:14:27.566242 1707cf000 Delete type=0 #34
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
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000089
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.594786 171567000 Recovering log #38
2026/03/31-15:50:48.595201 171567000 Delete type=0 #38
2026/03/31-15:50:48.595227 171567000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.567335 170fdb000 Recovering log #34
2026/03/29-21:14:27.567720 170fdb000 Delete type=3 #32
2026/03/29-21:14:27.567753 170fdb000 Delete type=0 #34
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
File diff suppressed because one or more lines are too long
View File
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000087
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.597410 170d5b000 Recovering log #38
2026/03/31-15:50:48.598033 170d5b000 Delete type=0 #38
2026/03/31-15:50:48.598068 170d5b000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.568770 1707cf000 Recovering log #34
2026/03/29-21:14:27.569097 1707cf000 Delete type=3 #32
2026/03/29-21:14:27.569138 1707cf000 Delete type=0 #34
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
+14 -14
View File
File diff suppressed because one or more lines are too long
View File
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000039
MANIFEST-000089
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/31-15:50:48.600045 17054f000 Recovering log #38
2026/03/31-15:50:48.600385 17054f000 Delete type=0 #38
2026/03/31-15:50:48.600414 17054f000 Delete type=3 #37
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
+3 -3
View File
@@ -1,3 +1,3 @@
2026/03/29-21:14:27.570654 170fdb000 Recovering log #34
2026/03/29-21:14:27.571032 170fdb000 Delete type=3 #32
2026/03/29-21:14:27.571059 170fdb000 Delete type=0 #34
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

Some files were not shown because too many files have changed in this diff Show More