[SWADE] Savage Worlds - Graph Paper Sheet (#7510)

* uploaded images

* add sheet

* updated readme

* updated readme

* updated readme

* Update readme.md

* upload gifs

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* fixed unskilled

* Update readme.md

* updated sheet.json

* resized gifs to 400px width

* pre-release fixes

* pre-release fixes

* removed obsolete image

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* renamed to SavageWorldsGraphPaper

* renamed folder

* Update readme.md

* fixed image paths

* skill lock does no longer lock mod/wd inputs

* removed charset declaration

* added wild die to roll templates

* changed secondary container height for list items

* removed style variable

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* extended Allies block and multiple fixes

* removed default values for renaming options

* added translation.json and some basic strings

* Update readme.md

* added more translation strings

* added more translation hooks

* added renaming option for integrity drawbacks

* fixed wrong description

* even more translations

* remaining translation hooks, new mixin for vehicle weapons, some css reductions

* Update readme.md

* Update readme.md

* updated translations

* added  

* Update readme.md

* Update readme.md

typo

* Update readme.md

spelling error

* Update readme.md

added link

* removed custom add item labels due to being not translatable

* removed @charset UTF-8;

* Update readme.md

* yet even more translation stuff

* dice parser includes renamed abbreviations

* removed placeholder translations from hexfields

* circumvented translation error for height

* removed untranslatable label from empty list

* removed die label from untrained bubble

* circumvented translation error for height

* updated settings strings

* removed transition from damage roll toggle

* updated readme

* updated translations

* Update readme.md

* Update readme.md

* ordered translations, removed UTF-8 declaration from CSS

* added string interpolation

* added preview image

* Update readme.md

* added extra sheet preview image

* optimized image

* Update readme.md

* fixed meta field and extra preview image

* string interpolation, missing translations, hyphens to underscore (fml)

* fixed introduced errors from refactoring

* translation fixes

* resolved conflict due to underscore naming scheme

* removed console log commands

* resolved conflict due to underscore naming scheme #2

* fixed missing skill track labels

* updated helper text

* Update readme.md

* removed obsolete leading whitespaces

* prepared scss file for translation overrides

* Update readme.md

* some JS clean-up

* added style option to disable skill die numbers

* added settings.gif

* Update readme.md

* added roll preview

* improved roll preview

* Update readme.md

* Update readme.md

* updated list item label

* reduced roll preview size

* reduced extra sheet preview size

* dice parser now captures X+ and X- references as well

* made lightest text color slightly darker

* switched global transitions to local ones to boost performance

* added missing transition

* updated readme.md

* updated readme.md and sheet.json

* added missing color transition

* Update readme.md

* fixed dice parser bug

* added missing opacity transition

* Update readme.md

* added comment to BS script function

* fixed positioning of hexfield

* prepared rolltemplates for higher rate of fires

* made max rof a global variable

* increases rate of fire range to 8

* updated readme.md

* added ammunition block

* added new help section for ammunition

* Update readme.md

* Update readme.md

* updated sheet.json and translations

* Update readme.md

* Update readme.md

* fixed button color

* added missing/changed translations, improved roll templates, extended skill settings

* streamlined roll template hooks

* added reroll button to roll templates

* cleaned up directory, updated sheet.json and readme.md

* optimized preview image

* Update readme.md

* Update readme.md

* Update readme.md

* added missing reroll, prepared skill rolls for referencing

* removed test button

* css fixes, added roll button and options to repeating lists

* fixed critical bug in dice parser

* added set max capacity to ammunition block

* removed redundant css

* updated sheet.json and readme.md

* Update readme.md

* updated sheet.json

* updated/added preview gifs

* Update readme.md

* Update readme.md

* Update readme.md

* removed obsolete/redundant css (575 lines), improved performance

* fixed button font-size

* removed obsolete characters from css

* removed more obsolete characters from css

* further css reductions

* pluralized label

* add line ending

* fixed attribute font-size

* added dice parser to helper roll buttons

* improved rate of fire handling

* added rof toggle to repeating lists

* Update readme.md

* updated sheet.json

* fixed sheet default options

* refactored running

* Update readme.md

* updated help text for dice roller

* fixed list rolls

* added override for wild die in lists

* added multiplier to augmentations

* added damage button to weapon rolls

* reduced html/css/translations

* html reduction

* updated readme.md

* updated readme.md

* added damage roll button to power list rolls

* added help texts for raise damage, list item options, and extra sheet

* updated readme.md

* added setting toggles and injection options

* added help entry for roll injections

* updated readme.md and sheet.json

* css fix for roll templates

* another css fix

* css fixes

* updated readme

* cleanup

* icon position for lower resolutions

* icon css reduction

* added settings to hide silhouette/skill markers, improved css performance

* rearranged some settings

* added setting to hide augmentation markers

* updated sheet.json

* updated readme

* alphabetically ordered settings

* fixed critical bug in rolls, added toggles for global queries

* updated readme

* bugfix

* small style adjusments

* small style adjusments

* new weight icon

* small icon adjustment

* updated sheet.json and preview image

* fixed renaming feature

* reduced file size of preview image

* fixed some Firefox css issues

* added three configurable custom buttons

* updated readme and sheet.json

* rof toggle is now applied to list damage rolls

* fixed font-size for damage roll templates

* small skill button width adjustment

* text overflow fix for firefox

* fixed missing silhouette switch

* added gm roll toggle

* fixed minor attribute inconsistency between wildcard and extras

* shortened sheetworkers, added toggle for damage dice exploding

* fixed exploding damage dice toggle default

* fixed exploding damage dice toggle default for powers

* refactored all skill rolls

* updated readme and sheet.json

* caught error with empty query modifier

* extended rol template

* extended settings

* added abilities block

* updated readme and sheet.json

* fixed unskilled rolls
This commit is contained in:
Sebastian
2020-10-13 17:42:07 -04:00
committed by GitHub
parent dabb082acb
commit 83f1ca7ebb
137 changed files with 34477 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="28" height="32" viewbox="0 0 27.712812921102035 32"><path fill="#fff" d="M12.12435565298214 0.9999999999999999Q13.856406460551018 0 15.588457268119894 1L25.980762113533157 7Q27.712812921102035 8 27.712812921102035 10L27.712812921102035 22Q27.712812921102035 24 25.980762113533157 25L15.588457268119894 31Q13.856406460551018 32 12.12435565298214 31L1.7320508075688772 25Q0 24 0 22L0 10Q0 8 1.7320508075688774 7Z"></path></svg>

After

Width:  |  Height:  |  Size: 487 B

@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="39" height="44" viewbox="0 0 38.1051177665153 44"><path fill="#fff" d="M17.32050807568877 0.9999999999999999Q19.05255888325765 0 20.784609690826528 0.9999999999999999L36.373066958946424 10Q38.1051177665153 11 38.1051177665153 13L38.1051177665153 31Q38.1051177665153 33 36.373066958946424 34L20.784609690826528 43Q19.05255888325765 44 17.32050807568877 43L1.7320508075688774 34Q0 33 0 31L0 13Q0 11 1.7320508075688774 10Z"></path></svg>

After

Width:  |  Height:  |  Size: 496 B

@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="52" height="60" viewbox="0 0 51.96152422706631 60"><path fill="#fff" d="M24.248711305964278 0.9999999999999999Q25.980762113533157 0 27.712812921102035 1L50.22947341949744 14Q51.96152422706631 15 51.96152422706631 17L51.96152422706631 43Q51.96152422706631 45 50.22947341949744 46L27.712812921102035 59Q25.980762113533157 60 24.248711305964278 59L1.7320508075688772 46Q0 45 0 43L0 17Q0 15 1.7320508075688774 14Z"></path></svg>

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

+421
View File
@@ -0,0 +1,421 @@
# Savage Worlds - Graph Paper (SWADE)
This character sheet was originally made for **Maschinenleben** (released later this year), a fan product for the **Savage Worlds Adventure Edition** (SWADE) about cyborgs struggling with their loss of self. Due to its extensive build and customization options, it can be used for many other settings as well. Join the [support game](https://app.roll20.net/join/8488284/oQJGfg) for bug reports and requests.
## Notable Features
* **Blocks:** Allies, Augmentations, Integrity/Sanity, Powers, Vehicles, and more
* **Fields On Demand:** Show only what you really need to keep the view tidy
* **Extra Sheet:** Alternative sheet with a simplified layout for non-player characters
* **Customization:** Optional rules and functions, custom skills, and renaming
* **Setting Rules:** Enable/Disable optional rules and functions, such as *No Power Points* or *Explode Run Die*
* **Template Rolls:** Multiple dice for multiple targets (RoF 1-8) with a custom Wild Die
* **Failures/Botches:** Dice that show a [1] or [2] are colored red or gray respectively
* **Health/Conditions:** Manage Wounds, Fatigue, and more with a simple click
* **Silhouettes:** They look fancy! You can also add color markers as indicators
## Previews & Gifs
<details>
<summary>Full Preview</summary>
![Full Preview](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/SavageWorldsGraphPaper.jpg)
</details>
<details>
<summary>Extra Sheet</summary>
![Extra Sheet](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/extra_sheet.png)
</details>
<details>
<summary>Roll Template</summary>
![Roll Template](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/roll_template.png)
</details>
<details>
<summary>Attributes</summary>
![Attributes](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/attributes.gif)
</details>
<details>
<summary>Edges & Hindrances</summary>
![Edges & Hindrances](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/features.gif)
</details>
<details>
<summary>Skills</summary>
![Skills](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/skills.gif)
</details>
<details>
<summary>Health</summary>
![Health](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/health.gif)
</details>
<details>
<summary>Augmentations & Integrity</summary>
![Augmentations & Integrity](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/augmentations.gif)
</details>
<details>
<summary>Repeating Lists & Options</summary>
![Repeating Lists & Options](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/power_options.gif)
</details>
<details>
<summary>Vehicles</summary>
![Vehicles](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/vehicles.gif)
</details>
<details>
<summary>Ammunition</summary>
![Ammunition](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/ammunition.gif)
</details>
<details>
<summary>Settings</summary>
![Settings](https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/previews/settings.gif)
</details>
## Latest Changes
#### Version 1.2.5
* Refactored all skill rolls
* Extended [Button] option in lists with a modifier field
* Added [Ace Damage] toggle to Engrams, Powers, and Weapons
* Added helper button to toggle global GM rolls
* Added Abilities block
#### Version 1.2.4
* Added three configurable custom buttons to Settings > Setup
* Fixed some minor CSS issues
#### Version 1.2.3
* Added helper button to toggle global Wild Die query
* Added helper button to toggle global Rate of Fire query
* Added helper button to toggle global Bonus Wild Die query
* Fixed critical bug that broke nearly all rolls
#### Version 1.2.2
* Added damage (re-)roll buttons to Roll Templates
* Roll Templates now have hooks for descriptions and three custom fields
* Added injection hook to list rolls to allow custom code
* Added setting toggles for list roll descriptions and injections
* Added [Multiplier] option to Augmentations
* Added [Wild Die Override] option to Engrams, Powers, and Weapons
* Added [Roll Description] option to Engrams, Powers, and Weapons
* Added [Roll Injection] option to Engrams, Powers, and Weapons
* Added help entries for extra sheet, list item options, and raise damage
* Updated older help entries and translations
* Reduced HTML and CSS
<details>
<summary>Previous Versions</summary>
#### Version 1.2.1
* Improved handling for Rate of Fire
* Fixed critical bug in Rate of Fire handling
* Dice roller codes are now parsed
* Added [Query RoF] option to Engrams, Powers, and Weapons
* Improved performance
* Fixed sheet default settings not being applied
* Added setting option to apply Fatigue to run rolls
#### Version 1.2.0
* Various improvements, refactoring, and bug/style fixes
* Enhanced usability of damage roll toggles for repeating lists
* Damage codes of powers are now processed by the dice parser
* Added setting menu with options to some interactive list items
* Powers: Show Damage, Show Trapping, Roll Button (Input)
* Engrams: Roll Button (Input)
* Weapons: Show Trapping, Roll Button (Input)
* Added the saved maximum capacity to ammunition magazines
* Updated the sheets help section
#### Version 1.1.1
* Added reroll button to Roll Templates
* Added additional toggles for skills
#### Version 1.1.0
* Added Ammunition block
* Added options to rename ammunition magazines
* Added new help section, *Ammunition: You can keep track of up to three named "magazines" in the Ammunition block. The buttons allow you to quickly add to or subtract from the values. You can save a value with [S] and restore it with [R].*
#### Version 1.0.2
* Increased Rate of Fire range from 6 to 8
#### Version 1.0.1
* Made lightest text color a bit darker
* Moved `transition` property to class scopes
* Dice parser now captures leading attribute shortcodes
#### Version 1.0
* Initial release
</details>
## Development
The character sheet is compiled from [Pug](https://pugjs.org/api/getting-started.html) templates with [SCSS/SASS](https://sass-lang.com/guide) (LibSass). You need both in order to contribute; do not directly modify the compiled HTML and CSS files because these changes will be overwritten! Use the `browser_preview.html` to get a local preview without the need to open Roll20 (non-functional, of course).
### Contribution Guidelines
* Make sure to always delete `@charset "UTF-8";` from the compiled CSS; Roll20 will not load it otherwise
* Make sure the compiled HTML has an Unix line ending
* The default `font-size` is `10px` optimized for 1440p or better resolutions, but keep 1080p in mind
* Follow the 8×8 pixel grid (starting top-left); the height of each block must be a multiple of 8
* The devil is in the detail; align and size all elements as precisely as possible (Chrome leads)
* Use [Block Element Modifiers](http://getbem.com/naming/) to name CSS classes; avoid redundancies as much as reasonable
* Use sheetworkers instead of auto-calculating fields
* Always go the "extra mile"
### Translations
Most of the sheet's strings can be changed via the translation.json. However, some strings need to be manually changed by the GM due to the renaming feature for Traits. Note that certain sheetworker scripts depend on English strings, such as the die codes (e.g. d4, d6, ...) for parsers. If you use [Roll20's translation generation](https://roll20.zendesk.com/hc/en-us/articles/360037773493-Character-Sheet-Translation#CharacterSheetTranslation-StepTwo,GeneratingtheTranslationFile) feature `i18nOutput`, make sure to add the following pairs afterward since they will not be automatically included. Order alphabetically and use `&nbsp;` for trailing whitespaces. Put CSS adjustments due to differing word lengths in `_translation_overrides.scss`.
<details>
<summary>Pseudo-Element Labels</summary>
```
"settings-tab-styles": "Styles",
"settings-tab-setup": "Setup",
"settings-tab-blocks": "Blocks",
"settings-tab-skills": "Skills",
"settings-tab-help": "Help",
"tab-skills": "Skills",
"tab-advancements": "Advancements",
"tab-notebook": "Notebook",
"tab-settings": "Settings",
"skill-track-die-label-d4-2": "2",
"skill-track-die-label-d4": "4",
"skill-track-die-label-d6": "6",
"skill-track-die-label-d8": "8",
"skill-track-die-label-d10": "10",
"skill-track-die-label-d12": "12",
"{": "{",
"}": "}"
```
</details>
<details>
<summary>Sheet Defaults Translations</summary>
```
"defaults-block-show-abilities": "[Block] Show Abilities",
"defaults-block-show-abilities-description": "List special abilities or monstrous powers.",
"defaults-block-show-allies": "[Block] Show Allies",
"defaults-block-show-allies-description": "Keep track of allied characters with a barebone mini sheet.",
"defaults-block-show-ammunition": "[Block] Show Ammunition",
"defaults-block-show-ammunition-description": "Keep track of your \"magazines\" for three weapons.",
"defaults-block-show-augmentations": "[Block] Show Augmentations",
"defaults-block-show-augmentations-description": "Install augmentations/cyberware and keep track of the Loss/Strain.",
"defaults-block-show-engrams": "[Block] Show Engrams",
"defaults-block-show-engrams-description": "Special programs or hardware to execute Hacking actions.",
"defaults-block-show-integrity": "[Block] Show Integrity",
"defaults-block-show-integrity-description": "Quantifies mental health/sanity and keeps track of mental afflictions. Maschinenleben.",
"defaults-block-show-power": "[Block] Show Power/Energy",
"defaults-block-show-power-description": "The energy/mana/etc. reserves of a character.",
"defaults-block-show-powerarmors": "[Block] Show Power Armors",
"defaults-block-show-powerarmors-description": "Vehicles and their modifications/weapons.",
"defaults-block-show-powers": "[Block] Show Powers/Spells",
"defaults-block-show-powers-description": "The known powers/spells of a character.",
"defaults-block-show-vehicles": "[Block] Show Vehicles",
"defaults-block-show-vehicles-description": "Vehicles and their modifications/weapons.",
"defaults-block-show-walkers": "[Block] Show Walkers",
"defaults-block-show-walkers-description": "Walkers/Mechs and their modifications/weapons.<h4 style='margin-top: 24px;'>Show/Hide Skills</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can show or hide skills from the list in accordance with the played Game Setting. This can also be done manually for each individual sheet in its Settings tab. There are two custom skills that can be renamed and modified within the sheet as well, for example to make specialized skills (e.g. specific weapons with custom bonus or Wild Die).</p>",
"defaults-function-explode-run-die": "[Function] Explode Run Die",
"defaults-function-explode-run-die-description": "Makes the run die Ace.",
"defaults-function-running-applies-fatigue": "[Function] Running Applies Fatigue",
"defaults-function-running-applies-fatigue-description": "Fatigue penalties are subtracted from the run roll.<h4 style='margin-top: 24px;'>Show/Hide Blocks</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can show or hide content blocks in accordance with the played Game Setting. This can also be done manually for each individual sheet in its Settings tab. Some blocks that were designed for Maschinenleben, such as Augmentations and Engrams, can be adapted for other purposes as well.</p>",
"defaults-function-running-ignores-wounds": "[Function] Running Ignores Wounds",
"defaults-function-running-ignores-wounds-description": "Wound penalties are not subtracted from the run roll.",
"defaults-rename-attribute-agi": "[Rename] Attribute: AGI to&nbsp;",
"defaults-rename-attribute-agi-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_agi</b>.",
"defaults-rename-attribute-agility": "[Rename] Attribute: Agility to&nbsp;",
"defaults-rename-attribute-agility-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_agility</b>.",
"defaults-rename-attribute-sma": "[Rename] Attribute: SMA to&nbsp;",
"defaults-rename-attribute-sma-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_sma</b>.",
"defaults-rename-attribute-smarts": "[Rename] Attribute: Smarts to&nbsp;",
"defaults-rename-attribute-smarts-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_smarts</b>.",
"defaults-rename-attribute-spi": "[Rename] Attribute: SPI to&nbsp;",
"defaults-rename-attribute-spi-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_spi</b>.",
"defaults-rename-attribute-spirit": "[Rename] Attribute: Spirit to&nbsp;",
"defaults-rename-attribute-spirit-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_spirit</b>.",
"defaults-rename-attribute-str": "[Rename] Attribute: STR to&nbsp;",
"defaults-rename-attribute-str-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_str</b>.",
"defaults-rename-attribute-strength": "[Rename] Attribute: Strength to&nbsp;",
"defaults-rename-attribute-strength-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_strength</b>.",
"defaults-rename-attribute-vig": "[Rename] Attribute: VIG to&nbsp;",
"defaults-rename-attribute-vig-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_vig</b>.<h4 style='margin-top: 24px;'>Rename Skills</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the labels of each skill, best kept below 15 characters due to layout constrains. This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename_attribute}</b> for each individual sheet. Note that changing the label does not affect the reference <b style='font-family: monospace;'>@{attribute}</b> for rolls. They will always be in English.</p>",
"defaults-rename-attribute-vigor": "[Rename] Attribute: Vigor to&nbsp;",
"defaults-rename-attribute-vigor-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_vigor</b>.",
"defaults-rename-block-allies": "[Rename] Block: Allies to&nbsp;",
"defaults-rename-block-allies-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_allies</b>.",
"defaults-rename-block-ammunition": "[Rename] Block: Ammunition to&nbsp;",
"defaults-rename-block-ammunition-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_ammunition</b>.",
"defaults-rename-block-apparel": "[Rename] Block: Apparel to&nbsp;",
"defaults-rename-block-apparel-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_apparel</b>.",
"defaults-rename-block-augmentations": "[Rename] Block: Augmentations to&nbsp;",
"defaults-rename-block-augmentations-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_augmentations</b>.",
"defaults-rename-block-engrams": "[Rename] Block: Engrams to&nbsp;",
"defaults-rename-block-engrams-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_engrams</b>.",
"defaults-rename-block-integrity": "[Rename] Block: Integrity to&nbsp;",
"defaults-rename-block-integrity-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_integrity</b>.",
"defaults-rename-block-inventory": "[Rename] Block: Inventory to&nbsp;",
"defaults-rename-block-inventory-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_inventory</b>.",
"defaults-rename-block-power": "[Rename] Block: Power to&nbsp;",
"defaults-rename-block-power-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_power</b>.",
"defaults-rename-block-powerarmors": "[Rename] Block: Power Armors to&nbsp;",
"defaults-rename-block-powerarmors-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_powerarmors</b>.",
"defaults-rename-block-powers": "[Rename] Block: Powers to&nbsp;",
"defaults-rename-block-powers-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_powers</b>.",
"defaults-rename-block-quick-notes": "[Rename] Block: Quick Notes to&nbsp;",
"defaults-rename-block-quick-notes-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_quick_notes</b>.",
"defaults-rename-block-vehicles": "[Rename] Block: Vehicles to&nbsp;",
"defaults-rename-block-vehicles-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_vehicles</b>.",
"defaults-rename-block-walkers": "[Rename] Block: Walkers to&nbsp;",
"defaults-rename-block-walkers-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_walkers</b>.",
"defaults-rename-block-weapons": "[Rename] Block: Weapons to&nbsp;",
"defaults-rename-block-weapons-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_weapons</b>.<h4 style='margin-top: 24px;'>Rename Integrity Hindrances (Maschinenleben)</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the Hindrances caused by the loss of Integrity (Sanity, Purity, etc.). This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename_integrity-attribute}</b> for each individual sheet. Note that they activate in intervals with each fraction of 10 below 70 — Discord triggers on 69.9 or lower, Dissonance on 59.9 or lower, and so forth.</p>",
"defaults-rename-integrity-alienation": "[Rename] Integrity: Alienation to&nbsp;",
"defaults-rename-integrity-alienation-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_alienation</b>.",
"defaults-rename-integrity-depersonalization": "[Rename] Integrity: Depersonalization to&nbsp;",
"defaults-rename-integrity-depersonalization-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_depersonalization</b>.",
"defaults-rename-integrity-derealization": "[Rename] Integrity: Derealization to&nbsp;",
"defaults-rename-integrity-derealization-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_derealization</b>.",
"defaults-rename-integrity-discord": "[Rename] Integrity: Discord to&nbsp;",
"defaults-rename-integrity-discord-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_discord</b>.",
"defaults-rename-integrity-dissonance": "[Rename] Integrity: Dissonance to&nbsp;",
"defaults-rename-integrity-dissonance-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_dissonance</b>.",
"defaults-rename-integrity-ego-death": "[Rename] Integrity: Ego Death to&nbsp;",
"defaults-rename-integrity-ego-death-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_ego_death</b>.",
"defaults-rename-integrity-psychosis": "[Rename] Integrity: Psychosis to&nbsp;",
"defaults-rename-integrity-psychosis-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_psychosis</b>.",
"defaults-rename-integrity-seizures": "[Rename] Integrity: Seizures to&nbsp;",
"defaults-rename-integrity-seizures-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_seizures</b>.",
"defaults-rename-label-age": "[Rename] Label: Age to&nbsp;",
"defaults-rename-label-age-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_age</b> (e.g. Number or Incarnation).",
"defaults-rename-label-bits": "[Rename] Label: #Bits to&nbsp;",
"defaults-rename-label-bits-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_bits</b> (e.g. Money or Gold).<h4 style='margin-top: 24px;'>Rename Blocks</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the blocks to better fit the Game Setting, such as \"Powers\" to \"Talismans\" or \"Walkers\" to \"Frames\". This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename_block_attribute}</b> for each individual sheet.</p>",
"defaults-rename-label-exp": "[Rename] Label: EXP to&nbsp;",
"defaults-rename-label-exp-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_exp</b> (e.g. Karma or Gems).",
"defaults-rename-label-eyes": "[Rename] Label: Eyes to&nbsp;",
"defaults-rename-label-eyes-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_eyes</b> (e.g. Sensors or Optics).",
"defaults-rename-label-gender": "[Rename] Label: Gender to&nbsp;",
"defaults-rename-label-gender-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_gender</b> (e.g. Sex or Version).",
"defaults-rename-label-hair": "[Rename] Label: Hair to&nbsp;",
"defaults-rename-label-hair-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_hair</b> (e.g. Horns or Mane).",
"defaults-rename-label-height": "[Rename] Label: Height to&nbsp;",
"defaults-rename-label-height-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_height</b> (e.g. Scale or Length).",
"defaults-rename-label-level": "[Rename] Label: Level to&nbsp;",
"defaults-rename-label-level-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_level</b> (e.g. Circle or Year).",
"defaults-rename-label-name": "[Rename] Label: Name to&nbsp;",
"defaults-rename-label-name-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_name</b> (e.g. Alias or Codename).",
"defaults-rename-label-origin": "[Rename] Label: Origin to&nbsp;",
"defaults-rename-label-origin-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_origin</b> (e.g. Race or Species).",
"defaults-rename-label-rank": "[Rename] Label: Rank to&nbsp;",
"defaults-rename-label-rank-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_rank</b> (e.g. Grade or Titel).",
"defaults-rename-label-weight": "[Rename] Label: Weight to&nbsp;",
"defaults-rename-label-weight-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_weight</b> (e.g. Mass or Your Mom).",
"defaults-rename-skill-academics": "[Rename] Skill: Academics to&nbsp;",
"defaults-rename-skill-academics-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_academics</b>.",
"defaults-rename-skill-athletics": "[Rename] Skill: Athletics to&nbsp;",
"defaults-rename-skill-athletics-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_athletics</b>.",
"defaults-rename-skill-boating": "[Rename] Skill: Boating to&nbsp;",
"defaults-rename-skill-boating-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_boating</b>.",
"defaults-rename-skill-common-knowledge": "[Rename] Skill: Common Knowl. to&nbsp;",
"defaults-rename-skill-common-knowledge-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_common_knowledge</b>.",
"defaults-rename-skill-custom-skill-1": "[Rename] Skill: Custom Skill #1 to&nbsp;",
"defaults-rename-skill-custom-skill-1-description": "Can be renamed directly in the sheet's Settings tab.",
"defaults-rename-skill-custom-skill-2": "[Rename] Skill: Custom Skill #2 to&nbsp;",
"defaults-rename-skill-custom-skill-2-description": "Can be renamed directly in the sheet's Settings tab.<h4 style='margin-top: 24px;'>Rename Labels</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the labels at the top of the sheet, such as \"Name\" to \"Alias\" or \"Origin\" to \"Race\". This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename_label_attribute}</b> for each individual sheet. Note that the labels are separated from the actual fields and do not affect the references (e.g. <b style='font-family: monospace;'>@{name}</b>). They will always be in English.</p>",
"defaults-rename-skill-driving": "[Rename] Skill: Driving to&nbsp;",
"defaults-rename-skill-driving-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_driving</b>.",
"defaults-rename-skill-electronics": "[Rename] Skill: Electronics to&nbsp;",
"defaults-rename-skill-electronics-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_electronics</b>.",
"defaults-rename-skill-faith": "[Rename] Skill: Faith to&nbsp;",
"defaults-rename-skill-faith-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_faith</b>.",
"defaults-rename-skill-fighting": "[Rename] Skill: Fighting to&nbsp;",
"defaults-rename-skill-fighting-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_fighting</b>.",
"defaults-rename-skill-focus": "[Rename] Skill: Focus to&nbsp;",
"defaults-rename-skill-focus-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_focus</b>.",
"defaults-rename-skill-gambling": "[Rename] Skill: Gambling to&nbsp;",
"defaults-rename-skill-gambling-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_gambling</b>.",
"defaults-rename-skill-hacking": "[Rename] Skill: Hacking to&nbsp;",
"defaults-rename-skill-hacking-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_hacking</b>.",
"defaults-rename-skill-healing": "[Rename] Skill: Healing to&nbsp;",
"defaults-rename-skill-healing-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_healing</b>.",
"defaults-rename-skill-intimidation": "[Rename] Skill: Intimidation to&nbsp;",
"defaults-rename-skill-intimidation-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_intimidation</b>.",
"defaults-rename-skill-language": "[Rename] Skill: Language to&nbsp;",
"defaults-rename-skill-language-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_language</b>.",
"defaults-rename-skill-magic": "[Rename] Skill: Magic to&nbsp;",
"defaults-rename-skill-magic-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_magic</b>.",
"defaults-rename-skill-notice": "[Rename] Skill: Notice to&nbsp;",
"defaults-rename-skill-notice-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_notice</b>.",
"defaults-rename-skill-occult": "[Rename] Skill: Occult to&nbsp;",
"defaults-rename-skill-occult-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_occult</b>.",
"defaults-rename-skill-performance": "[Rename] Skill: Performance to&nbsp;",
"defaults-rename-skill-performance-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_performance</b>.",
"defaults-rename-skill-persuasion": "[Rename] Skill: Persuasion to&nbsp;",
"defaults-rename-skill-persuasion-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_persuasion</b>.",
"defaults-rename-skill-piloting": "[Rename] Skill: Piloting to&nbsp;",
"defaults-rename-skill-piloting-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_piloting</b>.",
"defaults-rename-skill-psionics": "[Rename] Skill: Psionics to&nbsp;",
"defaults-rename-skill-psionics-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_psionics</b>.",
"defaults-rename-skill-repair": "[Rename] Skill: Repair to&nbsp;",
"defaults-rename-skill-repair-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_repair</b>.",
"defaults-rename-skill-research": "[Rename] Skill: Research to&nbsp;",
"defaults-rename-skill-research-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_research</b>.",
"defaults-rename-skill-riding": "[Rename] Skill: Riding to&nbsp;",
"defaults-rename-skill-riding-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_riding</b>.",
"defaults-rename-skill-science": "[Rename] Skill: Science to&nbsp;",
"defaults-rename-skill-science-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_science</b>.",
"defaults-rename-skill-shooting": "[Rename] Skill: Shooting to&nbsp;",
"defaults-rename-skill-shooting-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_shooting</b>.",
"defaults-rename-skill-spellcasting": "[Rename] Skill: Spellcasting to&nbsp;",
"defaults-rename-skill-spellcasting-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_spellcasting</b>.",
"defaults-rename-skill-stealth": "[Rename] Skill: Stealth to&nbsp;",
"defaults-rename-skill-stealth-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_stealth</b>.",
"defaults-rename-skill-survival": "[Rename] Skill: Survival to&nbsp;",
"defaults-rename-skill-survival-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_survival</b>.",
"defaults-rename-skill-taunt": "[Rename] Skill: Taunt to&nbsp;",
"defaults-rename-skill-taunt-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_taunt</b>.",
"defaults-rename-skill-thievery": "[Rename] Skill: Thievery to&nbsp;",
"defaults-rename-skill-thievery-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_thievery</b>.",
"defaults-rename-skill-weird-science": "[Rename] Skill: Weird Science to&nbsp;",
"defaults-rename-skill-weird-science-description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_weird_science</b>.",
"defaults-rule-augmentation-strain": "[Rule] Augmentation Strain",
"defaults-rule-augmentation-strain-description": "Use the Strain rules from the Science Fiction Companion (SFC 29).",
"defaults-rule-no-power-points": "[Rule] No Power Points",
"defaults-rule-no-power-points-description": "Use the No Power Points Setting Rule (SWADE 140).",
"defaults-skill-show-boating": "[Skill] Show Boating Skill",
"defaults-skill-show-boating-description": "Show the Boating (Agility) skill.",
"defaults-skill-show-custom-skill-1": "[Skill] Show Custom Skill #1",
"defaults-skill-show-custom-skill-1-description": "Show the Custom Skill #1, which can be renamed further down.",
"defaults-skill-show-custom-skill-2": "[Skill] Show Custom Skill #2",
"defaults-skill-show-custom-skill-2-description": "Show the Custom Skill #2, which can be renamed further down.<h4 style='margin-top: 24px;'>Rename Attributes</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the labels of each attribute and its abbreviation (max. 3 characters). This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename_attribute}</b> for each individual sheet. Note that changing the label does not affect the reference <b style='font-family: monospace;'>@{attribute}</b> for rolls. They will always be in English.</p>",
"defaults-skill-show-driving": "[Skill] Show Driving Skill",
"defaults-skill-show-driving-description": "Show the Driving (Agility) skill.",
"defaults-skill-show-electronics": "[Skill] Show Electronics Skill",
"defaults-skill-show-electronics-description": "Show the Electronics (Smarts) skill.",
"defaults-skill-show-faith": "[Skill] Show Faith Skill",
"defaults-skill-show-faith-description": "Show the Faith (Spirit) skill.",
"defaults-skill-show-focus": "[Skill] Show Focus Skill",
"defaults-skill-show-focus-description": "Show the Focus (Spirit) skill.",
"defaults-skill-show-language": "[Skill] Show Language Skill",
"defaults-skill-show-language-description": "Show the Language (Smarts) skill.",
"defaults-skill-show-magic": "[Skill] Show MAGIC Skill",
"defaults-skill-show-magic-description": "Show the MAGIC (Smarts) skill. Maschinenleben.",
"defaults-skill-show-occult": "[Skill] Show Occult Skill",
"defaults-skill-show-occult-description": "Show the Occult (Smarts) skill.",
"defaults-skill-show-piloting": "[Skill] Show Piloting Skill",
"defaults-skill-show-piloting-description": "Show the Piloting (Agility) skill.",
"defaults-skill-show-psionics": "[Skill] Show Psionics Skill",
"defaults-skill-show-psionics-description": "Show the Psionics (Smarts) skill.",
"defaults-skill-show-riding": "[Skill] Show Riding Skill",
"defaults-skill-show-riding-description": "Show the Riding (Agility) skill.",
"defaults-skill-show-spellcasting": "[Skill] Show Spellcasting Skill",
"defaults-skill-show-spellcasting-description": "Show the Spellcasting (Smarts) skill.",
"defaults-skill-show-weird-science": "[Skill] Show Weird Science Skill",
"defaults-skill-show-weird-science-description": "Show the Weird Science (Smarts) skill."
```
</details>
### Legal
The silhouette images were made from purchased assets and are only licensed for this sheet. Do not take them for any other purposes! This does not go for the human silhouettes which were made with the [HeroMachine 3](http://www.heromachine.com/heromachine-3-lab/) and are therefore free.
+924
View File
@@ -0,0 +1,924 @@
{
"html": "SavageWorldsGraphPaper.html",
"css": "SavageWorldsGraphPaper.css",
"authors": " Tetrakern",
"roll20userid": "1940185",
"preview": "SavageWorldsGraphPaper.jpg",
"instructions": "**Version:** 1.2.5\r\rThis character sheet was originally made for **Maschinenleben** (released later this year), a fan product for the **Savage Worlds Adventure Edition** (SWADE) about cyborgs struggling with their loss of self. Due to its extensive build and customization options, it may be used for many other settings as well.\r\r**Make sure to read the Help section in the Settings tab!**\r\r#### Notable Features\r\r* **Blocks:** Allies, Augmentations, Integrity/Sanity, Powers, Vehicles, and more\r* **Fields On Demand:** Show only what you really need to keep the view tidy\r* **Customization:** Optional rules and functions, custom skills, and renaming\r* **Rolls:** Multiple dice for multiple targets (RoF 1-8) with a custom Wild Die\r* **Failures/Botches:** Dice that show a [1] or [2] are colored red or gray\r* **Health/Conditions:** Manage Wounds, Fatigue, and more with a simple click\r* **Silhouettes:** They look fancy! You can also add color markers as indicators\r* **Extra Sheet:** Alternative sheet with a simplified layout for NPCs\r\r#### Notes\r\r* Boost performance by disabling style features\r* Requires a mouse to fully operate (hover); poor touch support\r* Some attributes have to be translated (renamed) manually\r* Join the [support game](https://app.roll20.net/join/8488284/oQJGfg) for bug reports and requests\r\r---\r\rYou can support development of this sheet by contributing to the [Ko-fi](https://ko-fi.com/tetrakern) of the author. This [Ko-fi](https://ko-fi.com/tetrakern) is not affiliated with Roll20; as such, contributions are voluntary and Roll20 cannot provide support or refunds for contributions.\r\r---\r\r#### Latest Changes\r\r##### Version 1.2.5\r\r* Refactored all skill rolls\r* Extended [Button] option in lists with a modifier field\r* Added [Ace Damage] toggle to Engrams, Powers, and Weapons\r* Added helper button to toggle global GM rolls\r* Added Abilities block\r\r##### Version 1.2.4\r\r* Added three configurable custom buttons to Settings > Setup\r\r##### Version 1.2.3\r\r* Added helper button to toggle global Wild Die query\r* Added helper button to toggle global Rate of Fire query\r* Added helper button to toggle global Bonus Wild Die query\r\r##### Version 1.2.2\r\r* Added damage (re-)roll buttons to Roll Templates\r* Roll Templates now have hooks for descriptions and three custom fields\r* Added injection hook to list rolls to allow custom code\r* Added setting toggles for list roll descriptions and injections\r* Added [Multiplier] option to Augmentations\r* Added [Wild Die Override] option to Engrams, Powers, and Weapons\r* Added [Roll Description] option to Engrams, Powers, and Weapons\r* Added [Roll Injection] option to Engrams, Powers, and Weapons\r* Added help entries for extra sheet, list item options, and raise damage\r* Updated older help entries and translations\r\r---",
"useroptions": [
{
"attribute": "toggle_pp",
"displayname": "[Rule] No Power Points",
"displaytranslationkey": "defaults-rule-no-power-points",
"type": "checkbox",
"value": "on",
"description": "Use the No Power Points Setting Rule (SWADE 140).",
"descriptiontranslationkey": "defaults-rule-no-power-points-description"
},
{
"attribute": "toggle_strain",
"displayname": "[Rule] Augmentation Strain",
"displaytranslationkey": "defaults-rule-augmentation-strain",
"type": "checkbox",
"value": "on",
"description": "Use the Strain rules from the Science Fiction Companion (SFC 29).",
"descriptiontranslationkey": "defaults-rule-augmentation-strain-description"
},
{
"attribute": "toggle_run_explode",
"displayname": "[Function] Explode Run Die",
"displaytranslationkey": "defaults-function-explode-run-die",
"type": "checkbox",
"value": "on",
"description": "Makes the run die Ace.",
"descriptiontranslationkey": "defaults-function-explode-run-die-description"
},
{
"attribute": "toggle_run_wounds",
"displayname": "[Function] Running Ignores Wounds",
"displaytranslationkey": "defaults-function-running-ignores-wounds",
"type": "checkbox",
"value": "on",
"description": "Wound penalties are not subtracted from the run roll.",
"descriptiontranslationkey": "defaults-function-running-ignores-wounds-description"
},
{
"attribute": "toggle_run_fatigue",
"displayname": "[Function] Running Applies Fatigue",
"displaytranslationkey": "defaults-function-running-applies-fatigue",
"type": "checkbox",
"value": "on",
"description": "Fatigue penalties are subtracted from the run roll.<h4 style='margin-top: 24px;'>Show/Hide Blocks</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can show or hide content blocks in accordance with the played Game Setting. This can also be done manually for each individual sheet in its Settings tab. Some blocks that were designed for Maschinenleben, such as Augmentations and Engrams, can be adapted for other purposes as well.</p>",
"descriptiontranslationkey": "defaults-function-running-applies-fatigue-description"
},
{
"attribute": "toggle_abilities_block",
"displayname": "[Block] Show Abilities",
"displaytranslationkey": "defaults-block-show-abilities",
"type": "checkbox",
"value": "on",
"description": "List special abilities or monstrous powers.",
"descriptiontranslationkey": "defaults-block-show-abilities-description"
},
{
"attribute": "toggle_allies_block",
"displayname": "[Block] Show Allies",
"displaytranslationkey": "defaults-block-show-allies",
"type": "checkbox",
"value": "on",
"description": "Keep track of allied characters with a barebone mini sheet.",
"descriptiontranslationkey": "defaults-block-show-allies-description"
},
{
"attribute": "toggle_ammunition_block",
"displayname": "[Block] Show Ammunition",
"displaytranslationkey": "defaults-block-show-ammunition",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Keep track of your loaded ammunition for three weapons.",
"descriptiontranslationkey": "defaults-block-show-ammunition-description"
},
{
"attribute": "toggle_augmentations_block",
"displayname": "[Block] Show Augmentations",
"displaytranslationkey": "defaults-block-show-augmentations",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Install augmentations/cyberware and keep track of the Loss/Strain.",
"descriptiontranslationkey": "defaults-block-show-augmentations-description"
},
{
"attribute": "toggle_engrams_block",
"displayname": "[Block] Show Engrams",
"displaytranslationkey": "defaults-block-show-engrams",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Special programs or hardware to execute Hacking actions.",
"descriptiontranslationkey": "defaults-block-show-engrams-description"
},
{
"attribute": "toggle_integrity_block",
"displayname": "[Block] Show Integrity",
"displaytranslationkey": "defaults-block-show-integrity",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Quantifies mental health/sanity and keeps track of mental afflictions. Maschinenleben.",
"descriptiontranslationkey": "defaults-block-show-integrity-description"
},
{
"attribute": "toggle_power_block",
"displayname": "[Block] Show Power/Energy",
"displaytranslationkey": "defaults-block-show-power",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "The energy/mana/etc. reserves of a character.",
"descriptiontranslationkey": "defaults-block-show-power-description"
},
{
"attribute": "toggle_powers_block",
"displayname": "[Block] Show Powers/Spells",
"displaytranslationkey": "defaults-block-show-powers",
"type": "checkbox",
"value": "on",
"description": "The known powers/spells of a character.",
"descriptiontranslationkey": "defaults-block-show-powers-description"
},
{
"attribute": "toggle_powerarmors_block",
"displayname": "[Block] Show Power Armors",
"displaytranslationkey": "defaults-block-show-powerarmors",
"type": "checkbox",
"value": "on",
"description": "Vehicles and their modifications/weapons.",
"descriptiontranslationkey": "defaults-block-show-powerarmors-description"
},
{
"attribute": "toggle_vehicles_block",
"displayname": "[Block] Show Vehicles",
"displaytranslationkey": "defaults-block-show-vehicles",
"type": "checkbox",
"value": "on",
"description": "Vehicles and their modifications/weapons.",
"descriptiontranslationkey": "defaults-block-show-vehicles-description"
},
{
"attribute": "toggle_walkers_block",
"displayname": "[Block] Show Walkers",
"displaytranslationkey": "defaults-block-show-walkers",
"type": "checkbox",
"value": "on",
"description": "Walkers/Mechs and their modifications/weapons.<h4 style='margin-top: 24px;'>Show/Hide Skills</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can show or hide skills from the list in accordance with the played Game Setting. This can also be done manually for each individual sheet in its Settings tab. There are two custom skills that can be renamed and modified within the sheet as well, for example to make specialized skills (e.g. specific weapons with custom bonus or Wild Die).</p>",
"descriptiontranslationkey": "defaults-block-show-walkers-description"
},
{
"attribute": "toggle_skill_boating",
"displayname": "[Skill] Show Boating Skill",
"displaytranslationkey": "defaults-skill-show-boating",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Show the Boating (Agility) skill.",
"descriptiontranslationkey": "defaults-skill-show-boating-description"
},
{
"attribute": "toggle_skill_driving",
"displayname": "[Skill] Show Driving Skill",
"displaytranslationkey": "defaults-skill-show-driving",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Show the Driving (Agility) skill.",
"descriptiontranslationkey": "defaults-skill-show-driving-description"
},
{
"attribute": "toggle_skill_electronics",
"displayname": "[Skill] Show Electronics Skill",
"displaytranslationkey": "defaults-skill-show-electronics",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Show the Electronics (Smarts) skill.",
"descriptiontranslationkey": "defaults-skill-show-electronics-description"
},
{
"attribute": "toggle_skill_faith",
"displayname": "[Skill] Show Faith Skill",
"displaytranslationkey": "defaults-skill-show-faith",
"type": "checkbox",
"value": "on",
"description": "Show the Faith (Spirit) skill.",
"descriptiontranslationkey": "defaults-skill-show-faith-description"
},
{
"attribute": "toggle_skill_focus",
"displayname": "[Skill] Show Focus Skill",
"displaytranslationkey": "defaults-skill-show-focus",
"type": "checkbox",
"value": "on",
"description": "Show the Focus (Spirit) skill.",
"descriptiontranslationkey": "defaults-skill-show-focus-description"
},
{
"attribute": "toggle_skill_language",
"displayname": "[Skill] Show Language Skill",
"displaytranslationkey": "defaults-skill-show-language",
"type": "checkbox",
"value": "on",
"description": "Show the Language (Smarts) skill.",
"descriptiontranslationkey": "defaults-skill-show-language-description"
},
{
"attribute": "toggle_skill_magic",
"displayname": "[Skill] Show MAGIC Skill",
"displaytranslationkey": "defaults-skill-show-magic",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Show the MAGIC (Smarts) skill. Maschinenleben.",
"descriptiontranslationkey": "defaults-skill-show-magic-description"
},
{
"attribute": "toggle_skill_occult",
"displayname": "[Skill] Show Occult Skill",
"displaytranslationkey": "defaults-skill-show-occult",
"type": "checkbox",
"value": "on",
"description": "Show the Occult (Smarts) skill.",
"descriptiontranslationkey": "defaults-skill-show-occult-description"
},
{
"attribute": "toggle_skill_piloting",
"displayname": "[Skill] Show Piloting Skill",
"displaytranslationkey": "defaults-skill-show-piloting",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Show the Piloting (Agility) skill.",
"descriptiontranslationkey": "defaults-skill-show-piloting-description"
},
{
"attribute": "toggle_skill_psionics",
"displayname": "[Skill] Show Psionics Skill",
"displaytranslationkey": "defaults-skill-show-psionics",
"type": "checkbox",
"value": "on",
"description": "Show the Psionics (Smarts) skill.",
"descriptiontranslationkey": "defaults-skill-show-psionics-description"
},
{
"attribute": "toggle_skill_riding",
"displayname": "[Skill] Show Riding Skill",
"displaytranslationkey": "defaults-skill-show-riding",
"type": "checkbox",
"value": "on",
"checked": "checked",
"description": "Show the Riding (Agility) skill.",
"descriptiontranslationkey": "defaults-skill-show-riding-description"
},
{
"attribute": "toggle_skill_spellcasting",
"displayname": "[Skill] Show Spellcasting Skill",
"displaytranslationkey": "defaults-skill-show-spellcasting",
"type": "checkbox",
"value": "on",
"description": "Show the Spellcasting (Smarts) skill.",
"descriptiontranslationkey": "defaults-skill-show-spellcasting-description"
},
{
"attribute": "toggle_skill_weird_science",
"displayname": "[Skill] Show Weird Science Skill",
"displaytranslationkey": "defaults-skill-show-weird-science",
"type": "checkbox",
"value": "on",
"description": "Show the Weird Science (Smarts) skill.",
"descriptiontranslationkey": "defaults-skill-show-weird-science-description"
},
{
"attribute": "toggle_skill_custom_skill_1",
"displayname": "[Skill] Show Custom Skill #1",
"displaytranslationkey": "defaults-skill-show-custom-skill-1",
"type": "checkbox",
"value": "on",
"description": "Show the Custom Skill #1, which can be renamed further down.",
"descriptiontranslationkey": "defaults-skill-show-custom-skill-1-description"
},
{
"attribute": "toggle_skill_custom_skill_2",
"displayname": "[Skill] Show Custom Skill #2",
"displaytranslationkey": "defaults-skill-show-custom-skill-2",
"type": "checkbox",
"value": "on",
"description": "Show the Custom Skill #2, which can be renamed further down.<h4 style='margin-top: 24px;'>Rename Attributes</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the labels of each attribute and its abbreviation (max. 3 characters). This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename-attribute}</b> for each individual sheet. Note that changing the label does not affect the reference <b style='font-family: monospace;'>@{attribute}</b> for rolls. They will always be in English.</p>",
"descriptiontranslationkey": "defaults-skill-show-custom-skill-2-description"
},
{
"attribute": "rename_agility",
"displayname": "[Rename] Attribute: Agility to ",
"displaytranslationkey": "defaults-rename-attribute-agility",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_agility</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-agility-description"
},
{
"attribute": "rename_agi",
"displayname": "[Rename] Attribute: AGI to ",
"displaytranslationkey": "defaults-rename-attribute-agi",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_agi</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-agi-description"
},
{
"attribute": "rename_smarts",
"displayname": "[Rename] Attribute: Smarts to ",
"displaytranslationkey": "defaults-rename-attribute-smarts",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_smarts</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-smarts-description"
},
{
"attribute": "rename_sma",
"displayname": "[Rename] Attribute: SMA to ",
"displaytranslationkey": "defaults-rename-attribute-sma",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_sma</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-sma-description"
},
{
"attribute": "rename_spirit",
"displayname": "[Rename] Attribute: Spirit to ",
"displaytranslationkey": "defaults-rename-attribute-spirit",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_spirit</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-spirit-description"
},
{
"attribute": "rename_spi",
"displayname": "[Rename] Attribute: SPI to ",
"displaytranslationkey": "defaults-rename-attribute-spi",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_spi</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-spi-description"
},
{
"attribute": "rename_strength",
"displayname": "[Rename] Attribute: Strength to ",
"displaytranslationkey": "defaults-rename-attribute-strength",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_strength</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-strength-description"
},
{
"attribute": "rename_str",
"displayname": "[Rename] Attribute: STR to ",
"displaytranslationkey": "defaults-rename-attribute-str",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_str</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-str-description"
},
{
"attribute": "rename_vigor",
"displayname": "[Rename] Attribute: Vigor to ",
"displaytranslationkey": "defaults-rename-attribute-vigor",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_vigor</b>.",
"descriptiontranslationkey": "defaults-rename-attribute-vigor-description"
},
{
"attribute": "rename_vig",
"displayname": "[Rename] Attribute: VIG to ",
"displaytranslationkey": "defaults-rename-attribute-vig",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_vig</b>.<h4 style='margin-top: 24px;'>Rename Skills</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the labels of each skill, best kept below 15 characters due to layout constrains. This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename-attribute}</b> for each individual sheet. Note that changing the label does not affect the reference <b style='font-family: monospace;'>@{attribute}</b> for rolls. They will always be in English.</p>",
"descriptiontranslationkey": "defaults-rename-attribute-vig-description"
},
{
"attribute": "rename_academics",
"displayname": "[Rename] Skill: Academics to ",
"displaytranslationkey": "defaults-rename-skill-academics",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_academics</b>.",
"descriptiontranslationkey": "defaults-rename-skill-academics-description"
},
{
"attribute": "rename_athletics",
"displayname": "[Rename] Skill: Athletics to ",
"displaytranslationkey": "defaults-rename-skill-athletics",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_athletics</b>.",
"descriptiontranslationkey": "defaults-rename-skill-athletics-description"
},
{
"attribute": "rename_boating",
"displayname": "[Rename] Skill: Boating to ",
"displaytranslationkey": "defaults-rename-skill-boating",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_boating</b>.",
"descriptiontranslationkey": "defaults-rename-skill-boating-description"
},
{
"attribute": "rename_common_knowledge",
"displayname": "[Rename] Skill: Common Knowl. to ",
"displaytranslationkey": "defaults-rename-skill-common-knowledge",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_common_knowledge</b>.",
"descriptiontranslationkey": "defaults-rename-skill-common-knowledge-description"
},
{
"attribute": "rename_driving",
"displayname": "[Rename] Skill: Driving to ",
"displaytranslationkey": "defaults-rename-skill-driving",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_driving</b>.",
"descriptiontranslationkey": "defaults-rename-skill-driving-description"
},
{
"attribute": "rename_electronics",
"displayname": "[Rename] Skill: Electronics to ",
"displaytranslationkey": "defaults-rename-skill-electronics",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_electronics</b>.",
"descriptiontranslationkey": "defaults-rename-skill-electronics-description"
},
{
"attribute": "rename_faith",
"displayname": "[Rename] Skill: Faith to ",
"displaytranslationkey": "defaults-rename-skill-faith",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_faith</b>.",
"descriptiontranslationkey": "defaults-rename-skill-faith-description"
},
{
"attribute": "rename_fighting",
"displayname": "[Rename] Skill: Fighting to ",
"displaytranslationkey": "defaults-rename-skill-fighting",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_fighting</b>.",
"descriptiontranslationkey": "defaults-rename-skill-fighting-description"
},
{
"attribute": "rename_focus",
"displayname": "[Rename] Skill: Focus to ",
"displaytranslationkey": "defaults-rename-skill-focus",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_focus</b>.",
"descriptiontranslationkey": "defaults-rename-skill-focus-description"
},
{
"attribute": "rename_gambling",
"displayname": "[Rename] Skill: Gambling to ",
"displaytranslationkey": "defaults-rename-skill-gambling",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_gambling</b>.",
"descriptiontranslationkey": "defaults-rename-skill-gambling-description"
},
{
"attribute": "rename_hacking",
"displayname": "[Rename] Skill: Hacking to ",
"displaytranslationkey": "defaults-rename-skill-hacking",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_hacking</b>.",
"descriptiontranslationkey": "defaults-rename-skill-hacking-description"
},
{
"attribute": "rename_healing",
"displayname": "[Rename] Skill: Healing to ",
"displaytranslationkey": "defaults-rename-skill-healing",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_healing</b>.",
"descriptiontranslationkey": "defaults-rename-skill-healing-description"
},
{
"attribute": "rename_intimidation",
"displayname": "[Rename] Skill: Intimidation to ",
"displaytranslationkey": "defaults-rename-skill-intimidation",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_intimidation</b>.",
"descriptiontranslationkey": "defaults-rename-skill-intimidation-description"
},
{
"attribute": "rename_language",
"displayname": "[Rename] Skill: Language to ",
"displaytranslationkey": "defaults-rename-skill-language",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_language</b>.",
"descriptiontranslationkey": "defaults-rename-skill-language-description"
},
{
"attribute": "rename_magic",
"displayname": "[Rename] Skill: MAGIC to ",
"displaytranslationkey": "defaults-rename-skill-magic",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_magic</b>.",
"descriptiontranslationkey": "defaults-rename-skill-magic-description"
},
{
"attribute": "rename_notice",
"displayname": "[Rename] Skill: Notice to ",
"displaytranslationkey": "defaults-rename-skill-notice",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_notice</b>.",
"descriptiontranslationkey": "defaults-rename-skill-notice-description"
},
{
"attribute": "rename_occult",
"displayname": "[Rename] Skill: Occult to ",
"displaytranslationkey": "defaults-rename-skill-occult",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_occult</b>.",
"descriptiontranslationkey": "defaults-rename-skill-occult-description"
},
{
"attribute": "rename_performance",
"displayname": "[Rename] Skill: Performance to ",
"displaytranslationkey": "defaults-rename-skill-performance",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_performance</b>.",
"descriptiontranslationkey": "defaults-rename-skill-performance-description"
},
{
"attribute": "rename_persuasion",
"displayname": "[Rename] Skill: Persuasion to ",
"displaytranslationkey": "defaults-rename-skill-persuasion",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_persuasion</b>.",
"descriptiontranslationkey": "defaults-rename-skill-persuasion-description"
},
{
"attribute": "rename_piloting",
"displayname": "[Rename] Skill: Piloting to ",
"displaytranslationkey": "defaults-rename-skill-piloting",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_piloting</b>.",
"descriptiontranslationkey": "defaults-rename-skill-piloting-description"
},
{
"attribute": "rename_psionics",
"displayname": "[Rename] Skill: Psionics to ",
"displaytranslationkey": "defaults-rename-skill-psionics",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_psionics</b>.",
"descriptiontranslationkey": "defaults-rename-skill-psionics-description"
},
{
"attribute": "rename_repair",
"displayname": "[Rename] Skill: Repair to ",
"displaytranslationkey": "defaults-rename-skill-repair",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_repair</b>.",
"descriptiontranslationkey": "defaults-rename-skill-repair-description"
},
{
"attribute": "rename_research",
"displayname": "[Rename] Skill: Research to ",
"displaytranslationkey": "defaults-rename-skill-research",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_research</b>.",
"descriptiontranslationkey": "defaults-rename-skill-research-description"
},
{
"attribute": "rename_riding",
"displayname": "[Rename] Skill: Riding to ",
"displaytranslationkey": "defaults-rename-skill-riding",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_riding</b>.",
"descriptiontranslationkey": "defaults-rename-skill-riding-description"
},
{
"attribute": "rename_science",
"displayname": "[Rename] Skill: Science to ",
"displaytranslationkey": "defaults-rename-skill-science",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_science</b>.",
"descriptiontranslationkey": "defaults-rename-skill-science-description"
},
{
"attribute": "rename_shooting",
"displayname": "[Rename] Skill: Shooting to ",
"displaytranslationkey": "defaults-rename-skill-shooting",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_shooting</b>.",
"descriptiontranslationkey": "defaults-rename-skill-shooting-description"
},
{
"attribute": "rename_spellcasting",
"displayname": "[Rename] Skill: Spellcasting to ",
"displaytranslationkey": "defaults-rename-skill-spellcasting",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_spellcasting</b>.",
"descriptiontranslationkey": "defaults-rename-skill-spellcasting-description"
},
{
"attribute": "rename_stealth",
"displayname": "[Rename] Skill: Stealth to ",
"displaytranslationkey": "defaults-rename-skill-stealth",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_stealth</b>.",
"descriptiontranslationkey": "defaults-rename-skill-stealth-description"
},
{
"attribute": "rename_survival",
"displayname": "[Rename] Skill: Survival to ",
"displaytranslationkey": "defaults-rename-skill-survival",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_survival</b>.",
"descriptiontranslationkey": "defaults-rename-skill-survival-description"
},
{
"attribute": "rename_taunt",
"displayname": "[Rename] Skill: Taunt to ",
"displaytranslationkey": "defaults-rename-skill-taunt",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_taunt</b>.",
"descriptiontranslationkey": "defaults-rename-skill-taunt-description"
},
{
"attribute": "rename_thievery",
"displayname": "[Rename] Skill: Thievery to ",
"displaytranslationkey": "defaults-rename-skill-thievery",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_thievery</b>.",
"descriptiontranslationkey": "defaults-rename-skill-thievery-description"
},
{
"attribute": "rename_weird_science",
"displayname": "[Rename] Skill: Weird Science to ",
"displaytranslationkey": "defaults-rename-skill-weird-science",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_weird_science</b>.",
"descriptiontranslationkey": "defaults-rename-skill-weird-science-description"
},
{
"attribute": "rename_custom_skill_1",
"displayname": "[Rename] Skill: Custom Skill #1 to ",
"displaytranslationkey": "defaults-rename-skill-custom-skill-1",
"type": "text",
"description": "Can be renamed directly in the sheet's Settings tab.",
"descriptiontranslationkey": "defaults-rename-skill-custom-skill-1-description"
},
{
"attribute": "rename_custom_skill_2",
"displayname": "[Rename] Skill: Custom Skill #2 to ",
"displaytranslationkey": "defaults-rename-skill-custom-skill-2",
"type": "text",
"description": "Can be renamed directly in the sheet's Settings tab.<h4 style='margin-top: 24px;'>Rename Labels</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the labels at the top of the sheet, such as \"Name\" to \"Alias\" or \"Origin\" to \"Race\". This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename-label-attribute}</b> for each individual sheet. Note that the labels are separated from the actual fields and do not affect the references (e.g. <b style='font-family: monospace;'>@{name}</b>). They will always be in English.</p>",
"descriptiontranslationkey": "defaults-rename-skill-custom-skill-2-description"
},
{
"attribute": "rename_label_name",
"displayname": "[Rename] Label: Name to ",
"displaytranslationkey": "defaults-rename-label-name",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_name</b> (e.g. Alias or Codename).",
"descriptiontranslationkey": "defaults-rename-label-name-description"
},
{
"attribute": "rename_label_origin",
"displayname": "[Rename] Label: Origin to ",
"displaytranslationkey": "defaults-rename-label-origin",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_origin</b> (e.g. Race or Species).",
"descriptiontranslationkey": "defaults-rename-label-origin-description"
},
{
"attribute": "rename_label_rank",
"displayname": "[Rename] Label: Rank to ",
"displaytranslationkey": "defaults-rename-label-rank",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_rank</b> (e.g. Grade or Titel).",
"descriptiontranslationkey": "defaults-rename-label-rank-description"
},
{
"attribute": "rename_label_level",
"displayname": "[Rename] Label: Level to ",
"displaytranslationkey": "defaults-rename-label-level",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_level</b> (e.g. Circle or Year).",
"descriptiontranslationkey": "defaults-rename-label-level-description"
},
{
"attribute": "rename_label_exp",
"displayname": "[Rename] Label: EXP to ",
"displaytranslationkey": "defaults-rename-label-exp",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_exp</b> (e.g. Karma or Gems).",
"descriptiontranslationkey": "defaults-rename-label-exp-description"
},
{
"attribute": "rename_label_gender",
"displayname": "[Rename] Label: Gender to ",
"displaytranslationkey": "defaults-rename-label-gender",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_gender</b> (e.g. Sex or Version).",
"descriptiontranslationkey": "defaults-rename-label-gender-description"
},
{
"attribute": "rename_label_age",
"displayname": "[Rename] Label: Age to ",
"displaytranslationkey": "defaults-rename-label-age",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_age</b> (e.g. Number or Incarnation).",
"descriptiontranslationkey": "defaults-rename-label-age-description"
},
{
"attribute": "rename_label_hair",
"displayname": "[Rename] Label: Hair to ",
"displaytranslationkey": "defaults-rename-label-hair",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_hair</b> (e.g. Horns or Mane).",
"descriptiontranslationkey": "defaults-rename-label-hair-description"
},
{
"attribute": "rename_label_eyes",
"displayname": "[Rename] Label: Eyes to ",
"displaytranslationkey": "defaults-rename-label-eyes",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_eyes</b> (e.g. Sensors or Optics).",
"descriptiontranslationkey": "defaults-rename-label-eyes-description"
},
{
"attribute": "rename_label_height",
"displayname": "[Rename] Label: Height to ",
"displaytranslationkey": "defaults-rename-label-height",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_height</b> (e.g. Scale or Length).",
"descriptiontranslationkey": "defaults-rename-label-height-description"
},
{
"attribute": "rename_label_weight",
"displayname": "[Rename] Label: Weight to ",
"displaytranslationkey": "defaults-rename-label-weight",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_weight</b> (e.g. Mass or Your Mom).",
"descriptiontranslationkey": "defaults-rename-label-weight-description"
},
{
"attribute": "rename_label_bits",
"displayname": "[Rename] Label: #Bits to ",
"displaytranslationkey": "defaults-rename-label-bits",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_label_bits</b> (e.g. Money or Gold).<h4 style='margin-top: 24px;'>Rename Blocks</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the blocks to better fit the Game Setting, such as \"Powers\" to \"Talismans\" or \"Walkers\" to \"Frames\". This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename-block-attribute}</b> for each individual sheet.</p>",
"descriptiontranslationkey": "defaults-rename-label-bits-description"
},
{
"attribute": "rename_block_allies",
"displayname": "[Rename] Block: Allies to ",
"displaytranslationkey": "defaults-rename-block-allies",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_allies</b>.",
"descriptiontranslationkey": "defaults-rename-block-allies-description"
},
{
"attribute": "rename_block_apparel",
"displayname": "[Rename] Block: Apparel to ",
"displaytranslationkey": "defaults-rename-block-apparel",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_apparel</b>.",
"descriptiontranslationkey": "defaults-rename-block-apparel-description"
},
{
"attribute": "rename_block_ammunition",
"displayname": "[Rename] Block: Ammunition to ",
"displaytranslationkey": "defaults-rename-block-ammunition",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_ammunition</b>.",
"descriptiontranslationkey": "defaults-rename-block-ammunition-description"
},
{
"attribute": "rename_block_augmentations",
"displayname": "[Rename] Block: Augmentations to ",
"displaytranslationkey": "defaults-rename-block-augmentations",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_augmentations</b>.",
"descriptiontranslationkey": "defaults-rename-block-augmentations-description"
},
{
"attribute": "rename_block_engrams",
"displayname": "[Rename] Block: Engrams to ",
"displaytranslationkey": "defaults-rename-block-engrams",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_engrams</b>.",
"descriptiontranslationkey": "defaults-rename-block-engrams-description"
},
{
"attribute": "rename_block_integrity",
"displayname": "[Rename] Block: Integrity to ",
"displaytranslationkey": "defaults-rename-block-integrity",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_integrity</b>.",
"descriptiontranslationkey": "defaults-rename-block-integrity-description"
},
{
"attribute": "rename_block_inventory",
"displayname": "[Rename] Block: Inventory to ",
"displaytranslationkey": "defaults-rename-block-inventory",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_inventory</b>.",
"descriptiontranslationkey": "defaults-rename-block-inventory-description"
},
{
"attribute": "rename_block_power",
"displayname": "[Rename] Block: Power to ",
"displaytranslationkey": "defaults-rename-block-power",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_power</b>.",
"descriptiontranslationkey": "defaults-rename-block-power-description"
},
{
"attribute": "rename_block_powers",
"displayname": "[Rename] Block: Powers to ",
"displaytranslationkey": "defaults-rename-block-powers",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_powers</b>.",
"descriptiontranslationkey": "defaults-rename-block-powers-description"
},
{
"attribute": "rename_block_powerarmors",
"displayname": "[Rename] Block: Power Armors to ",
"displaytranslationkey": "defaults-rename-block-powerarmors",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_powerarmors</b>.",
"descriptiontranslationkey": "defaults-rename-block-powerarmors-description"
},
{
"attribute": "rename_block_quick_notes",
"displayname": "[Rename] Block: Quick Notes to ",
"displaytranslationkey": "defaults-rename-block-quick-notes",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_quick_notes</b>.",
"descriptiontranslationkey": "defaults-rename-block-quick-notes-description"
},
{
"attribute": "rename_block_vehicles",
"displayname": "[Rename] Block: Vehicles to ",
"displaytranslationkey": "defaults-rename-block-vehicles",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_vehicles</b>.",
"descriptiontranslationkey": "defaults-rename-block-vehicles-description"
},
{
"attribute": "rename_block_walkers",
"displayname": "[Rename] Block: Walkers to ",
"displaytranslationkey": "defaults-rename-block-walkers",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_walkers</b>.",
"descriptiontranslationkey": "defaults-rename-block-walkers-description"
},
{
"attribute": "rename_block_weapons",
"displayname": "[Rename] Block: Weapons to ",
"displaytranslationkey": "defaults-rename-block-weapons",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_block_weapons</b>.<h4 style='margin-top: 24px;'>Rename Integrity Hindrances (Maschinenleben)</h4><p style='margin-bottom: 16px; max-width: 640px;'>You can rename the Hindrances caused by the loss of Integrity (Sanity, Purity, etc.). This can also be done manually with the <b style='font-family: monospace; white-space: nowrap;'>@{rename_integrity_attribute}</b> for each individual sheet. Note that they activate in intervals for each fraction of 10 below 70 — Discord triggers on 69.9 or lower, Dissonance on 59.9 or lower, and so forth.</p>",
"descriptiontranslationkey": "defaults-rename-block-weapons-description"
},
{
"attribute": "rename_discord",
"displayname": "[Rename] Integrity: Discord to ",
"displaytranslationkey": "defaults-rename-integrity-discord",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_discord</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-discord-description"
},
{
"attribute": "rename_psychosis",
"displayname": "[Rename] Integrity: Psychosis to ",
"displaytranslationkey": "defaults-rename-integrity-psychosis",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_psychosis</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-psychosis-description"
},
{
"attribute": "rename_seizures",
"displayname": "[Rename] Integrity: Seizures to ",
"displaytranslationkey": "defaults-rename-integrity-seizures",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_seizures</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-seizures-description"
},
{
"attribute": "rename_depersonalization",
"displayname": "[Rename] Integrity: Depersonalization to ",
"displaytranslationkey": "defaults-rename-integrity-depersonalization",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_depersonalization</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-depersonalization-description"
},
{
"attribute": "rename_dissonance",
"displayname": "[Rename] Integrity: Dissonance to ",
"displaytranslationkey": "defaults-rename-integrity-dissonance",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_dissonance</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-dissonance-description"
},
{
"attribute": "rename_alienation",
"displayname": "[Rename] Integrity: Alienation to ",
"displaytranslationkey": "defaults-rename-integrity-alienation",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_alienation</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-alienation-description"
},
{
"attribute": "rename_derealization",
"displayname": "[Rename] Integrity: Derealization to ",
"displaytranslationkey": "defaults-rename-integrity-derealization",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_derealization</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-derealization-description"
},
{
"attribute": "rename_ego_death",
"displayname": "[Rename] Integrity: Ego Death to ",
"displaytranslationkey": "defaults-rename-integrity-ego-death",
"type": "text",
"description": "Renamed via the attribute <b style='user-select: all; font-family: monospace; white-space: nowrap;'>rename_ego_death</b>.",
"descriptiontranslationkey": "defaults-rename-integrity-ego-death-description"
}
]
}
@@ -0,0 +1,822 @@
/* #############################################################################
VARIABLES
############################################################################# */
const dice = ['', 'd4', 'd6', 'd8', 'd10', 'd12'];
const renamedAbbr = ['rename_agi', 'rename_sma', 'rename_spi', 'rename_str', 'rename_vig'];
var parseCodes = { agi: '@{agility}!', sma: '@{smarts}!', spi: '@{spirit}!',
str: '@{strength}!', vig: '@{vigor}!' };
const parseDieCodes = { d4: 'd4!', d6: 'd6!', d8: 'd8!', d10: 'd10!', d12: 'd12!' };
/* #############################################################################
TRANSLATION SETUP
############################################################################# */
on("sheet:opened", function(e){
// Translations for query strings
setAttrs({
'query_rate_of_fire': getTranslationByKey('rate-of-fire'),
'query_modifier': getTranslationByKey('modifier'),
'query_wild_die': getTranslationByKey('wild-die'),
'query_roll_result': getTranslationByKey('roll-result'),
'query_target_number': getTranslationByKey('target-number'),
'query_damage_modifier': getTranslationByKey('damage-modifier'),
'query_bonus_wild_die': getTranslationByKey('bonus-wild-die'),
'none': getTranslationByKey('none')
});
// Include renamed Trait abbreviations
getAttrs(renamedAbbr, (values) => {
parseCodes = { agi: '@{agility}!', sma: '@{smarts}!', spi: '@{spirit}!',
str: '@{strength}!', vig: '@{vigor}!' };
_.each(renamedAbbr, (a) => {
// Skip if not defined
if (_.isUndefined(values[a])) return;
// Remove erroneous whitsapces
let v = values[a].replaceAll(' ', '').toLowerCase();
// Skip if empty string
if (v.length < 1) return;
parseCodes[v] = parseCodes[a.replace('rename_', '')];
});
});
});
/* #############################################################################
CUSTOM SHEET FUNCTIONS
############################################################################# */
var TETRA = TETRA || ( function() {
'use strict';
var version = '1.0',
// Parse and evaluate float number
toFloat = function(number, old = 0.0) {
let n = parseFloat(number);
n = _.isUndefined(n) ? old : n;
return isNaN(n) ? old : n;
},
// Parse and evaluate integer number
toInt = function(number, old = 0) {
let n = parseInt(number);
n = _.isUndefined(n) ? old : n;
return isNaN(n) ? old : n;
},
parseDiceCode = function(code) {
if (_.isUndefined(code)) return '';
code = code.toLowerCase();
// Replace abbreviations with attribute references (naive)
_.each(_.keys(parseCodes), (k) => {
code = code.replaceAll(`+${k}`, `+${parseCodes[k]}`);
code = code.replaceAll(`-${k}`, `-${parseCodes[k]}`);
code = code.replaceAll(`${k}+`, `${parseCodes[k]}+`);
code = code.replaceAll(`${k}-`, `${parseCodes[k]}-`);
});
// Add exclamation mark (!) to make dice explode (naive)
_.each(_.keys(parseDieCodes), (k) => {
code = code.replaceAll(`${k}`, `${parseDieCodes[k]}`);
});
return code;
},
// Update the roll queries for a trait
updateTraitRoll = function(trait) {
let traitAttributes = [trait, `${trait}_wd`, `${trait}_mod`];
// Get trait values: die, Wild Die, and modifier
getAttrs(traitAttributes, (values) => {
let die = values[trait],
wd = values[`${trait}_wd`],
ewd = '-10000', // Extra Wild Die
mod = values[`${trait}_mod`] || '0',
untrained = '0',
code = toInt(mod);
// Set up Wild Die
if (dice.includes(wd) && wd != '') {
ewd = wd;
} else if (wd == '') {
wd = '1d6';
} else {
wd = '-10000'; // Rolltemplate will not show results below -1000
}
// Account for untrained skill
if (die == 'd4-2') {
die = 'd4';
code -= 2;
untrained = '-2';
}
// Stringify code
if (code != 0) {
code = code > 0 ? `+${code}` : code.toString();
} else {
code = '';
}
// Build base code
code = die + code;
// Add custom Wild Die to code
code = ewd != '-10000' ? `${code} [${wd}]` : code;
setAttrs({ [`${trait}_roll`]: die,
[`${trait}_wd_roll`]: wd,
[`${trait}_extra_wd_roll`]: ewd,
[`${trait}_untrained_mod`]: untrained,
[`${trait}_code`]: code });
});
},
// Apply custom function to attributes in all rows of repeating section
doWithRepList = function(section, attributes, func = (v) => { return v }) {
let fullSection = section.includes('repeating_') ? section : `repeating_${section}`;
attributes = _.isArray(attributes) ? attributes : [attributes];
function process(idArray, attributes) {
let attributeArray = [];
// List of all requested attributes from all rows
_.each(idArray, (id) => {
_.each(attributes, (a) => {
attributeArray.push(`${fullSection}_${id}_${a}`);
});
});
getAttrs(attributeArray, (values) => {
func(values); // Pass all attribute values to custom function
});
}
getSectionIDs(fullSection, (idArray) => {
process(idArray, attributes);
});
};
return {
updateTraitRoll: updateTraitRoll,
doWithRepList: doWithRepList,
toFloat: toFloat,
toInt: toInt,
parseDiceCode: parseDiceCode
};
}());
/* #############################################################################
ATTRIBUTE DICE (AND SOAK)
############################################################################# */
const attributes = ['agility', 'smarts', 'spirit', 'strength', 'vigor'];
on('change:soak change:' + attributes.join(' change:'), (e) => {
// Derive target attribute and check if input value is a valid die
let value = _.isUndefined(e.newValue) ? 'd4' : e.newValue;
value = dice.includes(value) && value != '' ? value : 'd4';
// Set attributes to new value, silent to avoid triggering worker again
// but with a callback to update the attribute's roll query
setAttrs({ [e.sourceAttribute]: value },
{ silent: true },
TETRA.updateTraitRoll(e.sourceAttribute));
});
/* #############################################################################
SKILL DICE
############################################################################# */
const skills = ['academics', 'athletics', 'battle', 'boating', 'common_knowledge',
'driving', 'electronics', 'fighting', 'healing', 'intimidation',
'magic', 'notice', 'performance', 'persuasion', 'piloting',
'repair', 'research', 'riding', 'science', 'shooting', 'stealth',
'survival', 'taunt', 'thievery', 'gambling', 'hacking', 'faith',
'focus', 'language', 'occult', 'psionics', 'spellcasting',
'weird_science', 'custom_skill_1', 'custom_skill_2', 'unskilled'];
const skillDice = ['d4-2', 'd4', 'd6', 'd8', 'd10', 'd12'];
on('change:' + skills.join(' change:'), (e) => {
// Derive target attribute and check if input value is a valid die
let value = _.isUndefined(e.newValue) ? 'd4-2' : e.newValue;
value = skillDice.includes(value) ? value : 'd4-2';
// Set attributes to new value, silent to avoid triggering worker again
// but with a callback to update the attribute's roll query
setAttrs({ [e.sourceAttribute]: value },
{ silent: true },
TETRA.updateTraitRoll(e.sourceAttribute));
});
/* #############################################################################
WILD DICE
############################################################################# */
const wildTraits = ['soak'].concat(attributes).concat(skills).map((s) => { return `${s}_wd` });
on('change:' + wildTraits.join(' change:'), (e) => {
// Derive target attribute and check if input value is a valid die
let value = _.isUndefined(e.newValue) ? '' : e.newValue;
value = dice.includes(value) ? value : 'n/a';
// Set attributes to new value, silent to avoid triggering worker again
// but with a callback to update the attribute's roll query
setAttrs({ [e.sourceAttribute]: value },
{ silent: true },
TETRA.updateTraitRoll(e.sourceAttribute.replace('_wd', '')));
});
/* #############################################################################
NATURAL DICE
############################################################################# */
const naturalTraits = attributes.map((s) => { return `${s}_natural` });
on('change:' + naturalTraits.join(' change:'), (e) => {
// Check if new value is valid
let value = dice.includes(e.newValue) ? e.newValue : '';
value = _.isUndefined(e.newValue) ? 'd4' : value;
// Set attributes to new value, silent to avoid triggering worker again
setAttrs({ [e.sourceAttribute]: value }, { silent: true });
});
/* #############################################################################
RUN DIE
############################################################################# */
on('change:run', (e) => {
// Check if run value is a valid die
let value = dice.includes(e.newValue) ? e.newValue : '';
// Update run die
value = _.isUndefined(e.newValue) ? '' : value;
// Update run roll
let runRoll = value != '' ? value : 'd6';
// Set attributes to new values, silent to avoid triggering worker again
setAttrs({ [e.sourceAttribute]: value, ['run_roll']: runRoll },
{ silent: true });
});
/* #############################################################################
MODIFIERS
############################################################################# */
const modifiers = ['soak'].concat(attributes).concat(skills).map((s) => { return `${s}_mod` });
on('change:' + modifiers.join(' change:'), (e) => {
// Parse input value as integer
let value = TETRA.toInt(e.newValue, '');
// Set 0 to empty
value = value == 0 ? '' : value;
// Positive or negative prefix (required for roll query)
if (value != '') {
let s = String(value);
value = value > -1 && s.charAt(0) != '+' ? `+${s}` : s;
}
// Set attribute to new value, silent to avoid triggering worker again
setAttrs({ [e.sourceAttribute]: value },
{ silent: true },
TETRA.updateTraitRoll(e.sourceAttribute.replace('_mod', '')));
});
/* #############################################################################
SIMPLE STATISTICS
############################################################################# */
const simple = ['pace', 'flight', 'rads', 'power', 'power_consumed',
'power_maximum', 'armor_head', 'armor_torso', 'armor_arms',
'armor_legs', 'parry', 'toughness', 'integrity_maximum',
'carry_weight_maximum'];
on('change:' + simple.join(' change:'), (e) => {
// Parse input value as integer unless it is empty
let value = TETRA.toInt(e.newValue, '');
// Cannot be smaller than zero
if (value != '') {
value = value < 0 ? 0 : value;
}
// Set attribute to new value, silent to avoid triggering worker again
setAttrs({ [e.sourceAttribute]: value }, { silent: true });
});
/* #############################################################################
WOUND BOXES
############################################################################# */
const woundToggles = _.range(1, 7).map((n) => { return `wound_toggle_${n.toString()}` });
on('change:wounds change:wound_mitigation change:' + woundToggles.join(' change:'), (e) => {
let attributes = ['wounds', 'wound_mitigation'].concat(woundToggles);
// Get all relevant attributes
getAttrs(attributes, (values) => {
let setters = {};
// Get first inactive wound box
let firstInactiveWound = _.find(woundToggles, (ws) => {
return values[ws] == 'on';
});
// Get number of first inactive wound box
let firstInactiveNumber = (() => {
if (_.isUndefined(firstInactiveWound)) {
return 100;
}
let number = parseInt(firstInactiveWound.split('').pop());
return _.isUndefined(number) ? 100 : number;
})();
// Deactive all subsequent wound boxes
for (var i = firstInactiveNumber + 1; i < 7; ++i) {
setters[`wound_toggle_${i}`] = 'on';
};
// Limit active wounds to active wound boxes
if (values['wounds'] >= firstInactiveNumber) {
setters['wounds'] = firstInactiveNumber - 1;
} else {
setters['wounds'] = values['wounds'];
};
// Update wound-mitigation
let wm = isNaN(parseInt(values['wound_mitigation'])) ? '' : parseInt(values['wound_mitigation']);
if (wm != '') {
wm = wm < 0 ? 0 : wm;
}
setters['wound_mitigation'] = wm;
wm = isNaN(wm) ? 0 : wm;
// Update wound_mod
let wmod = setters['wounds'] - wm;
setters['wound_mod'] = wmod < 0 ? 0 : wmod;
setAttrs(setters, { silent: true });
});
});
/* #############################################################################
FATIGUE BOXES
############################################################################# */
const fatigueToggles = _.range(2, 4).map((n) => { return `fatigue_toggle_${n.toString()}` });
on('change:fatigue change:' + fatigueToggles.join(' change:'), (e) => {
let attributes = ['fatigue'].concat(fatigueToggles);
// Get all relevant attributes
getAttrs(attributes, (values) => {
let setters = {};
// Get first inactive box
let firstInactiveBox = _.find(fatigueToggles, (fs) => {
return values[fs] == 'on';
});
// Get number of first inactive box
let firstInactiveNumber = (() => {
if (_.isUndefined(firstInactiveBox)) {
return 100;
}
let number = parseInt(firstInactiveBox.split('').pop());
return _.isUndefined(number) ? 100 : number;
})();
// Deactive all subsequent boxes
for (var i = firstInactiveNumber + 1; i < 4; ++i) {
setters[`fatigue_toggle_${i}`] = 'on';
};
// Limit active fatigue to active boxes
if (values['fatigue'] >= firstInactiveNumber) {
setters['fatigue'] = firstInactiveNumber - 1;
} else {
setters['fatigue'] = values['fatigue'];
};
// Update fatigue_mod
let fmod = TETRA.toInt(setters['fatigue']);
setters['fatigue_mod'] = fmod;
setAttrs(setters, { silent: true });
});
});
/* #############################################################################
AUTO SIZE EDGES + HINDRANCES
############################################################################# */
// 10px Roboto
// Since Roll20 does not allow DOM access, yes, this BS is necessary.
// Don't take this as something to learn from! Stars above, no!
const letters = { 'A': 6.53, 'a': 5.45, 'B': 6.23, 'b': 5.63, 'C': 6.52,
'c': 5.23, 'D': 6.56, 'd': 5.64, 'E': 6.69, 'e': 5.31,
'F': 5.53, 'f': 3.48, 'G': 6.81, 'g': 5.63, 'H': 7.14,
'h': 5.52, 'I': 2.72, 'i': 2.44, 'J': 5.53, 'j': 2.39,
'K': 6.28, 'k': 5.08, 'L': 5.39, 'l': 2.44, 'M': 8.73,
'm': 8.77, 'N': 7.14, 'n': 5.53, 'O': 6.88, 'o': 5.70,
'P': 6.31, 'p': 5.63, 'Q': 6.88, 'q': 5.69, 'R': 6.17,
'r': 3.39, 'S': 5.94, 's': 5.16, 'T': 5.97, 't': 3.28,
'U': 6.48, 'u': 5.52, 'V': 6.38, 'v': 4.84, 'W': 8.88,
'w': 7.52, 'X': 6.28, 'x': 4.97, 'Y': 8.88, 'y': 7.52,
'Z': 6.28, 'z': 4.97, '#': 6.17, '&': 6.22, '(': 3.42,
')': 3.48, '+': 5.67, '-': 2.77, '=': 5.50, '*': 4.31,
'!': 2.58, '.': 2.64, ',': 1.97, '@': 8.98, ' ': 2.48,
'?': 4.73, '_': 4.52, '%': 7.33, 'Ä': 6.53, 'ä': 5.45,
'Ö': 6.88, 'ö': 5.70, 'Ü': 6.48, 'ü': 5.52, 'ß': 5.95,
'°': 3.75, '<': 5.09, '>': 5.23, '[': 2.66, ']': 2.66,
'{': 3.39, '}': 3.39, '$': 5.63, '"': 3.20 };
on('change:repeating_features:feature_name', (e) => {
let target = e.sourceAttribute.replace('_feature_name', '_feature_size');
getAttrs([e.sourceAttribute], (value) => {
// Split string into array
let chars = value[Object.keys(value)[0]].split(''),
stringWidth = 0.0;
// Sum up the width of each character
_.each(chars, (c) => {
stringWidth += _.has(letters, c) ? letters[c] : 5.0;
});
// Remove decimal points by rounding up
stringWidth = Math.ceil(stringWidth);
let offset = 4 - (stringWidth % 4),
elementWidth = stringWidth + offset;
// Maximum/minimum width
elementWidth = elementWidth > 180 ? 180 : elementWidth;
elementWidth = elementWidth < 32 ? 32 : elementWidth;
setAttrs({ [target]: elementWidth }, { silent: true });
});
});
/* #############################################################################
LOSS PROGRESS
############################################################################# */
on('change:integrity', (e) => {
// Parse as float or keep old value if invalid
let value = TETRA.toFloat(e.newValue, e.previousValue),
progress = Math.ceil(value),
setters = { integrity: value.toFixed(1) };
// Bar can only take numbers between 0 and 80
progress = progress > 80 ? 80 : progress;
progress = progress < 0 ? 0 : progress;
setters['integrity_bar_size'] = progress;
// Set corresponding psychological states
setters['discord'] = value < 70 ? 'on' : 'off';
setters['dissonance'] = value < 60 ? 'on' : 'off';
setters['psychosis'] = value < 50 ? 'on' : 'off';
setters['alienation'] = value < 40 ? 'on' : 'off';
setters['seizures'] = value < 30 ? 'on' : 'off';
setters['derealization'] = value < 20 ? 'on' : 'off';
setters['depersonalization'] = value < 10 ? 'on' : 'off';
setters['ego_death'] = value < 1 ? 'on' : 'off';
setAttrs(setters, { silent: true });
});
/* #############################################################################
REPEATING WEIGHT
############################################################################# */
function twoColSum(values, target, multi = false) {
let sum = 0.0;
// Turn into two-dimensional array
values = Object.entries(values);
// Continue to remove items from the array
while (values.length > 0) {
// Values must be in order of weight, toggle, multiplier!
let value = TETRA.toFloat(values.shift()[1]),
toggle = values.shift()[1],
multiplier = 1;
if (multi) {
multiplier = TETRA.toFloat(values.shift()[1]);
}
sum += toggle == 'on' ? value * multiplier : 0.0;
}
setAttrs({ [target]: sum.toFixed(1) });
}
on('remove:repeating_weapons change:repeating_weapons:weapon_weight change:repeating_weapons:weapon_weight_toggle', (e) => {
TETRA.doWithRepList('weapons',
['weapon_weight', 'weapon_weight_toggle'],
(v) => { twoColSum(v, 'carry_weight_weapons') });
});
on('remove:repeating_apparel change:repeating_apparel:apparel_weight change:repeating_apparel:apparel_weight_toggle', (e) => {
TETRA.doWithRepList('apparel',
['apparel_weight', 'apparel_weight_toggle'],
(v) => { twoColSum(v, 'carry_weight_apparel') });
});
on('remove:repeating_inventory change:repeating_inventory:inventory_weight change:repeating_inventory:inventory_weight_toggle change:repeating_inventory:inventory_amount', (e) => {
TETRA.doWithRepList('inventory',
['inventory_weight', 'inventory_weight_toggle', 'inventory_amount'],
(v) => { twoColSum(v, 'carry_weight_inventory', true) });
});
const carryWeights = ['carry_weight_apparel', 'carry_weight_weapons',
'carry_weight_inventory', 'carry_weight_maximum'];
on('change:' + carryWeights.join(' change:'), (e) => {
getAttrs(carryWeights, (value) => {
let weapons = TETRA.toFloat(value['carry_weight_weapons']),
apparel = TETRA.toFloat(value['carry_weight_apparel']),
inventory = TETRA.toFloat(value['carry_weight_inventory']),
total = (weapons + apparel + inventory).toFixed(1);
setAttrs({ ['carry_weight']: total }, { silent: true });
});
});
/* #############################################################################
LOSS
############################################################################# */
on('change:repeating_augmentations remove:repeating_augmentations', (e) => {
TETRA.doWithRepList('augmentations',
['augmentation_loss', 'augmentation_loss_toggle', 'augmentation_multiplier'],
(v) => { twoColSum(v, 'augmentations_total_loss', true) });
});
/* #############################################################################
INTEGRITY MOD
############################################################################# */
on('change:integrity_mod', (e) => {
setAttrs({ ['integrity_mod']: TETRA.toInt(e.newValue, '') });
});
/* #############################################################################
INTEGRITY CALCULATION
############################################################################# */
on('change:augmentations_total_loss change:integrity_maximum change:integrity_mod', (e) => {
getAttrs(['augmentations_total_loss', 'integrity_maximum', 'integrity_mod'], (values) => {
let loss = TETRA.toFloat(values['augmentations_total_loss']),
max = TETRA.toFloat(values['integrity_maximum'], 80),
mod = TETRA.toFloat(values['integrity_mod']);
setAttrs({ integrity: (max - loss + mod).toFixed(1) });
});
});
/* #############################################################################
REAPTING VEHICLE WEAPONS & SILHOUETTES
############################################################################# */
on('change:repeating_vehicles change:repeating_powerarmors', (e) => {
// Weapon count was changed
if (e.sourceAttribute.includes('weapons_count')) {
let value = TETRA.toInt(e.newValue, 0);
// Value must be between 0 and 10
value = value < 0 ? 0 : value;
value = value > 10 ? 10 : value;
setAttrs({ [e.sourceAttribute]: value }, { silent: true });
}
// Silhouette was changed
if (e.sourceAttribute.includes('silhouette')) {
let target = e.sourceAttribute.replace('_vehicle_silhouette_cycle', '_vehicle_silhouette');
getAttrs([target], (values) => {
let silhouette = TETRA.toInt(_.values(values)[0], 0);
setAttrs({ [target]: (silhouette + 1) % 17 }, { silent: true });
});
}
});
/* #############################################################################
AMMUNITION & BUTTONS
############################################################################# */
const ammoMods = ['1', '3', '5', '10'];
function changeAmmo(triggerName) {
let mod = TETRA.toInt(triggerName.replace('clicked:ammunition_', '')),
attributes = ['ammunition_select',
'ammunition_container_1',
'ammunition_container_2',
'ammunition_container_3'];
getAttrs(attributes, (values) => {
let target = values['ammunition_select'],
current = TETRA.toInt(values[target]); // The selector value is the attribute name of the box
// Add ammunition modifier
updated = current + mod;
// No negative ammunition
updated = updated < 0 ? 0 : updated;
setAttrs({ [target]: updated }, { silent: true });
});
}
on(`clicked:${ammoMods.map((s) => { return `ammunition_+${s}` }).join(' clicked:')}`, (e) => {
changeAmmo(e.triggerName);
});
on(`clicked:${ammoMods.map((s) => { return `ammunition_-${s}` }).join(' clicked:')}`, (e) => {
changeAmmo(e.triggerName);
});
on(`clicked:ammunition_set`, (e) => {
getAttrs(['ammunition_select'], (value) => {
let target = `${value['ammunition_select']}_max`;
getAttrs([value['ammunition_select']], (current) => {
update = TETRA.toInt(current[value['ammunition_select']]);
setAttrs({ [target]: update }, { silent: true });
});
});
});
on(`clicked:ammunition_reset`, (e) => {
getAttrs(['ammunition_select'], (value) => {
let target = value['ammunition_select'];
getAttrs([`${target}_max`], (max) => {
update = TETRA.toInt(max[`${target}_max`]);
setAttrs({ [target]: update }, { silent: true });
});
});
});
/* #############################################################################
REPEATING LISTS & OPTIONS
############################################################################# */
const listItems = ['engram', 'power', 'weapon'];
on(listItems.map(s => `change:repeating_${s}s:${s}_damage`).join(' '), (e) => {
let code = TETRA.parseDiceCode(e.newValue);
code = code.replaceAll('!', '@{explode_damage}'); // Toggle exploding damage dice
code = code == '' ? '0' : code;
setAttrs({ [`${e.sourceAttribute}_roll`]: code }, { silent: true });
});
on(listItems.map(s => `change:repeating_${s}s:skill_name`).join(' '), (e) => {
let array = skills.map((s) => { return `rename_${s}` }),
id = e.sourceAttribute.replace('skill_name', ''); // All rename_<skill> attributes
getAttrs(array, (values) => {
// Find corresponding attribute
let renameAttribute = Object.keys(values).find(key => values[key] === e.newValue),
update = {};
if (_.isUndefined(renameAttribute)) {
update[e.sourceAttribute] = e.previousValue; // Reset if input is invalid
} else {
update[`${id}skill_wd`] = `@{${renameAttribute.replace('rename_', '')}_wd}`;
update[`${id}skill_mod`] = `@{${renameAttribute.replace('rename_', '')}_mod}`;
update[`${id}skill_untrained_mod`] = `@{${renameAttribute.replace('rename_', '')}_untrained_mod}`;
update[`${id}skill_roll`] = `@{${renameAttribute.replace('rename_', '')}_roll}`;
update[`${id}skill_wd_roll`] = `@{${renameAttribute.replace('rename_', '')}_wd_roll}`;
update[`${id}skill_extra_wd_roll`] = `@{${renameAttribute.replace('rename_', '')}_extra_wd_roll}`;
}
setAttrs(update, { silent: true });
});
});
on(listItems.map(s => `change:repeating_${s}s:skill_bonus`).join(' '), (e) => {
let update = TETRA.toInt(e.newValue);
update = update == 0 ? '' : update > 0 ? `+${update}` : update;
setAttrs({ [e.sourceAttribute]: update }, { silent: true });
});
on(listItems.map(s => `change:repeating_${s}s:rof_override_toggle`).join(' '), (e) => {
let d = e.sourceAttribute.includes('weapon') ? '@{weapon_rof}' : '1',
update = e.newValue == 'on' ? `?{@{query_rate_of_fire}|${d}}` : '1',
target = e.sourceAttribute.replace('_toggle', '');
setAttrs({ [target]: update }, { silent: true });
});
on(listItems.map(s => `change:repeating_${s}s:wd_override_toggle`).join(' '), (e) => {
let update = e.newValue == 'on' ? `{{wd=@{wd_override_die}}} {{wdroll=[[ @{wd_override_die}!cs2 + (@{skill_untrained_mod})[Untrained] + (@{skill_mod}+0)[Flat] + (@{skill_bonus}+0)[Bonus] - (@{fatigue_mod})[Fatigue] - (@{wound_mod})[Wounds] + (?{@{query_modifier}|0})[Modifier] ]]}}` : '',
target = e.sourceAttribute.replace('_toggle', '');
setAttrs({ [target]: update }, { silent: true });
});
on(listItems.map(s => `change:repeating_${s}s:roll_description_toggle`).join(' '), (e) => {
let update = e.newValue == 'on' ? `@{roll_description_input}` : '',
target = e.sourceAttribute.replace('_toggle', '');
setAttrs({ [target]: update }, { silent: true });
});
on(listItems.map(s => `change:repeating_${s}s:roll_injection_toggle`).join(' '), (e) => {
let update = e.newValue == 'on' ? `@{roll_injection_input}` : '',
target = e.sourceAttribute.replace('_toggle', '');
setAttrs({ [target]: update }, { silent: true });
});
on(listItems.map(s => `change:repeating_${s}s:explode_damage_toggle`).join(' '), (e) => {
let update = e.newValue == 'on' ? '!' : ' ',
target = e.sourceAttribute.replace('_toggle', '');
setAttrs({ [target]: update }, { silent: true });
});
/* #############################################################################
HELPER BUTTONS
############################################################################# */
on('change:dice_roller_input', (e) => {
let code = TETRA.parseDiceCode(e.newValue);
setAttrs({ ['dice_roller_code']: code }, { silent: true });
});
/* #############################################################################
SETTINGS
############################################################################# */
on('change:toggle_global_rof', (e) => {
let update = e.newValue == 'on' ? '?{@{query_rate_of_fire}|1}' : '1';
setAttrs({ ['query_global_rof']: update }, { silent: true });
});
on('change:toggle_global_wd', (e) => {
let update = e.newValue == 'on' ? '?{@{query_wild_die}|d8|d4|d6|d10|d12|@{none},-10000-d20}' : '-10000-d20';
setAttrs({ ['query_global_wd']: update }, { silent: true });
});
on('change:toggle_global_bonus_wd', (e) => {
let update = e.newValue == 'on' ? '?{@{query_bonus_wild_die}|d4|d6|d8|d10|d12|@{none},-10000-d20}' : '-10000-d20';
setAttrs({ ['query_global_bonus_wd']: update }, { silent: true });
});
on('change:toggle_run_wounds', (e) => {
let update = e.newValue == 'on' ? '0' : '@{wound_mod}';
setAttrs({ ['run_wounds']: update }, { silent: true });
});
on('change:toggle_run_fatigue', (e) => {
let update = e.newValue == 'on' ? '@{fatigue_mod}' : '0';
setAttrs({ ['run_fatigue']: update }, { silent: true });
});
on('change:toggle_run_explode', (e) => {
let update = e.newValue == 'on' ? '@{run_roll}!' : '@{run_roll}';
setAttrs({ ['run_code']: update }, { silent: true });
});
@@ -0,0 +1,50 @@
@import url('https://fonts.googleapis.com/css?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;0,900;1,300;1,400;1,500;1,700;1,900&display=swap');
// Base
@import 'variables';
@import 'reset';
@import 'general';
@import 'hexagons';
@import 'color_cycle';
@import 'repeating';
@import 'hexfields';
@import 'tabs';
// Blocks
@import 'meta';
@import 'buttons';
@import 'attributes';
@import 'silhouette';
@import 'secondary';
@import 'armor';
@import 'skills';
@import 'advancements';
@import 'notebook';
@import 'settings';
@import 'features';
@import 'health';
@import 'power';
@import 'weapons';
@import 'apparel';
@import 'integrity';
@import 'abilities';
@import 'augmentations';
@import 'engrams';
@import 'powers';
@import 'vehicles';
@import 'powerarmor';
@import 'walkers';
@import 'allies';
@import 'quick_notes';
@import 'encumbrance';
@import 'inventory';
@import 'ammunition';
@import 'simple_trait';
@import 'extra_sheet';
@import 'rolltemplates';
// Arrangements
@import 'sections';
// Overrides
@import 'translation_overrides';
@@ -0,0 +1,27 @@
.sheet-abilities {
.sheet-repitem__size-radio {
&[value="6"]:checked ~ textarea {
height: 20px;
}
&[value="1"]:checked ~ textarea {
height: 36px;
}
&[value="2"]:checked ~ textarea {
height: 52px;
}
&[value="3"]:checked ~ textarea {
height: 68px;
}
&[value="4"]:checked ~ textarea {
height: 84px;
}
&[value="5"]:checked ~ textarea {
height: 100px;
}
}
}
@@ -0,0 +1,36 @@
.sheet-advancements {
color: $c-text-light;
font-size: $fs-s;
line-height: 16px;
padding: 8px 0 0 64px;
&__item {
display: flex;
background-color: $c-white;
border-bottom: 1px dotted $c-outline;
height: 16px;
width: 100%;
&:not(:last-child) {
margin-bottom: 8px;
}
}
&__rank {
font-weight: 700;
text-align: center;
margin-right: 8px;
width: 8px;
}
input[type=text] {
flex-grow: 1;
color: $c-text-light;
font-size: $fs-s;
line-height: 16px;
&::placeholder {
font-size: $fs-s;
}
}
}
@@ -0,0 +1,111 @@
.sheet-allies {
&__pace,
&__parry,
&__toughness,
&__size,
&__exp,
&__level {
width: 45px;
}
.sheet-header__labels {
padding-right: 30px;
}
.sheet-repitem__secondary {
align-items: flex-start;
justify-content: space-between;
height: auto;
.sheet-left {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
flex-shrink: 0;
padding: 5px 0 6px;
width: 44px;
button[type=roll],
.sheet-allies__health-field input[type=text] {
font-weight: 700;
border-radius: 2px;
height: 20px;
width: 20px;
}
button[type=roll] {
display: flex;
align-items: center;
justify-content: center;
color: $c-text-lightest;
font-size: $fs-s;
line-height: 1;
border: 1px dotted $c-outline;
margin-bottom: 4px !important;
&:hover {
background-color: $c-background-dark;
border-color: $c-background-dark;
span {
color: $c-white !important;
}
}
}
.sheet-allies__health-field {
position: relative;
&::before {
position: absolute;
top: 0;
left: 0;
display: block;
background-color: $c-background-hover;
color: $c-white;
font-family: Pictos;
font-size: 14px;
font-weight: 900;
line-height: 22px;
text-align: center;
border-radius: 2px;
height: 100%;
width: 100%;
}
&--wounds::before {
content: 'k';
}
&--fatigue::before {
content: 'Y';
}
input[type=text] {
position: relative;
z-index: 1;
color: $c-text-light;
font-size: 14px;
line-height: 20px;
text-align: center;
}
}
}
.sheet-right {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 5px 0 0 8px;
input[type=text].sheet-allies__note-field {
text-align: left;
padding: 0 2px;
margin-bottom: 4px;
border-bottom: 1px dotted $c-outline;
height: 20px;
width: 76px !important;
}
}
}
}
@@ -0,0 +1,149 @@
.sheet-ammunition {
position: relative;
margin-bottom: 16px;
width: 266px;
&__content {
display: flex;
padding: 6px 0 14px;
}
&__container {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background-color: $c-item;
border-radius: 2px;
height: 34px;
width: 40px;
&--1,
&--2 {
margin-right: 6px;
}
span {
position: absolute;
left: 0;
z-index: 0;
display: block;
background-color: $c-text-gray;
color: $c-white;
font-size: $fs-xs;
font-weight: 500;
line-height: 13px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
height: 12px;
width: 100%;
}
span:first-of-type {
top: 0;
border-radius: 2px 2px 0 0;
}
span:last-of-type {
bottom: -10px;
letter-spacing: -0.4px;
text-transform: uppercase;
padding: 0 2px;
border-radius: 0 0 2px 2px;
}
input[type=radio] {
position: absolute;
top: 0;
left: 0;
z-index: 1;
height: 100%;
width: 100%;
&::after {
content: '';
position: absolute;
bottom: -10px;
left: 0;
z-index: 1;
height: 10px;
width: 100%;
}
&:checked ~ span {
background-color: $c-background-dark;
}
&::before {
content: '';
border: 2px solid $c-text-gray;
border-width: 2px 2px 0;
border-radius: 2px;
height: 100%;
width: 100%;
}
&:checked::before {
border-color: $c-background-dark;
}
&:checked ~ input[type=text] {
color: $c-text-lighter;
}
}
input[type=text] {
position: relative;
z-index: 2;
color: $c-text-gray;
font-size: 14px;
font-weight: 700;
line-height: 1;
margin-top: 9px;
height: 14px;
width: 36px;
}
}
&__buttons {
flex-grow: 1;
> div {
display: flex;
justify-content: space-between;
&:first-child {
margin-bottom: 4px;
}
}
button[type=action] {
flex-shrink: 0;
align-items: center;
justify-content: center;
background-color: $c-item;
color: $c-text-lightest;
border: 1px dotted $c-outline;
border-radius: 2px;
padding: 0 4px;
height: 20px;
&:hover {
background-color: $c-background-dark;
color: $c-white !important;
border: 1px solid $c-background-dark;
}
&:not(:last-child) {
margin-right: 4px;
}
&:last-child {
flex-grow: 1;
max-width: 21px;
}
}
}
}
@@ -0,0 +1,15 @@
.sheet-apparel {
&__armor {
width: 40px;
margin-right: 8px;
}
&__tags {
text-align: left;
width: 210px;
}
&__weight {
width: 30px;
}
}
@@ -0,0 +1,98 @@
.sheet-armor {
z-index: 1;
display: flex;
flex-direction: column;
align-items: flex-end;
padding-right: 48px;
> .sheet-hexfield {
&:not(:last-child) {
margin-bottom: 36px;
}
&--armor-head,
&--armor-legs {
margin-right: 16px;
}
.sheet-hexfield__label--left {
background-color: $c-white;
padding-left: 4px;
}
textarea {
position: absolute;
top: 8px;
left: 36px;
color: $c-text-lighter;
font-size: 9px !important;
line-height: 1.6;
padding-top: 4px;
height: 60px;
width: 80px;
&::placeholder {
color: #f0f0f0;
font-size: 22px;
font-weight: 700;
line-height: 0.6;
}
}
}
&__decoration,
&__pointer {
position: absolute;
background: {
repeat: no-repeat;
size: contain;
}
opacity: .12;
}
&__decoration {
background: {
image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/decoration_line.png');
}
top: 15px;
left: -60px;
height: 322px;
width: 95px;
}
&__pointer {
transform: translateX(-100%);
&--head {
top: 17px;
left: -28px;
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/head_line.png');
height: 2px;
width: 122px;
}
&--torso {
top: -11px;
left: -33px;
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/torso_line.png');
height: 30px;
width: 131px;
}
&--arms {
top: -44px;
left: -30px;
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/arms_line.png');
height: 63px;
width: 97px;
}
&--legs {
top: -23px;
left: -27px;
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/legs_line.png');
height: 42px;
width: 98px;
}
}
}
@@ -0,0 +1,50 @@
.sheet-attribute {
position: relative;
font-size: 14px;
height: 48px;
width: 48px;
&__button {
position: absolute;
top: 50%;
left: 0;
color: $c-text-light;
font-size: 14px;
font-weight: 700;
transform: translate(-100%, -50%);
}
&:not(:hover) .sheet-hexfield--mod {
input:not(:focus) + .sheet-hexfield__label {
opacity: 0;
}
}
.sheet-hexfield {
position: absolute;
top: 37px;
&--nat {
left: 27px;
}
&--mod {
top: 9px;
left: 43px;
.sheet-hexfield__label {
color: $c-text-lightest;
}
.sheet-hexfield__input:not(:placeholder-shown) {
~ .sheet-hexfield__label {
color: $c-text-light;
}
}
}
&--wd {
left: 59px;
}
}
}
@@ -0,0 +1,66 @@
.sheet-toggle--strain {
&:checked ~ .sheet-augmentations {
.sheet-augmentations {
&__power,
&__slots {
display: none;
}
}
.sheet-a {
display: none;
}
.sheet-b {
display: inline;
}
}
}
.sheet-toggle-augmentation-markers:not(:checked) {
~ .sheet-augmentations .sheet-color-cycle {
display: none;
}
}
.sheet-augmentations {
.sheet-header__labels span {
text-transform: uppercase;
}
&__grade {
width: 60px;
}
&__power,
&__slots,
&__loss {
width: 40px;
}
.sheet-b {
display: none;
}
.sheet-color-cycle {
&__radio {
padding: 3px;
border: 1px solid transparent;
&--none {
border-color: $c-outline;
}
}
}
&__multiplier {
text-align: left;
width: 18px;
}
input.sheet-toggle:not(:checked) {
~ .sheet-augmentations__multiplier {
display: none;
}
}
}
@@ -0,0 +1,84 @@
.sheet-buttons {
display: flex;
flex-wrap: wrap;
margin-right: -4px;
width: 274px;
&::after {
content: '';
display: block;
flex-grow: 1000000;
}
> div,
> label {
margin: 0 4px;
}
> div {
position: relative;
z-index: 1;
display: flex;
flex-grow: 1;
white-space: nowrap;
border-radius: 2px;
margin-bottom: 8px;
height: 16px;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
z-index: -1;
display: block;
background-color: $c-item;
border: 1px dotted $c-outline;
border-radius: 2px;
width: 100%;
height: 100%;
}
}
button {
flex-shrink: 0;
flex-grow: 1;
justify-content: center;
color: $c-text-lightest;
font-size: $fs-s;
font-weight: 500;
line-height: 16px;
padding: 0 4px !important;
height: 16px;
&:hover {
background-color: $c-background-dark;
> span {
color: $c-white !important;
}
}
}
.sheet-dice-roller {
input[type=text].sheet-dice-roller__input {
flex-grow: 100;
width: auto;
&::placeholder {
font-size: $fs-s;
}
}
}
.sheet-label-toggle {
margin-bottom: 8px;
span {
font-size: $fs-s;
line-height: 16px;
height: 16px;
}
}
}
@@ -0,0 +1,69 @@
.sheet-color-cycle {
position: relative;
height: 16px;
width: 16px;
&__radio {
position: absolute;
top: 50%;
left: 50%;
z-index: 1;
background-color: transparent;
padding: 4px;
border-radius: 50%;
opacity: 0;
transform: translate(-50%, -50%);
&:checked {
opacity: 1;
& + input {
z-index: 3;
}
}
&--none,
&--novice {
z-index: 2;
&:checked {
background-color: transparent;
border-color: transparent;
}
}
&--red:checked {
background-color: $c-red;
border-color: $c-red;
}
&--yellow:checked {
background-color: $c-yellow;
border-color: $c-yellow;
}
&--blue:checked {
background-color: $c-blue;
border-color: $c-blue;
}
&--green:checked {
background-color: $c-green;
border-color: $c-green;
}
&--purple:checked {
background-color: $c-purple;
border-color: $c-purple;
}
&--gray:checked {
background-color: $c-gray;
border-color: $c-gray;
}
&:last-child:checked {
z-index: 1;
}
}
}
@@ -0,0 +1,78 @@
.sheet-encumbrance {
display: flex;
text-align: center;
margin: 16px 0 24px;
width: 266px;
.sheet-label {
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
height: 16px;
}
&__container {
&:not(:last-child) {
margin-right: 8px;
.sheet-encumbrance__content {
width: 48px;
}
}
&--summary {
flex-grow: 1;
}
}
&__content {
display: flex;
justify-content: center;
align-items: center;
background-color: $c-white;
font-size: $fs-l;
border-radius: 2px;
height: 32px;
overflow: hidden;
box-shadow: $shadow;
span {
user-select: none;
}
input[type=text] {
border-radius: 2px;
&:hover {
background-color: $c-background-hover;
}
&:focus {
background-color: $c-item;
font-size: 16px !important;
font-weight: 700;
height: 100%;
width: 100%;
~ * {
display: none;
}
}
}
&--summary {
flex-direction: row-reverse;
> div {
padding: 0 4px;
}
input[type=text],
span {
font-size: $fs-l;
width: 32px;
}
}
}
}
@@ -0,0 +1,12 @@
.sheet-engrams {
&__penalty {
width: 40px;
padding-right: 8px;
}
&__description {
flex-shrink: 0;
text-align: left;
width: 280px;
}
}
@@ -0,0 +1,245 @@
.sheet-extra {
width: 100%;
.sheet-buttons {
padding-bottom: 1px;
width: 100%;
> div {
margin-right: 8px;
}
}
.sheet-block {
margin-top: 16px;
}
.sheet-simple-trait {
&:not(:last-child) {
margin-right: 8px;
}
}
&-meta {
display: flex;
margin-bottom: 19px;
.sheet-meta-field:first-child {
flex-grow: 1;
}
.sheet-meta-field input[type=text].sheet-meta-field__input--name {
width: 100%;
}
}
.sheet-features {
margin-top: 16px;
}
.repcontainer {
&:empty ~ .repcontrol .repcontrol_add::before {
width: 474px;
}
}
.sheet-footer {
opacity: 0;
}
.sheet-quick-notes {
width: 100%;
&__content {
padding-bottom: 0;
}
}
}
.sheet-extra-attributes {
position: relative;
.sheet-container {
display: flex;
padding-top: 8px;
}
}
.sheet-extra-skills {
position: relative;
.sheet-container {
display: flex;
flex-wrap: wrap;
padding-top: 8px;
&::after {
content: '';
display: block;
flex-grow: 1000000;
}
}
&__selection-toggle {
&::after {
position: absolute;
top: 2px;
right: 20px;
display: block;
font-family: Pictos;
font-size: 10px;
line-height: 14px;
}
&:hover::after {
color: $c-text-light !important;
}
&:checked {
~ .sheet-container .sheet-simple-trait {
display: none;
}
~ .sheet-container {
justify-content: space-between;
}
&::after {
content: '3';
color: $c-text-light;
}
}
&:not(:checked) {
~ .sheet-container .sheet-extra-skills__toggle-label {
display: none;
}
&::after {
content: 'W';
color: $c-text-lightest;
}
}
}
&__toggle {
&-label {
flex-shrink: 0;
width: auto;
}
// Outer checkbox
&:not(:checked) + .sheet-simple-trait {
display: none;
}
// Inner checkbox
+ span {
user-select: none;
display: block;
color: $c-text-lightest;
font-size: 11px;
font-weight: 500;
line-height: 24px;
text-transform: capitalize;
white-space: nowrap;
padding: 0 4px;
}
&:hover + span {
color: $c-text-lighter;
}
&:checked + span {
color: $c-text;
}
}
}
.sheet-extra-secondary {
.sheet-container {
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 8px;
}
&__field {
flex-grow: 1;
width: auto;
&:not(:last-child) {
margin-right: 8px;
}
.sheet-label {
color: $c-text-lightest;
font-weight: 500;
line-height: 16px;
text-align: center;
text-transform: uppercase;
letter-spacing: -0.1px;
height: 16px;
}
}
input[type=text] {
line-height: 24px;
&::placeholder {
font-size: $fs-s;
line-height: 24px;
}
}
input[type=text].sheet-extra-secondary__input,
&__field > span {
display: block;
background-color: $c-white;
font-weight: 500;
text-align: center;
border: 1px solid $c-outline;
border-radius: 2px;
height: 24px;
width: 100%;
}
.sheet-simple-trait__expand {
border-color: $c-outline;
}
.sheet-divider {
border-right: 1px dotted $c-outline;
margin: 0 10px 0 2px;
height: 24px;
}
}
.sheet-extra-settings {
display: flex;
padding: 8px 0;
margin-top: 15px !important;
border-top: 1px dotted $c-outline;
&__item {
user-select: none;
line-height: 16px;
width: auto;
&:not(:last-child) {
margin-right: 8px;
}
span {
color: $c-text-gray;
font-size: $fs-s;
font-weight: 500;
}
}
input[type=checkbox]:checked {
~ span {
color: $c-text-lighter;
}
}
}
@@ -0,0 +1,164 @@
.sheet-features {
position: relative;
flex-grow: 1;
fieldset,
.repcontainer {
display: flex;
flex-wrap: wrap;
padding: 4px 0;
margin: 0 -4px;
&::after {
content: '';
display: block;
flex-grow: 1000000;
}
> * {
opacity: .6;
transition-delay: .4s;
transition: opacity .3s ease-in-out;
}
&:hover > * {
opacity: 1;
}
}
.repitem {
flex-grow: 1;
margin-top: 0;
}
.sheet-repitem {
position: relative;
display: flex;
padding-right: 6px;
margin: 4px;
width: auto;
}
.sheet-color-cycle__radio {
top: 1px;
left: 1px;
align-items: center;
padding: 0;
height: 14px;
width: 14px;
opacity: 1;
transform: none;
&::after {
display: flex;
align-items: center;
justify-content: center;
font-size: $fs-s;
font-weight: 700;
line-height: 1;
height: 100%;
width: 100%;
border-radius: 2px 0 0 2px;
}
&--novice:checked::after {
content: 'N';
background-color: rgba(0, 0, 0, .05);
color: $c-text-light;
}
&--seasoned:checked::after {
content: 'S';
background-color: $c-green;
color: $c-white;
}
&--veteran:checked::after {
content: 'V';
background-color: $c-blue;
color: $c-white;
}
&--heroic:checked::after {
content: 'H';
background-color: $c-purple;
color: $c-white;
}
&--legendary:checked::after {
content: 'L';
background-color: $c-yellow;
color: $c-white;
}
&--augmentation:checked::after {
content: 'A';
background-color: $c-background-dark;
color: $c-white;
}
&--dot:checked::after {
content: '';
background-color: $c-text-light;
border: 4px solid $c-item;
border-radius: 50%;
height: 14px;
width: 14px;
}
&--hindrance:checked::after {
content: '*';
background-color: $c-dark-red;
color: $c-white;
font-family: Pictos;
}
&--disabled:checked {
&::after {
content: 'e';
font-size: $fs-l;
font-family: Pictos;
}
~ *,
&::after {
color: $c-text-lightest;
text-shadow: 0 0 3px $c-white, 0 0 3px $c-white, 0 0 3px $c-white, 0 0 3px $c-white;
}
~ .sheet-features__inner-background {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 0;
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/unskilled_bg.png') repeat;
}
}
}
input[type=text].sheet-features__name {
z-index: 1;
line-height: 16px;
margin-left: 20px;
}
$sizes: 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96,
100, 104, 108, 112,116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
156, 160, 164, 168, 172, 176, 180;
@each $s in $sizes {
input[value="#{$s}"] + input {
width: #{$s}px;
}
}
.repcontainer.editmode {
.itemcontrol {
margin: 4px;
width: calc(100% - 8px) !important;
max-height: 16px;
}
}
}
@@ -0,0 +1,8 @@
.sheet-footer-section {
margin-top: 23px;
.sheet-right {
width: 330px;
padding-left: 64px;
}
}
@@ -0,0 +1,688 @@
// #############################################################################
// BASIC SETUP
// #############################################################################
*,
::before,
::after {
box-sizing: border-box;
}
p {
font-family: inherit;
font-size: inherit;
line-height: inherit;
margin: 0 0 8px 0;
}
ul {
list-style: none;
padding: 0;
margin: 0;
li b:first-child {
display: inline-block;
padding-right: 8px;
min-width: 96px;
}
}
textarea,
select,
button,
fieldset,
input,
option,
label {
display: flex;
background-color: transparent;
background-image: none;
font-family: inherit;
font-weight: 400;
text-decoration: none;
padding: 0;
margin: 0;
border: 0;
border-radius: 0;
outline: 0 !important;
min-width: 0;
box-shadow: none;
appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
&::placeholder {
color: $c-text-gray;
}
}
button,
label,
input[type=checkbox],
input[type=radio] {
cursor: pointer;
}
button,
button > span {
&:hover,
&:hover > span {
color: $c-text-hover !important;
}
}
button[type=action] {
color: $c-text-light;
font-size: $fs-s;
font-weight: 500;
line-height: 1;
}
input[type=text]:not(.sheet-hex) {
background-color: transparent;
color: $c-text;
font-size: $fs-s;
line-height: 20px;
text-overflow: ellipsis;
&::placeholder {
font-size: $fs-xs;
line-height: 20px;
}
&:not(.sheet-align-left) {
text-align: center;
}
}
input[type=hidden] {
display: none;
}
textarea {
color: $c-text-light;
font-size: 9px;
line-height: 1.6;
width: 100%;
resize: none;
}
input[type=checkbox].sheet-checkbox {
background-color: $c-white;
border: 1px solid $c-text-lighter;
border-radius: 2px;
height: 10px;
width: 10px;
&::before {
content: '';
display: block;
border-radius: 1px;
margin: 1px 0 0 1px;
height: 6px;
width: 6px;
}
&:checked::before {
background-color: $c-text-lighter;
}
}
.sheet-wrapper {
text-align: center;
}
.sheet-body {
color: $c-text;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: $fs-s;
line-height: 1;
text-align: left;
background: {
image: linear-gradient(to right, #fbfbfb 1px, transparent 1px),
linear-gradient(to bottom, #fbfbfb 1px, transparent 1px);
size: 8px 8px;
position: -1px -1px;
}
padding-top: 8px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
> div {
margin: 0 auto;
}
~ rolltemplate {
display: none;
}
}
.sheet-variant-radio {
display: inline-block;
&::after {
content: '';
display: inline-block;
padding: 3px;
border: 1px solid $c-outline;
border-radius: 50%;
}
&:checked::after {
background-color: $c-outline;
}
&--wildcard:checked ~ .sheet-body {
width: 800px;
.sheet-extra {
display: none;
}
}
&--extra:checked ~ .sheet-body {
width: 474px;
.sheet-wildcard {
display: none;
}
}
}
.sheet-wildcard {
.sheet-section {
display: flex;
justify-content: space-between;
> .sheet-left {
display: flex;
flex-direction: column;
flex-shrink: 0;
width: 470px;
}
> .sheet-right {
flex-grow: 1;
}
}
}
// #############################################################################
// GENERICS & COMMON
// #############################################################################
.sheet-hidden {
display: none;
}
.sheet-block {
position: relative;
margin-top: 40px;
}
.sheet-header {
display: flex;
justify-content: space-between;
padding-bottom: 4px;
border-bottom: 1px dotted $c-outline;
height: 16px;
&__title {
display: block;
flex-grow: 1;
color: $c-text-light;
font-size: $fs-l;
font-weight: 700;
text-transform: uppercase;
}
&__labels {
display: flex;
align-items: flex-end;
line-height: .5;
text-align: center;
text-transform: uppercase;
padding-right: 16px;
> span {
display: block;
}
}
}
.sheet-label,
.sheet-header__labels * {
color: $c-text-lightest;
font-size: $fs-xs;
}
.sheet-large-label {
color: $c-text-light;
font-size: $fs-l;
font-weight: 700;
text-transform: uppercase;
}
.sheet-footer {
color: $c-text-light;
line-height: 16px;
height: 16px;
}
.sheet-toggle {
&:not(:checked):not(.sheet-toggle--special) + *,
&:not(:checked):not(.sheet-toggle--special) ~ .repcontainer,
&:not(:checked):not(.sheet-toggle--special) ~ .repcontrol {
display: none;
}
&::after {
display: flex;
align-items: center;
justify-content: center;
color: $c-text-lighter;
line-height: 1;
width: 16px;
}
&:checked::after {
color: $c-text-light;
}
&--block {
display: none;
}
&--visibility {
position: absolute;
top: 4px;
right: 0;
&::after {
content: '`';
color: $c-text-gray;
font-size: $fs-s;
font-family: Pictos;
height: 10px;
}
&:checked::after {
color: $c-text-gray;
}
&:checked::after {
content: 'J';
}
}
&--arrow {
position: absolute;
right: 0;
top: 0;
&::after {
content: '';
font-size: $fs-xs;
line-height: 20px;
height: 20px;
width: 20px;
transform-origin: 9px 10px;
transition: transform .3s ease-in-out;
}
&:checked::after {
transform: rotate(90deg);
}
}
&--settings,
&--note-box,
&--loss {
&::after {
color: $c-text-lightest;
font-family: Pictos;
font-size: $fs-s;
padding-top: 1px;
width: 10px;
}
}
&--settings {
&::after {
content: 'y';
}
}
&--note-box {
&::after {
content: 'n';
}
}
&--loss {
&::after {
content: 'Q';
}
}
&--weight {
&::after {
content: 'V';
color: $c-text-lightest;
font-family: Pictos;
font-size: $fs-l;
padding-top: 1px;
width: 10px;
transform: rotateZ(-90deg) scaleX(0.75);
}
}
&--spoiler {
&::after {
content: '&';
color: $c-text-light;
font-family: Pictos;
font-size: 10px;
height: 100%;
}
&:checked::after {
content: '_';
}
}
&--list-roll {
&:not(:checked) ~ .sheet-repitem__skill-roll {
display: none;
}
}
}
.sheet-radio-track {
position: relative;
flex-shrink: 0;
background-color: $c-white;
box-shadow: $shadow;
&::before {
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
color: $c-white;
font-size: 9px;
height: 100%;
width: 100%;
}
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
border-radius: inherit;
height: 0;
width: 0;
transform: translate(-50%, -50%);
transition: height .3s ease-in-out,
width .3s ease-in-out,
background-color .1s ease-in-out;
}
&:hover::after,
&:hover ~ .sheet-radio-track:not(:checked)::after {
background-color: $c-background-hover;
height: 60%;
width: 60%;
}
&:checked {
&::after,
~ .sheet-radio-track:not(:checked)::after {
background-color: $c-background-dark;
height: 100%;
width: 100%;
transition-duration: .1s;
}
}
}
.sheet-tooltip {
pointer-events: none;
position: absolute;
display: flex;
align-items: center;
background-color: $c-background-tooltip;
color: $c-white;
font-size: $fs-s;
line-height: 1;
padding: 2px 6px;
border-radius: 2px;
opacity: 0;
transition: opacity .3s ease-in-out;
span:not(:last-child) {
margin-right: 2px;
}
// Arrow
&::after {
content: '';
position: absolute;
height: 10px;
width: 10px;
}
&--left {
top: 50%;
left: -6px;
transform: translate(-100%, -50%);
&::after {
top: 50%;
right: -8px;
border: 5px solid transparent;
border-left-color: $c-background-tooltip;
transform: translateY(-50%);
}
}
&--top {
top: -6px;
left: 50%;
transform: translate(-50%, -100%);
&::after {
bottom: -8px;
left: 50%;
border: 5px solid transparent;
border-top-color: $c-background-tooltip;
transform: translateX(-50%);
}
}
}
.sheet-damage-roll-toggle {
&-label {
display: block;
line-height: 4px;
text-align: center;
padding-right: 10px;
input[type=checkbox]:checked ~ span {
color: $c-text-light;
font-weight: 500;
}
.sheet-icon {
display: inline-block;
font-family: Pictos;
font-size: $fs-s;
margin-right: 4px;
}
}
~ .repcontainer .sheet-damage-button-overlay {
position: relative;
button[type=roll] {
position: absolute;
top: 0;
left: 0;
z-index: -1;
display: block;
height: 100%;
width: 100%;
}
}
&:checked ~ .repcontainer .sheet-damage-button-overlay {
button[type=roll] {
z-index: 1;
}
input[type=text] {
position: relative;
z-index: 0;
font-weight: 500;
&:placeholder-shown {
z-index: 2; // Keeps empty input above button
}
}
}
}
.sheet-label-toggle {
user-select: none;
flex-shrink: 0;
width: auto;
input[type=text].sheet-label-toggle__input {
background-color: $c-white;
color: $c-text-light;
line-height: 14px;
border: 1px solid $c-background-dark;
border-width: 1px;
border-radius: 0 2px 2px 0;
padding: 0 4px;
margin-left: -2px;
height: 14px;
width: 96px;
&:first-child {
border-left-width: 2px;
}
&--tiny {
width: 32px;
}
&::placeholder{
line-height: 12px;
}
}
span {
display: block;
flex-shrink: 0;
background-color: $c-background-dark;
color: $c-white;
font-size: $fs-xs;
font-weight: 500;
line-height: 15px;
border-radius: 2px;
padding: 0 4px;
height: 14px;
}
&--full-row {
flex-basis: 100%;
input[type=text].sheet-label-toggle__input {
text-align: left;
width: 100%;
}
}
input[type=checkbox] {
display: none;
&:not(:checked) {
+ span {
background-color: $c-text-gray;
}
~ input[type=text].sheet-label-toggle__input {
color: $c-text-lightest;
border-color: $c-text-gray;
}
}
}
}
// #############################################################################
// SETTING TOGGLES
// #############################################################################
.sheet-toggle-roboto:checked ~ .sheet-body {
font-family: $f-roboto;
}
.sheet-toggle-dark-labels:checked ~ .sheet-body {
.sheet-header__labels *,
.sheet-label,
.sheet-hexfield__label {
color: $c-text-light !important;
}
}
.sheet-toggle-skill-die-numbers:not(:checked) ~ .sheet-body {
.sheet-radio-track::before {
display: none;
}
}
.sheet-toggle-corners:not(:checked) ~ .sheet-body {
:not(.sheet-icon):not(.sheet-color-cycle__radio) {
border-radius: 0 !important;
&::before,
&::after {
border-radius: 0 !important;
}
}
}
.sheet-toggle-transitions:not(:checked) ~ .sheet-body {
*,
::before,
::after {
transition-duration: 0s !important;
}
}
.sheet-toggle-delays:not(:checked) ~ .sheet-body {
*,
::before,
::after {
transition-delay: 0s !important;
}
}
.sheet-toggle-grid:not(:checked) ~ .sheet-body {
background: none;
}
.sheet-toggle-description-input:not(:checked) ~ .repcontainer {
.sheet-roll-description {
display: none;
}
}
.sheet-toggle-injection-input:not(:checked) ~ .repcontainer {
.sheet-roll-injection {
display: none;
}
}
@@ -0,0 +1,9 @@
.sheet-header-section {
padding-top: 8px;
.sheet-left {
position: relative;
display: flex;
flex-grow: 1;
}
}
@@ -0,0 +1,284 @@
$box-size: 24px;
$box-margin: 8px;
.sheet-health {
position: relative;
display: flex;
align-items: flex-end;
> .sheet-hex {
order: 2;
}
.sheet-header__title {
margin-top: 8px;
}
&:hover {
.sheet-health__icons * {
opacity: 1;
}
}
&__icons {
display: flex;
.sheet-icon {
color: $c-text-lightest;
font-size: $fs-s;
line-height: 1;
opacity: 0;
transition: opacity .3s ease-in-out;
transition-delay: .4s;
&:checked {
color: $c-white;
opacity: 1;
&::after {
background-color: $c-background-dark;
border: 1px solid $c-background-dark;
}
}
&:not(:last-child) {
margin-right: 8px;
}
&::after {
display: flex;
align-items: center;
justify-content: center;
background-color: $c-white;
font-family: Pictos;
border: 1px dotted $c-outline;
border-radius: 50%;
margin: 2px 2px 6px;
height: 20px;
width: 20px;
}
&--shield::after {
content: 'b';
}
&--bug::after {
content: 'i';
}
&--fire::after {
content: 'r';
font-family: 'Pictos Custom';
}
&--hit::after {
content: 't';
font-family: 'Pictos Custom';
}
&--lightning::after {
content: 'e';
}
&--cancel::after {
content: 'd';
}
&--rad::after {
content: 'l';
}
&--tools::after {
content: 'x';
}
&--ecg::after {
content: 'Y';
}
}
}
&__track {
position: relative;
display: flex;
.sheet-radio-track,
.sheet-reset-button {
border-radius: 2px;
margin-right: $box-margin;
height: $box-size;
width: $box-size;
}
&:hover .sheet-reset-button:not(:checked),
&:hover .sheet-radio-track-toggle {
opacity: 1;
transition-delay: .4s;
}
.sheet-reset-button {
position: absolute;
z-index: 2;
opacity: 0;
transition: opacity .3s ease-in-out;
&::after {
content: '*';
display: flex;
align-items: center;
justify-content: center;
background-color: $c-background-dark;
color: $c-white;
font-family: Pictos;
line-height: 1;
border-radius: 2px;
height: 100%;
width: 100%;
}
&:checked {
display: none;
}
}
.sheet-radio-track-toggle {
position: absolute;
top: 24px;
z-index: 2;
height: 16px;
width: $box-size;
opacity: 0;
transition: opacity .3s ease-in-out;
&::before,
&::after {
content: '';
background-color: rgba(0, 0, 0, .1);
height: 4px;
width: 50%;
}
&::after {
background-color: rgba(0, 0, 0, .05);
}
&:checked {
flex-direction: row-reverse;
}
&:checked + input {
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/unskilled_bg.png') repeat;
&::before,
&::after {
display: none;
}
}
}
}
&__wounds {
order: 1;
.sheet-health__track {
flex-direction: row-reverse;
justify-content: flex-end;
}
.sheet-radio-track--6 {
margin-right: 0;
}
.sheet-radio-track-toggle {
&--6 {
left: 5 * ($box-size + $box-margin);
}
&--5 {
left: 4 * ($box-size + $box-margin);
}
&--4 {
left: 3 * ($box-size + $box-margin);
}
&--3 {
left: 2 * ($box-size + $box-margin);
}
&--2 {
left: $box-size + $box-margin;
}
}
}
&__center {
order: 3;
position: absolute;
left: 185px;
.sheet-hexfield {
position: absolute;
bottom: 8px;
transform: translateY(100%);
&--wound-mitigation {
left: 1px;
}
&--rads {
left: 33px;
}
}
}
.sheet-hex--64 {
margin: 0 4px;
&::after {
content: '';
display: flex;
align-items: center;
justify-content: center;
background: {
image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/skull.png');
repeat: no-repeat;
size: 32px;
position: center;
}
height: 100%;
width: 100%;
opacity: .15;
}
&:checked::after {
opacity: .5;
}
}
&__fatigue {
order: 4;
display: flex;
flex-direction: column;
align-items: flex-end;
.sheet-reset-button {
right: 0;
margin: 0;
}
.sheet-radio-track--1 {
margin-right: 0;
}
.sheet-radio-track-toggle {
&--3 {
right: 2 * ($box-size + $box-margin);
}
&--2 {
right: $box-size + $box-margin;
}
}
}
}
@@ -0,0 +1,50 @@
.sheet-hex {
position: relative;
display: block; // For attribute spans
background: {
repeat: no-repeat;
position: center;
}
color: $c-text-light;
font-weight: 700;
text-align: center;
padding: 0 6px;
filter: drop-shadow(rgba(0, 0, 0, 0.5) 0px 0px 0.7px);
&::placeholder {
color: $c-text-gray;
font-size: inherit;
font-weight: inherit;
line-height: inherit;
}
&--36 {
background: {
image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/hexagon_36.svg');
}
font-size: $fs-l;
line-height: 36px;
height: 36px !important; // Overwrite Roll20!
width: 36px;
}
&--48 {
background: {
image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/hexagon_48.svg');
}
font-size: 16px !important;
line-height: 48px;
height: 48px !important; // Overwrite Roll20!
width: 48px;
}
&--64 {
background: {
image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/hexagon_64.svg');
}
font-size: 18px !important; // Overwrite Roll20!
line-height: 64px;
height: 64px !important; // Overwrite Roll20!
width: 64px;
}
}
@@ -0,0 +1,89 @@
div:not(:hover) > .sheet-hide-until-needed,
div.sheet-health:not(:hover) .sheet-health__center .sheet-hexfield {
> div,
> input {
opacity: 0;
}
input:hover,
input:focus {
opacity: 1;
~ div,
~ input {
opacity: 1;
}
}
}
.sheet-hexfield {
position: relative;
white-space: nowrap;
color: $c-text-light;
height: 36px;
width: 36px;
transition: color .3s ease-in-out, opacity .3s ease-in-out;
div,
input {
transition: color .3s ease-in-out, opacity .3s ease-in-out;
transition-delay: .4s;
}
&-gray,
&-gray input {
color: $c-text-lightest;
}
// Nested Hexfields
.sheet-hexfield .sheet-hexfield__label {
color: $c-text-lightest;
}
&.sheet-stay-on-input {
input:not(:placeholder-shown) {
opacity: 1 !important;
~ :not(.sheet-exception) {
color: $c-text-light;
opacity: 1 !important;
}
}
}
&__label {
position: absolute;
top: 10px;
display: flex;
align-items: center;
justify-content: flex-end; // Left
font-size: 9px !important; // Override Roll20!
font-weight: 500;
line-height: 10px !important; // Override Roll20!
text-transform: uppercase;
height: 16px;
transform: translateX(-100%); // Left
&--right {
left: 36px;
justify-content: flex-start;
transform: translateX(0);
}
&--bottom {
top: 38px;
left: 18px;
align-items: flex-start;
justify-content: center;
transform: translateX(-50%);
}
&--up {
top: -18px;
left: 18px;
align-items: flex-end;
justify-content: center;
transform: translateX(-50%);
}
}
}
@@ -0,0 +1,118 @@
.sheet-integrity {
display: flex;
align-items: center;
justify-content: space-between;
&__status {
width: 320px;
}
&__progress {
position: relative;
display: flex;
justify-content: flex-end;
background-color: $c-outline;
border-radius: 2px;
height: 8px;
width: 100%;
overflow: hidden;
&-fill {
background-color: $c-background-dark;
height: 100%;
width: 100%; // Default; will be overwritten!
transition: width .3s ease-in-out;
}
}
@for $i from 0 through 80 {
&__bar-width[value="#{$i}"] {
& ~ .sheet-integrity__progress-fill {
width: #{$i*4}px;
}
}
}
&__marker {
position: absolute;
top: 0;
background-color: $c-white;
width: 2px;
height: 10px;
transform: translateX(-50%);
&--70 {
left: 40px;
}
&--60 {
left: 80px;
}
&--50 {
left: 120px;
}
&--40 {
left: 160px;
}
&--30 {
left: 200px;
}
&--20 {
left: 240px;
}
&--10 {
left: 280px;
}
}
&__loss-effects {
display: flex;
align-items: center;
justify-content: space-between;
font-size: $fs-s;
margin: 8px 0;
height: 16px;
width: 100%;
> span {
display: block;
color: $c-text-gray;
font-weight: 500;
white-space: nowrap;
transition: color .3s ease-in-out;
}
input[type=checkbox]:checked + span {
color: $c-text-light;
}
}
&__hexfields {
display: flex;
align-items: center;
.sheet-container {
position: relative;
}
.sheet-hexfield {
position: absolute;
bottom: -28px;
&--integrity-maximum {
right: -6px;
transform: translateX(-100%);
}
&--integrity-mod {
left: -5px;
transform: translateX(100%);
}
}
}
}
@@ -0,0 +1,26 @@
.sheet-inventory {
position: relative;
width: 266px;
&__amount,
&__weight {
width: 30px;
}
&__multi {
color: $c-text-lightest;
line-height: 11px;
text-align: center;
width: 8px;
}
.sheet-repitem__note-box {
width: 268px;
}
.repcontainer {
&:empty ~ .repcontrol .repcontrol_add::before {
width: 266px;
}
}
}
@@ -0,0 +1,62 @@
.sheet-meta {
width: 472px;
margin-bottom: 44px;
.sheet-container {
display: flex;
&:first-child {
margin-bottom: 4px;
}
}
.sheet-label {
text-transform: uppercase;
margin-top: 4px;
}
.sheet-meta-field {
&:not(:last-child) {
margin-right: 8px;
}
input.sheet-meta-field__input {
color: $c-text-lighter;
font-weight: 500;
line-height: 15px;
text-align: left;
border-bottom: 1px dotted $c-outline;
padding: 0 2px;
height: 16px;
&--name {
width: 136px;
}
&--size,
&--exp,
&--level,
&--age,
&--bennies {
width: 40px;
}
&--height,
&--weight {
width: 64px;
}
&--eyes,
&--hair,
&--rank,
&--origin,
&--gender {
width: 64px;
}
&--bits {
width: 64px;
}
}
}
}
@@ -0,0 +1,8 @@
.sheet-notebook {
padding: 8px 0 0 64px;
textarea {
@include note-grid;
height: 100%;
}
}
@@ -0,0 +1,24 @@
.sheet-power {
position: relative;
margin-right: -8px;
.sheet-header__title {
position: absolute;
top: 50%;
left: 0;
transform: translate(-100%, -50%);
}
.sheet-hexfield {
position: absolute;
bottom: -28px;
&--power-consumed {
left: -2px;
}
&--power-maximum {
left: 30px;
}
}
}
@@ -0,0 +1,17 @@
.sheet-powerarmors {
&__size,
&__armor,
&__pace,
&__mods,
&__weight,
&__weapons {
width: 45px;
}
.sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/powerarmor_01.png');
background-size: contain;
margin-top: 4px;
height: 56px;
}
}
@@ -0,0 +1,42 @@
input.sheet-toggle--pp {
&:checked ~ .sheet-powers {
.sheet-a {
display: none;
}
.sheet-b {
display: inline;
}
}
}
.sheet-powers {
&__ap,
&__pp,
&__penalty {
width: 40px;
}
&__duration {
width: 60px;
}
&__damage,
&__range {
width: 80px;
}
&__trapping {
width: 64px;
}
.sheet-b {
display: none;
}
input.sheet-toggle:not(:checked) {
~ .sheet-powers__trapping {
display: none;
}
}
}
@@ -0,0 +1,19 @@
.sheet-quick-notes {
position: relative;
width: 266px;
&__content {
padding: 8px 0;
}
&__content {
textarea {
@include note-grid;
height: 64px;
}
input[type=checkbox]:checked + textarea {
height: 128px;
}
}
}
@@ -0,0 +1,359 @@
.sheet-wildcard {
button.sheet-repitem__skill-roll--extra {
display: none;
}
}
.sheet-extra {
button.sheet-repitem__skill-roll--wildcard {
display: none;
}
}
fieldset,
.repcontainer {
padding: 6px 0;
min-height: 32px;
}
.repcontainer {
&:empty ~ .repcontrol .repcontrol_add::before {
content: '+ + +';
position: absolute;
top: -27px;
right: -16px;
background-color: $c-background-hover;
color: $c-text-lighter;
font-size: $fs-s;
line-height: 21px;
border-radius: 2px;
height: 20px;
width: 470px;
}
}
.repitem {
&:not(:first-child) {
margin-top: 4px;
}
input[type=text]::placeholder {
line-height: 20px;
}
}
.sheet-repitem {
position: relative;
background-color: $c-item;
border-radius: 2px;
width: 100%;
box-shadow: $shadow;
&:not(:last-child) {
margin-bottom: 4px;
}
button.sheet-repitem__skill-roll {
font-family: Pictos;
color: $c-text-light;
font-size: $fs-s;
height: 16px;
line-height: 15px;
margin-right: 4px !important;
}
&--full-field textarea {
font-size: $fs-s;
line-height: 16px;
padding: 2px 16px 2px 6px;
height: 20px;
}
&__size-radio {
position: absolute;
right: 0;
top: 2px;
z-index: 1;
&--1:not(:checked) {
z-index: 2;
}
&:checked {
z-index: 0;
opacity: 0;
+ input[type=radio] {
z-index: 3;
}
}
&::after {
content: attr(label);
display: block;
color: $c-text-gray;
font-family: Pictos;
font-size: 10px;
line-height: 15px;
text-align: center;
height: 16px;
width: 16px;
}
&:hover::after {
color: $c-text-light;
}
}
&__primary,
&__secondary {
display: flex;
align-items: center;
> input.sheet-stretch {
flex-grow: 1;
width: auto;
}
}
&__primary {
position: relative;
padding: 0 16px 0 6px;
height: 20px;
.sheet-toggle--note-box {
padding-right: 4px;
&::after {
padding-top: 0;
}
}
}
&__secondary {
padding-top: 1px;
height: 16px;
.sheet-toggle:not(:last-of-type) {
margin-right: 4px;
}
input[type=text]::placeholder {
line-height: 16px;
}
}
&__secondary,
&__frame {
color: $c-text-light;
font-size: 9px;
margin: 0 6px;
border-top: 1px dotted $c-outline;
input[type=text] {
color: $c-text-light;
font-size: 9px;
line-height: 16px;
&::placeholder {
font-size: 9px !important;
}
}
}
&__frame {
display: flex;
height: 64px;
&-silhouette {
background: {
repeat: no-repeat;
size: 80%;
position: center;
}
height: 100%;
width: 64px;
opacity: .25;
&-button {
height: 100% !important; // Overwrite Roll20!
width: 100%;
}
}
&-build {
flex-grow: 1;
margin-left: 8px;
height: 100%;
textarea {
padding-top: 6px;
height: 100%;
}
}
}
&__settings {
position: absolute;
bottom: 2px;
right: -1px;
z-index: 3;
background-color: $c-item;
padding: 4px 6px 0;
border: 1px solid #dbdbdb;
border-radius: 0 0 2px 2px;
border-width: 0 1px 1px;
width: calc(100% + 2px);
transform: translateY(100%);
&-content {
display: flex;
flex-wrap: wrap;
align-items: center;
border-top: 1px dotted $c-outline;
padding-top: 4px;
margin-top: -2px;
> label {
margin-bottom: 4px;
}
> :not(:last-child) {
margin-right: 4px;
}
}
}
&__label {
font-weight: 500;
margin: 0 4px 0 6px;
line-height: 16px;
&::after {
content: ':';
}
}
&__note-box {
position: absolute;
top: 4px;
right: -1px;
z-index: 3;
background-color: $c-item;
padding: 4px 6px;
border: 1px solid #dbdbdb;
border-radius: 2px 2px 0 0;
border-width: 1px 1px 0 1px;
width: calc(100% + 2px);
transform: translateY(-100%);
textarea {
border-bottom: 1px dotted $c-outline;
height: 60px;
}
}
.sheet-toggle--arrow {
&:not(:checked) ~ .sheet-repitem__weapons {
display: none;
}
}
&__subitem {
position: relative;
.sheet-repitem__primary,
input[type=text] {
font-size: 9px !important;
line-height: 16px;
height: 16px;
}
.sheet-repitem__note-box {
top: 2px;
padding: 4px 6px 2px;
}
}
.sheet-repitem__weapons {
.sheet-repitem__note-box {
right: -7px;
width: calc(100% + 14px);
}
.sheet-toggle {
&--arrow::after {
line-height: 16px;
margin: 1px 2px 0 0;
height: 16px;
width: 16px;
transform-origin: 7px 8px;
}
&--note-box::after {
padding-top: 1px;
}
}
}
&__weapons {
&-control {
&[value='0'] + .sheet-repitem__weapons {
display: none;
}
@for $i from 1 through 10 {
&[value='#{$i}'] + .sheet-repitem__weapons {
.sheet-repitem__subitem:nth-child(-n + #{$i+1}) {
@extend %show-weapon-row;
}
}
}
}
%show-weapon-row {
display: block;
}
.sheet-header {
border-bottom: 1px solid $c-outline;
&__labels {
padding-right: 30px;
width: 100%;
}
}
.sheet-repitem__subitem {
display: none;
&:not(.sheet-repitem__subitem--1) .sheet-repitem__primary {
border-top: 1px solid $c-outline;
}
}
.sheet-repitem__primary {
margin-right: 6px;
padding-right: 10px;
}
&-name {
flex-grow: 1;
text-align: left;
padding-left: 6px;
}
input[type=text].sheet-repitem__weapons-name {
padding-left: 0;
}
&-damage,
&-range {
width: 85px;
}
&-rof {
width: 30px;
}
}
}
@@ -0,0 +1,160 @@
.charsheet {
padding: 0 !important; // Override Roll20!
}
.charsheet button[type=roll] {
text-shadow: none;
font-size: inherit !important; // Override Roll20!
padding: 0 !important; // Override Roll20!
margin: 0 !important; // Override Roll20!
&::before {
display: none;
}
&:hover,
&:focus,
&:active {
background-color: transparent;
box-shadow: none;
}
}
.repcontrol {
position: absolute;
bottom: -1px;
right: 0;
z-index: 2;
display: flex;
}
.repcontrol button.btn {
position: relative;
color: transparent;
font-size: 0;
height: 16px;
width: 16px;
transition: color .3s ease-in-out, opacity .3s ease-in-out;
&::after,
&::before {
transition: color .3s ease-in-out, opacity .3s ease-in-out;
}
&:hover,
&:focus,
&:active {
background-color: transparent;
box-shadow: none;
}
&::after {
position: absolute;
top: 0;
left: 0;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
color: $c-text-gray;
font-family: Pictos;
font-size: 12px;
line-height: 1;
height: 100%;
width: 100%;
}
&:hover::after {
color: $c-text-light;
}
&:active::after {
color: black;
}
&.repcontrol_add {
order: 1;
&::after {
content: '&';
}
}
&.repcontrol_edit {
order: 2;
float: none;
&::after {
content: '_';
}
}
}
.repcontainer.editmode {
+ .repcontrol {
button.repcontrol_edit::after {
content: '3';
}
}
.sheet-repitem__note-box,
.sheet-repitem__settings {
display: none;
}
.itemcontrol {
z-index: 10;
display: flex !important; // Override Roll20!
justify-content: space-between;
background-color: rgba(255, 255, 255, 0.5) !important; // Override Roll20!
border-radius: 2px;
margin: 0 2px;
width: calc(100% - 4px) !important;
a.repcontrol_move {
order: 1;
font-size: 18px;
border-radius: 2px 0 0 2px;
padding: 0 2px 0 0;
}
button.repcontrol_del {
order: 2;
float: none !important; // Override Roll20!
font-family: Pictos;
font-size: 12px;
border-radius: 0 2px 2px 0;
padding: 0 0 0 4px;
}
a.repcontrol_move,
button.repcontrol_del {
display: flex;
align-items: center;
justify-content: center;
background: $c-white;
text-shadow: none;
color: $c-text;
line-height: 1;
border: 0;
height: 100%;
width: 20px;
max-height: 20px;
box-shadow: none;
&:hover {
color: black !important;
}
&:active {
color: black !important;
box-shadow: none;
background: $c-white;
}
}
}
div.repitem:hover .itemcontrol {
background-color: rgba(255, 255, 255, 0.7) !important; // Override Roll20!
}
}
@@ -0,0 +1,261 @@
.sheet-rolltemplate-TraitRoll,
.sheet-rolltemplate-DiceRoller {
// Use .showtip to increase specificity!
// Necessary to override other adjoining classes!
.inlinerollresult.showtip {
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
z-index: -1;
display: block;
background-color: $c-background-die;
height: 100%;
width: 100%;
}
}
}
.sheet-rolltemplate-TraitRoll,
.sheet-rolltemplate-DiceRoller,
.sheet-rolltemplate-RunRoll,
.sheet-rolltemplate-DamageRoll,
.sheet-rolltemplate-InfoBox {
color: $c-text;
padding-top: 8px;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
.inlinerollresult.showtip {
position: relative;
z-index: 1;
background-color: transparent;
padding: 0;
border: 0;
}
.sheet-rolltemplate {
position: relative;
background: {
color: $c-white;
image: linear-gradient(to right, #fbfbfb 1px, transparent 1px),
linear-gradient(to bottom, #fbfbfb 1px, transparent 1px);
size: 8px 8px;
position: -1px -1px;
}
padding: 8px;
border-radius: 2px;
box-shadow: $shadow;
&__header {
font-size: 12px;
font-weight: bold;
line-height: 16px;
text-align: center;
&:not(:last-child) {
border-bottom: 1px dotted $c-outline;
padding-bottom: 7px;
}
}
&__content {
position: relative;
font-size: 11px;
text-align: center;
&:not(:first-child) {
padding-top: 8px;
}
&:not(:last-child) {
border-bottom: 1px dotted $c-outline;
padding-bottom: 7px;
}
span {
font-size: 11px;
}
span.inlinerollresult {
font-weight: 400;
}
}
&__content-row {
display: flex;
align-items: center;
line-height: 16px;
> div {
text-overflow: ellipsis;
overflow: hidden;
}
> .sheet-left {
font-weight: 500;
text-align: right;
padding-right: 8px;
width: 96px;
min-width: 96px;
}
> .sheet-right {
text-align: left;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
padding: 0 24px 0 8px;
}
}
&__dice {
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
span {
display: block;
font-size: 11px;
line-height: 20px;
}
.sheet-left {
display: flex;
flex-wrap: wrap;
padding-right: 8px;
}
.sheet-right {
display: flex;
flex-shrink: 0;
padding: 0 4px;
}
&--damage {
flex-wrap: wrap;
}
}
&__roll {
flex-shrink: 0;
text-align: center;
border-radius: 2px;
min-width: 20px;
margin-top: 8px;
overflow: hidden;
box-shadow: $shadow;
&:not(:last-child) {
margin-right: 8px;
}
// [original-title*='"basicdiceroll"'] watches for exploding dice!
// This only occurs if there is no fullcrit and/or critfail!
span:not([original-title*='"basicdiceroll"']).fullcrit {
&::before {
background-color: $c-outline;
}
}
span:not([original-title*='"basicdiceroll"']).fullfail {
color: $c-white;
&::before {
background-color: $c-red;
}
}
&--wd {
height: 20px;
transform: rotateZ(45deg);
&:not(:last-child) {
margin-right: 16px;
}
span {
transform: rotateZ(-45deg);
&::before {
transform: rotateZ(45deg);
}
}
}
}
&__reroll {
position: absolute;
top: 2px;
right: -4px;
font-family: Pictos;
border: 4px solid $c-white;
}
&__roll-damage {
position: absolute;
top: 26px;
right: -4px;
font-family: 'Pictos Custom';
border: 4px solid $c-white;
}
&__button a {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
background-color: $c-item;
color: $c-text-lightest;
font-size: $fs-s;
font-weight: 500;
line-height: 9px;
border: 1px dotted $c-outline;
border-radius: 2px;
padding: 0 4px;
height: 20px;
min-width: 20px;
&:hover {
background-color: $c-background-dark;
color: $c-white !important;
border: 1px solid $c-background-dark;
}
}
}
}
.sheet-rolltemplate-TraitRoll,
.sheet-rolltemplate-DamageRoll {
.sheet-rolltemplate {
&__description {
color: $c-text-light;
font-size: 9px;
font-style: italic;
line-height: 16px;
text-align: center;
padding: 8px 0 7px;
border-bottom: 1px dotted $c-outline;
}
}
}
.sheet-rolltemplate-DamageRoll {
.sheet-rolltemplate {
&__damage-roll {
padding-right: 8px;
margin: 8px 0 0 8px;
&:not(:last-child) {
border-right: 1px dotted $c-outline;
}
span {
font-size: 16px;
line-height: 24px;
}
}
}
}
@@ -0,0 +1,35 @@
.sheet-secondary {
display: flex;
padding-right: 80px;
> :not(:last-child) {
margin-right: 24px;
}
.sheet-hexfield {
&--run {
top: -100px;
left: -16px;
}
&--flight {
top: -64px;
left: 16px;
}
&--soak-mod {
top: -36px;
left: 32px;
}
&--soak-wd {
top: -72px;
left: 64px;
}
}
.sheet-hexfield--soak > button[type=roll] {
color: $c-text-light;
font-weight: 700;
}
}
@@ -0,0 +1,95 @@
.sheet-sans {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
.sheet-section > .sheet-right:not(.sheet-sans) {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.sheet-section--footer > .sheet-right {
padding-top: 32px;
}
.sheet-section--traits {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin-left: 24px;
height: 400px;
}
.sheet-attributes {
position: absolute;
top: 0;
left: 0;
z-index: 2;
.sheet-attribute {
position: absolute;
&--agility {
top: 0;
left: 32px;
}
&--smarts {
top: 80px;
left: 16px;
}
&--spirit {
top: 160px;
left: 0;
}
&--strength {
top: 240px;
left: 16px;
}
&--vigor {
top: 320px;
left: 32px;
}
}
}
.sheet-armor {
position: absolute;
right: 0;
top: 22px;
}
.sheet-silhouette {
position: absolute;
top: 0;
left: 100px;
}
.sheet-secondary {
position: absolute;
bottom: 23px;
right: 0;
z-index: 2;
}
.sheet-section--features {
display: flex;
align-items: flex-start;
flex-grow: 1;
min-height: 176px;
padding: 24px 0 8px;
}
.sheet-section--resources {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 32px;
}
@@ -0,0 +1,192 @@
.sheet-settings {
text-align: center;
padding: 8px 0 0 64px;
&__page {
display: flex;
flex-direction: column;
align-items: flex-end;
text-align: left;
&-tab {
display: inline-block;
color: $c-text-lightest;
margin-bottom: 7px;
&::before,
&::after {
display: inline-block;
font-size: $fs-s;
font-weight: 500;
line-height: 15px;
height: 16px;
}
&::before {
content: attr(label);
}
&:not(:last-of-type)::after {
content: '|';
margin: 0 2px 0 4px;
}
&:checked::before {
color: $c-text-lighter;
}
&--styles {
&:not(:checked) ~ .sheet-settings__page--styles {
@extend %hide-disabled-settings-tab;
}
}
&--setup {
&:not(:checked) ~ .sheet-settings__page--setup {
@extend %hide-disabled-settings-tab;
}
}
&--blocks {
&:not(:checked) ~ .sheet-settings__page--blocks {
@extend %hide-disabled-settings-tab;
}
}
&--skills {
&:not(:checked) ~ .sheet-settings__page--skills {
@extend %hide-disabled-settings-tab;
}
}
&--help {
&:not(:checked) ~ .sheet-settings__page--help {
@extend %hide-disabled-settings-tab;
}
}
}
}
%hide-disabled-settings-tab {
display: none;
}
&__textarea-toggle {
&:not(:checked) + textarea {
display: none;
}
}
&__item {
user-select: none;
display: flex;
align-items: center;
width: 100%;
min-height: 16px;
&:not(:last-child) {
margin-bottom: 8px;
}
> span:first-of-type {
display: block;
flex-grow: 1;
color: $c-text-light;
font-size: $fs-s;
font-weight: 500;
line-height: 15px;
border-bottom: 1px dotted $c-outline;
margin-right: 12px;
height: 100%;
}
.sheet-checkbox {
margin-right: 4px;
}
&--text-input {
> span:first-of-type {
flex-grow: 0;
flex-shrink: 0;
margin-right: 0;
~ input[type=text] {
padding-left: 5px;
}
}
input[type=text] {
flex-grow: 1;
color: $c-text-light;
line-height: 15px;
border-bottom: 1px dotted $c-outline;
margin-right: 12px;
height: 16px;
width: auto;
&::placeholder {
font-size: $fs-s;
}
&:last-child {
margin-right: 26px;
}
+ span:last-of-type {
display: block;
flex-shrink: 0;
color: $c-text-lighter;
font-family: Pictos;
font-size: 11px;
margin: 0 4px 0 1px;
height: 16px;
width: 9px;
}
}
}
&--textarea {
flex-wrap: wrap;
textarea {
flex-basis: 100%;
background-color: $c-white;
font-size: $fs-s;
line-height: 16px;
padding: 4px;
border: 1px solid $c-outline;
border-radius: 2px;
height: 64px;
margin: 8px 4px 0 0;
transition: border-color .3s ease-in-out,
height .3s ease-in-out;
&:hover {
border-color: $c-background-dark;
}
&:focus {
border-color: $c-background-dark;
height: 192px;
}
}
}
&--help {
flex-wrap: wrap;
height: auto;
> span:first-of-type {
margin-right: 8px;
}
.sheet-bottom {
user-select: text;
flex-basis: 100%;
text-align: justify;
line-height: 1.6;
padding: 4px 0;
}
}
}
}
@@ -0,0 +1,178 @@
.sheet-toggle-silhouette-markers:not(:checked) {
+ .sheet-silhouette .sheet-color-cycle {
display: none;
}
}
.sheet-silhouette {
position: relative;
z-index: 1;
height: 300px;
width: 200px;
&__image {
background: {
image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/female_silhouette.png');
repeat: no-repeat;
size: contain;
}
height: 100%;
width: 100%;
&:hover ~ .sheet-color-cycle :checked {
opacity: 1;
transition-delay: 0.4s;
}
}
.sheet-color-cycle {
position: absolute;
transform: translateX(-50%);
&:hover :checked {
opacity: 1;
}
&__radio {
border: 2px solid $c-white;
opacity: 0;
transition: opacity .3s ease-in-out;
&:not(.sheet-color-cycle__radio--none):checked {
opacity: 1;
}
&--none {
background-color: #d9d9d9 !important;
}
}
}
&__head {
top: 26px;
left: 99px;
}
&__torso-upper {
top: 64px;
left: 99px;
}
&__torso-lower {
top: 100px;
left: 99px;
}
&__left-arm-upper {
top: 70px;
left: 128px;
}
&__left-arm-lower {
top: 109px;
left: 138px;
}
&__left-hand {
top: 134px;
left: 142px;
}
&__right-arm-upper {
top: 70px;
left: 69px;
}
&__right-arm-lower {
top: 109px;
left: 59px;
}
&__right-hand {
top: 134px;
left: 55px;
}
&__left-leg-upper {
top: 160px;
left: 125px;
}
&__left-leg-lower {
top: 230px;
left: 129px;
}
&__right-leg-upper {
top: 160px;
left: 72px;
}
&__right-leg-lower {
top: 230px;
left: 68px;
}
&__switch {
position: absolute;
bottom: 12px;
left: 50%;
z-index: 3;
&::after {
content: '[ ]';
display: block;
color: $c-text-gray;
font-family: Pictos;
font-size: 8px;
transform: translateX(-50%);
}
&:checked + .sheet-silhouette__image {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/male_silhouette.png');
}
// Marker position overwrites
&:checked ~ .sheet-silhouette {
&__left-arm-upper {
top: 70px;
left: 141px;
}
&__left-arm-lower {
top: 105px;
left: 150px;
}
&__left-hand {
top: 143px;
left: 147px;
}
&__right-arm-upper {
top: 70px;
left: 56px;
}
&__right-arm-lower {
top: 105px;
left: 47px;
}
&__right-hand {
top: 143px;
left: 50px;
}
&__left-leg-upper {
top: 172px;
left: 126px;
}
&__right-leg-upper {
top: 172px;
left: 71px;
}
}
}
}
@@ -0,0 +1,133 @@
$container-height: 24px;
.sheet-simple-trait {
position: relative;
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: space-between;
font-size: 11px;
line-height: $container-height;
padding-right: 6px;
border-radius: 2px;
height: $container-height;
min-width: 66px;
span {
color: $c-text;
}
.sheet-background {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
&__expand {
position: absolute;
top: 0;
left: 0;
z-index: 2;
border: 1px solid transparent;
border-radius: 2px;
height: 100% !important; // Override Roll20!
width: 100%;
transition: border .3s ease-in-out;
&:hover,
&:checked {
border-color: $c-outline;
}
&:checked ~ .sheet-simple-trait__inputs {
display: flex;
background-color: $c-white;
}
&:checked ~ .sheet-background {
background-color: $c-white;
}
}
button[type=roll].sheet-simple-trait__roll {
padding-left: 6px !important;
}
&__roll {
position: relative;
z-index: 3;
font-size: 11px;
font-weight: 500;
line-height: $container-height;
&:hover + .sheet-simple-trait__buttons {
pointer-events: all;
opacity: 1;
transition-delay: .7s;
}
}
&__custom-roll {
color: $c-text-light;
font-size: 10px;
font-weight: 500;
line-height: 16px;
&:not(:last-child) {
margin-right: 4px !important;
}
}
&__buttons {
pointer-events: none;
position: absolute;
left: 0;
top: 0;
z-index: 4;
display: flex;
background-color: $c-white;
padding: 0 4px;
border-radius: 2px;
height: 16px;
transform: translateY(-100%);
opacity: 0;
box-shadow: $shadow;
transition: opacity .3s ease-in-out;
&:hover {
pointer-events: all;
opacity: 1;
transition-delay: .7s;
}
}
&__label {
position: relative;
z-index: 1;
font-weight: 500;
margin-left: 8px;
}
&__inputs {
position: absolute;
bottom: 1px;
left: 0;
z-index: 4;
display: none;
background-color: $c-white;
border: 1px solid $c-outline;
border-width: 0 1px 1px 1px;
border-radius: 0 0 2px 2px;
padding: 0 6px;
width: 100%;
transform: translateY(100%);
> input[type=text] {
text-align: center;
border-top: 1px dotted $c-outline;
width: 33.3%;
}
}
}
@@ -0,0 +1,207 @@
.sheet-toggle-skill-markers:not(:checked) {
+ .sheet-skills .sheet-color-cycle {
display: none;
}
}
.sheet-skills {
position: relative;
padding-top: 8px;
&__lock {
&::after {
position: absolute;
top: 10px;
right: 0;
display: flex;
align-items: center;
justify-content: center;
color: $c-text-lightest;
font-family: Pictos;
font-size: 8px;
height: 16px;
width: 16px;
}
&:not(:checked) {
&::after {
content: ')';
}
+ .sheet-skills__wrapper {
.sheet-skills__step-button {
display: none;
}
}
}
&:checked::after {
content: '(';
}
&:checked ~ .sheet-skills__wrapper .sheet-skills__track {
input {
cursor: default;
pointer-events: none;
}
}
}
.sheet-header {
justify-content: flex-end;
border: none;
}
&__die {
width: 18px;
&:not(.sheet-a) {
margin-right: 3px;
}
}
&__mod,
&__wd {
width: 24px;
}
&__mod {
margin-right: 3px;
}
&__plus {
color: $c-text-gray;
font-size: $fs-l;
line-height: 1;
text-align: center;
width: 18px;
}
&__color-marker {
width: 16px;
.sheet-color-cycle__radio {
padding: 3px;
border: 1px solid transparent;
&--none {
border-color: $c-outline;
}
}
}
&__skill {
display: flex;
flex-direction: row-reverse;
align-items: center;
justify-content: flex-start;
height: 16px;
&:not(:last-child) {
margin-bottom: 8px;
}
input[type=text].sheet-skills__mod,
input[type=text].sheet-skills__wd {
background-color: $c-white;
font-size: 9px !important;
height: 14px;
box-shadow: $shadow;
&::placeholder {
line-height: 14px;
}
&:not(:placeholder-shown) {
background-color: $c-background-dark;
color: $c-white;
}
}
.sheet-skills__mod {
border-radius: 2px 0 0 2px;
}
.sheet-skills__wd {
border-radius: 0 2px 2px 0;
}
}
&__track {
display: flex;
flex-direction: row-reverse;
}
input[type=radio].sheet-radio-track {
height: 14px;
width: 18px;
&:not(:first-of-type) {
margin-right: 3px;
}
&:not(.sheet-d4-2):checked::before{
content: attr(label);
}
&.sheet-d12 {
border-radius: 0 2px 2px 0;
}
&.sheet-d4-2 {
border-radius: 2px 0 0 2px;
&:checked {
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/unskilled_bg.png') repeat;
&::after {
background-color: transparent;
}
~ button > span {
color: $c-text-lightest; // Untrained skill
}
}
}
}
button[type=roll] {
.sheet-tooltip {
z-index: 10;
white-space: nowrap;
&--left {
text-transform: uppercase;
}
}
&:hover .sheet-tooltip {
opacity: 1;
transition-delay: .4s;
}
}
button[type=roll].sheet-skills__step-button {
position: relative;
margin-right: -18px !important;
height: 14px;
width: 18px;
}
&__button {
position: relative;
align-items: center;
color: $c-text-light;
font-size: $fs-s;
font-weight: 500;
line-height: 1;
> span {
display: block;
padding: 1px 8px 1px 0;
max-width: 88px;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
@@ -0,0 +1,81 @@
.sheet-san-tabs {
position: absolute;
top: 0;
right: 0;
border-bottom: 1px dotted $c-outline;
height: 16px;
width: 266px;
~ div {
flex-basis: 100%;
}
}
.sheet-tab {
~ div {
min-height: 100%;
}
&::after {
content: attr(label);
position: relative;
z-index: 1;
display: block;
align-items: center;
justify-content: center;
color: $c-text-lightest;
font-size: $fs-s;
font-weight: 500;
line-height: 1;
padding: 3px 6px 0;
border: 1px dotted transparent;
border-width: 1px 1px 0 1px;
border-radius: 2px;
height: 16px;
transition: none;
}
&:hover::after {
color: $c-text-lighter;
}
&:checked::after {
background-color: $c-white;
color: $c-text-light;
border-color: $c-outline;
}
&--skills {
margin-left: 72px;
&:not(:checked) ~ .sheet-skills {
@extend %hide-disabled-tab;
}
}
&--advancements {
&:not(:checked) ~ .sheet-advancements {
@extend %hide-disabled-tab;
}
}
&--notebook {
&:not(:checked) ~ .sheet-notebook {
@extend %hide-disabled-tab;
}
~ .sheet-notebook {
height: calc(100% - 64px);
}
}
&--settings {
&:not(:checked) ~ .sheet-settings {
@extend %hide-disabled-tab;
}
}
}
%hide-disabled-tab {
display: none;
}
@@ -0,0 +1,218 @@
.sheet-trait-section {
> .sheet-left {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 470px;
}
.sheet-section-container--center-top {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding-bottom: 112px;
width: 100%;
}
.sheet-section-container--center-bottom {
position: relative;
display: flex;
align-items: center;
padding: 24px 0 32px 0;
width: 100%;
height: 100%;
}
.sheet-section-container--bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0 32px;
width: 100%;
}
}
.sheet-silhouette {
margin-left: -50px;
}
.sheet-secondary-block {
position: absolute;
left: 166px;
top: 350px;
z-index: 2;
display: flex;
align-items: center;
transform: translateY(-50%);
> *:not(:last-child) {
margin-right: 23px;
}
.sheet-hexfield {
&:hover .sheet-hexfield * {
opacity: 1 !important;
transition-delay: 0.4s;
}
.sheet-hexfield {
> * {
opacity: 0;
}
.sheet-hexfield__trait-field {
&:focus {
opacity: 1;
& ~ * {
opacity: 1;
}
}
}
.sheet-hexfield__label {
opacity: 0;
}
}
.sheet-hexfield--flight {
top: -28px;
left: 16px;
.sheet-hexfield__trait-field:not(:placeholder-shown) {
opacity: 1;
& ~ * {
opacity: 1;
color: $c-text-light;
}
}
}
.sheet-hexfield--running,
.sheet-hexfield--soak-bonus {
.sheet-hexfield__trait-field:not(:placeholder-shown) {
opacity: 1;
& + .sheet-hexfield__hexagon {
opacity: 1;
}
}
}
.sheet-hexfield--running {
top: -64px;
left: -17px;
}
.sheet-hexfield--soak-bonus {
top: 0;
left: 33px;
}
.sheet-hexfield--soak-wd {
top: -36px;
left: 66px;
.sheet-hexfield__trait-field {
color: $c-text-gray;
}
}
}
}
.sheet-armor-block {
position: absolute;
right: -25px;
top: 20px;
z-index: 1;
display: flex;
flex-direction: column;
align-items: flex-end;
transform: translateX(-100px);
> *:not(:last-child) {
margin-bottom: 40px;
}
.sheet-hexfield--armor {
&-head {
margin-right: 16px;
}
&-legs {
margin-right: 16px;
}
}
.sheet-textarea {
position: absolute;
top: 8px;
left: 37px;
color: $c-text-lighter;
font-size: 9px;
line-height: 1.5;
padding-top: 4px;
height: 56px;
width: 105px;
resize: none;
&::placeholder {
color: #f0f0f0;
font-size: 22px;
font-weight: 700;
line-height: 0.5;
}
}
.sheet-armor-decoration {
position: absolute;
top: 15px;
right: 16px;
opacity: .08 !important;
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/armor_line.png') no-repeat;
height: 316px;
width: 82px;
}
.sheet-armor-pointer {
position: absolute;
transform: translateX(-100%);
opacity: .08 !important;
&--head {
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/head_line.png') no-repeat;
top: 17px;
right: -48px;
height: 3px;
width: 111px;
}
&--torso {
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/torso_line.png') no-repeat;
top: -17px;
right: -42px;
height: 38px;
width: 110px;
}
&--arms {
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/arms_line.png') no-repeat;
top: -46px;
right: -13px;
height: 66px;
width: 78px;
}
&--legs {
background: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/legs_line.png') no-repeat;
top: -31px;
right: -15px;
height: 53px;
width: 76px;
}
}
}
@@ -0,0 +1 @@
// Put overrides for translations (width, size, etc.) here.
@@ -0,0 +1,49 @@
// FONTS
$f-roboto: Roboto, Arial, Helvetica, sans-serif;
// FONT SIZES (Overwrite Roll20!)
$fs-l: 12px;
$fs-s: 10px;
$fs-xs: 8px;
// COLORS
$c-text: #404040;
$c-text-light: #606060;
$c-text-lighter: #808080;
$c-text-lightest: #b0b0b0;
$c-text-gray: #d6d6d6;
$c-text-hover: #303030;
$c-outline: #e0e0e0;
$c-item: #fdfdfd;
$c-background-die: #fafafa;
$c-background-dark: #898989;
$c-background-hover: #f2f2f2;
$c-background-tooltip: #606060;
$c-white: #fff;
$c-red: #d9534f;
$c-dark-red: #923836;
$c-yellow: #f0ad4e;
$c-blue: #0275d8;
$c-green: #5cb85c;
$c-purple: #b25afd;
$c-gray: #545454;
// SHADOWS
$shadow: 0 0 1.5px 0 rgba(0, 0, 0, 0.5);
@mixin note-grid {
background: {
image: linear-gradient(to right, #f6f6f6 1px, transparent 1px),
linear-gradient(to bottom, #f6f6f6 1px, transparent 1px);
size: 16px 16px;
position: 4px -1px;
color: $c-white;
}
color: $c-text-light;
font-size: $fs-s;
line-height: 16px;
padding: 0 8px;
resize: none;
}
@@ -0,0 +1,80 @@
.sheet-vehicles {
&__size,
&__handling,
&__speed,
&__toughness,
&__crew,
&__weapons {
width: 45px;
}
.sheet-repitem__frame-silhouette-control {
&[value='0'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/car_01.png');
}
&[value='1'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/car_02.png');
}
&[value='2'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/car_03.png');
}
&[value='3'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/car_04.png');
}
&[value='4'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/sports-bike.png');
}
&[value='5'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/quad-bike.png');
}
&[value='6'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/tank.png');
}
&[value='7'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/aircraft_01.png');
}
&[value='8'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/aircraft_02.png');
}
&[value='9'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/aircraft_03.png');
}
&[value='10'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/watercraft_01.png');
}
&[value='11'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/watercraft_02.png');
}
&[value='12'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/watercraft_03.png');
}
&[value='13'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/spacecraft_01.png');
}
&[value='14'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/spacecraft_02.png');
}
&[value='15'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/spacecraft_03.png');
}
&[value='16'] ~ .sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/spacecraft_04.png');
}
}
}
@@ -0,0 +1,24 @@
.sheet-walkers {
&__size,
&__pace,
&__crew {
width: 35px;
}
&__strength {
width: 60px;
}
&__toughness,
&__mods,
&__weapons {
width: 45px;
}
.sheet-repitem__frame-silhouette {
background-image: url('https://raw.githubusercontent.com/Tetrakern/roll20-character-sheets/master/Savage%20Worlds%20-%20Graph%20Paper/img/walker.png');
background-size: contain;
margin-top: 4px;
height: 56px;
}
}
@@ -0,0 +1,37 @@
.sheet-weapons {
margin-top: 32px;
&__damage,
&__range {
width: 80px;
}
&__ap,
&__rof,
&__weight {
width: 30px;
}
&__shots {
width: 40px;
}
&__trapping {
width: 64px;
}
&__damage-button {
position: absolute;
top: 0;
left: 164px;
display: none;
height: 20px;
width: 80px;
}
input.sheet-toggle:not(:checked) {
~ .sheet-weapons__trapping {
display: none;
}
}
}
@@ -0,0 +1,4 @@
script(type="text/worker")
include ../scripts/workers.js
include _sheet.pug
@@ -0,0 +1,41 @@
input(type='checkbox',
name='attr_toggle_abilities_block',
checked=false,
class='sheet-toggle sheet-toggle--block')
.sheet-block.sheet-abilities
.sheet-header
span.sheet-header__title.sheet-apparel__name(name='attr_rename_block_abilities', data-i18n='abilities') Abilities
input(type='checkbox',
name='attr_abilities_visibility_toggle',
checked=true,
class='sheet-toggle sheet-toggle--visibility')
fieldset.repeating_abilities
.sheet-repitem.sheet-repitem--full-field
input(type='radio',
name='attr_ability_size',
value='1',
label='}',
data-i18n-label='}',
class='sheet-repitem__size-radio sheet-repitem__size-radio--1')
- var i = 1
while i < 6
- ++i
input(type='radio',
name='attr_ability_size',
value=`${i}`,
label='}',
data-i18n-label='}',
class='sheet-repitem__size-radio')
textarea(name='attr_ability',
placeholder='Ability: Description',
data-i18n-placeholder='ability-placeholder',
spellcheck='false')
.sheet-footer
@@ -0,0 +1,34 @@
-
const levelRanks = [['N', 'Novice'], ['S', 'Seasoned'], ['V', 'Veteran'],
['H', 'Heroic'], ['L', 'Legendary']]
.sheet-advancements
- var i = 0, j = 2, r = 0
while i < 5
- ++i
.sheet-advancements__item
input(type='text',
name=`attr_chargen_edge_${i}`,
placeholder='Novice',
data-i18n-placeholder='advancements-novice-placeholder',
spellcheck='false',
class='sheet-align-left')
while i < 27
.sheet-advancements__item
.sheet-advancements__rank
span(data-i18n=`advancements-rank-${levelRanks[r][0].toLowerCase()}`)= levelRanks[r][0]
- ++i
input(type='text',
name=`attr_advancement_${(i - 5)}`,
placeholder=levelRanks[r][1],
data-i18n-placeholder=`advancements-${levelRanks[r][1].toLowerCase()}-placeholder`,
spellcheck='false',
class='sheet-align-left')
if j % 4 == 0 && r < 4
- ++r
- ++j
@@ -0,0 +1,118 @@
input(type='checkbox',
name='attr_toggle_allies_block',
class='sheet-toggle sheet-toggle--block')
.sheet-block.sheet-allies
.sheet-header
span.sheet-header__title.sheet-allies__name(name='attr_rename_block_allies', data-i18n='allies') Allies
.sheet-header__labels
.sheet-allies__pace(data-i18n='pace') Pace
.sheet-allies__parry(data-i18n='parry') Parry
.sheet-allies__toughness(data-i18n='toughness') Tough.
.sheet-allies__size(data-i18n='size') Size
.sheet-allies__exp(data-i18n='exp') EXP
.sheet-allies__level(data-i18n='level') Level
input(type='checkbox',
name='attr_allies_visibility_toggle',
checked=true,
class='sheet-toggle sheet-toggle--visibility')
fieldset.repeating_allies
.sheet-repitem
.sheet-repitem__primary
input(type='text',
name='attr_ally_name',
placeholder='Name',
data-i18n-placeholder='allies-name-placeholder',
spellcheck='false',
class='sheet-align-left sheet-allies__name sheet-stretch')
input(type='text',
name='attr_ally_pace',
placeholder='6',
spellcheck='false',
class='sheet-allies__pace')
input(type='text',
name='attr_ally_parry',
placeholder='4',
spellcheck='false',
class='sheet-allies__parry')
input(type='text',
name='attr_ally_toughness',
placeholder='4',
spellcheck='false',
class='sheet-allies__toughness')
input(type='text',
name='attr_ally_size',
placeholder='0',
spellcheck='false',
class='sheet-allies__size')
input(type='text',
name='attr_ally_exp',
placeholder='0',
spellcheck='false',
class='sheet-allies__exp')
input(type='text',
name='attr_ally_level',
placeholder='1',
spellcheck='false',
class='sheet-allies__level')
input(type='checkbox',
name='attr_ally_note_box_toggle',
class='sheet-toggle sheet-toggle--note-box')
.sheet-repitem__note-box
textarea(name='attr_ally_note_box',
placeholder='Notes',
data-i18n-placeholder='allies-note-box-placeholder',
spellcheck='false')
input(type='checkbox',
name='attr_ally_notes_toggle',
class='sheet-toggle sheet-toggle--arrow')
.sheet-repitem__secondary
.sheet-left
- var rolls = ['2', '4', '6', '8', '10', '12']
- var i = 0
while i < 6
- var die = rolls[i] == 2 ? 'd4!cs2-2' : `d${rolls[i]}!cs2`
button(type='roll',
name=`roll_ally_roll_${die.replace('!cs2', '')}`,
value!=`&{template:TraitRoll} {{header=[^{ally}] @{ally_name} ^{rolls}: ${die.replace('!cs2', '')}}} {{commander=@{name}}} {{rof=[[ ?{@{query_rate_of_fire}|1} ]]}} {{modifier=?{@{query_modifier}|0}}} {{wd=?{@{query_wild_die}|@{none},-10000|d4|d6|d8|d10|d12}}} ${maxRof.map(n => `{{traitroll${n}=[[ ${die} + ?{@{query_modifier}|0} ]]}}`).join(' ')} {{wdroll=[[ ?{@{query_wild_die}|@{none},-10000|d4|d6|d8|d10|d12}!cs2 + ?{@{query_modifier}|0} ]]}} {{reroll=[r](~repeating_allies_ally_roll_${die.replace('!cs2', '')})}}`)
span(data-i18n=`die-button-number-${rolls[i]}`)= rolls[i]
- ++i
.sheet-allies__health-field.sheet-allies__health-field--wounds
input(type='text',
name='attr_ally_note_wounds',
spellcheck='false')
.sheet-allies__health-field.sheet-allies__health-field--fatigue
input(type='text',
name='attr_ally_note_fatigue',
spellcheck='false')
.sheet-right
- var i = 0
while i < 20
- ++i
input(type='text',
name=`attr_ally_note_field_${i}`,
placeholder=`Note #${i}`,
data-i18n-placeholder=`allies-note-field-${i}-placeholder`,
spellcheck='false',
class=`sheet-allies__note-field sheet-allies__note-field--${i}`)
.sheet-footer
@@ -0,0 +1,42 @@
input(type='checkbox',
name='attr_toggle_ammunition_block',
checked=true,
class='sheet-hidden sheet-toggle sheet-toggle-block')
.sheet-ammunition
.sheet-header
span.sheet-header__title(name='attr_rename_block_ammunition', data-i18n='ammunition') Ammunition
input(type='checkbox',
name='attr_ammunition_visibility_toggle',
checked=true,
class='sheet-toggle sheet-toggle--visibility')
.sheet-ammunition__content
- var i = 0
while i < 3
- ++i
.sheet-ammunition__container.sheet-ammunition__container--1
input(type='radio', name='attr_ammunition_select', value=`ammunition_container_${i}`, checked= i==1)
span(name=`attr_ammunition_container_${i}_max`) 0
input(type='text', name=`attr_ammunition_container_${i}`)
span(name=`attr_rename_ammunition_container_${i}`)= `Ammo #${i}`
.sheet-ammunition__buttons
.sheet-top
button(type='action' name='act_ammunition_+1') +1
button(type='action' name='act_ammunition_+3') +3
button(type='action' name='act_ammunition_+5') +5
button(type='action' name='act_ammunition_+10') +10
button(type='action' name='act_ammunition_set', data-i18n='ammunition-set') S
.sheet-bottom
button(type='action' name='act_ammunition_-1') 1
button(type='action' name='act_ammunition_-3') 3
button(type='action' name='act_ammunition_-5') 5
button(type='action' name='act_ammunition_-10') 10
button(type='action' name='act_ammunition_reset', data-i18n='ammunition-reset') R
.sheet-footer

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