diff --git a/Stars_Without_Number_Revised/ReadMe.md b/Stars_Without_Number_Revised/ReadMe.md index dae8e456c4..2d8b56a432 100644 --- a/Stars_Without_Number_Revised/ReadMe.md +++ b/Stars_Without_Number_Revised/ReadMe.md @@ -6,16 +6,16 @@ This sheet is created for use in Stars Without Number Revised Edition on Roll20. * [Karlinator](https://github.com/Karlinator) * [Jakob](https://github.com/joesinghaus) +* [Panzer](https://app.roll20.net/users/2223776/panzer) ### Contributors -* UI Design by [Panzer](https://app.roll20.net/users/2223776/panzer) * [MankiGames](https://github.com/MankiGames) * [Shadowriku](https://github.com/Shadowriku) * [RonaldZ](https://github.com/RonaldZ) * [jfredett](https://github.com/jfredett) * [CoalPoweredPuppet](https://github.com/CoalPoweredPuppet) -* [Kevin Searle](https://github.com/kevinsearle) +* Original First Edition sheet by [Kevin Searle](https://github.com/kevinsearle) ### QA/Testing @@ -25,8 +25,32 @@ This sheet is created for use in Stars Without Number Revised Edition on Roll20. Report any problems, suggestions, or features by [creating an issue](https://github.com/Karlinator/roll20-character-sheets/issues) on Github. +## Contributing + +* Contributions are welcome at [the GitHub](https://github.com/Karlinator/roll20-character-sheets). Just open a pull request. +* You will need to install [Node.js](https://nodejs.org), then run the following command in bash/cmd: + * npm install -g pug pug-cli sass jstransformer-uglify-es + * You may need to restart you computer. + * Then just make changes to the files in the Source folder, and use the file "build" or "pug_build.bat" and "sass_build.bat" depending on your OS. + ## Changelog +### 2.2.0 + +* Added autofill functionality for ship hulls and class ability. +* Added autofill buttons for armor, cyberware, foci, gear, ship modules, techniques, and weapons. +* Weapon encumbrance can now be modified in the weapon section. Weapons with 0 encumbrance will no longer be shown in the gear section. +* Added an extra field to put effort that is only committed as long as a power is active. +* Changed "Total" effort to "Uncommitted", and added auto-calculating. The formula for effort is now more accurate. +* Added the option to enable ammo tracking with ChatSetAttr to the sheet default settings. +* Added a place to track skill points that can only be spent on psionics. +* Added Discipline field to psychic techniques. +* Added switch Ship/Mech/Custom for the ship tab. +* Changed armor to be a repeating section. +* The gear section now has a header. +* Exert can now be used as a weapon's attack skill. +* The chat macro for skills is now sorted into trained/untrained ones, the latter of which can be disabled. + ### 2.1.0 * Additions diff --git a/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.pug b/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.pug index 934b30011b..eb4f36e7ed 100644 --- a/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.pug +++ b/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.pug @@ -8,7 +8,7 @@ div input(type="hidden", name="attr_attribute_query_int", value="+ @{intelligence_mod}[Intelligence]]]}} {{attribute= + INT}}") input(type="hidden", name="attr_attribute_query_wis", value="+ @{wisdom_mod}[Wisdom]]]}} {{attribute= + WIS}}") input(type="hidden", name="attr_attribute_query_cha", value="+ @{charisma_mod}[Charisma]]]}} {{attribute= + CHA}}") - input(type="hidden", name="attr_attribute_query_none", value="]]}}") + input(type="hidden", name="attr_attribute_query", value="?{Attribute|Strength,+ @{strength_mod}[Strength]]]}} {{attribute= + STR}}|Dexterity,+ @{dexterity_mod}[Dexterity]]]}} {{attribute= + DEX}}|Constitution,+ @{constitution_mod}[Constitution]]]}} {{attribute= + CON}}|Intelligence,+ @{intelligence_mod}[Intelligence]]]}} {{attribute= + INT}}|Wisdom,+ @{wisdom_mod}[Wisdom]]]}} {{attribute= + WIS}}|Charisma,+ @{charisma_mod}[Charisma]]]}} {{attribute= + CHA}}}") input(type="hidden", name="attr_burst_query", value="?{Burst|Yes,+ 2[Burst]|No, }") input(type="hidden", name="attr_extra_hp_query", value!="?{Extra hit points? Enter 2 for Warrior|0}[Bonus]") input(type="hidden", name="attr_modifier_query", value="+ ?{Modifier|0}[Mod]") diff --git a/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.scss b/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.scss index c2af296d13..f3d2d020b3 100644 --- a/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.scss +++ b/Stars_Without_Number_Revised/Source/Stars_Without_Number_Revised.scss @@ -18,8 +18,6 @@ $rt-gray: #bababa; /* polygon(0 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 22px 100%, 0 calc(100% - 22px)) */ -/* dummy */ -.charsheet { background: white } /* global styles */ .charsheet { background-color: white; @@ -49,11 +47,13 @@ textarea { padding: 1px 4px; font-size: 12px; margin: 0; + color: #000; display: block; } input[type=text], input[type=number] { padding: 1px 4px; font-size: 12px; + height: 20px; color: #000; } input[type=number][readonly="readonly"], @@ -67,6 +67,7 @@ input[type=number].sheet-no-spinners { } select { margin: 0; + color: #000; font-size: 12px; padding: 1px 2px; line-height: 18px; @@ -101,6 +102,8 @@ button[type=roll].sheet-invisible-button { .sheet-hider[value="0"] { + div, + label, + button, + span { display: none } } +.sheet-hider[value=""] + button { display: none } + .sheet-editmode[value="0"] ~ .sheet-content .sheet-empty-hider[value=""] + div { display: none } /* headings */ h1 { @@ -221,6 +224,10 @@ h3 { .sheet-flex { display: flex; } +.sheet-flex-start { + display: flex; + align-items: flex-start; +} .sheet-flex-center { display: flex; align-items: center; @@ -241,17 +248,18 @@ h3 { .sheet-halfgrid { display: grid; grid: auto/ 1fr 1fr; - grid-column-gap: 1%; + grid-column-gap: 5px; } .sheet-thirdsgrid { display: grid; grid: auto/ repeat(3, 1fr); - grid-column-gap: 2%; + grid-column-gap: 1%; } .sheet-column > div:not(:first-child) { margin-top: 5px } .sheet-col-1-3 { grid-column: 1/3 } .sheet-col-1-4 { grid-column: 1/4 } .sheet-col-1-5 { grid-column: 1/5 } +.sheet-col-2 { grid-column: 2 } .sheet-col-2-4 { grid-column: 2/4 } .sheet-col-3 { grid-column: 3 } .sheet-col-3-5 { grid-column: 3/5 } @@ -299,8 +307,9 @@ input[type=number].sheet-inline-input { color: #666; padding-right: 5px; line-height: 1; - div { + .sheet-label { font-size: .9em; + text-align: inherit; line-height: 14px; border-top: 1px solid #AAA; @@ -353,13 +362,22 @@ input[type=number].sheet-inline-input { font-size: 16px; color: #333; } - div { grid-column: 1/4 } + .sheet-label { grid-column: 1/4 } } button[type=roll].btn { width: 100%; &:hover { color: red } } } +.sheet-table-header { + font-size: .9em; + color: #666; + .sheet-center { text-align: center } + > div { + padding-left: 2px; + border-bottom: 1px solid #aaa; + } +} .sheet-blue-button { text-align: center; button[type=roll].btn { @@ -409,6 +427,13 @@ input[type=number].sheet-inline-input { } } } +.sheet-rep-grid { + display: grid; + align-items: start; + grid-column-gap: 3px; + margin-bottom: 3px; + .sheet-text-input { padding: 0 } +} /* global skill settings */ .sheet-skills-type[value="neither"] ~ div .sheet-skills-either, @@ -416,7 +441,8 @@ input[type=number].sheet-inline-input { .sheet-skills-type:not([value="revised"]) ~ div .sheet-skills-revised, .sheet-skills-type:not([value="neither"]) ~ div .sheet-skills-neither, .sheet-skills-query:not([value="hover"]) ~ div .sheet-skills-query-hover, -.sheet-skills-query[value="query"] ~ div .sheet-skills-query-display { +.sheet-skills-query[value="query"] ~ div .sheet-skills-query-display, +.sheet-skills-query[value="query"] ~ div .sheet-skills-query-ask { display: none; } .sheet-skills-query-display { @@ -481,6 +507,38 @@ input[type=number].sheet-inline-input { } } +/* generate buttons */ +.sheet-generate { + margin-bottom: 5px; + .sheet-generate-source { + height: 20px; + width: 170px; + } + .sheet-generate-info { + margin: 0 5px; + min-height: 20px; + flex-grow: 1; + background: $lightbox; + border-radius: 4px; + padding: 1px 4px; + } + .sheet-generate-button { + padding: 1px 8px; + border-radius: 4px; + cursor: pointer; + background: #223297; + color: #FFF; + input[type=checkbox] { + position: absolute; + visibility: hidden; + } + &:active { + outline: 5px auto; + outline-offset: -2px; + } + } +} + /* Character core */ .sheet-core { display: grid; @@ -498,7 +556,7 @@ input[type=number].sheet-inline-input { } } &.sheet-core-stats { - grid: auto / minmax(310px, 1fr) minmax(260px, 1fr) minmax(220px, 1fr); + grid: auto / minmax(310px, 1.2fr) minmax(260px, 1fr) minmax(220px, .8fr); } .sheet-main-content { margin-top: 3px; @@ -561,20 +619,19 @@ input[type=number].sheet-inline-input { .sheet-weapons { .sheet-edit { justify-content: space-between; - .sheet-name { - width: 135px; - flex-grow: 1; - } + padding-right: 1px; + .sheet-name { width: 138px } .sheet-ab { width: 45px } .sheet-weapon-skill { width: 80px } .sheet-attribute { width: 60px } .sheet-burst { width: 65px } - .sheet-damage { width: 70px } - .sheet-shock-damage { width: 60px } + .sheet-damage { width: 60px } + .sheet-shock-damage { width: 55px } .sheet-shock-ac { width: 55px } - .sheet-skill-to-damage { width: 40px } - .sheet-range { width: 70px } + .sheet-skill-to-damage { width: 30px } + .sheet-range { width: 60px } .sheet-ammo { width: 80px } + .sheet-enc { width: 40px } } .sheet-text-input { padding-right: 3px } @@ -698,7 +755,7 @@ input[type=number].sheet-inline-input { letter-spacing: 1px; cursor: pointer; text-transform: uppercase; - font-size: .8em; + font-size: 10px; input { visibility: hidden; position: absolute; @@ -724,7 +781,7 @@ input[type=number].sheet-inline-input { /* Psionics */ .sheet-psionics-effort { display: grid; - grid: auto/ auto 60px 60px 80px; + grid: auto/ auto 60px 60px 60px 80px; align-items: center; grid-column-gap: 4px; margin-top: 5px; @@ -732,15 +789,17 @@ input[type=number].sheet-inline-input { } .sheet-techniques { margin-top: 5px; - padding: 0 4px; > .sheet-flex-center { margin-bottom: 5px } - input[type=text] { width:100% } + .sheet-display .sheet-discipline { margin-left: auto } + .sheet-edit .sheet-discipline { + margin-left: 5px; + width: 90px; + } } /* Space Magic */ .sheet-spells { margin-top: 5px; - padding: 0 4px; > .sheet-flex-center { margin-bottom: 5px } > .sheet-flex { border-bottom: 1px solid #666; @@ -797,13 +856,13 @@ input[type=number].sheet-inline-input { /* Gear */ .sheet-armor { - .sheet-name { - width: 150px; + .sheet-total-ac { margin-left: auto; + font-weight: bold; + } + .sheet-armor-grid { + grid: auto / 40px 1fr 40px 75px 35px 70px; } - .sheet-ac { width: 45px } - .sheet-enc { width: 60px } - .sheet-type { width: 80px } } .sheet-readied-stowed { display: grid; @@ -825,43 +884,33 @@ input[type=number].sheet-inline-input { } .sheet-equipment { .repcontainer[data-groupname="repeating_weapons"] + .repcontrol { display: none } - .repitem { - margin-bottom: 2px; - input[type=text], input[type=number], select { background: transparent } - input[type=text] { - flex-grow: 1; - width: 0; - } - input[type=number] { - width: 45px; - margin: 0 3px; - } - select { width: 80px } + .sheet-gear-grid { + grid: auto / minmax(120px,1fr) 2fr 35px 70px; } .sheet-other h3 { margin-bottom: 5px } - textarea { height: 100px } + .sheet-other-gear { height: 100px } } /* Misc */ .sheet-misc { - h3 { margin-bottom: 4px } - .repitem { - display: flex; - align-items: center; - margin-bottom: 2px; - } + .sheet-text-input input { padding-left: 2px } + .repitem { margin-bottom: 2px } + .sheet-xp { width: 50px } } -.sheet-goals { - input[type=text] { - flex-grow: 1; - margin-right: 5px; - } - input[type=number] { width: 70px } -} -.sheet-languages input { width: 100% } -.sheet-notes { margin: 10px 0 } +.sheet-notes { margin-top: 5px } /* Ship tab */ +.sheet-ship-class { + &[value="fighter"] ~ .sheet-section .sheet-generate-source { + .sheet-frigate, .sheet-cruiser, .sheet-capital { display: none } + } + &[value="frigate"] ~ .sheet-section .sheet-generate-source { + .sheet-cruiser, .sheet-capital { display: none } + } + &[value="cruiser"] ~ .sheet-section .sheet-generate-source { + .sheet-capital { display: none } + } +} .sheet-ship { margin-top: -20px; grid: auto/ repeat(4, 1fr); @@ -869,6 +918,15 @@ input[type=number].sheet-inline-input { h3 { line-height: 1 } button[type=roll].btn { line-height: 1 } } + .sheet-type { + padding: 5px 8px; + h3 { line-height: 1 } + select { + height: 20px; + width: 80px; + background: transparent; + } + } .sheet-info { flex-wrap: wrap; .sheet-text-input { margin-bottom: 3px } @@ -882,6 +940,26 @@ input[type=number].sheet-inline-input { display: grid; grid: auto / 1fr 1fr; } + .sheet-hulltype { + position: relative; + .sheet-details { + position: absolute; + z-index: 1; + opacity: 1; + width: 250px; + top: 22px; + left: -63px; + transition: all 0.3s; + background: #FFF; + border: 1px solid #777; + border-radius: 8px; + padding: 5px; + } + input:not(:focus) ~ .sheet-details { + visibility: hidden; + opacity: 0; + } + } .sheet-input-color-negative[value^="-"] + .sheet-text-input input:first-child { color: red } .repcontainer { display: grid; @@ -930,6 +1008,12 @@ input[type=number].sheet-inline-input { } .sheet-description { font-style: italic } } + + .sheet-input-type[value="SHIP"] ~ div .sheet-vehicle-type:not(.sheet-vehicle-type-ship), + .sheet-input-type[value="MECH"] ~ div .sheet-vehicle-type:not(.sheet-vehicle-type-mech), + .sheet-input-type[value="VEHICLE"] ~ div .sheet-vehicle-type:not(.sheet-vehicle-type-custom) { + display: none; + } } .sheet-editmode[value="0"] ~ .sheet-ship { .sheet-ship-defenses, .sheet-ship-fitting { @@ -1036,14 +1120,7 @@ input[type=number].sheet-inline-input { min-height: 175px; position: relative; padding: 18px 20px; - } - .sheet-background { - width: 100%; - height: calc(100% - 175px); - position: absolute; - top: 153px; - left: 0; - background: #0F0F0F; + clip-path: polygon(0 7px, 7px 0, 173px 0, 177px 3px, 281px 3px, 289px 11px, 289px 82px, 100% 87px, 100% calc(100% - 6px), calc(100% - 6px) 100%, 22px 100%, 0 calc(100% - 22px)); } .sheet-header { width: 198px; @@ -1097,7 +1174,8 @@ input[type=number].sheet-inline-input { .sheet-rolltemplate-swn-default { .sheet-container { background: url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-black.png") top no-repeat, - url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat; + url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat, + #0F0F0F; } .sheet-name { color: $rt-gray } .sheet-rollname { margin-right: auto } @@ -1120,7 +1198,8 @@ input[type=number].sheet-inline-input { .sheet-rolltemplate-swn-attack { .sheet-container { background: url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-purple.png") top no-repeat, - url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat; + url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat, + #0F0F0F; } .sheet-name { color: $rt-purple } .sheet-title { @@ -1156,7 +1235,8 @@ input[type=number].sheet-inline-input { .sheet-rolltemplate-swn-skill { .sheet-container { background: url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-blue.png") top no-repeat, - url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat; + url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat, + #0F0F0F; } .sheet-name { color: $rt-blue } .sheet-title { @@ -1173,12 +1253,14 @@ input[type=number].sheet-inline-input { .sheet-container { &.sheet-success { background: url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-green.png") top no-repeat, - url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat; + url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat, + #0F0F0F; .sheet-name { color: $rt-green } } &.sheet-failure { background: url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-red.png") top no-repeat, - url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat; + url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat, + #0F0F0F; .sheet-name { color: $rt-red } } } diff --git a/Stars_Without_Number_Revised/Source/build b/Stars_Without_Number_Revised/Source/build index 6a44e2b231..694d5645cc 100755 --- a/Stars_Without_Number_Revised/Source/build +++ b/Stars_Without_Number_Revised/Source/build @@ -1,4 +1,4 @@ #!/usr/bin/env bash pug -o . Source/Stars_Without_Number_Revised.pug -scss --sourcemap=none --no-cache --style compressed Source/Stars_Without_Number_Revised.scss Stars_Without_Number_Revised.css +sass --no-source-map --style compressed Source/Stars_Without_Number_Revised.scss Stars_Without_Number_Revised.css diff --git a/Stars_Without_Number_Revised/Source/pug/character.pug b/Stars_Without_Number_Revised/Source/pug/character.pug index 750d6551ac..7d9ee1053e 100644 --- a/Stars_Without_Number_Revised/Source/pug/character.pug +++ b/Stars_Without_Number_Revised/Source/pug/character.pug @@ -25,13 +25,13 @@ //- We have foci in two locations, so they are outsourced to this mixin mixin foci +sectionheader("show_foci", "FOCI") - .foci.simple-repsection + .foci.grey-box.simple-repsection input(type="hidden", name="attr_show_focus_details", value="1").input-details .class-ability button.display.invisible-button(type="roll", name="roll_Class_ability", value!="&{template:swn-default} {{charname=@{name}}} {{title=^{CLASS_ABILITY}}} {{desc=@{class_ability}}}") .display .name.flex - div(data-i18n="CLASS_ABILITY") + div #[span(data-i18n="CLASS_ABILITY")]: #[span(name="attr_class")] label.details-button input(type="checkbox", name="attr_show_focus_details", value="1", checked) span(data-i18n="EXPAND") @@ -39,12 +39,44 @@ mixin foci span(name="attr_class_ability") .edit .name.flex - div(data-i18n="CLASS_ABILITY") + div #[span(data-i18n="CLASS_ABILITY")]: #[span(name="attr_class")] label.details-button input(type="checkbox", name="attr_show_focus_details", value="1", checked) span(data-i18n="EXPAND") .details textarea.details(name="attr_class_ability") + .generate.flex-start.edit + select(name="attr_generate_foci_source").generate-source + option(value="", data-i18n="CHOOSE_FOCUS", selected) + option(value="alert", data-i18n="ALERT") + option(value="armsman", data-i18n="ARMSMAN") + option(value="assassin", data-i18n="ASSASSIN") + option(value="authority", data-i18n="AUTHORITY") + option(value="close_combatant", data-i18n="CLOSE_COMBATANT") + option(value="connected", data-i18n="CONNECTED") + option(value="die_hard", data-i18n="DIE_HARD") + option(value="diplomat", data-i18n="DIPLOMAT") + option(value="gunslinger", data-i18n="GUNSLINGER") + option(value="hacker", data-i18n="HACKER") + option(value="healer", data-i18n="HEALER") + option(value="henchkeeper", data-i18n="HENCHKEEPER") + option(value="ironhide", data-i18n="IRONHIDE") + option(value="psychic_training", data-i18n="PSYCHIC_TRAINING") + option(value="savage_fray", data-i18n="SAVAGE_FRAY") + option(value="shocking_assault", data-i18n="SHOCKING_ASSAULT") + option(value="sniper", data-i18n="SNIPER") + option(value="specialist", data-i18n="SPECIALIST") + option(value="star_captain", data-i18n="STAR_CAPTAIN") + option(value="starfarer", data-i18n="STARFARER") + option(value="tinker", data-i18n="TINKER") + option(value="unarmed_combatant", data-i18n="UNARMED_COMBATANT") + option(value="unique_gift", data-i18n="UNIQUE_GIFT") + option(value="wanderer", data-i18n="WANDERER") + option(value="wild_psychic_talent", data-i18n="WILD_PSYCHIC_TALENT") + span(name="attr_generate_foci_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_foci_button") + span(data-i18n="ADD") fieldset.repeating_foci button.display.invisible-button(type="roll", name="roll_Focus", value!="&{template:swn-default} {{charname=@{name}}} {{info=^{FOCUS}}} {{title=@{focus_name}}} {{desc=@{focus_description}}}") .display @@ -55,7 +87,7 @@ mixin foci span(name="attr_focus_description") .edit.flex-wrap input.name(type="text", name="attr_focus_name", data-i18n-placeholder="FOCUS") - input.level(type="number", min="0", name="attr_focus_level", data-i18n-placeholder="LEVEL") + input.level(type="number", min="0", value="1", name="attr_focus_level", data-i18n-placeholder="LEVEL") textarea.details(name="attr_focus_description", data-i18n-placeholder="DESCRIPTION") input(type="hidden", name="attr_homebrew_skill_list", value="revised").skills-type @@ -91,7 +123,7 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer button(type="roll", name="roll_Skills_macro", data-i18n="SKILLS", value!=`/w "@{character_name}" &{template:swn-default} {{charname=@{name}}} {{title=^{SKILLS}}} {{buttons=@{macro_skills}}}`).unstyled-button input(type="hidden", name="attr_macro_weapons") button(type="roll", name="roll_Weapons_macro", data-i18n="WEAPONS", value!=`/w "@{character_name}" &{template:swn-default} {{charname=@{name}}} {{title=^{WEAPONS}}} {{buttons=@{macro_weapons}}}`).unstyled-button - input(type="hidden", name="attr_macro_psionics" value="[^{BIOPSIONICS} (-1),](~skill_biopsionics) [^{METAPSIONICS} (-1),](~skill_metapsionics) [^{PRECOGNITION} (-1),](~skill_precognition) [^{TELEKINESIS} (-1),](~skill_telekinesis) [^{TELEPATHY} (-1),](~skill_telepathy) [^{TELEPORTATION} (-1)](~skill_teleportation)") + input(type="hidden", name="attr_macro_psionics" value="").hider button(type="roll", name="roll_Psionics_macro", data-i18n="PSIONICS", value!=`/w "@{character_name}" &{template:swn-default} {{charname=@{name}}} {{title=^{PSYCHIC_SKILLS_TECHNIQUES}}} {{buttons=@{macro_psionics}}}`).unstyled-button.super-psionics.super input(type="hidden", name="attr_macro_magic") button(type="roll", name="roll_Magic_macro", data-i18n="MAGIC", value!=`/w "@{character_name}" &{template:swn-default} {{charname=@{name}}} {{title=^{SPACE_MAGIC}}} {{buttons=@{macro_magic}}}`).unstyled-button.super-magic.super @@ -102,7 +134,8 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer h3(data-i18n="CORE_STATISTICS") .main-content +text-input-duo("HP", "HP_max", false, {value: "0"}).important - button.unstyled-button(type="roll", name="roll_HP", data-i18n="HIT_POINTS" value!="&{template:swn-default} {{charname=@{name}}} {{title=^{HIT_POINTS}}} {{ =[[{@{level}d6 + @{level}*@{constitution_mod}[CON] + @{level}*@{extra_hp_query}, @{hp|max} + 1d1}kh1 ]]}} {{info=^{MAXIMUM_HP_1} @{level}d6 + @{level}*[[@{constitution_mod}[CON] + @{extra_hp_query}]] ^{MAXIMUM_HP_2} [[@{hp|max} + 1]]}}") + .label + button.unstyled-button(type="roll", name="roll_HP", data-i18n="HIT_POINTS" value!="&{template:swn-default} {{charname=@{name}}} {{title=^{HIT_POINTS}}} {{ =[[{@{level}d6 + @{level}*@{constitution_mod}[CON] + @{level}*@{extra_hp_query}, @{hp|max} + 1d1}kh1 ]]}} {{info=^{MAXIMUM_HP_1} @{level}d6 + @{level}*[[@{constitution_mod}[CON] + @{extra_hp_query}]] ^{MAXIMUM_HP_2} [[@{hp|max} + 1]]}}") +text-input-duo("strain", "strain_max", "SYSTEM_STRAIN", {value: "10", readonly: true, "data-i18n-title": "CONSTITUTION"})(min="0", value="0") +text-input("strain_permanent", "PERMANENT_STRAIN")(type="number", min="0", value="0").center +text-input-duo("xp", "xp_next", "XP_NEXT_LEVEL", {min: "0", value: "3"})(min="0", value="0") @@ -120,6 +153,7 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer th(data-i18n="BONUS") th(data-i18n="MODIFIER") tbody + input(type="hidden", name="attr_str_dex_mod", value="0") each attr in attributes tr td(data-i18n=attr.toUpperCase(), data-i18n-title=`${attr.toUpperCase()}_DESC`) @@ -138,7 +172,8 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer +text-input("credits", "CREDITS")(type="number", value="0").credits.center.col50 fieldset.repeating_resources +text-input-duo("resource_count", "resource_count_max", "").display - span(name="attr_resource_name") + .label + span(name="attr_resource_name") .flex-center.edit input(type="text", name="attr_resource_name") input(type="number", name="attr_resource_count") @@ -150,6 +185,56 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer .section +sectionheader("show_weapons", "WEAPONS") .weapons + .generate.flex-start.edit + select(name="attr_generate_weapons_source").generate-source + option(value="", data-i18n="CHOOSE_WEAPON", selected) + optgroup(data-i18n-label="RANGED_WEAPONS") + option(value="primitive_bow", data-i18n="PRIMITIVE_BOW") + option(value="advanced_bow", data-i18n="ADVANCED_BOW") + option(value="conversion_bow", data-i18n="CONVERSION_BOW") + option(value="grenade", data-i18n="GRENADE") + option(value="crude_pistol", data-i18n="CRUDE_PISTOL") + option(value="musket", data-i18n="MUSKET") + option(value="revolver", data-i18n="REVOLVER") + option(value="rifle", data-i18n="RIFLE") + option(value="shotgun", data-i18n="SHOTGUN") + option(value="semi_auto_pistol", data-i18n="SEMI_AUTO_PISTOL") + option(value="submachine_gun", data-i18n="SUBMACHINE_GUN") + option(value="combat_rifle", data-i18n="COMBAT_RIFLE") + option(value="combat_shotgun", data-i18n="COMBAT_SHOTGUN") + option(value="sniper_rifle", data-i18n="SNIPER_RIFLE") + option(value="void_carbine", data-i18n="VOID_CARBINE") + option(value="mag_pistol", data-i18n="MAG_PISTOL") + option(value="mag_rifle", data-i18n="MAG_RIFLE") + option(value="spike_thrower", data-i18n="SPIKE_THROWER") + option(value="laser_pistol", data-i18n="LASER_PISTOL") + option(value="laser_rifle", data-i18n="LASER_RIFLE") + option(value="thermal_pistol", data-i18n="THERMAL_PISTOL") + option(value="plasma_projector", data-i18n="PLASMA_PROJECTOR") + option(value="shear_rifle", data-i18n="SHEAR_RIFLE") + option(value="thunder_gun", data-i18n="THUNDER_GUN") + option(value="distortion_cannon", data-i18n="DISTORTION_CANNON") + optgroup(data-i18n-label="MELEE_WEAPONS") + option(value="small_primitive_weapon", data-i18n="SMALL_PRIMITIVE_WEAPON") + option(value="medium_primitive_weapon", data-i18n="MEDIUM_PRIMITIVE_WEAPON") + option(value="large_primitive_weapon", data-i18n="LARGE_PRIMITIVE_WEAPON") + option(value="small_advanced_weapon", data-i18n="SMALL_ADVANCED_WEAPON") + option(value="medium_advanced_weapon", data-i18n="MEDIUM_ADVANCED_WEAPON") + option(value="large_advanced_weapon", data-i18n="LARGE_ADVANCED_WEAPON") + option(value="stun_baton", data-i18n="STUN_BATON") + option(value="suit_ripper", data-i18n="SUIT_RIPPER") + option(value="punch", data-i18n="PUNCH") + optgroup(data-i18n-label="HEAVY_WEAPONS") + option(value="heavy_machine_gun", data-i18n="HEAVY_MACHINE_GUN") + option(value="rocket_launcher", data-i18n="ROCKET_LAUNCHER") + option(value="railgun", data-i18n="RAILGUN") + option(value="anti_vehicle_laser", data-i18n="ANTI_VEHICLE_LASER") + option(value="hydra_array", data-i18n="HYDRA_ARRAY") + option(value="vortex_cannon", data-i18n="VORTEX_CANNON") + span(name="attr_generate_weapons_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_weapons_button") + span(data-i18n="ADD") fieldset.repeating_weapons input(type="hidden", name="attr_weapon_api", value="") input(type="hidden", name="attr_weapon_attack_display", value="") @@ -172,12 +257,13 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer | / span(name="attr_weapon_ammo_max") .edit.flex-wrap.grey-box-bordered - +text-input("weapon_name", "NAME").name + +text-input("weapon_name", "NAME").grow.name +text-input("weapon_attack", "ATTACK_BONUS_SHORT")(type="number", value="0").ab.center +fake-text-input("SKILL").skills-either.weapon-skill.center select(name="attr_weapon_skill_bonus") - option.skills-revised(value="@{skill_shoot}", data-i18n="SHOOT") + option.skills-revised(value="@{skill_exert}", data-i18n="EXERT") option.skills-revised(value="@{skill_punch}", data-i18n="PUNCH") + option.skills-revised(value="@{skill_shoot}", data-i18n="SHOOT", selected) option.skills-revised(value="@{skill_stab}", data-i18n="STAB") option.skills-first(value="@{skill_combat_energy}", data-i18n="COMBAT_ENERGY") option.skills-first(value="@{skill_combat_gunnery}", data-i18n="COMBAT_GUNNERY") @@ -192,22 +278,27 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer select(name="attr_weapon_attribute_mod") each attr in attributes option(value=`@{${attr}_mod}`, data-i18n=`${attr.toUpperCase()}_SHORT`) + option(value=`@{str_dex_mod}`, data-i18n=`STR_DEX`) +fake-text-input("BURST").burst.center select(name="attr_weapon_burst") option(value="", data-i18n="NO", selected) option(value="@{burst_query}", data-i18n="ASK") option(value="+ 2[Burst]", data-i18n="ALWAYS") - +text-input("weapon_damage", "DAMAGE")(value="0").damage.center + +text-input("weapon_damage", "DAMAGE")(value="0").damage.grow.center +fake-text-input("+SKILL").skill-to-damage.center input(type="checkbox", name="attr_weapon_skill_to_damage", value="@{weapon_skill_bonus}") - +text-input("weapon_shock_damage")(value="0").shock-damage.center - input(type="checkbox", name="attr_weapon_shock", value!="{{shock=[[@{weapon_shock_damage} + @{weapon_attribute_mod}[Attribute] + @{weapon_skill_to_damage}[Skill]]] ^{SHOCK_DAMAGE_AGAINST_AC_LEQ} @{weapon_shock_ac}!}}") - span(data-i18n="SHOCK") + .text-input.shock-damage.center + input(type="text", name="attr_weapon_shock_damage", value="0") + label.label + input(type="checkbox", name="attr_weapon_shock", value!="{{shock=[[@{weapon_shock_damage} + @{weapon_attribute_mod}[Attribute] + @{weapon_skill_to_damage}[Skill]]] ^{SHOCK_DAMAGE_AGAINST_AC_LEQ} @{weapon_shock_ac}!}}") + span(data-i18n="SHOCK") +text-input("weapon_shock_ac", "SHOCK_AC")(type="number", value="10").shock-ac.center - +text-input("weapon_range", "RANGE").range.center + +text-input("weapon_range", "RANGE").range.grow.center +text-input-duo("weapon_ammo", "weapon_ammo_max", "", {value: "0"}).ammo.center - input(type="checkbox", name="attr_weapon_use_ammo", value!="{{ammo=[[0@{weapon_ammo} - (1 @{weapon_burst})]] / @{weapon_ammo|max}}}") - span(data-i18n="AMMO") + label.label + input(type="checkbox", name="attr_weapon_use_ammo", value!="{{ammo=[[0@{weapon_ammo} - (1 @{weapon_burst})]] / @{weapon_ammo|max}}}") + span(data-i18n="AMMO") + +text-input("weapon_encumbrance", "ENCUMBRANCE_SHORT")(type="number", value="0").enc.center //- Foci .section.foci-left @@ -231,28 +322,121 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer .skills-psionic.skill-container(data-i18n-list="SKILL_ORDER_PSIONIC") each skill in skills.psionic +makeSkill(skill) + .skill.skill-points + .display.flex-center + span(data-i18n="UNSPENT_PSIONIC_SKILL_POINTS").name + span(name="attr_unspent_psionic_skill_points").level + .edit.flex-center + span(data-i18n="UNSPENT_PSIONIC_SKILL_POINTS").name + input(type="number", min="0", value="0", name="attr_unspent_psionic_skill_points").level .skills-repeating fieldset.repeating_psychic-skills +makeSkill("", true) .psionics-effort.grey-box h3(data-i18n="COMMITTED_EFFORT") + +text-input("psionics_committed_effort_current", "CURRENT")(type="number", value="0", min="0").center +text-input("psionics_committed_effort_scene", "SCENE")(type="number", value="0", min="0").center +text-input("psionics_committed_effort_day", "DAY")(type="number", value="0", min="0").center - +text-input("psionics_total_effort", "MAXIMUM")(type="number", value="0", readonly, data-i18n-title="MAXIMUM_EFFORT_DESC").center - .techniques.simple-repsection + +text-input("psionics_total_effort", "UNCOMMITTED")(type="number", value="1", readonly, data-i18n-title="MAXIMUM_EFFORT_DESC").center + .techniques.grey-box.simple-repsection .flex-center h3(data-i18n="PSYCHIC_TECHNIQUES") label.details-button input(type="checkbox", name="attr_show_technique_details", value="1", checked) span(data-i18n="EXPAND") + .generate.flex-start.edit + select(name="attr_generate_techniques_source").generate-source + option(data-i18n="CHOOSE_TECHNIQUE") + optgroup(data-i18n-label="BIOPSIONICS") + option(value="psychic_succor", data-i18n="PSYCHIC_SUCCOR") + option(value="mastered_succor", data-i18n="MASTERED_SUCCOR") + option(value="organic_purification_protocols", data-i18n="ORGANIC_PURIFICATION_PROTOCOLS") + option(value="remote_repair", data-i18n="REMOTE_REPAIR") + option(value="invincible_stand", data-i18n="INVINCIBLE_STAND") + option(value="major_organ_restoration", data-i18n="MAJOR_ORGAN_RESTORATION") + option(value="tissue_integrity_field", data-i18n="TISSUE_INTEGRITY_FIELD") + option(value="accelerated_succor", data-i18n="ACCELERATED_SUCCOR") + option(value="metamorph", data-i18n="METAMORPH") + option(value="teratic_overload", data-i18n="TERATIC_OVERLOAD") + option(value="holistic_optimization_patterning", data-i18n="HOLISTIC_OPTIMIZATION_PATTERNING") + option(value="quintessential_reconstruction", data-i18n="QUINTESSENTIAL_RECONSTRUCTION") + optgroup(data-i18n-label="METAPSIONICS") + option(value="psychic_refinement", data-i18n="PSYCHIC_REFINEMENT") + option(value="cloak_powers", data-i18n="CLOAK_POWERS") + option(value="mindtracing", data-i18n="MINDTRACING") + option(value="synthetic_adaptation", data-i18n="SYNTHETIC_ADAPTATION") + option(value="neural_trap", data-i18n="NEURAL_TRAP") + option(value="psychic_static", data-i18n="PSYCHIC_STATIC") + option(value="suspended_manifestation", data-i18n="SUSPENDED_MANIFESTATION") + option(value="concert_of_minds", data-i18n="CONCERT_OF_MINDS") + option(value="metadimensional_friction", data-i18n="METADIMENSIONAL_FRICTION") + option(value="psychic_tutelage", data-i18n="PSYCHIC_TUTELAGE") + option(value="surge_momentum", data-i18n="SURGE_MOMENTUM") + option(value="flawless_mastery", data-i18n="FLAWLESS_MASTERY") + option(value="impervious_pavis_of_will", data-i18n="IMPERVIOUS_PAVIS_OF_WILL") + optgroup(data-i18n-label="PRECOGNITION") + option(value="oracle", data-i18n="ORACLE") + option(value="intuitive_response", data-i18n="INTUITIVE_RESPONSE") + option(value="sense_the_need", data-i18n="SENSE_THE_NEED") + option(value="terminal_reflection", data-i18n="TERMINAL_REFLECTION") + option(value="alternate_outcome", data-i18n="ALTERNATE_OUTCOME") + option(value="destinys_shield", data-i18n="DESTINYS_SHIELD") + option(value="anguished_vision", data-i18n="ANGUISHED_VISION") + option(value="cursed_luck", data-i18n="CURSED_LUCK") + option(value="forced_outcome", data-i18n="FORCED_OUTCOME") + option(value="not_my_time", data-i18n="NOT_MY_TIME") + option(value="prophecy", data-i18n="PROPHECY") + optgroup(data-i18n-label="TELEKINESIS") + option(value="telekinetic_manipulation", data-i18n="TELEKINETIC_MANIPULATION") + option(value="kinetic_transversal", data-i18n="KINETIC_TRANSVERSAL") + option(value="pressure_field", data-i18n="PRESSURE_FIELD") + option(value="telekinetic_armory", data-i18n="TELEKINETIC_ARMORY") + option(value="impact_sump", data-i18n="IMPACT_SUMP") + option(value="slip_field", data-i18n="SLIP_FIELD") + option(value="telekinetic_expertise", data-i18n="TELEKINETIC_EXPERTISE") + option(value="thermokinesis", data-i18n="THERMOKINESIS") + option(value="tangible_force_construct", data-i18n="TANGIBLE_FORCE_CONSTRUCT") + option(value="telekinetic_ram", data-i18n="TELEKINETIC_RAM") + option(value="reactive_telekinesis", data-i18n="REACTIVE_TELEKINESIS") + option(value="force_puppetry", data-i18n="FORCE_PUPPETRY") + option(value="telekinetic_flight", data-i18n="TELEKINETIC_FLIGHT") + optgroup(data-i18n-label="TELEPATHY") + option(value="telepathic_contact", data-i18n="TELEPATHIC_CONTACT") + option(value="facile_mind", data-i18n="FACILE_MIND") + option(value="transmit_thought", data-i18n="TRANSMIT_THOUGHT") + option(value="far_thought", data-i18n="FAR_THOUGHT") + option(value="suppress_cognition", data-i18n="SUPPRESS_COGNITION") + option(value="reflex_response", data-i18n="REFLEX_RESPONSE") + option(value="telepathic_assault", data-i18n="TELEPATHIC_ASSAULT") + option(value="memory_editing", data-i18n="MEMORY_EDITING") + option(value="unity_of_thought", data-i18n="UNITY_OF_THOUGHT") + optgroup(data-i18n-label="TELEPORTATION") + option(value="personal_apportation", data-i18n="PERSONAL_APPORTATION") + option(value="proficient_apportation", data-i18n="PROFICIENT_APPORTATION") + option(value="spatial_awareness", data-i18n="SPATIAL_AWARENESS") + option(value="burdened_apportation", data-i18n="BURDENED_APPORTATION") + option(value="perceptive_dislocation", data-i18n="PERCEPTIVE_DISLOCATION") + option(value="spatial_synchrony_mandala", data-i18n="SPATIAL_SYNCHRONY_MANDALA") + option(value="effortless_apportation", data-i18n="EFFORTLESS_APPORTATION") + option(value="stutterjump", data-i18n="STUTTERJUMP") + option(value="rift_reduplication", data-i18n="RIFT_REDUPLICATION") + option(value="deep_intrusion", data-i18n="DEEP_INTRUSION") + option(value="offensive_apportation", data-i18n="OFFENSIVE_APPORTATION") + span(name="attr_generate_techniques_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_techniques_button") + span(data-i18n="ADD") input(type="hidden", name="attr_show_technique_details", value="1").input-details fieldset.repeating_techniques - button.display.invisible-button(name="roll_Technique", type="roll", value!="&{template:swn-default} {{charname=@{name}}} {{info=^{PSYCHIC_TECHNIQUE}}} {{title=@{technique_name}}} {{desc=@{technique_description}}}") + button.display.invisible-button(name="roll_Technique", type="roll", value!="&{template:swn-default} {{charname=@{name}}} {{info=^{PSYCHIC_TECHNIQUE} — @{technique_discipline}}} {{title=@{technique_name}}} {{desc=@{technique_description}}}") .display - .name #[span(name="attr_technique_name")] + .name.flex + span(name="attr_technique_name") + span.discipline(name="attr_technique_discipline") .details #[span(name="attr_technique_description")] - .edit - input.name(type="text", name="attr_technique_name", data-i18n-placeholder="TECHNIQUE") + .edit.flex-wrap + input.name.grow(type="text", name="attr_technique_name", data-i18n-placeholder="TECHNIQUE") + input.discipline(type="text", name="attr_technique_discipline", data-i18n-placeholder="DISCIPLINE") textarea.details(name="attr_technique_description", data-i18n-placeholder="DESCRIPTION") .magic .skill-container @@ -262,7 +446,7 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer .skills-repeating fieldset.repeating_magic-skills +makeSkill("", true) - .spells.simple-repsection + .spells.grey-box.simple-repsection .flex-center h3(data-i18n="SPELLS") label.details-button @@ -336,44 +520,212 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer +text-input("credits", "CREDITS")(value="0", min="0", type="number").center +text-input("credits_owed", "CREDITS_OWED")(value="0", min="0", type="number").center .grey-box + .generate.flex-start.edit + select(name="attr_generate_gear_source").generate-source + option(data-i18n="CHOOSE_GEAR") + optgroup(data-i18n-label="AMMO_AND_POWER") + option(value="ammo_20_rounds", data-i18n="AMMO_20_ROUNDS") + option(value="ammo_missile", data-i18n="AMMO_MISSILE") + option(value="power_cell_type_a", data-i18n="POWER_CELL_TYPE_A") + option(value="power_cell_type_b", data-i18n="POWER_CELL_TYPE_B") + option(value="solar_recharger", data-i18n="SOLAR_RECHARGER") + option(value="telekinetic_generator", data-i18n="TELEKINETIC_GENERATOR") + optgroup(data-i18n-label="COMMUNICATIONS") + option(value="comm_server", data-i18n="COMM_SERVER") + option(value="compad", data-i18n="COMPAD") + option(value="field_radio", data-i18n="FIELD_RADIO") + option(value="translator_torc", data-i18n="TRANSLATOR_TORC") + optgroup(data-i18n-label="COMPUTING_GEAR") + option(value="black_slab", data-i18n="BLACK_SLAB") + option(value="data_phase_tab", data-i18n="DATA_PHASE_TAB") + option(value="data_protocol", data-i18n="DATA_PROTOCOL") + option(value="dataslab", data-i18n="DATASLAB") + option(value="line_shunt", data-i18n="LINE_SHUNT") + option(value="remote_link_unit", data-i18n="REMOTE_LINK_UNIT") + option(value="stiletto_charge", data-i18n="STILETTO_CHARGE") + option(value="storage_unit", data-i18n="STORAGE_UNIT") + option(value="tightbeam_link_unit", data-i18n="TIGHTBEAM_LINK_UNIT") + optgroup(data-i18n-label="FIELD_EQUIPMENT") + option(value="atmofilter", data-i18n="ATMOFILTER") + option(value="backpack", data-i18n="BACKPACK") + option(value="binoculars", data-i18n="BINOCULARS") + option(value="climbing_harness", data-i18n="CLIMBING_HARNESS") + option(value="glowbug", data-i18n="GLOWBUG") + option(value="grapnel_launcher", data-i18n="GRAPNEL_LAUNCHER") + option(value="grav_chute", data-i18n="GRAV_CHUTE") + option(value="grav_harness", data-i18n="GRAV_HARNESS") + option(value="instapanel", data-i18n="INSTAPANEL") + option(value="low_light_goggles", data-i18n="LOW_LIGHT_GOGGLES") + option(value="navcomp", data-i18n="NAVCOMP") + option(value="portabox", data-i18n="PORTABOX") + option(value="pressure_tent", data-i18n="PRESSURE_TENT") + option(value="rations_1_day", data-i18n="RATIONS_1_DAY") + option(value="rope_20_meters", data-i18n="ROPE_20_METERS") + option(value="scout_report", data-i18n="SCOUT_REPORT") + option(value="survey_scanner", data-i18n="SURVEY_SCANNER") + option(value="survival_kit", data-i18n="SURVIVAL_KIT") + option(value="telescoping_pole", data-i18n="TELESCOPING_POLE") + option(value="thermal_flare", data-i18n="THERMAL_FLARE") + option(value="trade_goods", data-i18n="TRADE_GOODS") + option(value="trade_metals", data-i18n="TRADE_METALS") + option(value="vacc_fresher", data-i18n="VACC_FRESHER") + option(value="vacc_skin", data-i18n="VACC_SKIN") + option(value="vacc_suit", data-i18n="VACC_SUIT") + optgroup(data-i18n-label="PHARMACEUTICALS") + option(value="bezoar", data-i18n="BEZOAR") + option(value="brainwave", data-i18n="BRAINWAVE") + option(value="hush", data-i18n="HUSH") + option(value="lift", data-i18n="LIFT") + option(value="psych", data-i18n="PSYCH") + option(value="pretech_cosmetic", data-i18n="PRETECH_COSMETIC") + option(value="reverie", data-i18n="REVERIE") + option(value="squeal", data-i18n="SQUEAL") + option(value="tsunami", data-i18n="TSUNAMI") + optgroup(data-i18n-label="TOOLS_AND_MEDICAL") + option(value="bioscanner", data-i18n="BIOSCANNER") + option(value="lazarus_patch", data-i18n="LAZARUS_PATCH") + option(value="medkit", data-i18n="MEDKIT") + option(value="metatool", data-i18n="METATOOL") + option(value="spare_parts", data-i18n="SPARE_PARTS") + option(value="tailored_antiallergens", data-i18n="TAILORED_ANTIALLERGENS") + option(value="toolkit_postech", data-i18n="TOOLKIT_POSTECH") + option(value="toolkit_pretech", data-i18n="TOOLKIT_PRETECH") + span(name="attr_generate_gear_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_gear_button") + span(data-i18n="ADD") + .table-header.gear-grid.rep-grid + .name(data-i18n="NAME") + .details(data-i18n="DESCRIPTION") + .enc(data-i18n="ENCUMBRANCE_SHORT") + .status(data-i18n="STATUS") fieldset.repeating_weapons - .flex - input.name(type="text", name="attr_weapon_name", readonly) - input.encumbrance(type="number", min="0", value="0", name="attr_weapon_encumbrance", data-i18n-title="ENCUMBRANCE") - select.status(name="attr_weapon_status") - option(value="", data-i18n="OTHER", selected) - option(value="READIED", data-i18n="READIED") - option(value="STOWED", data-i18n="STOWED") + input(type="hidden", name="attr_weapon_encumbrance", value="0").hider + .gear-grid.rep-grid + +text-input("weapon_name")(readonly) + +fake-text-input() + textarea(name="attr_weapon_description") + +text-input("weapon_encumbrance")(type="number", value="0").center + +fake-text-input() + select.status(name="attr_weapon_status") + option(value="", data-i18n="OTHER", selected) + option(value="READIED", data-i18n="READIED") + option(value="STOWED", data-i18n="STOWED") fieldset.repeating_gear - .flex - input.name(type="text", name="attr_gear_name", data-i18n-placeholder="ITEM") - input.encumbrance(type="number", min="0", value="0", name="attr_gear_encumbrance", data-i18n-title="ENCUMBRANCE") - select.status(name="attr_gear_status") - option(value="", data-i18n="OTHER", selected) - option(value="READIED", data-i18n="READIED") - option(value="STOWED", data-i18n="STOWED") + .gear-grid.rep-grid + +text-input("gear_name")(data-i18n-placeholder="ITEM") + +fake-text-input() + textarea(name="attr_gear_description") + +text-input("gear_encumbrance")(type="number", value="0").center + +fake-text-input() + select.status(name="attr_gear_status") + option(value="", data-i18n="OTHER", selected) + option(value="READIED", data-i18n="READIED") + option(value="STOWED", data-i18n="STOWED") .grey-box.other h3(data-i18n="OTHER_EQUIPMENT") textarea(name="attr_gear_other").other-gear .column - .armor.grey-box.flex-center - h3(data-i18n="ARMOR") - +text-input("armor_name", "NAME").name - +text-input("armor_ac", "AC")(type="number", value="0").center.ac - +text-input("armor_encumbrance", "ENCUMBRANCE_SHORT")(type="number", value="0").center.enc - +fake-text-input("TYPE").type.center - select(name="attr_armor_type") - option(value="none", data-i18n="NONE") - option(value="primitive", data-i18n="PRIMITIVE") - option(value="street", data-i18n="STREET", selected) - option(value="combat", data-i18n="COMBAT") - option(value="powered", data-i18n="POWERED") + .armor.grey-box + .flex-center + h3(data-i18n="ARMOR") + .total-ac #[span(data-i18n="AC")] #[span(name="attr_AC")] + .generate.flex-start.edit + select(name="attr_generate_armor_source").generate-source + option(value="", data-i18n="CHOOSE_ARMOR", selected) + optgroup(data-i18n-label="PRIMITIVE") + option(value="shield", data-i18n="SHIELD") + option(value="leather_jacks_thick_hides_quilted_armor", data-i18n="LEATHER_JACKS_THICK_HIDES_QUILTED_ARMOR") + option(value="cuirass_brigandine_linothorax_half_plate", data-i18n="CUIRASS_BRIGANDINE_LINOTHORAX_HALF_PLATE") + option(value="full_plate_layered_mail", data-i18n="FULL_PLATE_LAYERED_MAIL") + optgroup(data-i18n-label="STREET") + option(value="warpaint", data-i18n="WARPAINT") + option(value="armored_undersuit", data-i18n="ARMORED_UNDERSUIT") + option(value="secure_clothing", data-i18n="SECURE_CLOTHING") + option(value="armored_vacc_suit", data-i18n="ARMORED_VACC_SUIT") + option(value="deflector_array", data-i18n="DEFLECTOR_ARRAY") + optgroup(data-i18n-label="COMBAT") + option(value="force_pavis", data-i18n="FORCE_PAVIS") + option(value="security_armor", data-i18n="SECURITY_ARMOR") + option(value="woven_body_armor", data-i18n="WOVEN_BODY_ARMOR") + option(value="combat_field_uniform", data-i18n="COMBAT_FIELD_UNIFORM") + option(value="icarus_harness", data-i18n="ICARUS_HARNESS") + optgroup(data-i18n-label="POWERED") + option(value="vestimentum", data-i18n="VESTIMENTUM") + option(value="assault_suit", data-i18n="ASSAULT_SUIT") + option(value="storm_armor", data-i18n="STORM_ARMOR") + option(value="field_emitter_panoply", data-i18n="FIELD_EMITTER_PANOPLY") + span(name="attr_generate_armor_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_armor_button") + span(data-i18n="ADD") + .table-header.armor-grid.rep-grid + .active.center(data-i18n="ACTIVE?") + .name(data-i18n="NAME") + .ac(data-i18n="AC") + .type(data-i18n="TYPE") + .enc(data-i18n="ENCUMBRANCE_SHORT") + .status(data-i18n="STATUS") + .armor-grid.rep-grid.edit + +text-input("innate_ac_name")(value="Innate AC").col-2 + +text-input("innate_ac")(type="number", value="10").center + fieldset.repeating_armor + .armor-grid.rep-grid + +fake-text-input().center + input(type="checkbox", name="attr_armor_active", value="1") + +text-input("armor_name") + +text-input("armor_ac")(type="number", value="0").center + +fake-text-input() + select(name="attr_armor_type") + option(value="none", data-i18n="NONE") + option(value="PRIMITIVE", data-i18n="PRIMITIVE") + option(value="STREET", data-i18n="STREET", selected) + option(value="COMBAT", data-i18n="COMBAT") + option(value="POWERED", data-i18n="POWERED") + option(value="SHIELD", data-i18n="SHIELD") + +text-input("armor_encumbrance")(type="number", value="0").center + +fake-text-input() + select(name="attr_armor_status") + option(value="", data-i18n="OTHER", selected) + option(value="READIED", data-i18n="READIED") + option(value="STOWED", data-i18n="STOWED") .cyberware.simple-repsection.grey-box .flex-center h3(data-i18n="CYBERWARE") label.details-button input(type="checkbox", name="attr_show_cyberware_details", value="1", checked) span(data-i18n="EXPAND") + .generate.flex-start.edit + select(name="attr_generate_cyberware_source").generate-source + option(value="", data-i18n="CHOOSE_CYBERWARE", selected) + option(value="adrenal_suppression_pump", data-i18n="ADRENAL_SUPPRESSION_PUMP") + option(value="bioadaptation_augments", data-i18n="BIOADAPTATION_AUGMENTS") + option(value="body_arsenal_array", data-i18n="BODY_ARSENAL_ARRAY") + option(value="body_sculpting", data-i18n="BODY_SCULPTING") + option(value="dermal_armor", data-i18n="DERMAL_ARMOR") + option(value="drone_control_link", data-i18n="DRONE_CONTROL_LINK") + option(value="eelskin_capacitor_mesh", data-i18n="EELSKIN_CAPACITOR_MESH") + option(value="gecko_anchors", data-i18n="GECKO_ANCHORS") + option(value="ghost_talker_transceiver", data-i18n="GHOST_TALKER_TRANSCEIVER") + option(value="holdout_cavity", data-i18n="HOLDOUT_CAVITY") + option(value="holoskin_emitter", data-i18n="HOLOSKIN_EMITTER") + option(value="identity_submersion_trigger", data-i18n="IDENTITY_SUBMERSION_TRIGGER") + option(value="immunofiltration_systems", data-i18n="IMMUNOFILTRATION_SYSTEMS") + option(value="induced_coma_trigger", data-i18n="INDUCED_COMA_TRIGGER") + option(value="neurointruder_alert", data-i18n="NEUROINTRUDER_ALERT") + option(value="panspectral_optics", data-i18n="PANSPECTRAL_OPTICS") + option(value="pressure_sheathing", data-i18n="PRESSURE_SHEATHING") + option(value="prosthetic_limb", data-i18n="PROSTHETIC_LIMB") + option(value="revenant_wiring", data-i18n="REVENANT_WIRING") + option(value="slowtime_window", data-i18n="SLOWTIME_WINDOW") + option(value="stabilization_overrides", data-i18n="STABILIZATION_OVERRIDES") + option(value="tagger_nanites", data-i18n="TAGGER_NANITES") + option(value="toxin_injector", data-i18n="TOXIN_INJECTOR") + option(value="twitchlock_actuators", data-i18n="TWITCHLOCK_ACTUATORS") + span(name="attr_generate_cyberware_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_cyberware_button") + span(data-i18n="ADD") input(type="hidden", name="attr_show_cyberware_details", value="1").input-details fieldset.repeating_cyberware button.display.invisible-button(name="roll_Cyberware", type="roll", value!="&{template:swn-default} {{charname=@{name}}} {{title=@{cyberware_name}}} {{info=^{CYBERWARE}; @{cyberware_strain} ^{STRAIN}}} {{desc=@{cyberware_description}}}") @@ -396,10 +748,13 @@ input(type="hidden", name="attr_setting_skill_query", value="hover").skills-quer .goals.grey-box.col-1-3 h3(data-i18n="GOALS") fieldset.repeating_goals - input(type="text", name="attr_goal_name") - input(type="number", min="0", data-i18n-placeholder="XP", name="attr_goal_xp") + .flex + +text-input("goal_name").name.grow + +text-input("goal_xp")(type="number", min="0", data-i18n-placeholder="XP").xp.center .languages.grey-box h3(data-i18n="LANGUAGES") fieldset.repeating_languages - input(type="text", name="attr_language") - textarea.notes(name="attr_notes", data-i18n-placeholder="NOTES") + +text-input("language") + .halfgrid.notes + textarea(name="attr_notes", data-i18n-placeholder="NOTES") + textarea(name="attr_other_notes", data-i18n-placeholder="NOTES") diff --git a/Stars_Without_Number_Revised/Source/pug/header.pug b/Stars_Without_Number_Revised/Source/pug/header.pug index 6d135dc389..3b648ccb40 100644 --- a/Stars_Without_Number_Revised/Source/pug/header.pug +++ b/Stars_Without_Number_Revised/Source/pug/header.pug @@ -51,6 +51,10 @@ input(type="hidden", name="attr_show_settings" value="0").hider span(data-i18n="HEROIC_CHARACTERS").colon-after input(type="checkbox", name="attr_setting_heroic_enable", value="1") span(data-i18n="HEROIC_CHARACTERS_DESC") + input(type="hidden", name="attr_setting_heroic_enable", value="0").hider + label + span(data-i18n="DEFY_DOOM_DIE_SIZE") + input(type="number", name="attr_doom_size", value="6") p label span(data-i18n="SUBSYSTEMS").colon-after @@ -77,12 +81,6 @@ input(type="hidden", name="attr_show_settings" value="0").hider option(value="hide", data-i18n="EDIT_MODE_ONLY") div h2(data-i18n="GENERAL SETTINGS") - p - label - span(data-i18n="SHIP_TAB_LABEL").colon-after - select(name="attr_setting_ship_tab_name") - option(value="SHIP", data-i18n="SHIP", selected) - option(value="MECH", data-i18n="MECH") p label span(data-i18n="FOCI_LOCATION").colon-after @@ -90,6 +88,10 @@ input(type="hidden", name="attr_show_settings" value="0").hider option(value="left", data-i18n="LEFT_COLUMN") option(value="right", data-i18n="RIGHT_COLUMN") span(data-i18n="FOCI_LOCATION_DESC") + p + label + span(data-i18n="UNTRAINED_SKILLS_IN_QUICK_MACRO").colon-after + input(type="checkbox", name="attr_setting_show_untrained_skills", value="1", checked) p label span(data-i18n="QUERY_FOR_MODIFIERS").colon-after @@ -101,23 +103,15 @@ input(type="hidden", name="attr_show_settings" value="0").hider input(type="checkbox", name="attr_setting_individual_hidden", value="1", checked) span(data-i18n="FINE_NPC_WHISPERING_DESC") h2(data-i18n="GLOBAL_STATS") - p.flex-between + p label span(data-i18n="EFFORT_MODIFIER") input(type="number", name="attr_psionics_extra_effort", value="0") - label - span(data-i18n="INNATE_AC") - input(type="number", name="attr_innate_ac", value="10") - p - input(type="hidden", name="attr_setting_heroic_enable", value="0").hider - label - span(data-i18n="DEFY_DOOM_DIE_SIZE") - input(type="number", name="attr_doom_size", value="6") //- Choose Character/Ship .tabs.flex label input(type="radio", name="attr_tab", value="ship") - span(name="attr_setting_ship_tab_name" data-i18n-dynamic) + span(name="attr_ship_vehicle_type", data-i18n-dynamic) label.pc-tab input(type="radio", name="attr_tab", value="character", checked) span(data-i18n="CHARACTER") diff --git a/Stars_Without_Number_Revised/Source/pug/mixins.pug b/Stars_Without_Number_Revised/Source/pug/mixins.pug index e81b1773a4..62bc757323 100644 --- a/Stars_Without_Number_Revised/Source/pug/mixins.pug +++ b/Stars_Without_Number_Revised/Source/pug/mixins.pug @@ -28,9 +28,9 @@ mixin text-input(name, label, extraclass) label(class=["text-input", classes]) input(type="text", name=`attr_${name}`, class=extraclass)&attributes(attributes) if (label) - div(data-i18n=label) + .label(data-i18n=label) else - div + .label block mixin text-input-duo(name1, name2, label, attributes2) @@ -51,10 +51,9 @@ mixin text-input-duo(name1, name2, label, attributes2) span / input(type="number", name=`attr_${name2}`)&attributes(attributes2) if (label) - div(data-i18n=label) + .label(data-i18n=label) else - div - block + block mixin fake-text-input(label) //- Creates a label container that looks like one of the underlined text inputs. @@ -65,7 +64,7 @@ mixin fake-text-input(label) class is passed on to the containing label label(class=["text-input", attributes.class]) block - div(data-i18n=label) + .label(data-i18n=label) mixin makeSave(name) //- Creates a saving throw button @@ -100,21 +99,21 @@ mixin makeSkill(skillName, custom, label) else span(data-i18n=skillName.toUpperCase()).name select(name=`attr_${skillPrefix}_query`).query.skills-query-hover - option(value="@{attribute_query_str}" data-i18n="STRENGTH_SHORT") - option(value="@{attribute_query_dex}" data-i18n="DEXTERITY_SHORT") - option(value="@{attribute_query_con}" data-i18n="CONSTITUTION_SHORT") - option(value="@{attribute_query_int}" data-i18n="INTELLIGENCE_SHORT") - option(value="@{attribute_query_wis}" data-i18n="WISDOM_SHORT") - option(value="@{attribute_query_cha}" data-i18n="CHARISMA_SHORT") - option(value="@{attribute_query_none}" data-i18n="NONE", selected) + option(value="@{attribute_query_str}", data-i18n="STRENGTH_SHORT") + option(value="@{attribute_query_dex}", data-i18n="DEXTERITY_SHORT") + option(value="@{attribute_query_con}", data-i18n="CONSTITUTION_SHORT") + option(value="@{attribute_query_int}", data-i18n="INTELLIGENCE_SHORT") + option(value="@{attribute_query_wis}", data-i18n="WISDOM_SHORT") + option(value="@{attribute_query_cha}", data-i18n="CHARISMA_SHORT") + option(value="@{attribute_query}", data-i18n="ASK", selected) .skills-query-display - input(type="hidden", name=`attr_${skillPrefix}_query`, value="@{attribute_query_none}") - span.str + #[span(data-i18n="STRENGTH_SHORT")] - span.dex + #[span(data-i18n="DEXTERITY_SHORT")] - span.con + #[span(data-i18n="CONSTITUTION_SHORT")] - span.int + #[span(data-i18n="INTELLIGENCE_SHORT")] - span.wis + #[span(data-i18n="WISDOM_SHORT")] - span.cha + #[span(data-i18n="CHARISMA_SHORT")] + input(type="hidden", name=`attr_${skillPrefix}_query`, value="@{attribute_query}") + span.str + #[span(data-i18n="STRENGTH_SHORT")] + span.dex + #[span(data-i18n="DEXTERITY_SHORT")] + span.con + #[span(data-i18n="CONSTITUTION_SHORT")] + span.int + #[span(data-i18n="INTELLIGENCE_SHORT")] + span.wis + #[span(data-i18n="WISDOM_SHORT")] + span.cha + #[span(data-i18n="CHARISMA_SHORT")] input(type="hidden", name=`attr_${skillPrefix}`, value="-1").add-plus span(name=`attr_${skillPrefix}`).level div(class=["edit", custom ? "flex-wrap" : "flex-center"]) @@ -123,13 +122,13 @@ mixin makeSkill(skillName, custom, label) else div(data-i18n=skillName.toUpperCase()).name select(name=`attr_${skillPrefix}_query`).query - option(value="@{attribute_query_str}" data-i18n="STRENGTH_SHORT") - option(value="@{attribute_query_dex}" data-i18n="DEXTERITY_SHORT") - option(value="@{attribute_query_con}" data-i18n="CONSTITUTION_SHORT") - option(value="@{attribute_query_int}" data-i18n="INTELLIGENCE_SHORT") - option(value="@{attribute_query_wis}" data-i18n="WISDOM_SHORT") - option(value="@{attribute_query_cha}" data-i18n="CHARISMA_SHORT") - option(value="@{attribute_query_none}" data-i18n="NONE", selected) + option(value="@{attribute_query_str}", data-i18n="STRENGTH_SHORT") + option(value="@{attribute_query_dex}", data-i18n="DEXTERITY_SHORT") + option(value="@{attribute_query_con}", data-i18n="CONSTITUTION_SHORT") + option(value="@{attribute_query_int}", data-i18n="INTELLIGENCE_SHORT") + option(value="@{attribute_query_wis}", data-i18n="WISDOM_SHORT") + option(value="@{attribute_query_cha}", data-i18n="CHARISMA_SHORT") + option(value="@{attribute_query}", data-i18n="ASK", selected).skills-query-ask input(type="number", min="-1", value="-1", name=`attr_${skillPrefix}`).level select(name=`attr_${skillPrefix}_specialist`).dice option(value="2d6" selected) 2d6 diff --git a/Stars_Without_Number_Revised/Source/pug/rolltemplate.pug b/Stars_Without_Number_Revised/Source/pug/rolltemplate.pug index a4802e9ea2..1b16dc1913 100644 --- a/Stars_Without_Number_Revised/Source/pug/rolltemplate.pug +++ b/Stars_Without_Number_Revised/Source/pug/rolltemplate.pug @@ -1,6 +1,5 @@ rolltemplate.sheet-rolltemplate-swn-default .container - .background .header .name {{charname}} .title {{title}} @@ -30,7 +29,6 @@ rolltemplate.sheet-rolltemplate-swn-default rolltemplate.sheet-rolltemplate-swn-attack .container - .background .header .name {{charname}} .title @@ -72,7 +70,6 @@ rolltemplate.sheet-rolltemplate-swn-attack rolltemplate.sheet-rolltemplate-swn-skill .container - .background .header .name {{charname}} .title @@ -84,7 +81,6 @@ rolltemplate.sheet-rolltemplate-swn-skill mixin save-success .container.success - .background .header .name {{charname}} .title {{title}} @@ -97,7 +93,6 @@ mixin save-success mixin save-failure .container.failure - .background .header .name {{charname}} .title {{title}} diff --git a/Stars_Without_Number_Revised/Source/pug/ship.pug b/Stars_Without_Number_Revised/Source/pug/ship.pug index 5e3de4eadb..5dc6158bdc 100644 --- a/Stars_Without_Number_Revised/Source/pug/ship.pug +++ b/Stars_Without_Number_Revised/Source/pug/ship.pug @@ -1,3 +1,13 @@ +input(type="hidden", name="attr_ship_class_normalised", value="").ship-class +input(type="hidden", name="attr_ship_vehicle_type", value="SHIP").input-type + +.type.col-3.core-box.flex-between.edit + h3(data-i18n="VEHICLE_TYPE") + select(name="attr_ship_vehicle_type") + option(value="SHIP", data-i18n="SHIP", selected) + option(value="MECH", data-i18n="MECH") + option(value="VEHICLE", data-i18n="CUSTOM") + .menus.col-4.core-box.flex-between h3(data-i18n="QUICK_MENUS") input(type="hidden", name="attr_macro_ship_weapons", value="") @@ -5,21 +15,26 @@ //- Ship header .info.core-box-text.flex.col-1-3 - +text-input("ship_name", "NAME").col40.important - +text-input("ship_hulltype", "HULL_TYPE").colsixth.grow - +text-input("ship_class", "CLASS").colsixth - +text-input("ship_cargo_tonnage", "CARGO").colsixth - +text-input("ship_home_port", "HOME_PORT").col25 - +text-input("ship_operating_cost", "OPERATING_COST").col25 - +text-input("ship_maintenance_cost", "MAINTENANCE COST").col25 - +text-input("ship_last_maintenance", "LAST_MAINTENANCE").col25 + +text-input("ship_name", "NAME").col40.grow.important + .text-input.col25.grow.hulltype + input(type="text", name="attr_ship_hulltype") + .label(data-i18n="HULL_TYPE") + .details(data-i18n="HULL_TYPE_BLURB") + +text-input("ship_class", "CLASS").colsixth.vehicle-type.vehicle-type-ship.vehicle-type-mech + +text-input("ship_size", "SIZE").colsixth.vehicle-type.vehicle-type-custom + +text-input("ship_cargo_tonnage", "CARGO").colsixth.vehicle-type.vehicle-type-ship + +text-input("ship_ground_speed", "GROUND_SPEED").col25.vehicle-type.vehicle-type-custom + +text-input("ship_home_port", "HOME_PORT").col25.vehicle-type.vehicle-type-ship + +text-input("ship_operating_cost", "OPERATING_COST").col25.grow + +text-input("ship_maintenance_cost", "MAINTENANCE COST").col25.grow + +text-input("ship_last_maintenance", "LAST_MAINTENANCE").col25.grow .data.core-box-text +text-input("ship_speed", "SPEED")(type="number", min="0") +text-input("ship_ac", "AC")(type="number", min="0") +text-input("ship_armor", "ARMOR")(type="number", min="0") - +text-input("ship_crew_min", "CREW_MIN")(type="number", min="0") - +text-input("ship_crew", "CURRENT")(type="number", min="0") - +text-input("ship_crew_max", "MAX")(type="number", min="0") + +text-input("ship_crew_min", "CREW_MIN")(type="number", min="0").vehicle-type.vehicle-type-ship.vehicle-type-custom + +text-input("ship_crew", "CURRENT")(type="number", min="0").vehicle-type.vehicle-type-ship.vehicle-type-custom + +text-input("ship_crew_max", "MAX")(type="number", min="0").vehicle-type.vehicle-type-ship.vehicle-type-custom .stats.core-box-text +text-input-duo("ship_hp", "ship_hp_max", "HIT_POINTS", {min: "0"})(min="0").important input(type="hidden", name="attr_ship_power" value="0").input-color-negative @@ -33,6 +48,32 @@ .section.col-1-3 +sectionheader("show_ship_weapons", "WEAPONS") .ship-weapons + .generate.flex-start.edit.vehicle-type.vehicle-type-ship + select(name="attr_generate_ship-weapons_source").generate-source + option(value="", data-i18n="CHOOSE_WEAPON", selected) + option(value="charged_particle_caster", data-i18n="CHARGED_PARTICLE_CASTER").frigate + option(value="flak_emitter_battery", data-i18n="FLAK_EMITTER_BATTERY").frigate + option(value="fractal_impact_charge", data-i18n="FRACTAL_IMPACT_CHARGE").fighter + option(value="gravcannon", data-i18n="GRAVCANNON").cruiser + option(value="lightning_charge_mantle", data-i18n="LIGHTNING_CHARGE_MANTLE").capital + option(value="mag_spike_array", data-i18n="MAG_SPIKE_ARRAY").frigate + option(value="mass_cannon", data-i18n="MASS_CANNON").capital + option(value="multifocal_laser", data-i18n="MULTIFOCAL_LASER").fighter + option(value="nuclear_missiles", data-i18n="NUCLEAR_MISSILES").frigate + option(value="plasma_beam", data-i18n="PLASMA_BEAM").frigate + option(value="polyspectral_mes_beam", data-i18n="POLYSPECTRAL_MES_BEAM").fighter + option(value="reaper_battery", data-i18n="REAPER_BATTERY").fighter + option(value="sandthrower", data-i18n="SANDTHROWER").fighter + option(value="singularity_gun", data-i18n="SINGULARITY_GUN").capital + option(value="smart_cloud", data-i18n="SMART_CLOUD").cruiser + option(value="spike_inversion_projector", data-i18n="SPIKE_INVERSION_PROJECTOR").cruiser + option(value="spinal_beam_cannon", data-i18n="SPINAL_BEAM_CANNON").cruiser + option(value="torpedo_launcher", data-i18n="TORPEDO_LAUNCHER").frigate + option(value="vortex_tunnel_inductor", data-i18n="VORTEX_TUNNEL_INDUCTOR").capital + span(name="attr_generate_ship-weapons_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_ship-weapons_button") + span(data-i18n="ADD") fieldset.repeating_ship-weapons input(type="hidden", name="attr_weapon_api", value="") button(type="roll", name="roll_Attack", value!="&{template:swn-attack} {{charname=@{ship_name}}} {{title=@{weapon_name} – @{weapon_qualities}}} {{attack=[[1d20 + @{weapon_attack_bonus}[Attack Bonus] @{modifier_query}]]}} {{damage=[[@{weapon_damage}]]}} @{weapon_use_ammo} @{weapon_api}").display.invisible-button @@ -72,13 +113,66 @@ +text-input("weapon_damage", "DAMAGE")(value="0").center.damage +text-input("weapon_qualities", "QUALITIES").qualities +text-input-duo("weapon_ammo", "weapon_ammo_max", "", {min: "0"})(min="0") - input(type="checkbox", name="attr_weapon_use_ammo", value="{{ammo=[[@{weapon_ammo} - 1]] / @{weapon_ammo_max}}}") - span(data-i18n="AMMO") + label.label + input(type="checkbox", name="attr_weapon_use_ammo", value="{{ammo=[[@{weapon_ammo} - 1]] / @{weapon_ammo_max}}}") + span(data-i18n="AMMO") //- Fittings .section.col-3-5.row-3-5 +sectionheader("show_ship_fittings", "FITTING") .ship-fitting + .generate.flex-start.edit.vehicle-type.vehicle-type-ship + select(name="attr_generate_ship-fittings_source").generate-source + option(value="", data-i18n="CHOOSE_FITTING", selected) + option(value="advanced_lab", data-i18n="ADVANCED_LAB").frigate + option(value="advanced_nav_computer", data-i18n="ADVANCED_NAV_COMPUTER").frigate + option(value="amphibious_operation", data-i18n="AMPHIBIOUS_OPERATION").fighter + option(value="armory", data-i18n="ARMORY").frigate + option(value="atmospheric_configuration", data-i18n="ATMOSPHERIC_CONFIGURATION").fighter + option(value="auto_targeting_system", data-i18n="AUTO_TARGETING_SYSTEM").fighter + option(value="automation_support", data-i18n="AUTOMATION_SUPPORT").fighter + option(value="boarding_tubes", data-i18n="BOARDING_TUBES").frigate + option(value="cargo_lighter", data-i18n="CARGO_LIGHTER").frigate + option(value="cargo_space", data-i18n="CARGO_SPACE").fighter + option(value="cold_sleep_pods", data-i18n="COLD_SLEEP_PODS").frigate + option(value="colony_core", data-i18n="COLONY_CORE").frigate + option(value="drill_course_regulator", data-i18n="DRILL_COURSE_REGULATOR").frigate + option(value="spike_drive_2", data-i18n="SPIKE_DRIVE_2").fighter + option(value="spike_drive_3", data-i18n="SPIKE_DRIVE_3").fighter + option(value="spike_drive_4", data-i18n="SPIKE_DRIVE_4").frigate + option(value="spike_drive_5", data-i18n="SPIKE_DRIVE_5").frigate + option(value="spike_drive_6", data-i18n="SPIKE_DRIVE_6").cruiser + option(value="drop_pod", data-i18n="DROP_POD").frigate + option(value="emissions_dampers", data-i18n="EMISSIONS_DAMPERS").fighter + option(value="exodus_bay", data-i18n="EXODUS_BAY").cruiser + option(value="extended_life_support", data-i18n="EXTENDED_LIFE_SUPPORT").fighter + option(value="extended_medbay", data-i18n="EXTENDED_MEDBAY").frigate + option(value="extended_store", data-i18n="EXTENDED_STORE").fighter + option(value="fuel_bunkers", data-i18n="FUEL_BUNKERS").fighter + option(value="fuel_scoops", data-i18n="FUEL_SCOOPS").frigate + option(value="hydroponic_production", data-i18n="HYDROPONIC_PRODUCTION").cruiser + option(value="lifeboats", data-i18n="LIFEBOATS").frigate + option(value="luxury_cabins", data-i18n="LUXURY_CABINS").frigate + option(value="mobile_extractor", data-i18n="MOBILE_EXTRACTOR").frigate + option(value="mobile_factory", data-i18n="MOBILE_FACTORY").cruiser + option(value="precognitive_nav_chamber", data-i18n="PRECOGNITIVE_NAV_CHAMBER").frigate + option(value="psionic_anchorpoint", data-i18n="PSIONIC_ANCHORPOINT").frigate + option(value="sensor_mask", data-i18n="SENSOR_MASK").frigate + option(value="ship_bay_fighter", data-i18n="SHIP_BAY_FIGHTER").cruiser + option(value="ship_bay_frigate", data-i18n="SHIP_BAY_FRIGATE").capital + option(value="ships_locker", data-i18n="SHIPS_LOCKER").frigate + option(value="shiptender_mount", data-i18n="SHIPTENDER_MOUNT").frigate + option(value="smugglers_hold", data-i18n="SMUGGLERS_HOLD").fighter + option(value="survey_sensor_array", data-i18n="SURVEY_SENSOR_ARRAY").frigate + option(value="system_drive", data-i18n="SYSTEM_DRIVE").fighter + option(value="teleportation_pads", data-i18n="TELEPORTATION_PADS").frigate + option(value="tractor_beams", data-i18n="TRACTOR_BEAMS").frigate + option(value="vehicle_transport_fittings", data-i18n="VEHICLE_TRANSPORT_FITTINGS").frigate + option(value="workshop", data-i18n="WORKSHOP").frigate + span(name="attr_generate_ship-fittings_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_ship-fittings_button") + span(data-i18n="ADD") fieldset.repeating_ship-fittings .display input(type="hidden", name="attr_fitting_broken", value="0").hider @@ -104,6 +198,22 @@ .section.col-1-3 +sectionheader("show_ship_defenses", "DEFENSES") .ship-defenses + .generate.flex-start.edit.vehicle-type.vehicle-type-ship + select(name="attr_generate_ship-defenses_source").generate-source + option(value="", data-i18n="CHOOSE_DEFENSE", selected) + option(value="ablative_hull_compartments", data-i18n="ABLATIVE_HULL_COMPARTMENTS").capital + option(value="augmented_plating", data-i18n="AUGMENTED_PLATING").fighter + option(value="boarding_countermeasures", data-i18n="BOARDING_COUNTERMEASURES").frigate + option(value="burst_ecm_generator", data-i18n="BURST_ECM_GENERATOR").frigate + option(value="foxer_drones", data-i18n="FOXER_DRONES").cruiser + option(value="grav_eddy_displacer", data-i18n="GRAV_EDDY_DISPLACER").frigate + option(value="hardened_polyceramic_overlay", data-i18n="HARDENED_POLYCERAMIC_OVERLAY").fighter + option(value="planetary_defense_array", data-i18n="PLANETARY_DEFENSE_ARRAY").frigate + option(value="point_defense_lasers", data-i18n="POINT_DEFENSE_LASERS").frigate + span(name="attr_generate_ship-defenses_info").generate-info + label.generate-button + input(type="checkbox", name="attr_generate_ship-defenses_button") + span(data-i18n="ADD") fieldset.repeating_ship-defenses .display input(type="hidden", name="attr_defense_broken", value="0").hider @@ -127,7 +237,7 @@ //- Notes .section.col-1-5 - +sectionheader("show_ship_other)", "OTHER_NOTES") + +sectionheader("show_ship_other)", "NOTES") .halfgrid textarea(name="attr_ship_notes") textarea(name="attr_ship_other_notes") diff --git a/Stars_Without_Number_Revised/Source/pug_build.bat b/Stars_Without_Number_Revised/Source/pug_build.bat new file mode 100644 index 0000000000..6606cb585b --- /dev/null +++ b/Stars_Without_Number_Revised/Source/pug_build.bat @@ -0,0 +1 @@ +pug -o ..\ Stars_Without_Number_Revised.pug diff --git a/Stars_Without_Number_Revised/Source/sass_build.bat b/Stars_Without_Number_Revised/Source/sass_build.bat new file mode 100644 index 0000000000..75255582da --- /dev/null +++ b/Stars_Without_Number_Revised/Source/sass_build.bat @@ -0,0 +1 @@ +sass --no-source-map --style compressed Stars_Without_Number_Revised.scss ..\Stars_Without_Number_Revised.css diff --git a/Stars_Without_Number_Revised/Source/workers.js b/Stars_Without_Number_Revised/Source/workers.js index 1ec1d2a7cc..450bba00de 100644 --- a/Stars_Without_Number_Revised/Source/workers.js +++ b/Stars_Without_Number_Revised/Source/workers.js @@ -1,14 +1,15 @@ /* global getAttrs, setAttrs, getSectionIDs, generateRowID, on ,removeRepeatingRow, _, getTranslationByKey */ (function () { "use strict"; - // Data constants + /* Data constants */ const sheetName = "Stars Without Number (revised)"; - const sheetVersion = "2.1.0"; + const sheetVersion = "2.2.0"; const translate = getTranslationByKey; const attributes = ["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"]; const effortAttributes = ["wisdom_mod", "constitution_mod", "psionics_extra_effort", "skill_biopsionics", "skill_precognition", "skill_telepathy", "skill_teleportation", - "skill_telekinesis", "skill_metapsionics" + "skill_telekinesis", "skill_metapsionics", "psionics_committed_effort_current", + "psionics_committed_effort_scene", "psionics_committed_effort_day" ]; const shipStatEvent = [ ...["hardpoints", "power", "mass"].map(x => `change:repeating_ship-weapons:weapon_${x}`), @@ -19,7 +20,7 @@ "remove:repeating_ship-fittings" ].join(" "); const weaponSkills = [ - "skill_shoot", "skill_punch", "skill_stab", "skill_combat_energy", + "skill_exert", "skill_punch", "skill_shoot", "skill_stab", "skill_combat_energy", "skill_combat_gunnery", "skill_combat_primitive", "skill_combat_projectile", "skill_combat_psitech", "skill_combat_unarmed", "skill_telekinesis" ]; @@ -43,435 +44,54 @@ "vehicle_land", "vehicle_space", "vehicle_water"], psionic: ["biopsionics", "metapsionics", "precognition", "telekinesis", "telepathy", "teleportation"], }; - // HD AC AB Damage #attacks move morale skills saves armor_type - const statblockData = { - barbarian_hero: ["6", "16", "8", "Weapon+3", "1", "10m", "11", "3", "12", "PRIMITIVE"], - barbarian_tribal: ["1", "12", "2", "Weapon", "1", "10m", "8", "1", "15", "PRIMITIVE"], - civilian_security_bot: ["1", "15", "1", "1d8[Stun]", "1", "10m", "12", "1", "15"], - companion_bot: ["1", "12", "0", "1d2[Unarmed]", "1", "10m", "6", "1", "15"], - elite_fighter: ["3", "16", "4", "Weapon+1", "1", "10m", "10", "2", "14", "COMBAT"], - gang_boss: ["3", "14", "4", "Weapon+1", "1", "10m", "9", "2", "15"], - gang_member: ["1", "12", "1", "Weapon", "1", "10m", "7", "1", "15"], - geneengineered_killer: ["4", "16", "5", "Weapon+1", "1", "15m", "10", "2", "13"], - geneengineered_murder_beast: ["10", "18", "10", "1d10", "4", "20m", "12", "3", "10"], - greater_lone_predator: ["5", "16", "6", "1d10", "2", "10m", "9", "2", "12"], - heavy_warbot: ["6", "18", "8", "2d8[Plasma]", "2", "15m", "10", "2", "12"], - heroic_fighter: ["6", "16", "8", "Weapon+3", "1", "10m", "11", "3", "12", "COMBAT"], - industrial_work_bot: ["2", "15", "0", "1d10[Crush]", "1", "5", "8", "1", "14"], - janitor_bot: ["1", "14", "0", "Unarmed", "1", "5m", "8", "1", "15"], - large_aggressive_prey_animal: ["5", "13", "4", "1d10", "1", "15m", "8", "1", "12"], - large_pack_hunter: ["2", "14", "2", "1d6", "1", "15m", "9", "1", "14"], - legendary_fighter: ["10", "20", "12", "Weapon+4", "2", "10m", "12", "5", "10", "POWERED"], - lesser_lone_predator: ["3", "14", "4", "1d8", "2", "15m", "8", "2", "14"], - martial_human: ["1", "10", "1", "Weapon", "1", "10m", "8", "1", "15"], - military_elite: ["3", "16", "4", "Weapon+1", "1", "10m", "10", "2", "14", "COMBAT"], - military_soldier: ["1", "16", "1", "Weapon", "1", "10m", "9", "1", "15", "COMBAT"], - normal_human: ["1", "10", "0", "Unarmed", "1", "10m", "6", "1", "15"], - peaceful_human: ["1", "10", "0", "Unarmed", "1", "10m", "6", "1", "15"], - pirate_king: ["7", "18", "9", "Weapon+2", "1", "10m", "11", "3", "12", "POWERED"], - police_officer: ["1", "14", "1", "Weapon", "1", "10m", "8", "1", "15"], - repair_bot: ["1", "14", "0", "1d6[Tool]", "1", "10m", "8", "1", "15"], - serial_killer: ["6", "12", "8", "Weapon+3", "1", "10m", "12", "3", "12"], - skilled_professional: ["1", "10", "0", "Weapon", "1", "10m", "6", "2", "15"], - small_pack_hunter: ["1", "13", "1", "1d4", "1", "15m", "8", "1", "15"], - small_vicious_beast: ["1hp", "14", "1", "1d2", "1", "10m", "7", "1", "15"], - soldier_bot: ["2", "16", "1", "Weapon", "1", "10m", "10", "1", "14"], - terrifying_apex_predator: ["8", "16", "8", "1d10", "2", "20m", "9", "2", "11"], - veteran_fighter: ["2", "14", "2", "Weapon+1", "1", "10m", "9", "1", "14"], - warrior_tyrant: ["8", "20", "10", "Weapon+3", "1", "10m", "11", "3", "11", "POWERED"] + const shipStats = ["ship_ac", "ship_armor", "ship_class", "ship_crew_max", "ship_crew_min", + "ship_hardpoints_max", "ship_hp", "ship_hp_max", "ship_mass_max", "ship_power_max", "ship_speed"]; + const reverseHullTypes = { + [translate("BATTLESHIP").toLowerCase()]: "battleship", + [translate("BULK_FREIGHTER").toLowerCase()]: "bulk_freighter", + [translate("CARRIER").toLowerCase()]: "carrier", + [translate("CORVETTE").toLowerCase()]: "corvette", + [translate("FLEET_CRUISER").toLowerCase()]: "fleet_cruiser", + [translate("FREE_MERCHANT").toLowerCase()]: "free_merchant", + [translate("HEAVY_FRIGATE").toLowerCase()]: "heavy_frigate", + [translate("LARGE_STATION").toLowerCase()]: "large_station", + [translate("PATROL_BOAT").toLowerCase()]: "patrol_boat", + [translate("SMALL_STATION").toLowerCase()]: "small station", + [translate("STRIKE_FIGHTER").toLowerCase()]: "strike_fighter", + [translate("SHUTTLE").toLowerCase()]: "shuttle", }; - const shipData = { - defenses: { - ablative_hull_compartments: { - class: "CAPITAL", - effect: `+1 ${translate("AC")}, +20 ${translate("MAXIMUM_HIT_POINTS").toLowerCase()}.`, - mass: "2#", - name: translate("ABLATIVE_HULL_COMPARTMENTS"), - power: "5", + const reverseClasses= { + [translate("ADVENTURER").toLowerCase()]: "adventurer", + [translate("EXPERT").toLowerCase()]: "expert", + [translate("PSYCHIC").toLowerCase()]: "psychic", + [translate("WARRIOR").toLowerCase()]: "warrior", + }; + const autofillSections = ["armor", "cyberware", "foci", "gear", "ship-defenses", "ship-fittings", "ship-weapons", "techniques", "weapons"]; + const autofillData = { + "classes": { + adventurer: { + class_ability: translate("ADVENTURER_CLASS_ABILITY"), }, - augmented_plating: { - class: "FIGHTER", - effect: `+2 ${translate("AC")}, -1 ${translate("SPEED")}.`, - mass: "1#", - name: translate("AUGMENTED_PLATING"), - power: "0", + expert: { + class_ability: translate("EXPERT_CLASS_ABILITY"), }, - boarding_countermeasures: { - class: "FRIGATE", - effect: translate("BOARDING_COUNTERMEASURES_DESC"), - mass: "1#", - name: translate("BOARDING_COUNTERMEASURES"), - power: "2", + psychic: { + class_ability: translate("PSYCHIC_CLASS_ABILITY"), }, - burst_ecm_generator: { - class: "FRIGATE", - effect: translate("BURST_ECM_GENERATOR_DESC"), - mass: "1#", - name: translate("BURST_ECM_GENERATOR"), - power: "2", - }, - foxer_drones: { - class: "CRUISER", - effect: translate("FOXER_DRONES_DESC"), - mass: "1#", - name: translate("FOXER_DRONES"), - power: "2", - }, - grav_eddy_displacer: { - class: "FRIGATE", - effect: translate("GRAV_EDDY_DISPLACER_DESC"), - mass: "2#", - name: translate("GRAV_EDDY_DISPLACER"), - power: "5", - }, - hardened_polyceramic_overlay: { - class: "FIGHTER", - effect: translate("HARDENED_POLYCERAMIC_OVERLAY_DESC"), - mass: "1#", - name: translate("HARDENED_POLYCERAMIC_OVERLAY"), - power: "0", - }, - planetary_defense_array: { - class: "FRIGATE", - effect: translate("PLANETARY_DEFENSE_ARRAY_DESC"), - mass: "2#", - name: translate("PLANETARY_DEFENSE_ARRAY"), - power: "4", - }, - point_defense_lasers: { - class: "FRIGATE", - effect: translate("POINT_DEFENSE_LASERS_DESC"), - mass: "2#", - name: translate("POINT_DEFENSE_LASERS"), - power: "3", + warrior: { + attack_bonus: "1", + class_ability: translate("WARRIOR_CLASS_ABILITY"), }, }, - fittings: { - advanced_lab: { - class: "FRIGATE", - effect: translate("ADVANCED_LAB_DESC"), - mass: "2", - name: translate("ADVANCED_LAB"), - power: "1#", - }, - advanced_nav_computer: { - class: "FRIGATE", - effect: translate("ADVANCED_NAV_COMPUTER_DESC"), - mass: "0", - name: translate("ADVANCED_NAV_COMPUTER"), - power: "1#", - }, - amphibious_operation: { - class: "FIGHTER", - effect: translate("AMPHIBIOUS_OPERATION_DESC"), - mass: "1#", - name: translate("AMPHIBIOUS_OPERATION"), - power: "1", - }, - armory: { - class: "FRIGATE", - effect: translate("ARMORY_DESC"), - mass: "0", - name: translate("ARMORY"), - power: "0", - }, - atmospheric_configuration: { - class: "FIGHTER", - effect: translate("ATMOSPHERIC_CONFIGURATION_DESC"), - mass: "1#", - name: translate("ATMOSPHERIC_CONFIGURATION"), - power: "0", - }, - auto_targeting_system: { - class: "FIGHTER", - effect: translate("AUTO_TARGETING_SYSTEM_DESC"), - mass: "0", - name: translate("AUTO_TARGETING_SYSTEM"), - power: "1", - }, - automation_support: { - class: "FIGHTER", - effect: translate("AUTOMATION_SUPPORT_DESC"), - mass: "1", - name: translate("AUTOMATION_SUPPORT"), - power: "2", - }, - boarding_tubes: { - class: "FRIGATE", - effect: translate("BOARDING_TUBES_DESC"), - mass: "1", - name: translate("BOARDING_TUBES"), - power: "0", - }, - cargo_lighter: { - class: "FRIGATE", - effect: translate("CARGO_LIGHTER_DESC"), - mass: "2", - name: translate("CARGO_LIGHTER"), - power: "0", - }, - cargo_space: { - class: "FIGHTER", - effect: translate("CARGO_SPACE_DESC"), - mass: "1", - name: translate("CARGO_SPACE"), - power: "0", - }, - cold_sleep_pods: { - class: "FRIGATE", - effect: translate("COLD_SLEEP_PODS_DESC"), - mass: "1", - name: translate("COLD_SLEEP_PODS"), - power: "1", - }, - colony_core: { - class: "FRIGATE", - effect: translate("COLONY_CORE_DESC"), - mass: "2#", - name: translate("COLONY_CORE"), - power: "4", - }, - drill_course_regulator: { - class: "FRIGATE", - effect: translate("DRILL_COURSE_REGULATOR_DESC"), - mass: "1", - name: translate("DRILL_COURSE_REGULATOR"), - power: "1#", - }, - spike_drive_2: { - class: "FIGHTER", - effect: translate("SPIKE_DRIVE_2_DESC"), - mass: "1#", - name: translate("SPIKE_DRIVE_2"), - power: "1#", - }, - spike_drive_3: { - class: "FIGHTER", - effect: translate("SPIKE_DRIVE_3_DESC"), - mass: "2#", - name: translate("SPIKE_DRIVE_3"), - power: "2#", - }, - spike_drive_4: { - class: "FRIGATE", - effect: translate("SPIKE_DRIVE_4_DESC"), - mass: "3#", - name: translate("SPIKE_DRIVE_4"), - power: "2#", - }, - spike_drive_5: { - class: "FRIGATE", - effect: translate("SPIKE_DRIVE_5_DESC"), - mass: "3#", - name: translate("SPIKE_DRIVE_5"), - power: "3#", - }, - spike_drive_6: { - class: "CRUISER", - effect: translate("SPIKE_DRIVE_6_DESC"), - mass: "4#", - name: translate("SPIKE_DRIVE_6"), - power: "3#", - }, - drop_pod: { - class: "FRIGATE", - effect: translate("DROP_POD_DESC"), - mass: "2", - name: translate("DROP_POD"), - power: "0", - }, - emissions_dampers: { - class: "FIGHTER", - effect: translate("EMISSIONS_DAMPERS_DESC"), - mass: "1#", - name: translate("EMISSIONS_DAMPERS"), - power: "1#", - }, - exodus_bay: { - class: "CRUISER", - effect: translate("EXODUS_BAY_DESC"), - mass: "2#", - name: translate("EXODUS_BAY"), - power: "1#", - }, - extended_life_support: { - class: "FIGHTER", - effect: translate("EXTENDED_LIFE_SUPPORT_DESC"), - mass: "1#", - name: translate("EXTENDED_LIFE_SUPPORT"), - power: "1#", - }, - extended_medbay: { - class: "FRIGATE", - effect: translate("EXTENDED_MEDBAY_DESC"), - mass: "1", - name: translate("EXTENDED_MEDBAY"), - power: "1", - }, - extended_store: { - class: "FIGHTER", - effect: translate("EXTENDED_STORE_DESC"), - mass: "1#", - name: translate("EXTENDED_STORE"), - power: "0", - }, - fuel_bunkers: { - class: "FIGHTER", - effect: translate("FUEL_BUNKERS_DESC"), - mass: "1", - name: translate("FUEL_BUNKERS"), - power: "0", - }, - fuel_scoops: { - class: "FRIGATE", - effect: translate("FUEL_SCOOPS_DESC"), - mass: "1#", - name: translate("FUEL_SCOOPS"), - power: "2", - }, - hydroponic_production: { - class: "CRUISER", - effect: translate("HYDROPONIC_PRODUCTION_DESC"), - mass: "2#", - name: translate("HYDROPONIC_PRODUCTION"), - power: "1#", - }, - lifeboats: { - class: "FRIGATE", - effect: translate("LIFEBOATS_DESC"), - mass: "1", - name: translate("LIFEBOATS"), - power: "0", - }, - luxury_cabins: { - class: "FRIGATE", - effect: translate("LUXURY_CABINS_DESC"), - mass: "1#", - name: translate("LUXURY_CABINS"), - power: "1", - }, - mobile_extractor: { - class: "FRIGATE", - effect: translate("MOBILE_EXTRACTOR_DESC"), - mass: "1", - name: translate("MOBILE_EXTRACTOR"), - power: "2", - }, - mobile_factory: { - class: "CRUISER", - effect: translate("MOBILE_FACTORY_DESC"), - mass: "2#", - name: translate("MOBILE_FACTORY"), - power: "3", - }, - precognitive_nav_chamber: { - class: "FRIGATE", - effect: translate("PRECOGNITIVE_NAV_CHAMBER_DESC"), - mass: "0", - name: translate("PRECOGNITIVE_NAV_CHAMBER"), - power: "1", - }, - psionic_anchorpoint: { - class: "FRIGATE", - effect: translate("PSIONIC_ANCHORPOINT_DESC"), - mass: "0", - name: translate("PSIONIC_ANCHORPOINT"), - power: "3", - }, - sensor_mask: { - class: "FRIGATE", - effect: translate("SENSOR_MASK_DESC"), - mass: "0", - name: translate("SENSOR_MASK"), - power: "1#", - }, - ship_bay_fighter: { - class: "CRUISER", - effect: translate("SHIP_BAY_FIGHTER_DESC"), - mass: "2", - name: translate("SHIP_BAY_FIGHTER"), - power: "0", - }, - ship_bay_frigate: { - class: "CAPITAL", - effect: translate("SHIP_BAY_FRIGATE_DESC"), - mass: "4", - name: translate("SHIP_BAY_FRIGATE"), - power: "1", - }, - ships_locker: { - class: "FRIGATE", - effect: translate("SHIPS_LOCKER_DESC"), - mass: "0", - name: translate("SHIPS_LOCKER"), - power: "0", - }, - shiptender_mount: { - class: "FRIGATE", - effect: translate("SHIPTENDER_MOUNT_DESC"), - mass: "1", - name: translate("SHIPTENDER_MOUNT"), - power: "1", - }, - smugglers_hold: { - class: "FIGHTER", - effect: translate("SMUGGLERS_HOLD_DESC"), - mass: "1", - name: translate("SMUGGLERS_HOLD"), - power: "0", - }, - survey_sensor_array: { - class: "FRIGATE", - effect: translate("SURVEY_SENSOR_ARRAY_DESC"), - mass: "1", - name: translate("SURVEY_SENSOR_ARRAY"), - power: "2", - }, - system_drive: { - class: "FIGHTER", - effect: translate("SYSTEM_DRIVE_DESC"), - mass: "-2#", - name: translate("SYSTEM_DRIVE"), - power: "-1#", - }, - teleportation_pads: { - class: "FRIGATE", - effect: translate("TELEPORTATION_PADS_DESC"), - mass: "1", - name: translate("TELEPORTATION_PADS"), - power: "1", - }, - tractor_beams: { - class: "FRIGATE", - effect: translate("TRACTOR_BEAMS_DESC"), - mass: "1", - name: translate("TRACTOR_BEAMS"), - power: "2", - }, - vehicle_transport_fittings: { - class: "FRIGATE", - effect: translate("VEHICLE_TRANSPORT_FITTINGS_DESC"), - mass: "1#", - name: translate("VEHICLE_TRANSPORT_FITTINGS"), - power: "0", - }, - workshop: { - class: "FRIGATE", - effect: translate("WORKSHOP_DESC"), - mass: "0.5#", - name: translate("WORKSHOP"), - power: "1", - }, - }, - hulltypes: { + "hulltypes": { battleship: { ship_ac: "16", ship_armor: "20", - ship_class: "CAPITAL", + ship_class: translate("CAPITAL"), ship_crew_max: "1000", ship_crew_min: "200", ship_hardpoints_max: "15", - ship_hp_max: "100", + ship_hp: "100", ship_mass_max: "50", ship_power_max: "75", ship_speed: "0", @@ -479,11 +99,11 @@ bulk_freighter: { ship_ac: "11", ship_armor: "0", - ship_class: "CRUISER", + ship_class: translate("CRUISER"), ship_crew_max: "40", ship_crew_min: "10", ship_hardpoints_max: "2", - ship_hp_max: "40", + ship_hp: "40", ship_mass_max: "25", ship_power_max: "15", ship_speed: "0", @@ -491,11 +111,11 @@ carrier: { ship_ac: "14", ship_armor: "10", - ship_class: "CAPITAL", + ship_class: translate("CAPITAL"), ship_crew_max: "1500", ship_crew_min: "300", ship_hardpoints_max: "4", - ship_hp_max: "75", + ship_hp: "75", ship_mass_max: "100", ship_power_max: "50", ship_speed: "0", @@ -503,11 +123,11 @@ corvette: { ship_ac: "13", ship_armor: "10", - ship_class: "FRIGATE", + ship_class: translate("FRIGATE"), ship_crew_max: "40", ship_crew_min: "10", ship_hardpoints_max: "6", - ship_hp_max: "40", + ship_hp: "40", ship_mass_max: "15", ship_power_max: "15", ship_speed: "2", @@ -515,11 +135,11 @@ fleet_cruiser: { ship_ac: "14", ship_armor: "15", - ship_class: "CRUISER", + ship_class: translate("CRUISER"), ship_crew_max: "200", ship_crew_min: "50", ship_hardpoints_max: "10", - ship_hp_max: "60", + ship_hp: "60", ship_mass_max: "30", ship_power_max: "50", ship_speed: "1", @@ -527,11 +147,11 @@ free_merchant: { ship_ac: "14", ship_armor: "2", - ship_class: "FRIGATE", + ship_class: translate("FRIGATE"), ship_crew_max: "6", ship_crew_min: "1", ship_hardpoints_max: "2", - ship_hp_max: "20", + ship_hp: "20", ship_mass_max: "15", ship_power_max: "10", ship_speed: "3", @@ -539,11 +159,11 @@ heavy_frigate: { ship_ac: "15", ship_armor: "10", - ship_class: "FRIGATE", + ship_class: translate("FRIGATE"), ship_crew_max: "120", ship_crew_min: "30", ship_hardpoints_max: "8", - ship_hp_max: "50", + ship_hp: "50", ship_mass_max: "20", ship_power_max: "25", ship_speed: "1", @@ -551,11 +171,11 @@ large_station: { ship_ac: "17", ship_armor: "20", - ship_class: "CAPITAL", + ship_class: translate("CAPITAL"), ship_crew_max: "1000", ship_crew_min: "100", ship_hardpoints_max: "30", - ship_hp_max: "120", + ship_hp: "120", ship_mass_max: "75", ship_power_max: "125", ship_speed: "", @@ -563,11 +183,11 @@ patrol_boat: { ship_ac: "14", ship_armor: "5", - ship_class: "FRIGATE", + ship_class: translate("FRIGATE"), ship_crew_max: "20", ship_crew_min: "5", ship_hardpoints_max: "4", - ship_hp_max: "25", + ship_hp: "25", ship_mass_max: "10", ship_power_max: "15", ship_speed: "4", @@ -575,11 +195,11 @@ small_station: { ship_ac: "11", ship_armor: "5", - ship_class: "CRUISER", + ship_class: translate("CRUISER"), ship_crew_max: "200", ship_crew_min: "20", ship_hardpoints_max: "10", - ship_hp_max: "120", + ship_hp: "120", ship_mass_max: "40", ship_power_max: "50", ship_speed: "", @@ -587,11 +207,11 @@ strike_fighter: { ship_ac: "16", ship_armor: "5", - ship_class: "FIGHTER", + ship_class: translate("FIGHTER"), ship_crew_max: "1", ship_crew_min: "1", ship_hardpoints_max: "1", - ship_hp_max: "8", + ship_hp: "8", ship_mass_max: "2", ship_power_max: "5", ship_speed: "5", @@ -599,192 +219,1417 @@ shuttle: { ship_ac: "11", ship_armor: "0", - ship_class: "FIGHTER", + ship_class: translate("FIGHTER"), ship_crew_max: "10", ship_crew_min: "1", ship_hardpoints_max: "1", - ship_hp_max: "15", + ship_hp: "15", ship_mass_max: "5", ship_power_max: "3", ship_speed: "3", }, }, - weapons: { + // HD AC AB Damage #attacks move morale skills saves armor_type + // TODO: Clean this up into a maintainable format + "statblocks": { + barbarian_hero: ["6", "16", "8", "Weapon+3", "1", "10m", "11", "3", "12", "PRIMITIVE"], + barbarian_tribal: ["1", "12", "2", "Weapon", "1", "10m", "8", "1", "15", "PRIMITIVE"], + civilian_security_bot: ["1", "15", "1", "1d8[Stun]", "1", "10m", "12", "1", "15"], + companion_bot: ["1", "12", "0", "1d2[Unarmed]", "1", "10m", "6", "1", "15"], + elite_fighter: ["3", "16", "4", "Weapon+1", "1", "10m", "10", "2", "14", "COMBAT"], + gang_boss: ["3", "14", "4", "Weapon+1", "1", "10m", "9", "2", "15"], + gang_member: ["1", "12", "1", "Weapon", "1", "10m", "7", "1", "15"], + geneengineered_killer: ["4", "16", "5", "Weapon+1", "1", "15m", "10", "2", "13"], + geneengineered_murder_beast: ["10", "18", "10", "1d10", "4", "20m", "12", "3", "10"], + greater_lone_predator: ["5", "16", "6", "1d10", "2", "10m", "9", "2", "12"], + heavy_warbot: ["6", "18", "8", "2d8[Plasma]", "2", "15m", "10", "2", "12"], + heroic_fighter: ["6", "16", "8", "Weapon+3", "1", "10m", "11", "3", "12", "COMBAT"], + industrial_work_bot: ["2", "15", "0", "1d10[Crush]", "1", "5", "8", "1", "14"], + janitor_bot: ["1", "14", "0", "Unarmed", "1", "5m", "8", "1", "15"], + large_aggressive_prey_animal: ["5", "13", "4", "1d10", "1", "15m", "8", "1", "12"], + large_pack_hunter: ["2", "14", "2", "1d6", "1", "15m", "9", "1", "14"], + legendary_fighter: ["10", "20", "12", "Weapon+4", "2", "10m", "12", "5", "10", "POWERED"], + lesser_lone_predator: ["3", "14", "4", "1d8", "2", "15m", "8", "2", "14"], + martial_human: ["1", "10", "1", "Weapon", "1", "10m", "8", "1", "15"], + military_elite: ["3", "16", "4", "Weapon+1", "1", "10m", "10", "2", "14", "COMBAT"], + military_soldier: ["1", "16", "1", "Weapon", "1", "10m", "9", "1", "15", "COMBAT"], + normal_human: ["1", "10", "0", "Unarmed", "1", "10m", "6", "1", "15"], + peaceful_human: ["1", "10", "0", "Unarmed", "1", "10m", "6", "1", "15"], + pirate_king: ["7", "18", "9", "Weapon+2", "1", "10m", "11", "3", "12", "POWERED"], + police_officer: ["1", "14", "1", "Weapon", "1", "10m", "8", "1", "15"], + repair_bot: ["1", "14", "0", "1d6[Tool]", "1", "10m", "8", "1", "15"], + serial_killer: ["6", "12", "8", "Weapon+3", "1", "10m", "12", "3", "12"], + skilled_professional: ["1", "10", "0", "Weapon", "1", "10m", "6", "2", "15"], + small_pack_hunter: ["1", "13", "1", "1d4", "1", "15m", "8", "1", "15"], + small_vicious_beast: ["1hp", "14", "1", "1d2", "1", "10m", "7", "1", "15"], + soldier_bot: ["2", "16", "1", "Weapon", "1", "10m", "10", "1", "14"], + terrifying_apex_predator: ["8", "16", "8", "1d10", "2", "20m", "9", "2", "11"], + veteran_fighter: ["2", "14", "2", "Weapon+1", "1", "10m", "9", "1", "14"], + warrior_tyrant: ["8", "20", "10", "Weapon+3", "1", "10m", "11", "3", "11", "POWERED"] + }, + "armor": { + armored_undersuit: { + armor_ac: "13", + armor_encumbrance: "0", + armor_type: "STREET", + }, + armored_vacc_suit: { + armor_ac: "13", + armor_encumbrance: "2", + armor_type: "STREET", + }, + assault_suit: { + armor_ac: "18", + armor_encumbrance: "2", + armor_type: "POWERED", + }, + combat_field_uniform: { + armor_ac: "16", + armor_encumbrance: "1", + armor_type: "COMBAT", + }, + cuirass_brigandine_linothorax_half_plate: { + armor_ac: "15", + armor_encumbrance: "1", + armor_type: "PRIMITIVE", + }, + deflector_array: { + armor_ac: "18", + armor_encumbrance: "0", + armor_type: "STREET", + }, + field_emitter_panoply: { + armor_ac: "20", + armor_encumbrance: "1", + armor_encumbrance_bonus: "4", + armor_type: "POWERED", + }, + force_pavis: { + armor_ac: "15", + armor_ac_bonus: "1", + armor_encumbrance: "1", + armor_type: "SHIELD", + }, + full_plate_layered_mail: { + armor_ac: "17", + armor_encumbrance: "2", + armor_type: "PRIMITIVE", + }, + icarus_harness: { + armor_ac: "16", + armor_encumbrance: "1", + armor_type: "COMBAT", + }, + leather_jacks_thick_hides_quilted_armor: { + armor_ac: "13", + armor_encumbrance: "1", + armor_type: "PRIMITIVE", + }, + secure_clothing: { + armor_ac: "13", + armor_encumbrance: "1", + armor_type: "STREET", + }, + security_armor: { + armor_ac: "14", + armor_encumbrance: "1", + armor_type: "COMBAT", + }, + shield: { + armor_ac: "13", + armor_ac_bonus: "1", + armor_encumbrance: "1", + armor_type: "SHIELD", + }, + storm_armor: { + armor_ac: "19", + armor_encumbrance: "2", + armor_encumbrance_bonus: "4", + armor_type: "POWERED", + }, + vestimentum: { + armor_ac: "18", + armor_encumbrance: "0", + armor_type: "POWERED", + }, + warpaint: { + armor_ac: "12", + armor_encumbrance: "0", + armor_type: "STREET", + }, + woven_body_armor: { + armor_ac: "15", + armor_encumbrance: "2", + armor_type: "COMBAT", + } + }, + "cyberware": { + adrenal_suppression_pump: { + cyberware_strain: "1" + }, + bioadaptation_augments: { + cyberware_strain: "1" + }, + body_arsenal_array: { + cyberware_strain: "1" + }, + body_sculpting: { + cyberware_strain: "1" + }, + dermal_armor: { + cyberware_strain: "2" + }, + drone_control_link: { + cyberware_strain: "1" + }, + eelskin_capacitor_mesh: { + cyberware_strain: "1" + }, + gecko_anchors: { + cyberware_strain: "1" + }, + ghost_talker_transceiver: { + cyberware_strain: "1" + }, + holdout_cavity: { + cyberware_strain: "1" + }, + holoskin_emitter: { + cyberware_strain: "1" + }, + identity_submersion_trigger: { + cyberware_strain: "1" + }, + immunofiltration_systems: { + cyberware_strain: "2" + }, + induced_coma_trigger: { + cyberware_strain: "1" + }, + neurointruder_alert: { + cyberware_strain: "1" + }, + panspectral_optics: { + cyberware_strain: "1" + }, + pressure_sheathing: { + cyberware_strain: "1" + }, + prosthetic_limb: { + cyberware_strain: "1" + }, + revenant_wiring: { + cyberware_strain: "3" + }, + slowtime_window: { + cyberware_strain: "2" + }, + stabilization_overrides: { + cyberware_strain: "2" + }, + tagger_nanites: { + cyberware_strain: "1" + }, + toxin_injector: { + cyberware_strain: "2" + }, + twitchlock_actuators: { + cyberware_strain: "2" + }, + }, + "foci": { + alert: {}, + armsman: {}, + assassin: {}, + authority: {}, + close_combatant: {}, + connected: {}, + die_hard: {}, + diplomat: {}, + gunslinger: {}, + hacker: {}, + healer: {}, + henchkeeper: {}, + ironhide: {}, + psychic_training: {}, + savage_fray: {}, + shocking_assault: {}, + sniper: {}, + specialist: {}, + star_captain: {}, + starfarer: {}, + tinker: {}, + unarmed_combatant: {}, + unique_gift: {}, + wanderer: {}, + wild_psychic_talent: {}, + }, + "gear": { + ammo_20_rounds: { + gear_encumbrance: "1#", + }, + ammo_missile: { + gear_encumbrance: "1", + }, + atmofilter: { + gear_encumbrance: "1", + }, + backpack: { + gear_encumbrance: "1", + }, + bezoar: { + gear_encumbrance: "0", + }, + binoculars: { + gear_encumbrance: "1", + }, + bioscanner: { + gear_encumbrance: "1", + }, + black_slab: { + gear_encumbrance: "1", + }, + brainwave: { + gear_encumbrance: "0", + }, + climbing_harness: { + gear_encumbrance: "1", + }, + comm_server: { + gear_encumbrance: "3", + }, + compad: { + gear_encumbrance: "0", + }, + data_phase_tab: { + gear_encumbrance: "1", + }, + data_protocol: { + gear_encumbrance: "0", + }, + dataslab: { + gear_encumbrance: "1", + }, + field_radio: { + gear_encumbrance: "1", + }, + glowbug: { + gear_encumbrance: "0", + }, + grapnel_launcher: { + gear_encumbrance: "1", + }, + grav_chute: { + gear_encumbrance: "1", + }, + grav_harness: { + gear_encumbrance: "3", + }, + hush: { + gear_encumbrance: "0", + }, + instapanel: { + gear_encumbrance: "1#", + }, + lazarus_patch: { + gear_encumbrance: "1#", + }, + lift: { + gear_encumbrance: "0", + }, + line_shunt: { + gear_encumbrance: "0", + }, + low_light_goggles: { + gear_encumbrance: "1", + }, + medkit: { + gear_encumbrance: "2", + }, + metatool: { + gear_encumbrance: "1", + }, + navcomp: { + gear_encumbrance: "1", + }, + portabox: { + gear_encumbrance: "1", + }, + power_cell_type_a: { + gear_encumbrance: "1#", + }, + power_cell_type_b: { + gear_encumbrance: "1", + }, + pressure_tent: { + gear_encumbrance: "4", + }, + pretech_cosmetic: { + gear_encumbrance: "0", + }, + psych: { + gear_encumbrance: "0", + }, + rations_1_day: { + gear_encumbrance: "1#", + }, + remote_link_unit: { + gear_encumbrance: "1", + }, + reverie: { + gear_encumbrance: "0", + }, + rope_20_meters: { + gear_encumbrance: "2/1", + }, + scout_report: { + gear_encumbrance: "0", + }, + solar_recharger: { + gear_encumbrance: "3", + }, + spare_parts: { + gear_encumbrance: "1#", + }, + squeal: { + gear_encumbrance: "0", + }, + stiletto_charge: { + gear_encumbrance: "1", + }, + storage_unit: { + gear_encumbrance: "3", + }, + survey_scanner: { + gear_encumbrance: "1", + }, + survival_kit: { + gear_encumbrance: "1", + }, + tailored_antiallergens: { + gear_encumbrance: "0", + }, + telekinetic_generator: { + gear_encumbrance: "2", + }, + telescoping_pole: { + gear_encumbrance: "0", + }, + thermal_flare: { + gear_encumbrance: "0", + }, + tightbeam_link_unit: { + gear_encumbrance: "1", + }, + toolkit_postech: { + gear_encumbrance: "3", + }, + toolkit_pretech: { + gear_encumbrance: "1", + }, + trade_goods: { + gear_encumbrance: "1#", + }, + trade_metals: { + gear_encumbrance: "1#", + }, + translator_torc: { + gear_encumbrance: "0", + }, + tsunami: { + gear_encumbrance: "0", + }, + vacc_fresher: { + gear_encumbrance: "1", + }, + vacc_skin: { + gear_encumbrance: "1", + }, + vacc_suit: { + gear_encumbrance: "2", + }, + }, + "ship-defenses": { + ablative_hull_compartments: { + class: "CAPITAL", + defense_effect: `+1 ${translate("AC")}, +20 ${translate("MAXIMUM_HIT_POINTS").toLowerCase()}.`, + defense_mass: "2#", + defense_power: "5", + }, + augmented_plating: { + class: "FIGHTER", + defense_effect: `+2 ${translate("AC")}, -1 ${translate("SPEED")}.`, + defense_mass: "1#", + defense_power: "0", + }, + boarding_countermeasures: { + class: "FRIGATE", + defense_effect: translate("BOARDING_COUNTERMEASURES_DESC"), + defense_mass: "1#", + defense_power: "2", + }, + burst_ecm_generator: { + class: "FRIGATE", + defense_effect: translate("BURST_ECM_GENERATOR_DESC"), + defense_mass: "1#", + defense_power: "2", + }, + foxer_drones: { + class: "CRUISER", + defense_effect: translate("FOXER_DRONES_DESC"), + defense_mass: "1#", + defense_power: "2", + }, + grav_eddy_displacer: { + class: "FRIGATE", + defense_effect: translate("GRAV_EDDY_DISPLACER_DESC"), + defense_mass: "2#", + defense_power: "5", + }, + hardened_polyceramic_overlay: { + class: "FIGHTER", + defense_effect: translate("HARDENED_POLYCERAMIC_OVERLAY_DESC"), + defense_mass: "1#", + defense_power: "0", + }, + planetary_defense_array: { + class: "FRIGATE", + defense_effect: translate("PLANETARY_DEFENSE_ARRAY_DESC"), + defense_mass: "2#", + defense_power: "4", + }, + point_defense_lasers: { + class: "FRIGATE", + defense_effect: translate("POINT_DEFENSE_LASERS_DESC"), + defense_mass: "2#", + defense_power: "3", + }, + }, + "ship-fittings": { + advanced_lab: { + class: "FRIGATE", + fitting_mass: "2", + fitting_power: "1#", + }, + advanced_nav_computer: { + class: "FRIGATE", + fitting_mass: "0", + fitting_power: "1#", + }, + amphibious_operation: { + class: "FIGHTER", + fitting_mass: "1#", + fitting_power: "1", + }, + armory: { + class: "FRIGATE", + fitting_mass: "0", + fitting_power: "0", + }, + atmospheric_configuration: { + class: "FIGHTER", + fitting_mass: "1#", + fitting_power: "0", + }, + auto_targeting_system: { + class: "FIGHTER", + fitting_mass: "0", + fitting_power: "1", + }, + automation_support: { + class: "FIGHTER", + fitting_mass: "1", + fitting_power: "2", + }, + boarding_tubes: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "0", + }, + cargo_lighter: { + class: "FRIGATE", + fitting_mass: "2", + fitting_power: "0", + }, + cargo_space: { + class: "FIGHTER", + fitting_mass: "1", + fitting_power: "0", + }, + cold_sleep_pods: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "1", + }, + colony_core: { + class: "FRIGATE", + fitting_mass: "2#", + fitting_power: "4", + }, + drill_course_regulator: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "1#", + }, + spike_drive_2: { + class: "FIGHTER", + fitting_mass: "1#", + fitting_power: "1#", + }, + spike_drive_3: { + class: "FIGHTER", + fitting_mass: "2#", + fitting_power: "2#", + }, + spike_drive_4: { + class: "FRIGATE", + fitting_mass: "3#", + fitting_power: "2#", + }, + spike_drive_5: { + class: "FRIGATE", + fitting_mass: "3#", + fitting_power: "3#", + }, + spike_drive_6: { + class: "CRUISER", + fitting_mass: "4#", + fitting_power: "3#", + }, + drop_pod: { + class: "FRIGATE", + fitting_mass: "2", + fitting_power: "0", + }, + emissions_dampers: { + class: "FIGHTER", + fitting_mass: "1#", + fitting_power: "1#", + }, + exodus_bay: { + class: "CRUISER", + fitting_mass: "2#", + fitting_power: "1#", + }, + extended_life_support: { + class: "FIGHTER", + fitting_mass: "1#", + fitting_power: "1#", + }, + extended_medbay: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "1", + }, + extended_store: { + class: "FIGHTER", + fitting_mass: "1#", + fitting_power: "0", + }, + fuel_bunkers: { + class: "FIGHTER", + fitting_mass: "1", + fitting_power: "0", + }, + fuel_scoops: { + class: "FRIGATE", + fitting_mass: "1#", + fitting_power: "2", + }, + hydroponic_production: { + class: "CRUISER", + fitting_mass: "2#", + fitting_power: "1#", + }, + lifeboats: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "0", + }, + luxury_cabins: { + class: "FRIGATE", + fitting_mass: "1#", + fitting_power: "1", + }, + mobile_extractor: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "2", + }, + mobile_factory: { + class: "CRUISER", + fitting_mass: "2#", + fitting_power: "3", + }, + precognitive_nav_chamber: { + class: "FRIGATE", + fitting_mass: "0", + fitting_power: "1", + }, + psionic_anchorpoint: { + class: "FRIGATE", + fitting_mass: "0", + fitting_power: "3", + }, + sensor_mask: { + class: "FRIGATE", + fitting_mass: "0", + fitting_power: "1#", + }, + ship_bay_fighter: { + class: "CRUISER", + fitting_mass: "2", + fitting_power: "0", + }, + ship_bay_frigate: { + class: "CAPITAL", + fitting_mass: "4", + fitting_power: "1", + }, + ships_locker: { + class: "FRIGATE", + fitting_mass: "0", + fitting_power: "0", + }, + shiptender_mount: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "1", + }, + smugglers_hold: { + class: "FIGHTER", + fitting_mass: "1", + fitting_power: "0", + }, + survey_sensor_array: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "2", + }, + system_drive: { + class: "FIGHTER", + fitting_mass: "-2#", + fitting_power: "-1#", + }, + teleportation_pads: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "1", + }, + tractor_beams: { + class: "FRIGATE", + fitting_mass: "1", + fitting_power: "2", + }, + vehicle_transport_fittings: { + class: "FRIGATE", + fitting_mass: "1#", + fitting_power: "0", + }, + workshop: { + class: "FRIGATE", + fitting_mass: "0.5#", + fitting_power: "1", + }, + }, + "ship-weapons": { charged_particle_caster: { class: "FRIGATE", - damage: "3d6", - hardpoints: "2", - name: translate("CHARGED_PARTICLE_CASTER"), - mass: "1", - power: "10", - qualities: `${translate("AP")} 15, ${translate("CLUMSY")}`, + weapon_damage: "3d6", + weapon_hardpoints: "2", + weapon_mass: "1", + weapon_power: "10", + weapon_qualities: `${translate("AP")} 15, ${translate("CLUMSY")}`, }, flak_emitter_battery: { class: "FRIGATE", - damage: "2d6", - hardpoints: "1", - name: translate("FLAK_EMITTER_BATTERY"), - mass: "3", - power: "5", - qualities: `${translate("AP")} 10, ${translate("FLAK")}`, + weapon_damage: "2d6", + weapon_hardpoints: "1", + weapon_mass: "3", + weapon_power: "5", + weapon_qualities: `${translate("AP")} 10, ${translate("FLAK")}`, }, fractal_impact_charge: { - ammo: "4", + weapon_ammo: "4", class: "FIGHTER", - damage: "2d6", - hardpoints: "1", - name: translate("FRACTAL_IMPACT_CHARGE"), - mass: "1", - power: "5", - qualities: `${translate("AP")} 15`, + weapon_damage: "2d6", + weapon_hardpoints: "1", + weapon_mass: "1", + weapon_power: "5", + weapon_qualities: `${translate("AP")} 15`, }, gravcannon: { class: "CRUISER", - damage: "4d6", - hardpoints: "3", - name: translate("GRAVCANNON"), - mass: "4", - power: "15", - qualities: `${translate("AP")} 20`, + weapon_damage: "4d6", + weapon_hardpoints: "3", + weapon_mass: "4", + weapon_power: "15", + weapon_qualities: `${translate("AP")} 20`, }, lightning_charge_mantle: { class: "CAPITAL", - damage: "1d20", - hardpoints: "2", - name: translate("LIGHTNING_CHARGE_MANTLE"), - mass: "5", - power: "15", - qualities: `${translate("AP")} 5, ${translate("CLOUD")}`, + weapon_damage: "1d20", + weapon_hardpoints: "2", + weapon_mass: "5", + weapon_power: "15", + weapon_qualities: `${translate("AP")} 5, ${translate("CLOUD")}`, }, mag_spike_array: { - ammo: "5", + weapon_ammo: "5", class: "FRIGATE", - damage: "2d6+2", - hardpoints: "2", - name: translate("MAG_SPIKE_ARRAY"), - mass: "2", - power: "5", - qualities: `${translate("AP")} 10, ${translate("FLAK")}`, + weapon_damage: "2d6+2", + weapon_hardpoints: "2", + weapon_mass: "2", + weapon_power: "5", + weapon_qualities: `${translate("AP")} 10, ${translate("FLAK")}`, }, mass_cannon: { - ammo: "4", + weapon_ammo: "4", class: "CAPITAL", - damage: "2d20", - hardpoints: "4", - name: translate("MASS_CANNON"), - mass: "5", - power: "10", - qualities: `${translate("AP")} 20`, + weapon_damage: "2d20", + weapon_hardpoints: "4", + weapon_mass: "5", + weapon_power: "10", + weapon_qualities: `${translate("AP")} 20`, }, multifocal_laser: { class: "FIGHTER", - damage: "1d4", - hardpoints: "1", - name: translate("MULTIFOCAL_LASER"), - mass: "1", - power: "5", - qualities: `${translate("AP")} 20`, + weapon_damage: "1d4", + weapon_hardpoints: "1", + weapon_mass: "1", + weapon_power: "5", + weapon_qualities: `${translate("AP")} 20`, }, nuclear_missiles: { - ammo: "5", + weapon_ammo: "5", class: "FRIGATE", - damage: "", - hardpoints: "2", - name: translate("NUCLEAR_MISSILES"), - mass: "1", - power: "5", - qualities: "", + weapon_damage: "", + weapon_hardpoints: "2", + weapon_mass: "1", + weapon_power: "5", + weapon_qualities: "", }, plasma_beam: { class: "FRIGATE", - damage: "3d6", - hardpoints: "2", - name: translate("PLASMA_BEAM"), - mass: "2", - power: "5", - qualities: `${translate("AP")} 10`, + weapon_damage: "3d6", + weapon_hardpoints: "2", + weapon_mass: "2", + weapon_power: "5", + weapon_qualities: `${translate("AP")} 10`, }, polyspectral_mes_beam: { class: "FIGHTER", - damage: "2d4", - hardpoints: "1", - name: translate("POLYSPECTRAL_MES_BEAM"), - mass: "1", - power: "5", - qualities: `${translate("AP")} 25`, + weapon_damage: "2d4", + weapon_hardpoints: "1", + weapon_mass: "1", + weapon_power: "5", + weapon_qualities: `${translate("AP")} 25`, }, reaper_battery: { class: "FIGHTER", - damage: "3d4", - hardpoints: "1", - name: translate("REAPER_BATTERY"), - mass: "1", - power: "4", - qualities: translate("CLUMSY"), + weapon_damage: "3d4", + weapon_hardpoints: "1", + weapon_mass: "1", + weapon_power: "4", + weapon_qualities: translate("CLUMSY"), }, sandthrower: { class: "FIGHTER", - damage: "2d4", - hardpoints: "1", - name: translate("SANDTHROWER"), - mass: "1", - power: "3", - qualities: translate("FLAK"), + weapon_damage: "2d4", + weapon_hardpoints: "1", + weapon_mass: "1", + weapon_power: "3", + weapon_qualities: translate("FLAK"), }, singularity_gun: { class: "CAPITAL", - damage: "5d20", - hardpoints: "5", - name: translate("SINGULARITY_GUN"), - mass: "10", - power: "25", - qualities: `${translate("AP")} 25`, + weapon_damage: "5d20", + weapon_hardpoints: "5", + weapon_mass: "10", + weapon_power: "25", + weapon_qualities: `${translate("AP")} 25`, }, smart_cloud: { class: "CRUISER", - damage: "3d10", - hardpoints: "2", - name: translate("SMART_CLOUD"), - mass: "5", - power: "10", - qualities: `${translate("CLOUD")}, ${translate("CLUMSY")}`, + weapon_damage: "3d10", + weapon_hardpoints: "2", + weapon_mass: "5", + weapon_power: "10", + weapon_qualities: `${translate("CLOUD")}, ${translate("CLUMSY")}`, }, spike_inversion_projector: { class: "CRUISER", - damage: "3d8", - hardpoints: "3", - name: translate("SPIKE_INVERSION_PROJECTOR"), - mass: "3", - power: "10", - qualities: `${translate("AP")} 15`, + weapon_damage: "3d8", + weapon_hardpoints: "3", + weapon_mass: "3", + weapon_power: "10", + weapon_qualities: `${translate("AP")} 15`, }, spinal_beam_cannon: { class: "CRUISER", - damage: "3d10", - hardpoints: "3", - name: translate("SPINAL_BEAM_CANNON"), - mass: "5", - power: "10", - qualities: `${translate("AP")} 15, ${translate("CLUMSY")}`, + weapon_damage: "3d10", + weapon_hardpoints: "3", + weapon_mass: "5", + weapon_power: "10", + weapon_qualities: `${translate("AP")} 15, ${translate("CLUMSY")}`, }, torpedo_launcher: { - ammo: "4", + weapon_ammo: "4", class: "FRIGATE", - damage: "3d8", - hardpoints: "1", - name: translate("TORPEDO_LAUNCHER"), - mass: "3", - power: "10", - qualities: `${translate("AP")} 20`, + weapon_damage: "3d8", + weapon_hardpoints: "1", + weapon_mass: "3", + weapon_power: "10", + weapon_qualities: `${translate("AP")} 20`, }, vortex_tunnel_inductor: { class: "CAPITAL", - damage: "3d20", - hardpoints: "4", - name: translate("VORTEX_TUNNEL_INDUCTOR"), - mass: "10", - power: "20", - qualities: `${translate("AP")} 20, ${translate("CLUMSY")}`, + weapon_damage: "3d20", + weapon_hardpoints: "4", + weapon_mass: "10", + weapon_power: "20", + weapon_qualities: `${translate("AP")} 20, ${translate("CLUMSY")}`, + }, + }, + "techniques": { + accelerated_succor: { + level: "3", + technique_discipline: translate("BIOPSIONICS"), + }, + alternate_outcome: { + level: "2", + technique_discipline: translate("PRECOGNITION"), + }, + anguished_vision: { + level: "3", + technique_discipline: translate("PRECOGNITION"), + }, + burdened_apportation: { + level: "2", + technique_discipline: translate("TELEPORTATION"), + }, + cloak_powers: { + level: "1", + technique_discipline: translate("METAPSIONICS"), + }, + concert_of_minds: { + level: "3", + technique_discipline: translate("METAPSIONICS"), + }, + cursed_luck: { + level: "3", + technique_discipline: translate("PRECOGNITION"), + }, + deep_intrusion: { + level: "4", + technique_discipline: translate("TELEPORTATION"), + }, + destinys_shield: { + level: "2", + technique_discipline: translate("PRECOGNITION"), + }, + effortless_apportation: { + level: "3", + technique_discipline: translate("TELEPORTATION"), + }, + facile_mind: { + level: "1", + technique_discipline: translate("TELEPATHY"), + }, + far_thought: { + level: "2", + technique_discipline: translate("TELEPATHY"), + }, + flawless_mastery: { + level: "4", + technique_discipline: translate("METAPSIONICS"), + }, + force_puppetry: { + level: "4", + technique_discipline: translate("TELEKINESIS"), + }, + forced_outcome: { + level: "3", + technique_discipline: translate("PRECOGNITION"), + }, + holistic_optimization_patterning: { + level: "4", + technique_discipline: translate("BIOPSIONICS"), + }, + impact_sump: { + level: "2", + technique_discipline: translate("TELEKINESIS"), + }, + impervious_pavis_of_will: { + level: "4", + technique_discipline: translate("METAPSIONICS"), + }, + intuitive_response: { + level: "1", + technique_discipline: translate("PRECOGNITION"), + }, + invincible_stand: { + level: "2", + technique_discipline: translate("BIOPSIONICS"), + }, + kinetic_transversal: { + level: "1", + technique_discipline: translate("TELEKINESIS"), + }, + major_organ_restoration: { + level: "2", + technique_discipline: translate("BIOPSIONICS"), + }, + mastered_succor: { + level: "1", + technique_discipline: translate("BIOPSIONICS"), + }, + memory_editing: { + level: "4", + technique_discipline: translate("TELEPATHY"), + }, + metadimensional_friction: { + level: "3", + technique_discipline: translate("METAPSIONICS"), + }, + metamorph: { + level: "3", + technique_discipline: translate("BIOPSIONICS"), + }, + mindtracing: { + level: "1", + technique_discipline: translate("METAPSIONICS"), + }, + neural_trap: { + level: "2", + technique_discipline: translate("METAPSIONICS"), + }, + not_my_time: { + level: "4", + technique_discipline: translate("PRECOGNITION"), + }, + offensive_apportation: { + level: "4", + technique_discipline: translate("TELEPORTATION"), + }, + oracle: { + level: "0", + technique_discipline: translate("PRECOGNITION"), + }, + organic_purification_protocols: { + level: "1", + technique_discipline: translate("BIOPSIONICS"), + }, + perceptive_dislocation: { + level: "2", + technique_discipline: translate("TELEPORTATION"), + }, + personal_apportation: { + level: "0", + technique_discipline: translate("TELEPORTATION"), + }, + pressure_field: { + level: "1", + technique_discipline: translate("TELEKINESIS"), + }, + proficient_apportation: { + level: "1", + technique_discipline: translate("TELEPORTATION"), + }, + prophecy: { + level: "4", + technique_discipline: translate("PRECOGNITION"), + }, + psychic_refinement: { + level: "0", + technique_discipline: translate("METAPSIONICS"), + }, + psychic_static: { + level: "2", + technique_discipline: translate("METAPSIONICS"), + }, + psychic_succor: { + level: "0", + technique_discipline: translate("BIOPSIONICS"), + }, + psychic_tutelage: { + level: "3", + technique_discipline: translate("METAPSIONICS"), + }, + quintessential_reconstruction: { + level: "4", + technique_discipline: translate("BIOPSIONICS"), + }, + reactive_telekinesis: { + level: "3", + technique_discipline: translate("TELEKINESIS"), + }, + reflex_response: { + level: "3", + technique_discipline: translate("TELEPATHY"), + }, + remote_repair: { + level: "1", + technique_discipline: translate("BIOPSIONICS"), + }, + rift_reduplication: { + level: "3", + technique_discipline: translate("TELEPORTATION"), + }, + sense_the_need: { + level: "1", + technique_discipline: translate("PRECOGNITION"), + }, + slip_field: { + level: "2", + technique_discipline: translate("TELEKINESIS"), + }, + spatial_awareness: { + level: "1", + technique_discipline: translate("TELEPORTATION"), + }, + spatial_synchrony_mandala: { + level: "2", + technique_discipline: translate("TELEPORTATION"), + }, + stutterjump: { + level: "3", + technique_discipline: translate("TELEPORTATION"), + }, + suppress_cognition: { + level: "2", + technique_discipline: translate("TELEPATHY"), + }, + surge_momentum: { + level: "3", + technique_discipline: translate("METAPSIONICS"), + }, + suspended_manifestation: { + level: "2", + technique_discipline: translate("METAPSIONICS"), + }, + synthetic_adaptation: { + level: "1", + technique_discipline: translate("METAPSIONICS"), + }, + tangible_force_construct: { + level: "3", + technique_discipline: translate("TELEKINESIS"), + }, + telekinetic_armory: { + level: "1", + technique_discipline: translate("TELEKINESIS"), + }, + telekinetic_expertise: { + level: "2", + technique_discipline: translate("TELEKINESIS"), + }, + telekinetic_flight: { + level: "4", + technique_discipline: translate("TELEKINESIS"), + }, + telekinetic_manipulation: { + level: "0", + technique_discipline: translate("TELEKINESIS"), + }, + telekinetic_ram: { + level: "3", + technique_discipline: translate("TELEKINESIS"), + }, + telepathic_assault: { + level: "3", + technique_discipline: translate("TELEPATHY"), + }, + telepathic_contact: { + level: "0", + technique_discipline: translate("TELEPATHY"), + }, + teratic_overload: { + level: "3", + technique_discipline: translate("BIOPSIONICS"), + }, + terminal_reflection: { + level: "1", + technique_discipline: translate("PRECOGNITION"), + }, + thermokinesis: { + level: "2", + technique_discipline: translate("TELEKINESIS"), + }, + tissue_integrity_field: { + level: "2", + technique_discipline: translate("BIOPSIONICS"), + }, + transmit_thought: { + level: "1", + technique_discipline: translate("TELEPATHY"), + }, + unity_of_thought: { + level: "4", + technique_discipline: translate("TELEPATHY"), + }, + }, + "weapons": { + advanced_bow: { + weapon_ammo: "1", + weapon_damage: "1d6", + weapon_encumbrance: "2", + weapon_range: "100/150", + }, + anti_vehicle_laser: { + weapon_ammo: "15", + weapon_damage: "3d10", + weapon_range: "2000/4000", + }, + combat_rifle: { + weapon_ammo: "30", + weapon_burst: true, + weapon_damage: "1d12", + weapon_encumbrance: "2", + weapon_range: "100/300", + }, + combat_shotgun: { + weapon_ammo: "12", + weapon_burst: true, + weapon_damage: "3d4", + weapon_encumbrance: "2", + weapon_range: "10/30", + }, + conversion_bow: { + weapon_ammo: "1", + weapon_damage: "1d8", + weapon_encumbrance: "2", + weapon_range: "150/300", + }, + crude_pistol: { + weapon_ammo: "1", + weapon_damage: "1d6", + weapon_encumbrance: "1", + weapon_range: "5/15", + }, + distortion_cannon: { + weapon_attack: "1", + weapon_ammo: "6", + weapon_damage: "2d12", + weapon_encumbrance: "2", + weapon_range: "100/300", + }, + grenade: { + weapon_damage: "2d6", + weapon_encumbrance: "1", + weapon_range: "10/30", + }, + heavy_machine_gun: { + weapon_ammo: "10", + weapon_damage: "3d6", + weapon_encumbrance: "3", + weapon_range: "500/2000", + }, + hydra_array: { + weapon_ammo: "10", + weapon_damage: "3d6", + weapon_range: "4000/8000", + }, + large_advanced_weapon: { + weapon_attribute_mod: "@{strength_mod}", + weapon_damage: "1d10+1", + weapon_encumbrance: "2", + weapon_shock_ac: "15", + weapon_shock_damage: "2", + weapon_skill_bonus: "@{skill_stab}", + }, + large_primitive_weapon: { + weapon_attribute_mod: "@{strength_mod}", + weapon_damage: "1d8+1", + weapon_encumbrance: "2", + weapon_shock_ac: "15", + weapon_shock_damage: "2", + weapon_skill_bonus: "@{skill_stab}", + }, + laser_pistol: { + weapon_attack: "1", + weapon_ammo: "10", + weapon_damage: "1d6", + weapon_encumbrance: "1", + weapon_range: "100/300", + }, + laser_rifle: { + weapon_attack: "1", + weapon_ammo: "20", + weapon_burst: true, + weapon_damage: "1d10", + weapon_encumbrance: "2", + weapon_range: "300/500", + }, + mag_pistol: { + weapon_ammo: "6", + weapon_damage: "2d6+2", + weapon_encumbrance: "1", + weapon_range: "100/300", + }, + mag_rifle: { + weapon_ammo: "10", + weapon_damage: "2d8+2", + weapon_encumbrance: "2", + weapon_range: "300/600", + }, + medium_advanced_weapon: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d8+1", + weapon_encumbrance: "1", + weapon_shock_ac: "13", + weapon_shock_damage: "2", + weapon_skill_bonus: "@{skill_stab}", + }, + medium_primitive_weapon: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d6+1", + weapon_encumbrance: "1", + weapon_shock_ac: "13", + weapon_shock_damage: "2", + weapon_skill_bonus: "@{skill_stab}", + }, + musket: { + weapon_ammo: "1", + weapon_damage: "1d12", + weapon_encumbrance: "2", + weapon_range: "25/50", + }, + plasma_projector: { + weapon_attack: "1", + weapon_ammo: "6", + weapon_damage: "2d8", + weapon_encumbrance: "2", + weapon_range: "50/100", + }, + primitive_bow: { + weapon_ammo: "1", + weapon_damage: "1d6", + weapon_encumbrance: "2", + weapon_range: "50/75", + }, + punch: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d2", + weapon_skill_bonus: "@{skill_punch}", + }, + railgun: { + weapon_ammo: "20", + weapon_damage: "3d8", + weapon_range: "4000/8000", + }, + revolver: { + weapon_ammo: "6", + weapon_damage: "1d8", + weapon_encumbrance: "1", + weapon_range: "30/100", + }, + rifle: { + weapon_ammo: "6", + weapon_damage: "1d10+2", + weapon_encumbrance: "2", + weapon_range: "200/400", + }, + rocket_launcher: { + weapon_ammo: "1", + weapon_damage: "3d10", + weapon_encumbrance: "2", + weapon_range: "2000/4000", + }, + semi_auto_pistol: { + weapon_ammo: "12", + weapon_damage: "1d6+1", + weapon_encumbrance: "1", + weapon_range: "30/100", + }, + shear_rifle: { + weapon_attack: "1", + weapon_ammo: "10", + weapon_burst: true, + weapon_damage: "2d8", + weapon_encumbrance: "2", + weapon_range: "100/300", + }, + shotgun: { + weapon_ammo: "2", + weapon_damage: "3d4", + weapon_encumbrance: "2", + weapon_range: "10/30", + }, + small_advanced_weapon: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d6", + weapon_encumbrance: "1", + weapon_shock_ac: "15", + weapon_shock_damage: "1", + weapon_skill_bonus: "@{skill_stab}", + }, + small_primitive_weapon: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d4", + weapon_encumbrance: "1", + weapon_shock_ac: "15", + weapon_shock_damage: "1", + weapon_skill_bonus: "@{skill_stab}", + }, + sniper_rifle: { + weapon_ammo: "1", + weapon_damage: "2d8", + weapon_encumbrance: "2", + weapon_range: "1000/2000", + }, + spike_thrower: { + weapon_ammo: "15", + weapon_burst: true, + weapon_damage: "3d8", + weapon_encumbrance: "2", + weapon_range: "20/40", + }, + stun_baton: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d8", + weapon_encumbrance: "1", + weapon_shock_ac: "15", + weapon_shock_damage: "1", + weapon_skill_bonus: "@{skill_stab}", + }, + submachine_gun: { + weapon_ammo: "20", + weapon_burst: true, + weapon_damage: "1d8", + weapon_encumbrance: "1", + weapon_range: "30/100", + }, + suit_ripper: { + weapon_attribute_mod: "@{str_dex_mod}", + weapon_damage: "1d6", + weapon_encumbrance: "1", + weapon_skill_bonus: "@{skill_stab}", + }, + thermal_pistol: { + weapon_attack: "1", + weapon_ammo: "5", + weapon_damage: "2d6", + weapon_encumbrance: "1", + weapon_range: "25/50", + }, + thunder_gun: { + weapon_attack: "1", + weapon_ammo: "6", + weapon_damage: "2d10", + weapon_encumbrance: "2", + weapon_range: "100/300", + }, + void_carbine: { + weapon_ammo: "10", + weapon_damage: "2d6", + weapon_encumbrance: "2", + weapon_range: "100/300", + }, + vortex_cannon: { + weapon_ammo: "5", + weapon_damage: "5d12", + weapon_range: "1000/2000", }, }, }; @@ -812,7 +1657,9 @@ // Populates the repeating section repeating_${SName} with new // rows from the data array. Every entry of the array is expected // to be an object, and its key/value pairs will be written into - // the repeating section as a new row. + // the repeating section as a new row. If data is not an array + // but a single object, it will be treated like an array with + // a single element. callback = callback || (() => {}); const createdIDs = [], getRowID = () => { @@ -824,7 +1671,7 @@ } } }; - const setting = data.map(o => { + const setting = (Array.isArray(data) ? data : [data]).map(o => { const newID = getRowID(); return Object.entries(o).reduce((m, [key, value]) => { m[`repeating_${sName}_${newID}_${key}`] = String(value); @@ -853,16 +1700,40 @@ getAttrs([...effortAttributes, "psionics_total_effort"], v => { const attrBonus = Math.max(parseInt(v.wisdom_mod), parseInt(v.constitution_mod)) || 0, skillBonus = Math.max(...skills.psionic.map(x => parseInt(v[`skill_${x}`]) || 0)); - const psionics_total_effort = 1 + attrBonus + skillBonus + (parseInt(v.psionics_extra_effort) || 0); + const psionics_total_effort = Math.max(1 + attrBonus + skillBonus, 1) + parseInt(v.psionics_extra_effort) - + parseInt(v.psionics_committed_effort_current) - parseInt(v.psionics_committed_effort_scene) - + parseInt(v.psionics_committed_effort_day); mySetAttrs({ psionics_total_effort }, v); }); }; const calculateAC = () => { - getAttrs(["dexterity_mod", "armor_ac", "innate_ac", "npc", "AC"], v => { - const AC = Math.max(parseInt(v.armor_ac) || 0, parseInt(v.innate_ac) || 0) + - (parseInt(v.dexterity_mod) || 0); - if (v.npc != "1") mySetAttrs({AC}, v); + getSectionIDs("repeating_armor", idArray => { + const sourceAttrs = [ + ...idArray.map(id => `repeating_armor_${id}_armor_ac`), + ...idArray.map(id => `repeating_armor_${id}_armor_active`), + ...idArray.map(id => `repeating_armor_${id}_armor_type`), + "npc", "AC", "innate_ac", "dexterity_mod", + ]; + getAttrs(sourceAttrs, v => { + if (v.npc == "1") return; + const baseAC = Math.max( + parseInt(v.innate_ac) || 0, + ...idArray.filter(id => v[`repeating_armor_${id}_armor_active`] === "1") + .filter(id => v[`repeating_armor_${id}_armor_type`] !== "SHIELD" ) + .map(id => parseInt(v[`repeating_armor_${id}_armor_ac`]) || 0) + ); + const shieldAC = Math.max( + 0, + ...idArray.filter(id => v[`repeating_armor_${id}_armor_active`] === "1") + .filter(id => v[`repeating_armor_${id}_armor_type`] === "SHIELD" ) + .map(id => parseInt(v[`repeating_armor_${id}_armor_ac`]) || 0) + ); + const AC = (shieldAC > 0 ? shieldAC <= baseAC ? (baseAC + 1) : shieldAC : baseAC) + + (parseInt(v.dexterity_mod) || 0); + + mySetAttrs({AC}, v); + }); }); }; @@ -888,15 +1759,20 @@ [`${attr}_mod`]: String(mod + (parseInt(v[`${attr}_bonus`]) || 0)) }; - mySetAttrs(setting, v, { - silent: false - }, () => { + mySetAttrs(setting, v, null, () => { calculateSaves(); generateWeaponDisplay(); + calculateStrDexMod(); if (attr === "dexterity") calculateAC(); }); }); }; + const calculateStrDexMod = () => { + getAttrs(["str_dex_mod", "strength_mod", "dexterity_mod"], v => { + const str_dex_mod = Math.max(parseInt(v.strength_mod), parseInt(v.dexterity_mod)); + mySetAttrs({str_dex_mod}, v); + }); + }; const calculateNextLevelXP = () => { var xp = [0, 3, 6, 12, 18, 27, 39, 54, 72, 93]; @@ -922,37 +1798,48 @@ }; const calculateGearReadiedStowed = () => { + const doCalc = (gearIDs, weaponIDs, armorIDs) => { + const attrs = [ + ...gearIDs.map(id => `repeating_gear_${id}_gear_encumbrance`), + ...gearIDs.map(id => `repeating_gear_${id}_gear_status`), + ...armorIDs.map(id => `repeating_armor_${id}_armor_encumbrance`), + ...armorIDs.map(id => `repeating_armor_${id}_armor_status`), + ...weaponIDs.map(id => `repeating_weapons_${id}_weapon_encumbrance`), + ...weaponIDs.map(id => `repeating_weapons_${id}_weapon_status`), + "gear_readied", "gear_readied_max", "gear_readied_over", + "gear_stowed", "gear_stowed_max", "gear_stowed_over", + ]; + getAttrs(attrs, v => { + const [gear_readied, gear_stowed] = armorIDs.reduce((m, id) => { + if (v[`repeating_armor_${id}_armor_status`] === "READIED") + m[0] += parseInt(v[`repeating_armor_${id}_armor_encumbrance`]) || 0; + else if (v[`repeating_armor_${id}_armor_status`] === "STOWED") + m[1] += parseInt(v[`repeating_armor_${id}_armor_encumbrance`]) || 0; + return m; + }, weaponIDs.reduce((m, id) => { + if (v[`repeating_weapons_${id}_weapon_status`] === "READIED") + m[0] += parseInt(v[`repeating_weapons_${id}_weapon_encumbrance`]) || 0; + else if (v[`repeating_weapons_${id}_weapon_status`] === "STOWED") + m[1] += parseInt(v[`repeating_weapons_${id}_weapon_encumbrance`]) || 0; + return m; + }, gearIDs.reduce((m, id) => { + if (v[`repeating_gear_${id}_gear_status`] === "READIED") + m[0] += parseInt(v[`repeating_gear_${id}_gear_encumbrance`]) || 0; + else if (v[`repeating_gear_${id}_gear_status`] === "STOWED") + m[1] += parseInt(v[`repeating_gear_${id}_gear_encumbrance`]) || 0; + return m; + }, [0, 0]))); + const gear_readied_over = (gear_readied > parseInt(v.gear_readied_max)) ? "1" : "0"; + const gear_stowed_over = (gear_stowed > parseInt(v.gear_stowed_max)) ? "1" : "0"; + const setting = {gear_readied, gear_stowed, gear_readied_over, gear_stowed_over}; + + mySetAttrs(setting, v, {silent: true}); + }); + }; + getSectionIDs("repeating_gear", gearIDs => { getSectionIDs("repeating_weapons", weaponIDs => { - const attrs = [ - ...gearIDs.map(id => `repeating_gear_${id}_gear_encumbrance`), - ...gearIDs.map(id => `repeating_gear_${id}_gear_status`), - ...weaponIDs.map(id => `repeating_weapons_${id}_weapon_encumbrance`), - ...weaponIDs.map(id => `repeating_weapons_${id}_weapon_status`), - "armor_encumbrance", - "gear_readied", "gear_readied_max", "gear_readied_over", - "gear_stowed", "gear_stowed_max", "gear_stowed_over", - ]; - getAttrs(attrs, v => { - const [gear_readied, gear_stowed] = weaponIDs.reduce((m, id) => { - if (v[`repeating_weapons_${id}_weapon_status`] === "READIED") - m[0] += parseInt(v[`repeating_weapons_${id}_weapon_encumbrance`]) || 0; - else if (v[`repeating_weapons_${id}_weapon_status`] === "STOWED") - m[1] += parseInt(v[`repeating_weapons_${id}_weapon_encumbrance`]) || 0; - return m; - }, gearIDs.reduce((m, id) => { - if (v[`repeating_gear_${id}_gear_status`] === "READIED") - m[0] += parseInt(v[`repeating_gear_${id}_gear_encumbrance`]) || 0; - else if (v[`repeating_gear_${id}_gear_status`] === "STOWED") - m[1] += parseInt(v[`repeating_gear_${id}_gear_encumbrance`]) || 0; - return m; - }, [parseInt(v.armor_encumbrance) || 0, 0])); - const gear_readied_over = (gear_readied > parseInt(v.gear_readied_max)) ? "1" : "0"; - const gear_stowed_over = (gear_stowed > parseInt(v.gear_stowed_max)) ? "1" : "0"; - const setting = {gear_readied, gear_stowed, gear_readied_over, gear_stowed_over}; - - mySetAttrs(setting, v, {silent: true}); - }); + getSectionIDs("repeating_armor", armorIDs => doCalc(gearIDs, weaponIDs, armorIDs)); }); }); }; @@ -1024,6 +1911,7 @@ }); }); }; + const handleAmmoAPI = (sName) => { const formula = (sName === "weapons") ? "[[-1 - @{weapon_burst}]]" : "-1" ; getSectionIDs(`repeating_${sName}`, idArray => { @@ -1053,7 +1941,6 @@ if (v.tab === "npc" && v.npc === "0") setAttrs({tab: "character"}); }); }; - const validateSuperTab = () => { getAttrs(["setting_super_type", "tab_super"], v => { const setting = {}; @@ -1062,7 +1949,6 @@ mySetAttrs(setting, v); }); }; - const validateStrain = () => { getAttrs(["strain", "strain_permanent", "strain_max"], v => { const currentStrain = parseInt(v.strain) || 0, @@ -1072,12 +1958,12 @@ if (strain !== currentStrain) setAttrs({ strain }); }); }; - const validateWeaponSkills = (ids) => { // Makes sure that the select for the weapon skill is never in an invalid state. const prefixes = (ids && ids.map(id => `repeating_weapons_${id}`)) || ["repeating_weapons"]; getAttrs(["homebrew_skill_list", ...prefixes.map(p => `${p}_weapon_skill_bonus`)], v => { - const revisedList = ["@{skill_shoot}", "@{skill_punch}", "@{skill_stab}", "@{skill_telekinesis}", "0"], + const revisedList = ["@{skill_exert}", "@{skill_punch}", "@{skill_shoot}", "@{skill_stab}", + "@{skill_telekinesis}", "0"], firstList = ["@{skill_combat_energy}", "@{skill_combat_gunnery}", "@{skill_combat_primitive}", "@{skill_combat_projectile}", "@{skill_combat_psitech}", "@{skill_combat_unarmed}", "@{skill_telekinesis}", "0" ], @@ -1096,11 +1982,11 @@ /* NPC */ const fillNPC = () => { getAttrs(["npc_stat_block"], (v) => { - if (v.npc_stat_block && statblockData[v.npc_stat_block]) { + if (v.npc_stat_block && autofillData.statblocks[v.npc_stat_block]) { const [ HD, AC, npc_attack_bonus, damage, attacks, npc_move, npc_morale, npc_skills, npc_saves, armor_type - ] = statblockData[v.npc_stat_block]; + ] = autofillData.statblocks[v.npc_stat_block]; const setting = { AC, npc_attack_bonus, npc_move, npc_morale, npc_skills, npc_saves}; @@ -1117,7 +2003,7 @@ attack_name: translate("ATTACK"), attack_number: attacks }; - fillRepeatingSectionFromData("npc-attacks", [ newAttack ]); + fillRepeatingSectionFromData("npc-attacks", newAttack); } } }); @@ -1168,7 +2054,26 @@ }); }; - /* Menu builder */ + /* Menu builders */ + /* Helper functions for producing skill chat menus */ + const skillToMacro = v => skill => { + const namedSkills = [ + "culture_one", "culture_two", "culture_three", + "culture_alien", "profession", "magic2" + ]; + if (namedSkills.includes(skill)) + return [`@{skill_${skill}_name} (${sign(v[`skill_${skill}`])})`, `skill_${skill}`]; + else + return [`^{${skill.toUpperCase()}} (${sign(v[`skill_${skill}`])})`, `skill_${skill}`]; + }; + const idToSkillMacro = (v, sName) => id => { + const prefix = `repeating_${sName}_${id}_skill`; + return [`${v[`${prefix}_name`]} (${sign(v[prefix])})`, prefix]; + }; + const buildSkillMacro = ([name, command], index, allSkills) => { + return buildLink(name, command, index + 1 === allSkills.length); + }; + /* End helper functions */ const buildSaveMenu = () => { getAttrs(["homebrew_luck_save", "macro_saves"], v => { const macro_saves = buildLink(`^{PHYSICAL} (v@{save_physical})`, ("save_physical")) + " " + @@ -1181,37 +2086,28 @@ }; const buildSkillMenu = () => { getSectionIDs("repeating_skills", idArray => { - const namedSkills = [ - "culture_one", - "culture_two", - "culture_three", - "culture_alien", - "profession" - ]; const sourceAttrs = [ ...skills.revised.map(sk => `skill_${sk}`), ...skills.first.map(sk => `skill_${sk}`), "homebrew_skill_list", + "setting_show_untrained_skills", "macro_skills", ...idArray.map(id => `repeating_skills_${id}_skill_name`), ...idArray.map(id => `repeating_skills_${id}_skill`), ]; getAttrs(sourceAttrs, v => { - const skillList = (v.homebrew_skill_list === "revised") ? skills.revised : - ((v.homebrew_skill_list === "first") ? skills.first : []); + const skillList = skills[v.homebrew_skill_list] || []; + const hasSkills = skillList.filter(skill => v[`skill_${skill}`] !== "-1").length || + idArray.filter(id => v[`repeating_skills_${id}_skill`] !== "-1").length; - const macro_skills = [ - ...skillList.map((skill, index) => { - if (namedSkills.includes(skill)) - return buildLink(`@{skill_${skill}_name} (${sign(v[`skill_${skill}`])})`, `skill_${skill}`); - else return buildLink(`^{${skill.toUpperCase()}} (${sign(v[`skill_${skill}`])})`, - `skill_${skill}`, (index + 1 === skillList.length) && idArray.length === 0); - }), - ...idArray.map((id, index) => { - const prefix = `repeating_skills_${id}_skill`; - return buildLink(`${v[`${prefix}_name`]} (${sign(v[prefix])})`, prefix, index + 1 === idArray.length); - }) - ].join(" "); + const macro_skills = `${[ + ...skillList.filter(skill => v[`skill_${skill}`] !== "-1").map(skillToMacro(v)), + ...idArray.filter(id => v[`repeating_skills_${id}_skill`] !== "-1").map(idToSkillMacro(v, "skills")) + ].map(buildSkillMacro).join(" ")}${v.setting_show_untrained_skills === "1" ? `${ + hasSkills ? `\n\n**^{UNTRAINED}**\n` : ""}${[ + ...skillList.filter(skill => v[`skill_${skill}`] === "-1").map(skillToMacro(v)), + ...idArray.filter(id => v[`repeating_skills_${id}_skill`] === "-1").map(idToSkillMacro(v, "skills")) + ].map(buildSkillMacro).join(" ")}` : ""}`; mySetAttrs({ macro_skills }, v); }); }); @@ -1229,17 +2125,13 @@ ]; getAttrs(sourceAttrs, v => { if (v.setting_super_type == "magic" || v.setting_super_type == "neither") return; - const macro_psionics = [ - ...skills.psionic.map((skill, index) => { - return buildLink(`^{${skill.toUpperCase()}} (${sign(v[`skill_${skill}`])})`, `skill_${skill}`, index === 5 && skillIDs.length === 0); - }), - ...skillIDs.map(id => { - const prefix = `repeating_psychic-skills_${id}_skill`; - return buildLink(`${v[`${prefix}_name`]} (${sign(v[prefix])})`, prefix); - }) - ].join(" ") + (techniqueIDs.length ? "\n\n" : "") + - techniqueIDs.map(id => buildLink(v[`repeating_techniques_${id}_technique_name`], - `repeating_techniques_${id}_technique`)).join(" "); + const macro_psionics = `${[ + ...skills.psionic.filter(skill => v[`skill_${skill}`] !== "-1").map(skillToMacro(v)), + ...skillIDs.filter(id => v[`repeating_psychic-skills_${id}_skill`] !== "-1") + .map(idToSkillMacro(v, "psychic-skills")) + ].map(buildSkillMacro).join(" ")}${(techniqueIDs.length ? "\n\n" : "")}${ + techniqueIDs.map((id, index, allIDs) => buildLink(v[`repeating_techniques_${id}_technique_name`], + `repeating_techniques_${id}_technique`, index + 1 === allIDs.length)).join(" ")}`; mySetAttrs({ macro_psionics }, v); }); }); @@ -1257,15 +2149,12 @@ ]; getAttrs(sourceAttrs, v => { if (v.setting_super_type == "psionics" || v.setting_super_type == "neither") return; - const macro_magic = [ - buildLink(`^{MAGIC} (${sign(v.skill_magic)})`, ("skill_magic"), skillIDs.length === 0 && !v.skill_magic2_name), - (v.skill_magic2_name ? buildLink(`@{skill_magic2_name} (${sign(v.skill_magic2)})`, ("skill_magic2"), skillIDs.length === 0) : ""), - ...skillIDs.map(id => { - const prefix = `repeating_magic-skills_${id}_skill`; - return buildLink(`${v[`${prefix}_name`]} (${sign(v[prefix])})`, prefix); - }) - ].join(" ") + (spellIDs.length ? "\n\n" : "") + - spellIDs.map(id => buildLink(v[`repeating_spells_${id}_spell_name`], `repeating_spells_${id}_spell`)).join(" "); + const macro_magic = `${[ + ...(v.skill_magic2_name ? ["magic", "magic2"] : ["magic"]).map(skillToMacro(v)), + ...skillIDs.map(idToSkillMacro(v, "magic-skills")) + ].map(buildSkillMacro).join(" ")}${spellIDs.length ? "\n\n" : ""}${ + spellIDs.map(id => buildLink(v[`repeating_spells_${id}_spell_name`], `repeating_spells_${id}_spell`)) + .join(" ")}`; mySetAttrs({ macro_magic }, v); }); }); @@ -1344,6 +2233,177 @@ }); }; + /* Autofill stuff */ + const fillClassStats = () => { + getAttrs(["class", "class_ability", "attack_bonus"], v => { + const label = v.class && reverseClasses[v.class.toLowerCase()]; + if (label && autofillData.classes.hasOwnProperty(label)) { + const data = Object.assign({}, autofillData.classes[label]); + Object.keys(data).forEach(key => { + if (!(["", "0"].includes(String(v[key])))) delete data[key]; + }); + mySetAttrs(data, v); + } + }); + }; + const getShipMultiplier = (shipClass) => { + if ((shipClass || "").toLowerCase() === "frigate") return 2; + else if ((shipClass || "").toLowerCase() === "cruiser") return 3; + else if ((shipClass || "").toLowerCase() === "capital") return 4; + else return 1; + }; + const getAutofillData = (sName, v, data, label) => { + // Transforms the stored data to be suitable for + // inclusion into the sheet. + const output = Object.assign({}, data); + if (sName === "ship-defenses") { + if (label) output.defense_name = translate(label.toUpperCase()); + if (output.defense_mass.includes("#")) { + output.defense_mass = String(parseInt(output.defense_mass) * v.ship_multiplier); + } + } + if (sName === "ship-fittings") { + if (label) { + output.fitting_name = translate(label.toUpperCase()); + output.fitting_effect = translate(`${label.toUpperCase()}_DESC`); + } + if (output.fitting_mass.includes("#")) { + output.fitting_mass = String(Math.round(parseFloat(output.fitting_mass) * v.ship_multiplier)); + } + if (output.fitting_power.includes("#")) { + output.fitting_power = String(parseInt(output.fitting_power) * v.ship_multiplier); + } + } + if (sName === "ship-weapons") { + if (label) output.weapon_name = translate(label.toUpperCase()); + if (output.weapon_ammo) { + output.weapon_ammo_max = output.weapon_ammo; + output.weapon_use_ammo = "{{ammo=[[@{weapon_ammo} - 1]] / @{weapon_ammo_max}}}"; + } + } + if (sName === "weapons") { + if (label) output.weapon_name = translate(label.toUpperCase()); + if (output.weapon_ammo) { + output.weapon_ammo_max = output.weapon_ammo; + output.weapon_use_ammo = "{{ammo=[[0@{weapon_ammo} - (1 @{weapon_burst})]] / @{weapon_ammo|max}}}"; + } + if (output.weapon_shock_damage) { + output.weapon_shock = "{{shock=[[@{weapon_shock_damage} + @{weapon_attribute_mod}[Attribute] + @{weapon_skill_to_damage}[Skill]]] ^{SHOCK_DAMAGE_AGAINST_AC_LEQ} @{weapon_shock_ac}!}}"; + } + if (output.weapon_burst) { + output.weapon_burst = "@{burst_query}"; + } + if (!output.weapon_attribute_mod) { + output.weapon_attribute_mod = "@{dexterity_mod}"; + } + } + if (sName === "armor") { + if (label) output.armor_name = translate(label.toUpperCase()); + } + if (sName === "cyberware") { + if (label) { + output.cyberware_name = translate(label.toUpperCase()); + output.cyberware_description = translate(`${label.toUpperCase()}_DESC`); + } + } + if (sName === "foci") { + if (label) { + output.focus_name = translate(label.toUpperCase()); + output.focus_level = "1"; + output.focus_description = translate(`${label.toUpperCase()}_DESC`); + } + } + if (sName === "techniques") { + if (label) { + output.technique_name = translate(label.toUpperCase()); + output.technique_description = translate(`${label.toUpperCase()}_DESC`); + } + } + if (sName === "gear") { + if (label) { + output.gear_name = translate(label.toUpperCase()); + output.gear_description = translate(`${label.toUpperCase()}_DESC`); + } + if (output.gear_encumbrance === "1#") { + output.gear_encumbrance = "1"; + output.gear_description = `${translate("ENCUMBRANCE")} 1/3. ${output.gear_description}`; + } + } + return output; + }; + const getAutofillInfo = (sName, v, inputData, label) => { + const data = getAutofillData(sName, v, inputData, label); + // Generates info text from the stored data + if (sName === "ship-defenses") { + return `${translate(data.class)}+. ${translate("POWER_INIT")}: ${data.defense_power}, ` + + `${translate("MASS_INIT")}: ${data.defense_mass}. ${data.defense_effect}`; + } + if (sName === "ship-fittings") { + return `${translate(data.class)}+. ${translate("POWER_INIT")}: ${data.fitting_power}, ` + + `${translate("MASS_INIT")}: ${data.fitting_mass}. ${data.fitting_effect}`; + } + if (sName === "ship-weapons") { + return `${translate(data.class)}+. ` + + `${translate("POWER_INIT")}: ${data.weapon_power}, ` + + `${translate("MASS_INIT")}: ${data.weapon_mass}, ` + + `${translate("HARDPOINTS_INIT")}: ${data.weapon_hardpoints}. ` + + `${translate("DAMAGE_SHORT")} ${data.weapon_damage}. ` + + `${data.weapon_qualities}${(data.weapon_ammo ? `, ${translate("AMMO")}: ${data.weapon_ammo}`: "")}.`; + } + if (sName === "weapons") { + const getNamedAttrMod = expr => { + if (expr === "@{dexterity_mod}") return translate("DEXTERITY_SHORT"); + else if (expr === "@{strength_mod}") return translate("STRENGTH_SHORT"); + else if (expr === "@{str_dex_mod}") return translate("STR_DEX"); + }; + return `${translate("DAMAGE_SHORT")} ${data.weapon_damage}${data.weapon_burst ? ` (${translate("BURST")})` : ""}` + + (data.weapon_ab ? `, ${translate("ATTACK_BONUS_SHORT")} +${data.weapon_ab}`: "") + + (data.weapon_range ? `, ${translate("RANGE")} ${data.weapon_range}`: "") + + (data.weapon_ammo ? `, ${translate("AMMO")} ${data.weapon_ammo}`: "") + + (data.weapon_shock ? `, ${data.weapon_shock_damage} ${translate("SHOCK_DAMAGE_AGAINST_AC_LEQ")} ${data.weapon_shock_ac}` : "") + + `, +${getNamedAttrMod(data.weapon_attribute_mod)}` + + (data.weapon_encumbrance ? `, ${translate("ENCUMBRANCE_SHORT")} ${data.weapon_encumbrance}` : "") + "."; + } + if (sName === "armor") { + return `${translate("AC")} ${data.armor_ac}, ${translate(data.armor_type)}, ` + + `${translate("ENCUMBRANCE_SHORT")} ${data.armor_encumbrance}.`; + } + if (sName === "cyberware") { + return `${translate("STRAIN")}: ${data.cyberware_strain}.`; + } + if (sName === "techniques") { + if (data.level === "0") return `${translate("CORE_TECHNIQUE")}.`; + else return `${translate("LEVEL")}-${data.level}.`; + } + return ""; + }; + const generateAutofillRow = (sName) => { + // Event handler for generating a new row when button is pressed + getAttrs([`generate_${sName}_source`, "ship_class"], v => { + const label = v[`generate_${sName}_source`]; + v.ship_multiplier = getShipMultiplier(v.ship_class); + if (label && autofillData[sName].hasOwnProperty(label)) { + const data = getAutofillData(sName, v, autofillData[sName][label], label); + delete data.class; + delete data.level; + fillRepeatingSectionFromData(sName, data); + } + }); + }; + const generateAutofillInfo = (sName) => { + // Event handler for showing info about the selected item + getAttrs([`generate_${sName}_source`, "ship_class"], v => { + const label = v[`generate_${sName}_source`]; + v.ship_multiplier = getShipMultiplier(v.ship_class); + if (label && autofillData[sName].hasOwnProperty(label)) { + const info = getAutofillInfo(sName, v, autofillData[sName][label], label); + if (info) setAttrs({ + [`generate_${sName}_info`]: info + }); + } + else setAttrs({[`generate_${sName}_info`]: " "}); + }); + }; /* Translations */ const setTranslatedDefaults = () => { @@ -1354,14 +2414,15 @@ skill_culture_three_name: { trans: `${translate("CULTURE")}/`, default: "Culture/" }, skill_profession_name: { trans: `${translate("PROFESSION")}/`, default: "Profession/"}, }; - getAttrs([...Object.keys(specialSkills), "homebrew_skill_list"], v => { + getAttrs([...Object.keys(specialSkills), "homebrew_skill_list", "innate_ac_name"], v => { + const setting = {}; if (v.homebrew_skill_list === "first") { - const setting = {}; Object.entries(specialSkills).forEach(([name, data]) => { if (v[name] === data.default && v[name] !== data.trans) setting[name] = data.trans; }); - setAttrs(setting); } + setting.innate_ac_name = translate("INNATE_AC"); + mySetAttrs(setting, v); }); }; const handleAttributeQueries = () => { @@ -1371,34 +2432,33 @@ const translated = translate(attr.toUpperCase()); return `${translated},+ @{${attr}_mod}[${translated}]]]}} ` + `{{attribute= + ${translate(`${attr.toUpperCase()}_SHORT`)}}}`; - }).concat([`${translate("NONE")},]]}}`]); + }); - getAttrs(["attribute_query_none", "setting_skill_query", + getAttrs(["attribute_query", "setting_skill_query", ...attributes.map(a => `attribute_query_${a.slice(0,3)}`)], v => { if (v.setting_skill_query === "hover" || v.setting_skill_query === "hide") { mySetAttrs({ + attribute_query: `?{${translate("ATTRIBUTE")}|${[attrQueries[0], ...attrQueries.slice(1)].join("|")}}`, attribute_query_str: `+ @{strength_mod}[${translate("STRENGTH")}]]]}} {{attribute= + ${translate(`STRENGTH_SHORT`)}}}`, attribute_query_dex: `+ @{dexterity_mod}[${translate("DEXTERITY")}]]]}} {{attribute= + ${translate(`DEXTERITY_SHORT`)}}}`, attribute_query_con: `+ @{constitution_mod}[${translate("CONSTITUTION")}]]]}} {{attribute= + ${translate(`CONSTITUTION_SHORT`)}}}`, attribute_query_int: `+ @{intelligence_mod}[${translate("INTELLIGENCE")}]]]}} {{attribute= + ${translate(`INTELLIGENCE_SHORT`)}}}`, attribute_query_wis: `+ @{wisdom_mod}[${translate("WISDOM")}]]]}} {{attribute= + ${translate(`WISDOM_SHORT`)}}}`, attribute_query_cha: `+ @{charisma_mod}[${translate("CHARISMA")}]]]}} {{attribute= + ${translate(`CHARISMA_SHORT`)}}}`, - attribute_query_none: `]]}}`, }, v); } else if (v.setting_skill_query === "query") { mySetAttrs({ + attribute_query: `?{${translate("ATTRIBUTE")}|${[attrQueries[0], ...attrQueries.slice(1)].join("|")}}`, attribute_query_str: `?{${translate("ATTRIBUTE")}|${[attrQueries[0], ...attrQueries.slice(1)].join("|")}}`, attribute_query_dex: `?{${translate("ATTRIBUTE")}|${[attrQueries[1], attrQueries[0], ...attrQueries.slice(2)].join("|")}}`, attribute_query_con: `?{${translate("ATTRIBUTE")}|${[attrQueries[2], ...attrQueries.slice(0,2), ...attrQueries.slice(3)].join("|")}}`, attribute_query_int: `?{${translate("ATTRIBUTE")}|${[attrQueries[3], ...attrQueries.slice(0,3), ...attrQueries.slice(4)].join("|")}}`, attribute_query_wis: `?{${translate("ATTRIBUTE")}|${[attrQueries[4], ...attrQueries.slice(0,4), ...attrQueries.slice(5)].join("|")}}`, - attribute_query_cha: `?{${translate("ATTRIBUTE")}|${[attrQueries[5], ...attrQueries.slice(0,5), attrQueries[6]].join("|")}}`, - attribute_query_none: `?{${translate("ATTRIBUTE")}|${[attrQueries[6], ...attrQueries.slice(0,6)].join("|")}}`, + attribute_query_cha: `?{${translate("ATTRIBUTE")}|${[attrQueries[5], ...attrQueries.slice(0,5)].join("|")}}`, }, v); } - }); }; const handleModifierQuery = () => { @@ -1425,6 +2485,32 @@ }; /* Ship Code */ + const fillShipStats = () => { + getAttrs(["ship_hulltype", ...shipStats], v => { + const label = v.ship_hulltype && reverseHullTypes[v.ship_hulltype.toLowerCase()]; + if (label && autofillData.hulltypes.hasOwnProperty(label)) { + const data = Object.assign({}, autofillData.hulltypes[label]); + data.ship_hp_max = data.ship_hp; + Object.keys(data).forEach(key => { + if (!(["", 0, "0"].includes(v[key]))) delete data[key]; + }); + mySetAttrs(data, v); + } + }); + }; + const setShipClass = () => { + // Sets the internal ship_class_normalised attribute responsible + // for filtering ship modules according to class. + getAttrs(["ship_class", "ship_class_normalised"], v => { + if (["fighter", translate("FIGHTER").toLowerCase()].includes(v.ship_class.toLowerCase())) + setAttrs({ship_class_normalised: "fighter"}); + else if (["frigate", translate("FRIGATE").toLowerCase()].includes(v.ship_class.toLowerCase())) + setAttrs({ship_class_normalised: "frigate"}); + else if (["cruiser", translate("CRUISER").toLowerCase()].includes(v.ship_class.toLowerCase())) + setAttrs({ship_class_normalised: "cruiser"}); + else mySetAttrs({ship_class_normalised: ""}, v); + }); + }; const calculateShipStats = () => { // Calculates power, mass, and hardpoints remaining. const doCalc = (weaponIDs, fittingIDs, defenseIDs) => { @@ -1469,6 +2555,7 @@ /** * Migrations */ + /* Upgrade event handler */ const handleUpgrade = () => { getAttrs(["character_sheet"], v => { if (!v.character_sheet || v.character_sheet.indexOf(sheetName) !== 0) @@ -1478,6 +2565,7 @@ }); }; + /* Versioned upgrade */ const upgradeSheet = (version, firstTime = false, finalTime = false) => { // Any version upgrade code should go here const performUpgrade = (version) => { @@ -1494,8 +2582,6 @@ // recalculate these things just to be sure, in case the v1.6.2 update // missed them. buildShipWeaponsMenu(); - buildSkillMenu(); - buildPsionicsMenu(); buildAttacksMenu(); buildMagicMenu(); generateWeaponDisplay(); @@ -1561,6 +2647,56 @@ }); }); } + /** v2.2.0 + * convert single armor line to repeating armor + * Change @{attribute_query_none} to @{attribute_query} + **/ + else if (major == 2 && minor < 2) { + const upgradeFunction = _.after(2, () => { + calculateStrDexMod(); + calculateEffort(); + buildPsionicsMenu(); + buildSkillMenu(); + + upgradeSheet("2.2.0"); + }); + getAttrs(["armor_name", "armor_ac", "armor_encumbrance", "armor_type", "setting_ship_tab_name"], v => { + if (v.armor_ac) { + const data = { + armor_active: "1", + armor_ac: v.armor_ac, + armor_encumbrance: v.armor_encumbrance || "0", + armor_name: v.armor_name || "", + armor_status: "READIED", + armor_type: (v.armor_type || "").toUpperCase() + }; + fillRepeatingSectionFromData("armor", data, upgradeFunction); + } else upgradeFunction(); + if (v.setting_ship_tab_name === "MECH") setAttrs({ + ship_vehicle_type: "MECH" + }); + }); + getSectionIDs("repeating_skills", skillIDs => getSectionIDs("repeating_magic-skills", magicIDs => { + getSectionIDs("repeating_psychic-skills", psychicIDs => { + const sourceAttrs = [ + ...skillIDs.map(id => `repeating_skills_${id}_skill_query`), + ...magicIDs.map(id => `repeating_magic-skills_${id}_skill_query`), + ...psychicIDs.map(id => `repeating_psychic-skills_${id}_skill_query`), + ...skills.revised.map(skill => `skill_${skill}_query`), + ...skills.first.map(skill => `skill_${skill}_query`), + ...skills.psionic.map(skill => `skill_${skill}_query`), + "skill_magic_query", "skill_magic2_query" + ]; + getAttrs(sourceAttrs, v => { + const setting = sourceAttrs.reduce((m, attrName) => { + if (v[attrName] === "@{attribute_query_none}") m[attrName] = "@{attribute_query}"; + return m; + }, {}); + mySetAttrs(setting, v, {}, upgradeFunction); + }); + }); + })); + } /** Final upgrade clause, always leave this around */ else upgradeSheet(sheetVersion, false, true); }; @@ -1572,7 +2708,6 @@ if (!finalTime) performUpgrade(version); }); }; - /* Main upgrade from pre-worker versioning */ const upgradeFrom162 = () => { console.log("Upgrading from versionless sheet (assumed to be fresh or v1.6.2)."); @@ -1588,7 +2723,6 @@ if (technique) { const newRowId = generateRowID(); setting[`repeating_techniques_${newRowId}_technique_name`] = technique; - console.log(`Migrating psionic technique #${i}: ${technique}.`); } } setAttrs(setting); @@ -1600,20 +2734,17 @@ if (cyberware) { const newRowId = generateRowID(); setting[`repeating_cyberware_${newRowId}_cyberware_name`] = cyberware; - console.log(`Migrating cyberware #${i}: ${cyberware}.`); } } setAttrs(setting); }); getAttrs(["languages"], v => { if (v.languages) { - console.log("Language migration started."); const setting = {}; v.languages.split(/\r?\n/).filter(l => !!l).forEach(language => { const newRowId = generateRowID(); setting[`repeating_languages_${newRowId}_language`] = language; - console.log(`Language migrated: ${language}.`); }); setAttrs(setting); } @@ -1727,11 +2858,11 @@ // NPC attack if (v.damage) { - const newAttack = [{ + const newAttack = { attack_damage: v.damage, attack_name: translate("ATTACK"), attack_number: v.npc_attacks || "1" - }]; + }; fillRepeatingSectionFromData("npc-attacks", newAttack, upgradeFunction); } else upgradeFunction(); @@ -1806,7 +2937,7 @@ return row; }); fillRepeatingSectionFromData("ship-weapons", data, upgradeFunction); - setAttrs(setting, {silent: false}, upgradeFunction); + setAttrs(setting, null, upgradeFunction); }); }); // convert skills @@ -1865,7 +2996,7 @@ m[`repeating_cyberware_${id}_cyberware_name`] = v[`repeating_cyberware_${id}_cyberware`]; return m; }, {}); - setAttrs(setting, {silent: false}, upgradeFunction); + setAttrs(setting, null, upgradeFunction); }); }); // convert goals @@ -1882,7 +3013,7 @@ m[`repeating_goals_${id}_goal_xp`] = v[`repeating_goals_${id}_misc_goal_xp`]; return m; }, {}); - setAttrs(setting, {silent: false}, upgradeFunction); + setAttrs(setting, null, upgradeFunction); }); }); // convert languages @@ -1893,7 +3024,7 @@ m[`repeating_languages_${id}_language`] = v[`repeating_languages_${id}_languages`]; return m; }, {}); - setAttrs(setting, {silent: false}, upgradeFunction); + setAttrs(setting, null, upgradeFunction); }); }); // convert gear status @@ -1906,7 +3037,7 @@ m[`repeating_gear_${id}_gear_status`] = "stowed"; return m; }, {}); - setAttrs(setting, {silent: false}, upgradeFunction); + setAttrs(setting, null, upgradeFunction); }); }); // convert defenses @@ -1975,6 +3106,7 @@ }); /* Character sheet */ + on("change:class", fillClassStats); attributes.forEach(attr => on(`change:${attr} change:${attr}_bonus`, () => calculateMod(attr))); on(weaponDisplayEvent, generateWeaponDisplay); @@ -1982,18 +3114,19 @@ on("change:repeating_weapons:weapon_name", () => validateWeaponSkills()); on("change:homebrew_skill_list", () => getSectionIDs("repeating_weapons", validateWeaponSkills)); - on("change:strain change:strain_perm", validateStrain); + on("change:strain change:strain_permanent", validateStrain); on("change:constitution", calculateMaxStrain); on("change:level", calculateSaves); on(effortAttributes.map(x => `change:${x}`).join(" "), calculateEffort); - on("change:armor_ac change:innate_ac", calculateAC); + on("change:repeating_armor change:innate_ac remove:repeating_armor", calculateAC); on("change:strength", calculateGearReadiedStowedMax); - on("change:repeating_gear remove:repeating_gear change:armor_encumbrance change:repeating_weapons" + - " remove:repeating_weapons change:gear_readied change:gear_stowed", calculateGearReadiedStowed); + on("change:repeating_gear remove:repeating_gear change:armor_encumbrance change:repeating_weapons " + + "remove:repeating_weapons change:gear_readied change:gear_stowed change:repeating_armor " + + "remove:repeating_armor", calculateGearReadiedStowed); on("change:level change:setting_xp_scheme", calculateNextLevelXP); @@ -2007,10 +3140,12 @@ ...skills.first.map(x => `change:skill_${x}`), "change:homebrew_skill_list", "change:repeating_skills", + "change:setting_show_untrained_skills", "remove:repeating_skills", ].join(" "), buildSkillMenu); - on([...skills.psionic.map(x => `change:skill_${x}`), + on([ + ...skills.psionic.map(x => `change:skill_${x}`), "change:setting_super_type change:repeating_techniques remove:repeating_techniques", "change:repeating_psychic-skills remove:repeating_psychic-skills" ].join(" "), buildPsionicsMenu); @@ -2019,13 +3154,20 @@ "change:repeating_magic-skills remove:repeating_magic-skills " + "change:skill_magic change:skill_magic2_name change:skill_magic2", buildMagicMenu); + /* Repeating autofill */ + autofillSections.forEach(sName => { + on(`change:generate_${sName}_source`, () => generateAutofillInfo(sName)); + on(`change:generate_${sName}_button`, () => generateAutofillRow(sName)); + }); + /* Ship sheet */ + on("change:ship_hulltype", fillShipStats); + on("change:ship_class", setShipClass); on(shipStatEvent, calculateShipStats); on("change:repeating_ship-weapons:weapon_name change:repeating_ship-weapons:weapon_attack_bonus " + "remove:repeating_ship-weapons", buildShipWeaponsMenu); - /* NPC sheet */ on("change:npc_stat_block", fillNPC); on("change:npc_rolls_hidden", handleNPCRollHide); diff --git a/Stars_Without_Number_Revised/Stars_Without_Number_Revised.css b/Stars_Without_Number_Revised/Stars_Without_Number_Revised.css index b5e07a255d..e8ba07e4b7 100644 --- a/Stars_Without_Number_Revised/Stars_Without_Number_Revised.css +++ b/Stars_Without_Number_Revised/Stars_Without_Number_Revised.css @@ -1 +1 @@ -.charsheet{background:#fff}.charsheet{background-color:white;padding:0 !important;font-size:12px;min-width:800px;color:#000}div,span,label,textarea,button[type=roll],h1,h2,h3{box-sizing:border-box}label{margin:0;padding:0;color:inherit;font-size:1em;font-weight:normal;width:auto}p{font-size:1em;margin:0 0 5px;line-height:inherit}textarea{resize:vertical;padding:1px 4px;font-size:12px;margin:0;display:block}input[type=text],input[type=number]{padding:1px 4px;font-size:12px;color:#000}input[type=number][readonly="readonly"],input[type=number].sheet-no-spinners{-moz-appearance:textfield}input[type=number][readonly="readonly"]::-webkit-inner-spin-button,input[type=number][readonly="readonly"]::-webkit-outer-spin-button,input[type=number].sheet-no-spinners::-webkit-inner-spin-button,input[type=number].sheet-no-spinners::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}select{margin:0;font-size:12px;padding:1px 2px;line-height:18px;height:22px}button[type=roll].btn{margin:0}button[type=roll].sheet-unstyled-button{text-shadow:none;box-shadow:none;color:inherit;text-align:inherit;padding:0;border:none;border-radius:0;font-size:inherit;background:transparent}button[type=roll].sheet-unstyled-button::before{content:""}button[type=roll].sheet-invisible-button{position:absolute;z-index:1;opacity:0;left:0;width:100%;height:100%;top:0}button[type=roll].sheet-invisible-button:hover+div{color:#2B3FEA;border-color:#2B3FEA}.sheet-hider[value="0"]+div,.sheet-hider[value="0"]+label,.sheet-hider[value="0"]+button,.sheet-hider[value="0"]+span{display:none}.sheet-editmode[value="0"] ~ .sheet-content .sheet-empty-hider[value=""]+div{display:none}h1{font-family:"Contrail One",sans-serif;background-color:#9B9B9B;padding-left:5px;color:#fff;font-size:1.3em;line-height:22px;font-weight:normal}h1::after{content:"";position:absolute;right:0;background-color:#223297;background-position:center;background-size:100%;width:22px;height:22px}h2{font-family:"Contrail One",sans-serif;padding-left:5px;border:2px solid #000;background-color:#ccc;color:#000;font-size:1.1em;margin:5px 0;width:175px;line-height:18px}h3{font-size:1.2em;font-family:"Contrail One",sans-serif;color:#6B6B6B;line-height:1.5;font-weight:normal}.sheet-npc-input[value="0"] ~ .sheet-tabs .sheet-npc-tab,.sheet-npc-input[value="1"] ~ .sheet-tabs .sheet-pc-tab,.sheet-tab-input:not([value="character"]) ~ .sheet-character,.sheet-tab-input:not([value="ship"]) ~ .sheet-ship,.sheet-tab-input:not([value="npc"]) ~ .sheet-npc{display:none}.sheet-content{min-width:800px;display:grid;grid-gap:5px}.sheet-editmode[value="0"] ~ .sheet-content .sheet-edit,.sheet-editmode[value="0"] ~ .sheet-content .repcontrol,.sheet-editmode[value="1"] ~ .sheet-content .sheet-display{display:none}.sheet-header{margin-bottom:10px}.sheet-header input{opacity:0;position:absolute}.sheet-header .sheet-logo{width:480px}.sheet-header .sheet-npc-chooser{cursor:pointer;margin-left:auto;color:#fff}.sheet-header .sheet-npc-chooser span{padding:3px 6px}.sheet-header .sheet-npc-chooser input:not(:checked) ~ .sheet-pc-label,.sheet-header .sheet-npc-chooser input:checked ~ .sheet-npc-label{background:#11194B}.sheet-header .sheet-npc-chooser input:checked ~ .sheet-pc-label,.sheet-header .sheet-npc-chooser input:not(:checked) ~ .sheet-npc-label{background:#223297}.sheet-header .sheet-edit-button{margin:0 5px 0 20px}.sheet-header .sheet-settings-gear,.sheet-header .sheet-edit-button{cursor:pointer;font-size:16px;font-family:pictos}.sheet-header .sheet-settings-gear input:not(:checked)+span,.sheet-header .sheet-edit-button input:not(:checked)+span{color:#888}.sheet-header .sheet-settings-gear input:checked+span,.sheet-header .sheet-edit-button input:checked+span{color:#223297}.sheet-footer{font-size:10px;border-top:1px solid #ccc;margin-top:10px;color:#666}.sheet-footer button[type="roll"].btn:hover{color:#223297}.sheet-tabs{margin-bottom:10px;width:100%;position:relative;z-index:2;border-top:1px solid #333;font-family:"Contrail One",sans-serif;flex-flow:row-reverse;justify-content:flex-end}.sheet-tabs input{opacity:0;position:absolute}.sheet-tabs input:checked+span{background:#11194B}.sheet-tabs input:not(:checked)+span{background:#223297}.sheet-tabs span{padding:1px 25px 0}.sheet-tabs label{cursor:pointer;line-height:17px;display:flex;margin:-1px -10px 0 0;color:#fff;clip-path:polygon(0 0, 100% 0, 100% 10px, calc(100% - 10px) 100%, 0 100%)}.sheet-flex{display:flex}.sheet-flex-center{display:flex;align-items:center}.sheet-flex-between{display:flex;align-items:center;justify-content:space-between}.sheet-flex-wrap{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start}.sheet-grow{flex-grow:1}.sheet-halfgrid{display:grid;grid:auto/ 1fr 1fr;grid-column-gap:1%}.sheet-thirdsgrid{display:grid;grid:auto/repeat(3, 1fr);grid-column-gap:2%}.sheet-column>div:not(:first-child){margin-top:5px}.sheet-col-1-3{grid-column:1/3}.sheet-col-1-4{grid-column:1/4}.sheet-col-1-5{grid-column:1/5}.sheet-col-2-4{grid-column:2/4}.sheet-col-3{grid-column:3}.sheet-col-3-5{grid-column:3/5}.sheet-col-4{grid-column:4}.sheet-col-4-7{grid-column:4/7}.sheet-col-5-7{grid-column:5/7}.sheet-row-3-5{grid-row:3/5}.sheet-col55{width:55%}.sheet-col50{width:50%}.sheet-col40{width:40%}.sheet-colthird{width:calc(100%/3)}.sheet-col25{width:25%}.sheet-colsixth{width:calc(100%/6)}.sheet-grey-box,.sheet-grey-box-bordered{padding:4px;background:#F0F0F0}.sheet-grey-box-bordered{border:1px solid #aaa}.sheet-core-box{padding:8px;background:#F0F0F0}.sheet-core-box-text{padding:8px 3px 3px 8px;background:#F0F0F0}input[type=text].sheet-inherit{border-radius:0;border:none;background:transparent;box-shadow:none;padding:0;color:inherit;font:inherit}input[type=number].sheet-inline-input{position:relative;z-index:2;vertical-align:baseline;padding:0 3px}.sheet-text-input{color:#666;padding-right:5px;line-height:1}.sheet-text-input div{font-size:.9em;line-height:14px;border-top:1px solid #AAA}.sheet-text-input div input[type="checkbox"]{height:14px;margin:0 3px 0 0}.sheet-text-input input[type=text],.sheet-text-input input[type=number],.sheet-text-input textarea{background:transparent;padding:1px 0;width:100%;border-radius:0;color:#223297;border:none;text-align:inherit;font-weight:inherit;box-shadow:none}.sheet-text-input input[type=text][readonly="readonly"],.sheet-text-input input[type=number][readonly="readonly"],.sheet-text-input textarea[readonly="readonly"]{cursor:default}.sheet-text-input input[type=text],.sheet-text-input input[type=number]{font-size:1.1em}.sheet-text-input textarea{height:20px;min-height:20px}.sheet-text-input>input[type=checkbox]{height:14px;margin:3px 0}.sheet-text-input select{width:100%;height:20px;color:#223297;background:transparent;border:none}.sheet-text-input.sheet-important{font-weight:bold;font-size:1.1em}.sheet-text-input.sheet-center{text-align:center}.sheet-text-input.sheet-duo{display:grid;text-align:center;grid:auto / 1fr 5px 1fr;align-items:center;align-content:start;grid-column-gap:4px}.sheet-text-input.sheet-duo>span{font-size:16px;color:#333}.sheet-text-input.sheet-duo div{grid-column:1/4}.sheet-text-input button[type=roll].btn{width:100%}.sheet-text-input button[type=roll].btn:hover{color:red}.sheet-blue-button{text-align:center}.sheet-blue-button button[type=roll].btn{background:#2B3FEA;width:35px;height:35px;display:block;margin:0 auto;color:white}.sheet-blue-button button[type=roll].btn::before{content:""}.sheet-lower{text-transform:lowercase}.sheet-space-before::before,.sheet-space-after::after{content:" "}.sheet-colon-after::after{content:":"}.sheet-hide-empty[value=""]+span{display:none}.sheet-add-plus:not([value^="-"])+span::before{content:"+"}.sheet-api{font-size:.8em;background:#F0F0F0;border-radius:5px;padding:1px;line-height:1;vertical-align:super}.sheet-simple-repsection .repitem{margin-bottom:3px}.sheet-simple-repsection textarea{margin:3px 0 0;height:50px}.sheet-simple-repsection .sheet-display .sheet-name{font-weight:bold;font-size:1.1em;border-bottom:1px solid #777}.sheet-simple-repsection .sheet-display .sheet-details{line-height:1.4;text-align:justify;white-space:pre-wrap}.sheet-skills-type[value="neither"] ~ div .sheet-skills-either,.sheet-skills-type:not([value="first"]) ~ div .sheet-skills-first,.sheet-skills-type:not([value="revised"]) ~ div .sheet-skills-revised,.sheet-skills-type:not([value="neither"]) ~ div .sheet-skills-neither,.sheet-skills-query:not([value="hover"]) ~ div .sheet-skills-query-hover,.sheet-skills-query[value="query"] ~ div .sheet-skills-query-display{display:none}.sheet-skills-query-display input:not([value*="str"]) ~ .sheet-str,.sheet-skills-query-display input:not([value*="dex"]) ~ .sheet-dex,.sheet-skills-query-display input:not([value*="con"]) ~ .sheet-con,.sheet-skills-query-display input:not([value*="int"]) ~ .sheet-int,.sheet-skills-query-display input:not([value*="wis"]) ~ .sheet-wis,.sheet-skills-query-display input:not([value*="cha"]) ~ .sheet-cha{display:none}.sheet-skills-query[value="hover"] ~ div .sheet-skill:hover .sheet-skills-query-display,.sheet-skill .sheet-display .sheet-query:focus+.sheet-skills-query-display{display:none}.repcontrol{display:flex;margin-top:4px}.repcontrol button{padding:3px 10px}.repcontrol_edit{order:1;margin-left:auto}.repcontrol button{background:#223297;color:#FFF;box-shadow:none;text-shadow:none}.repcontrol_move,.repcontrol_del{padding:1px 10px}.itemcontrol{z-index:100}.sheet-section-toggle-header{position:relative}.sheet-section-toggle-header input{cursor:pointer;position:absolute;width:22px;height:100%;z-index:2;right:0;opacity:0}.sheet-section-toggle-header input+h1::after{background-image:url("https://svgshare.com/i/6Vz.svg")}.sheet-section-toggle-header input:not(:checked)+h1::after{transform:rotate(180deg)}.sheet-section-toggle-header+input+div{margin-top:5px}.sheet-settings label{font-weight:bold}.sheet-settings label span{margin-right:4px}.sheet-settings select{width:120px;display:inline-block}.sheet-settings select.sheet-wide{width:170px}.sheet-core{display:grid;grid-column-gap:5px}.sheet-core.sheet-core-info{grid:auto / 2.5fr 1fr .8fr}.sheet-core.sheet-core-info .sheet-info{flex-wrap:wrap;padding-right:3px}.sheet-core.sheet-core-info .sheet-info .sheet-important{width:calc(60% - 22px)}.sheet-core.sheet-core-info .sheet-info .sheet-level{width:44px}.sheet-core.sheet-core-info .sheet-info .sheet-level-rest{width:calc(40% - 22px)}.sheet-core.sheet-core-stats{grid:auto/minmax(310px, 1fr) minmax(260px, 1fr) minmax(220px, 1fr)}.sheet-core .sheet-main-content{margin-top:3px;display:grid;grid:auto/repeat(3, 1fr);grid-row-gap:3px}.sheet-core .sheet-main-content .sheet-left-margin{margin-left:15px}.sheet-saves .sheet-flex{margin-top:4px}.sheet-menus-content{display:grid;grid:auto / 1fr 1fr}.sheet-character .sheet-menus button[type=roll].btn{margin-right:auto}.sheet-menus button[type=roll].btn{color:#2B3FEA;font-size:1.1em}.sheet-menus button[type=roll].btn:hover{color:red}.sheet-attributes{font-size:1.1em;line-height:16px}.sheet-attributes table{width:100%;height:100%}.sheet-attributes td:first-child,.sheet-attributes .sheet-mod{font-weight:bold}.sheet-attributes td:not(:first-child){text-align:center}.sheet-attributes input[type=number]{width:45px}.sheet-attributes .sheet-mod{font-size:1.1em}.sheet-editmode[value="0"] ~ .sheet-content .sheet-resources .repcontainer{grid:auto / 1fr 1fr}.sheet-resources .sheet-credits{margin-left:auto}.sheet-resources .repcontainer{display:grid;grid-row-gap:3px;margin-top:3px}.sheet-resources input[type=text]{width:calc(100% - 8em);margin-right:auto}.sheet-resources .sheet-slash{margin:0 2px}.sheet-weapons .sheet-edit{justify-content:space-between}.sheet-weapons .sheet-edit .sheet-name{width:135px;flex-grow:1}.sheet-weapons .sheet-edit .sheet-ab{width:45px}.sheet-weapons .sheet-edit .sheet-weapon-skill{width:80px}.sheet-weapons .sheet-edit .sheet-attribute{width:60px}.sheet-weapons .sheet-edit .sheet-burst{width:65px}.sheet-weapons .sheet-edit .sheet-damage{width:70px}.sheet-weapons .sheet-edit .sheet-shock-damage{width:60px}.sheet-weapons .sheet-edit .sheet-shock-ac{width:55px}.sheet-weapons .sheet-edit .sheet-skill-to-damage{width:40px}.sheet-weapons .sheet-edit .sheet-range{width:70px}.sheet-weapons .sheet-edit .sheet-ammo{width:80px}.sheet-weapons .sheet-text-input{padding-right:3px}.sheet-weapons .repitem{margin-bottom:3px}.sheet-weapons .sheet-display{font-size:1.1em;border:1px solid #888;text-indent:-10px;padding:2px 4px 2px 14px}.sheet-weapons .sheet-display .sheet-name{font-weight:bold}.sheet-weapons .repitem:nth-child(odd) .sheet-display{background:#D3D3D3}.sheet-skill-container,.sheet-skills-repeating .repcontainer{display:grid;grid:auto / 1fr 1fr;grid-gap:4px 1%}.sheet-skill{position:relative}.sheet-skill .sheet-display,.sheet-skill .sheet-edit{border:1px solid #888;padding:2px 4px;height:100%}.sheet-skill .sheet-display{font-weight:bold;font-size:1.1em}.sheet-skill .sheet-display .sheet-dice[value="3d6d1"]+.sheet-name::after{content:"3d6"}.sheet-skill .sheet-display .sheet-dice[value="4d6d2"]+.sheet-name::after{content:"4d6"}.sheet-skill .sheet-display .sheet-name{margin-right:auto}.sheet-skill .sheet-display .sheet-name::after{vertical-align:super;margin-left:2px;font-weight:normal;font-size:.7em}.sheet-skill .sheet-display .sheet-query{width:55px;background:transparent;border-color:transparent;position:relative;height:18px;z-index:2;margin:0 2px;outline:none;color:inherit;flex-shrink:0;line-height:16px;padding:0}.sheet-skill:not(:hover) .sheet-display .sheet-query:not(:focus){display:none}.sheet-skill .sheet-skills-query-display{margin:0 3px;flex-shrink:0;font-weight:normal}.sheet-skill .sheet-edit input[type="text"].sheet-name{width:100%;margin-bottom:2px}.sheet-skill .sheet-edit div.sheet-name{flex-grow:1;width:0;padding:1px 2px}.sheet-skill .sheet-edit .sheet-level{margin:0 2px;padding:1px 2px;width:40px}.sheet-skill .sheet-edit .sheet-query{width:50px}.sheet-skill .sheet-edit .sheet-dice{width:35px}.sheet-skill .sheet-edit.sheet-flex-wrap select,.sheet-skill .sheet-edit.sheet-flex-wrap input{flex-grow:1}.sheet-skill.sheet-skill-points .sheet-display{font-size:1.1em;font-weight:bold;width:100%}.sheet-skill.sheet-skill-points .sheet-name{background:#000;color:#fff;flex-grow:0;margin-right:auto;width:auto;padding:0 4px}.sheet-skill.sheet-skill-points .sheet-edit .sheet-level{margin:0}.sheet-skill-container .sheet-skill:nth-of-type(4n+1),.sheet-skill-container .sheet-skill:nth-of-type(4n+2){background:#D3D3D3}.repcontainer[data-groupname="repeating_skills"] .repitem:nth-of-type(4n+1) .sheet-skill,.repcontainer[data-groupname="repeating_skills"] .repitem:nth-of-type(4n+2) .sheet-skill{background:#D3D3D3}.sheet-skills-type:not([value="neither"]) ~ div .sheet-skills-repeating,.sheet-psionics .sheet-skills-repeating,.sheet-magic .sheet-skills-repeating{margin-top:4px}.sheet-skill-blurb{font-style:italic;text-align:center}.sheet-details-button{margin-left:auto;font-weight:bold;color:#999;letter-spacing:1px;cursor:pointer;text-transform:uppercase;font-size:.8em}.sheet-details-button input{visibility:hidden;position:absolute}.sheet-details-button input:checked+span{color:#333}.sheet-input-details:not([value="1"]) ~ div .sheet-details{display:none}.sheet-super-type:not([value="psionics"]) ~ div .sheet-super-psionics-only,.sheet-super-type:not([value="magic"]) ~ div .sheet-super-magic-only,.sheet-super-type:not([value="both"]) ~ div .sheet-super-both,.sheet-super-type[value="magic"] ~ div .sheet-super-psionics,.sheet-super-type[value="psionics"] ~ div .sheet-super-magic,.sheet-super-type[value="neither"] ~ div .sheet-super{display:none}.sheet-tab-input:not([value="psionics"]) ~ .sheet-psionics,.sheet-tab-input:not([value="magic"]) ~ .sheet-magic{display:none}.sheet-psionics-effort{display:grid;grid:auto/ auto 60px 60px 80px;align-items:center;grid-column-gap:4px;margin-top:5px}.sheet-psionics-effort h3{line-height:1}.sheet-techniques{margin-top:5px;padding:0 4px}.sheet-techniques>.sheet-flex-center{margin-bottom:5px}.sheet-techniques input[type=text]{width:100%}.sheet-spells{margin-top:5px;padding:0 4px}.sheet-spells>.sheet-flex-center{margin-bottom:5px}.sheet-spells>.sheet-flex{border-bottom:1px solid #666;margin-bottom:3px}.sheet-spells>.sheet-flex :not(:first-child){text-align:center}.sheet-spells .sheet-edit .sheet-name{width:220px;flex-grow:1}.sheet-spells .sheet-edit .sheet-prepared{margin:0 3px}.sheet-spells .sheet-edit .sheet-prepared,.sheet-spells .sheet-edit .sheet-damage{width:60px}.sheet-spells .sheet-display .sheet-name{padding-bottom:1px}.sheet-spells .sheet-display span.sheet-prepared{margin:0 4px 0 auto}.sheet-spells .sheet-display input[type=number].sheet-prepared{padding:0 4px;position:relative;z-index:2}.sheet-foci-loc[value="left"] ~ .sheet-column .sheet-foci-right,.sheet-foci-loc[value="right"] ~ .sheet-column .sheet-foci-left{display:none}.sheet-foci .sheet-details-button{position:relative;z-index:2}.sheet-foci .sheet-class-ability{position:relative}.sheet-foci .sheet-class-ability .sheet-edit .sheet-name{font-weight:bold;font-size:1.1em;border-bottom:1px solid #777}.sheet-foci .sheet-class-ability .sheet-name,.sheet-foci .sheet-class-ability .sheet-edit textarea,.sheet-foci .sheet-class-ability .sheet-display{margin-bottom:3px}.sheet-foci .sheet-edit .sheet-name{flex-grow:1}.sheet-foci .sheet-edit .sheet-level{margin-left:3px;width:60px}.sheet-foci .sheet-display .sheet-level{margin-left:auto}.sheet-armor .sheet-name{width:150px;margin-left:auto}.sheet-armor .sheet-ac{width:45px}.sheet-armor .sheet-enc{width:60px}.sheet-armor .sheet-type{width:80px}.sheet-readied-stowed{display:grid;align-items:center;grid:auto / 1fr 60px 60px 80px 80px;grid-column-gap:7px}.sheet-readied-stowed .sheet-input-gear-over[value="1"]+.sheet-text-input input:first-child{color:red}.sheet-cyberware h3{margin:5px 0}.sheet-cyberware .sheet-edit{flex-wrap:wrap}.sheet-cyberware .sheet-edit input[type=text]{width:0;flex-grow:1}.sheet-cyberware .sheet-edit>span{margin:0 3px}.sheet-equipment .repcontainer[data-groupname="repeating_weapons"]+.repcontrol{display:none}.sheet-equipment .repitem{margin-bottom:2px}.sheet-equipment .repitem input[type=text],.sheet-equipment .repitem input[type=number],.sheet-equipment .repitem select{background:transparent}.sheet-equipment .repitem input[type=text]{flex-grow:1;width:0}.sheet-equipment .repitem input[type=number]{width:45px;margin:0 3px}.sheet-equipment .repitem select{width:80px}.sheet-equipment .sheet-other h3{margin-bottom:5px}.sheet-equipment textarea{height:100px}.sheet-misc h3{margin-bottom:4px}.sheet-misc .repitem{display:flex;align-items:center;margin-bottom:2px}.sheet-goals input[type=text]{flex-grow:1;margin-right:5px}.sheet-goals input[type=number]{width:70px}.sheet-languages input{width:100%}.sheet-notes{margin:10px 0}.sheet-ship{margin-top:-20px;grid:auto/repeat(4, 1fr)}.sheet-ship .sheet-menus h3{line-height:1}.sheet-ship .sheet-menus button[type=roll].btn{line-height:1}.sheet-ship .sheet-info{flex-wrap:wrap}.sheet-ship .sheet-info .sheet-text-input{margin-bottom:3px}.sheet-ship .sheet-data{display:grid;grid:auto/repeat(3, 1fr)}.sheet-ship .sheet-data .sheet-text-input,.sheet-ship .sheet-data .sheet-text-input input[type=number]{text-align:center}.sheet-ship .sheet-stats{display:grid;grid:auto / 1fr 1fr}.sheet-ship .sheet-input-color-negative[value^="-"]+.sheet-text-input input:first-child{color:red}.sheet-ship .repcontainer{display:grid;grid-row-gap:3px}.sheet-ship .repitem,.sheet-ship .repitem .sheet-edit,.sheet-ship .repitem .sheet-display{width:100%}.sheet-ship .sheet-grey-box-bordered{padding-right:0}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-name{width:calc(100% - 200px)}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-damage{width:65px}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-duo{width:80px}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-qualities{width:calc(100% - 195px)}.sheet-ship .sheet-ship-weapons .sheet-display{text-indent:-10px;padding-left:14px}.sheet-ship .sheet-ship-defenses .sheet-edit .sheet-name,.sheet-ship .sheet-ship-defenses .sheet-edit .sheet-effect,.sheet-ship .sheet-ship-fitting .sheet-edit .sheet-name,.sheet-ship .sheet-ship-fitting .sheet-edit .sheet-effect{flex:1 1 auto;width:0}.sheet-ship .sheet-ship-defenses .sheet-display,.sheet-ship .sheet-ship-fitting .sheet-display{text-indent:-10px;padding:2px 4px 2px 14px}.sheet-ship .sheet-edit .sheet-broken{width:50px}.sheet-ship .sheet-edit .sheet-number{width:50px}.sheet-ship .sheet-display .sheet-name{font-weight:bold}.sheet-ship .sheet-display .sheet-broken{color:red;text-transform:uppercase}.sheet-ship .sheet-display .sheet-description{font-style:italic}.sheet-editmode[value="0"] ~ .sheet-ship .sheet-ship-defenses,.sheet-editmode[value="0"] ~ .sheet-ship .sheet-ship-fitting{background:#F0F0F0;padding:3px 0}.sheet-npc{margin-top:-20px;grid:auto / 3fr .8fr 2.2fr}.sheet-npc .sheet-input-individual-hide:not([value="1"]) ~ .sheet-rolls .sheet-individual-hide{display:none}.sheet-npc .sheet-menus h3{line-height:1}.sheet-npc .sheet-menus button[type=roll].btn{line-height:1}.sheet-npc .sheet-info{display:grid;grid:auto/repeat(5, 1fr) 1.3fr}.sheet-npc .sheet-npc-hp{display:grid;grid:auto / 40px 1fr}.sheet-npc .sheet-individual-hide input[type="checkbox"]{margin-right:2px}.sheet-npc .sheet-npc-rep-header{margin:4px}.sheet-npc .sheet-rolls>:first-child{margin-bottom:5px}.sheet-npc .sheet-npc-checkbox{font-size:.9em}.sheet-npc .sheet-npc-checkbox span{vertical-align:middle;margin-right:4px}.sheet-npc .repcontainer{display:grid;grid-gap:3px}.sheet-npc .sheet-full-attacks{margin:0 6px 0 auto}.sheet-npc .sheet-grey-box-bordered{padding-right:1px}.sheet-npc .sheet-text-input{padding-right:3px}.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-name{width:0;flex-grow:1}.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-attacks,.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-ab{width:50px}.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-burst,.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-damage{width:65px}.sheet-npc .sheet-npc-attacks .sheet-display{font-size:1.1em;font-weight:bold;padding:4px 8px}.sheet-npc .sheet-npc-attacks .sheet-display .sheet-attacks[value="1"]+span{display:none}.sheet-npc .sheet-npc-attacks .sheet-display .sheet-attacks{text-transform:lowercase}.sheet-npc .sheet-npc-abilities .sheet-npc-checkbox{margin-left:auto}.sheet-npc .sheet-npc-abilities .sheet-edit .sheet-name{width:100px}.sheet-npc .sheet-npc-abilities .sheet-edit .sheet-description{width:0;flex-grow:1}.sheet-npc .sheet-npc-abilities .sheet-display{text-indent:-10px;padding:4px 8px 4px 18px}.sheet-npc .sheet-npc-abilities .sheet-display .sheet-name{font-weight:bold}.sheet-npc .sheet-npc-abilities .sheet-display .sheet-description{font-style:italic}.withoutavatars .sheet-rolltemplate-swn-default,.withoutavatars .sheet-rolltemplate-swn-attack,.withoutavatars .sheet-rolltemplate-swn-skill,.withoutavatars .sheet-rolltemplate-swn-save{margin-left:-11px}.sheet-rolltemplate-swn-default,.sheet-rolltemplate-swn-attack,.sheet-rolltemplate-swn-skill,.sheet-rolltemplate-swn-save{margin-left:-41px;width:292px;color:#FFF;font-family:"Arial",sans-serif}.sheet-rolltemplate-swn-default div,.sheet-rolltemplate-swn-attack div,.sheet-rolltemplate-swn-skill div,.sheet-rolltemplate-swn-save div{box-sizing:border-box}.sheet-rolltemplate-swn-default .sheet-container .inlinerollresult,.sheet-rolltemplate-swn-attack .sheet-container .inlinerollresult,.sheet-rolltemplate-swn-skill .sheet-container .inlinerollresult,.sheet-rolltemplate-swn-save .sheet-container .inlinerollresult{padding:0;font-family:inherit;background:transparent;border-color:transparent;border:none}.sheet-rolltemplate-swn-default .sheet-container,.sheet-rolltemplate-swn-attack .sheet-container,.sheet-rolltemplate-swn-skill .sheet-container,.sheet-rolltemplate-swn-save .sheet-container{min-height:175px;position:relative;padding:18px 20px}.sheet-rolltemplate-swn-default .sheet-background,.sheet-rolltemplate-swn-attack .sheet-background,.sheet-rolltemplate-swn-skill .sheet-background,.sheet-rolltemplate-swn-save .sheet-background{width:100%;height:calc(100% - 175px);position:absolute;top:153px;left:0;background:#0F0F0F}.sheet-rolltemplate-swn-default .sheet-header,.sheet-rolltemplate-swn-attack .sheet-header,.sheet-rolltemplate-swn-skill .sheet-header,.sheet-rolltemplate-swn-save .sheet-header{width:198px}.sheet-rolltemplate-swn-default .sheet-header .sheet-name,.sheet-rolltemplate-swn-attack .sheet-header .sheet-name,.sheet-rolltemplate-swn-skill .sheet-header .sheet-name,.sheet-rolltemplate-swn-save .sheet-header .sheet-name{margin-bottom:12px;font-size:13px;line-height:1;height:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:"Times New Roman",serif;font-weight:bold}.sheet-rolltemplate-swn-default .sheet-header .sheet-title,.sheet-rolltemplate-swn-attack .sheet-header .sheet-title,.sheet-rolltemplate-swn-skill .sheet-header .sheet-title,.sheet-rolltemplate-swn-save .sheet-header .sheet-title{font-size:14px;height:32px;line-height:16px;overflow:hidden;font-weight:bold;margin-bottom:24px}.sheet-rolltemplate-swn-default .sheet-content,.sheet-rolltemplate-swn-attack .sheet-content,.sheet-rolltemplate-swn-skill .sheet-content,.sheet-rolltemplate-swn-save .sheet-content{position:relative}.sheet-rolltemplate-swn-default .sheet-rolls .inlinerollresult,.sheet-rolltemplate-swn-attack .sheet-rolls .inlinerollresult,.sheet-rolltemplate-swn-skill .sheet-rolls .inlinerollresult,.sheet-rolltemplate-swn-save .sheet-rolls .inlinerollresult{font-size:36px;font-weight:bold;line-height:29px;white-space:nowrap}.sheet-rolltemplate-swn-default .sheet-rolls,.sheet-rolltemplate-swn-attack .sheet-rolls,.sheet-rolltemplate-swn-skill .sheet-rolls,.sheet-rolltemplate-swn-save .sheet-rolls{height:35px;display:flex;align-items:start}.sheet-rolltemplate-swn-default .sheet-rollname,.sheet-rolltemplate-swn-attack .sheet-rollname,.sheet-rolltemplate-swn-skill .sheet-rollname,.sheet-rolltemplate-swn-save .sheet-rollname{font-size:12px;line-height:1}.sheet-rolltemplate-swn-default a,.sheet-rolltemplate-swn-attack a,.sheet-rolltemplate-swn-skill a,.sheet-rolltemplate-swn-save a{color:inherit}.sheet-rolltemplate-swn-default a:hover,.sheet-rolltemplate-swn-attack a:hover,.sheet-rolltemplate-swn-skill a:hover,.sheet-rolltemplate-swn-save a:hover{color:red}.sheet-rolltemplate-swn-default a[href^="~"],.sheet-rolltemplate-swn-attack a[href^="~"],.sheet-rolltemplate-swn-skill a[href^="~"],.sheet-rolltemplate-swn-save a[href^="~"]{padding:0;background:transparent;border:none;line-height:1.4}.sheet-rolltemplate-swn-default .sheet-container{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-black.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat}.sheet-rolltemplate-swn-default .sheet-name{color:#bababa}.sheet-rolltemplate-swn-default .sheet-rollname{margin-right:auto}.sheet-rolltemplate-swn-default .sheet-desc,.sheet-rolltemplate-swn-default .sheet-buttons{font-size:12px;line-height:1.4}.sheet-rolltemplate-swn-default .sheet-info{font-style:italic;font-size:10px;line-height:1;margin:-10px 0 5px}.sheet-rolltemplate-swn-default .sheet-info .inlinerollresult{font-size:1em;font-weight:normal}.sheet-rolltemplate-swn-attack .sheet-container{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-purple.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat}.sheet-rolltemplate-swn-attack .sheet-name{color:#b291ec}.sheet-rolltemplate-swn-attack .sheet-title .inlinerollresult{font-size:1em;pointer-events:none}.sheet-rolltemplate-swn-attack .sheet-damage{margin-left:auto}.sheet-rolltemplate-swn-attack .sheet-roll{margin-left:10px}.sheet-rolltemplate-swn-attack .sheet-rolls:not(:first-of-type){margin-top:5px}.sheet-rolltemplate-swn-attack .sheet-shock{font-style:italic;margin-top:4px;font-size:12px}.sheet-rolltemplate-swn-attack .sheet-info{font-style:italic;font-size:10px}.sheet-rolltemplate-swn-attack .sheet-info>span:first-child{margin-right:10px}.sheet-rolltemplate-swn-attack .sheet-info .inlinerollresult{font-weight:normal;font-size:1em;margin-left:2px}.sheet-rolltemplate-swn-attack .sheet-desc{font-size:12px;line-height:1.4}.sheet-rolltemplate-swn-skill .sheet-container{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-blue.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat}.sheet-rolltemplate-swn-skill .sheet-name{color:#80b0ff}.sheet-rolltemplate-swn-skill .sheet-title .sheet-italic{font-style:italic}.sheet-rolltemplate-swn-skill .sheet-title .inlinerollresult{font-size:1em;pointer-events:none}.sheet-rolltemplate-swn-skill .sheet-rollname{margin-right:auto}.sheet-rolltemplate-swn-save .sheet-container.sheet-success{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-green.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat}.sheet-rolltemplate-swn-save .sheet-container.sheet-success .sheet-name{color:#83db53}.sheet-rolltemplate-swn-save .sheet-container.sheet-failure{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-red.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat}.sheet-rolltemplate-swn-save .sheet-container.sheet-failure .sheet-name{color:#ff8080}.sheet-rolltemplate-swn-save .sheet-vs{margin:0 10px}.sheet-rolltemplate-swn-save .sheet-rollname{margin-right:auto} +.charsheet{background-color:#fff;padding:0 !important;font-size:12px;min-width:800px;color:#000}div,span,label,textarea,button[type=roll],h1,h2,h3{box-sizing:border-box}label{margin:0;padding:0;color:inherit;font-size:1em;font-weight:normal;width:auto}p{font-size:1em;margin:0 0 5px;line-height:inherit}textarea{resize:vertical;padding:1px 4px;font-size:12px;margin:0;color:#000;display:block}input[type=text],input[type=number]{padding:1px 4px;font-size:12px;height:20px;color:#000}input[type=number][readonly=readonly],input[type=number].sheet-no-spinners{-moz-appearance:textfield}input[type=number][readonly=readonly]::-webkit-inner-spin-button,input[type=number][readonly=readonly]::-webkit-outer-spin-button,input[type=number].sheet-no-spinners::-webkit-inner-spin-button,input[type=number].sheet-no-spinners::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}select{margin:0;color:#000;font-size:12px;padding:1px 2px;line-height:18px;height:22px}button[type=roll].btn{margin:0}button[type=roll].sheet-unstyled-button{text-shadow:none;box-shadow:none;color:inherit;text-align:inherit;padding:0;border:none;border-radius:0;font-size:inherit;background:transparent}button[type=roll].sheet-unstyled-button::before{content:""}button[type=roll].sheet-invisible-button{position:absolute;z-index:1;opacity:0;left:0;width:100%;height:100%;top:0}button[type=roll].sheet-invisible-button:hover + div{color:#2b3fea;border-color:#2b3fea}.sheet-hider[value="0"] + div,.sheet-hider[value="0"] + label,.sheet-hider[value="0"] + button,.sheet-hider[value="0"] + span{display:none}.sheet-hider[value=""] + button{display:none}.sheet-editmode[value="0"] ~ .sheet-content .sheet-empty-hider[value=""] + div{display:none}h1{font-family:"Contrail One",sans-serif;background-color:#9b9b9b;padding-left:5px;color:#fff;font-size:1.3em;line-height:22px;font-weight:normal}h1::after{content:"";position:absolute;right:0;background-color:#223297;background-position:center;background-size:100%;width:22px;height:22px}h2{font-family:"Contrail One",sans-serif;padding-left:5px;border:2px solid #000;background-color:#ccc;color:#000;font-size:1.1em;margin:5px 0;width:175px;line-height:18px}h3{font-size:1.2em;font-family:"Contrail One",sans-serif;color:#6b6b6b;line-height:1.5;font-weight:normal}.sheet-npc-input[value="0"] ~ .sheet-tabs .sheet-npc-tab,.sheet-npc-input[value="1"] ~ .sheet-tabs .sheet-pc-tab,.sheet-tab-input:not([value=character]) ~ .sheet-character,.sheet-tab-input:not([value=ship]) ~ .sheet-ship,.sheet-tab-input:not([value=npc]) ~ .sheet-npc{display:none}.sheet-content{min-width:800px;display:grid;grid-gap:5px}.sheet-editmode[value="0"] ~ .sheet-content .sheet-edit,.sheet-editmode[value="0"] ~ .sheet-content .repcontrol,.sheet-editmode[value="1"] ~ .sheet-content .sheet-display{display:none}.sheet-header{margin-bottom:10px}.sheet-header input{opacity:0;position:absolute}.sheet-header .sheet-logo{width:480px}.sheet-header .sheet-npc-chooser{cursor:pointer;margin-left:auto;color:#fff}.sheet-header .sheet-npc-chooser span{padding:3px 6px}.sheet-header .sheet-npc-chooser input:not(:checked) ~ .sheet-pc-label,.sheet-header .sheet-npc-chooser input:checked ~ .sheet-npc-label{background:#11194b}.sheet-header .sheet-npc-chooser input:checked ~ .sheet-pc-label,.sheet-header .sheet-npc-chooser input:not(:checked) ~ .sheet-npc-label{background:#223297}.sheet-header .sheet-edit-button{margin:0 5px 0 20px}.sheet-header .sheet-settings-gear,.sheet-header .sheet-edit-button{cursor:pointer;font-size:16px;font-family:pictos}.sheet-header .sheet-settings-gear input:not(:checked) + span,.sheet-header .sheet-edit-button input:not(:checked) + span{color:#888}.sheet-header .sheet-settings-gear input:checked + span,.sheet-header .sheet-edit-button input:checked + span{color:#223297}.sheet-footer{font-size:10px;border-top:1px solid #ccc;margin-top:10px;color:#666}.sheet-footer button[type=roll].btn:hover{color:#223297}.sheet-tabs{margin-bottom:10px;width:100%;position:relative;z-index:2;border-top:1px solid #333;font-family:"Contrail One",sans-serif;flex-flow:row-reverse;justify-content:flex-end}.sheet-tabs input{opacity:0;position:absolute}.sheet-tabs input:checked + span{background:#11194b}.sheet-tabs input:not(:checked) + span{background:#223297}.sheet-tabs span{padding:1px 25px 0}.sheet-tabs label{cursor:pointer;line-height:17px;display:flex;margin:-1px -10px 0 0;color:#fff;clip-path:polygon(0 0, 100% 0, 100% 10px, calc(100% - 10px) 100%, 0 100%)}.sheet-flex{display:flex}.sheet-flex-start{display:flex;align-items:flex-start}.sheet-flex-center{display:flex;align-items:center}.sheet-flex-between{display:flex;align-items:center;justify-content:space-between}.sheet-flex-wrap{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start}.sheet-grow{flex-grow:1}.sheet-halfgrid{display:grid;grid:auto/1fr 1fr;grid-column-gap:5px}.sheet-thirdsgrid{display:grid;grid:auto/repeat(3, 1fr);grid-column-gap:1%}.sheet-column > div:not(:first-child){margin-top:5px}.sheet-col-1-3{grid-column:1/3}.sheet-col-1-4{grid-column:1/4}.sheet-col-1-5{grid-column:1/5}.sheet-col-2{grid-column:2}.sheet-col-2-4{grid-column:2/4}.sheet-col-3{grid-column:3}.sheet-col-3-5{grid-column:3/5}.sheet-col-4{grid-column:4}.sheet-col-4-7{grid-column:4/7}.sheet-col-5-7{grid-column:5/7}.sheet-row-3-5{grid-row:3/5}.sheet-col55{width:55%}.sheet-col50{width:50%}.sheet-col40{width:40%}.sheet-colthird{width:calc(100%/3)}.sheet-col25{width:25%}.sheet-colsixth{width:calc(100%/6)}.sheet-grey-box,.sheet-grey-box-bordered{padding:4px;background:#f0f0f0}.sheet-grey-box-bordered{border:1px solid #aaa}.sheet-core-box{padding:8px;background:#f0f0f0}.sheet-core-box-text{padding:8px 3px 3px 8px;background:#f0f0f0}input[type=text].sheet-inherit{border-radius:0;border:none;background:transparent;box-shadow:none;padding:0;color:inherit;font:inherit}input[type=number].sheet-inline-input{position:relative;z-index:2;vertical-align:baseline;padding:0 3px}.sheet-text-input{color:#666;padding-right:5px;line-height:1}.sheet-text-input .sheet-label{font-size:.9em;text-align:inherit;line-height:14px;border-top:1px solid #aaa}.sheet-text-input .sheet-label input[type=checkbox]{height:14px;margin:0 3px 0 0}.sheet-text-input input[type=text],.sheet-text-input input[type=number],.sheet-text-input textarea{background:transparent;padding:1px 0;width:100%;border-radius:0;color:#223297;border:none;text-align:inherit;font-weight:inherit;box-shadow:none}.sheet-text-input input[type=text][readonly=readonly],.sheet-text-input input[type=number][readonly=readonly],.sheet-text-input textarea[readonly=readonly]{cursor:default}.sheet-text-input input[type=text],.sheet-text-input input[type=number]{font-size:1.1em}.sheet-text-input textarea{height:20px;min-height:20px}.sheet-text-input > input[type=checkbox]{height:14px;margin:3px 0}.sheet-text-input select{width:100%;height:20px;color:#223297;background:transparent;border:none}.sheet-text-input.sheet-important{font-weight:bold;font-size:1.1em}.sheet-text-input.sheet-center{text-align:center}.sheet-text-input.sheet-duo{display:grid;text-align:center;grid:auto/1fr 5px 1fr;align-items:center;align-content:start;grid-column-gap:4px}.sheet-text-input.sheet-duo > span{font-size:16px;color:#333}.sheet-text-input.sheet-duo .sheet-label{grid-column:1/4}.sheet-text-input button[type=roll].btn{width:100%}.sheet-text-input button[type=roll].btn:hover{color:red}.sheet-table-header{font-size:.9em;color:#666}.sheet-table-header .sheet-center{text-align:center}.sheet-table-header > div{padding-left:2px;border-bottom:1px solid #aaa}.sheet-blue-button{text-align:center}.sheet-blue-button button[type=roll].btn{background:#2b3fea;width:35px;height:35px;display:block;margin:0 auto;color:#fff}.sheet-blue-button button[type=roll].btn::before{content:""}.sheet-lower{text-transform:lowercase}.sheet-space-before::before,.sheet-space-after::after{content:" "}.sheet-colon-after::after{content:":"}.sheet-hide-empty[value=""] + span{display:none}.sheet-add-plus:not([value^="-"]) + span::before{content:"+"}.sheet-api{font-size:.8em;background:#f0f0f0;border-radius:5px;padding:1px;line-height:1;vertical-align:super}.sheet-simple-repsection .repitem{margin-bottom:3px}.sheet-simple-repsection textarea{margin:3px 0 0;height:50px}.sheet-simple-repsection .sheet-display .sheet-name{font-weight:bold;font-size:1.1em;border-bottom:1px solid #777}.sheet-simple-repsection .sheet-display .sheet-details{line-height:1.4;text-align:justify;white-space:pre-wrap}.sheet-rep-grid{display:grid;align-items:start;grid-column-gap:3px;margin-bottom:3px}.sheet-rep-grid .sheet-text-input{padding:0}.sheet-skills-type[value=neither] ~ div .sheet-skills-either,.sheet-skills-type:not([value=first]) ~ div .sheet-skills-first,.sheet-skills-type:not([value=revised]) ~ div .sheet-skills-revised,.sheet-skills-type:not([value=neither]) ~ div .sheet-skills-neither,.sheet-skills-query:not([value=hover]) ~ div .sheet-skills-query-hover,.sheet-skills-query[value=query] ~ div .sheet-skills-query-display,.sheet-skills-query[value=query] ~ div .sheet-skills-query-ask{display:none}.sheet-skills-query-display input:not([value*=str]) ~ .sheet-str,.sheet-skills-query-display input:not([value*=dex]) ~ .sheet-dex,.sheet-skills-query-display input:not([value*=con]) ~ .sheet-con,.sheet-skills-query-display input:not([value*=int]) ~ .sheet-int,.sheet-skills-query-display input:not([value*=wis]) ~ .sheet-wis,.sheet-skills-query-display input:not([value*=cha]) ~ .sheet-cha{display:none}.sheet-skills-query[value=hover] ~ div .sheet-skill:hover .sheet-skills-query-display,.sheet-skill .sheet-display .sheet-query:focus + .sheet-skills-query-display{display:none}.repcontrol{display:flex;margin-top:4px}.repcontrol button{padding:3px 10px}.repcontrol_edit{order:1;margin-left:auto}.repcontrol button{background:#223297;color:#fff;box-shadow:none;text-shadow:none}.repcontrol_move,.repcontrol_del{padding:1px 10px}.itemcontrol{z-index:100}.sheet-section-toggle-header{position:relative}.sheet-section-toggle-header input{cursor:pointer;position:absolute;width:22px;height:100%;z-index:2;right:0;opacity:0}.sheet-section-toggle-header input + h1::after{background-image:url("https://svgshare.com/i/6Vz.svg")}.sheet-section-toggle-header input:not(:checked) + h1::after{transform:rotate(180deg)}.sheet-section-toggle-header + input + div{margin-top:5px}.sheet-settings label{font-weight:bold}.sheet-settings label span{margin-right:4px}.sheet-settings select{width:120px;display:inline-block}.sheet-settings select.sheet-wide{width:170px}.sheet-generate{margin-bottom:5px}.sheet-generate .sheet-generate-source{height:20px;width:170px}.sheet-generate .sheet-generate-info{margin:0 5px;min-height:20px;flex-grow:1;background:#f0f0f0;border-radius:4px;padding:1px 4px}.sheet-generate .sheet-generate-button{padding:1px 8px;border-radius:4px;cursor:pointer;background:#223297;color:#fff}.sheet-generate .sheet-generate-button input[type=checkbox]{position:absolute;visibility:hidden}.sheet-generate .sheet-generate-button:active{outline:5px auto;outline-offset:-2px}.sheet-core{display:grid;grid-column-gap:5px}.sheet-core.sheet-core-info{grid:auto/2.5fr 1fr .8fr}.sheet-core.sheet-core-info .sheet-info{flex-wrap:wrap;padding-right:3px}.sheet-core.sheet-core-info .sheet-info .sheet-important{width:calc(60% - 22px)}.sheet-core.sheet-core-info .sheet-info .sheet-level{width:44px}.sheet-core.sheet-core-info .sheet-info .sheet-level-rest{width:calc(40% - 22px)}.sheet-core.sheet-core-stats{grid:auto/minmax(310px, 1.2fr) minmax(260px, 1fr) minmax(220px, 0.8fr)}.sheet-core .sheet-main-content{margin-top:3px;display:grid;grid:auto/repeat(3, 1fr);grid-row-gap:3px}.sheet-core .sheet-main-content .sheet-left-margin{margin-left:15px}.sheet-saves .sheet-flex{margin-top:4px}.sheet-menus-content{display:grid;grid:auto/1fr 1fr}.sheet-character .sheet-menus button[type=roll].btn{margin-right:auto}.sheet-menus button[type=roll].btn{color:#2b3fea;font-size:1.1em}.sheet-menus button[type=roll].btn:hover{color:red}.sheet-attributes{font-size:1.1em;line-height:16px}.sheet-attributes table{width:100%;height:100%}.sheet-attributes td:first-child,.sheet-attributes .sheet-mod{font-weight:bold}.sheet-attributes td:not(:first-child){text-align:center}.sheet-attributes input[type=number]{width:45px}.sheet-attributes .sheet-mod{font-size:1.1em}.sheet-editmode[value="0"] ~ .sheet-content .sheet-resources .repcontainer{grid:auto/1fr 1fr}.sheet-resources .sheet-credits{margin-left:auto}.sheet-resources .repcontainer{display:grid;grid-row-gap:3px;margin-top:3px}.sheet-resources input[type=text]{width:calc(100% - 8em);margin-right:auto}.sheet-resources .sheet-slash{margin:0 2px}.sheet-weapons .sheet-edit{justify-content:space-between;padding-right:1px}.sheet-weapons .sheet-edit .sheet-name{width:138px}.sheet-weapons .sheet-edit .sheet-ab{width:45px}.sheet-weapons .sheet-edit .sheet-weapon-skill{width:80px}.sheet-weapons .sheet-edit .sheet-attribute{width:60px}.sheet-weapons .sheet-edit .sheet-burst{width:65px}.sheet-weapons .sheet-edit .sheet-damage{width:60px}.sheet-weapons .sheet-edit .sheet-shock-damage{width:55px}.sheet-weapons .sheet-edit .sheet-shock-ac{width:55px}.sheet-weapons .sheet-edit .sheet-skill-to-damage{width:30px}.sheet-weapons .sheet-edit .sheet-range{width:60px}.sheet-weapons .sheet-edit .sheet-ammo{width:80px}.sheet-weapons .sheet-edit .sheet-enc{width:40px}.sheet-weapons .sheet-text-input{padding-right:3px}.sheet-weapons .repitem{margin-bottom:3px}.sheet-weapons .sheet-display{font-size:1.1em;border:1px solid #888;text-indent:-10px;padding:2px 4px 2px 14px}.sheet-weapons .sheet-display .sheet-name{font-weight:bold}.sheet-weapons .repitem:nth-child(odd) .sheet-display{background:#d3d3d3}.sheet-skill-container,.sheet-skills-repeating .repcontainer{display:grid;grid:auto/1fr 1fr;grid-gap:4px 1%}.sheet-skill{position:relative}.sheet-skill .sheet-display,.sheet-skill .sheet-edit{border:1px solid #888;padding:2px 4px;height:100%}.sheet-skill .sheet-display{font-weight:bold;font-size:1.1em}.sheet-skill .sheet-display .sheet-dice[value="3d6d1"] + .sheet-name::after{content:"3d6"}.sheet-skill .sheet-display .sheet-dice[value="4d6d2"] + .sheet-name::after{content:"4d6"}.sheet-skill .sheet-display .sheet-name{margin-right:auto}.sheet-skill .sheet-display .sheet-name::after{vertical-align:super;margin-left:2px;font-weight:normal;font-size:.7em}.sheet-skill .sheet-display .sheet-query{width:55px;background:transparent;border-color:transparent;position:relative;height:18px;z-index:2;margin:0 2px;outline:none;color:inherit;flex-shrink:0;line-height:16px;padding:0}.sheet-skill:not(:hover) .sheet-display .sheet-query:not(:focus){display:none}.sheet-skill .sheet-skills-query-display{margin:0 3px;flex-shrink:0;font-weight:normal}.sheet-skill .sheet-edit input[type=text].sheet-name{width:100%;margin-bottom:2px}.sheet-skill .sheet-edit div.sheet-name{flex-grow:1;width:0;padding:1px 2px}.sheet-skill .sheet-edit .sheet-level{margin:0 2px;padding:1px 2px;width:40px}.sheet-skill .sheet-edit .sheet-query{width:50px}.sheet-skill .sheet-edit .sheet-dice{width:35px}.sheet-skill .sheet-edit.sheet-flex-wrap select,.sheet-skill .sheet-edit.sheet-flex-wrap input{flex-grow:1}.sheet-skill.sheet-skill-points .sheet-display{font-size:1.1em;font-weight:bold;width:100%}.sheet-skill.sheet-skill-points .sheet-name{background:#000;color:#fff;flex-grow:0;margin-right:auto;width:auto;padding:0 4px}.sheet-skill.sheet-skill-points .sheet-edit .sheet-level{margin:0}.sheet-skill-container .sheet-skill:nth-of-type(4n+1),.sheet-skill-container .sheet-skill:nth-of-type(4n+2){background:#d3d3d3}.repcontainer[data-groupname=repeating_skills] .repitem:nth-of-type(4n+1) .sheet-skill,.repcontainer[data-groupname=repeating_skills] .repitem:nth-of-type(4n+2) .sheet-skill{background:#d3d3d3}.sheet-skills-type:not([value=neither]) ~ div .sheet-skills-repeating,.sheet-psionics .sheet-skills-repeating,.sheet-magic .sheet-skills-repeating{margin-top:4px}.sheet-skill-blurb{font-style:italic;text-align:center}.sheet-details-button{margin-left:auto;font-weight:bold;color:#999;letter-spacing:1px;cursor:pointer;text-transform:uppercase;font-size:10px}.sheet-details-button input{visibility:hidden;position:absolute}.sheet-details-button input:checked + span{color:#333}.sheet-input-details:not([value="1"]) ~ div .sheet-details{display:none}.sheet-super-type:not([value=psionics]) ~ div .sheet-super-psionics-only,.sheet-super-type:not([value=magic]) ~ div .sheet-super-magic-only,.sheet-super-type:not([value=both]) ~ div .sheet-super-both,.sheet-super-type[value=magic] ~ div .sheet-super-psionics,.sheet-super-type[value=psionics] ~ div .sheet-super-magic,.sheet-super-type[value=neither] ~ div .sheet-super{display:none}.sheet-tab-input:not([value=psionics]) ~ .sheet-psionics,.sheet-tab-input:not([value=magic]) ~ .sheet-magic{display:none}.sheet-psionics-effort{display:grid;grid:auto/auto 60px 60px 60px 80px;align-items:center;grid-column-gap:4px;margin-top:5px}.sheet-psionics-effort h3{line-height:1}.sheet-techniques{margin-top:5px}.sheet-techniques > .sheet-flex-center{margin-bottom:5px}.sheet-techniques .sheet-display .sheet-discipline{margin-left:auto}.sheet-techniques .sheet-edit .sheet-discipline{margin-left:5px;width:90px}.sheet-spells{margin-top:5px}.sheet-spells > .sheet-flex-center{margin-bottom:5px}.sheet-spells > .sheet-flex{border-bottom:1px solid #666;margin-bottom:3px}.sheet-spells > .sheet-flex :not(:first-child){text-align:center}.sheet-spells .sheet-edit .sheet-name{width:220px;flex-grow:1}.sheet-spells .sheet-edit .sheet-prepared{margin:0 3px}.sheet-spells .sheet-edit .sheet-prepared,.sheet-spells .sheet-edit .sheet-damage{width:60px}.sheet-spells .sheet-display .sheet-name{padding-bottom:1px}.sheet-spells .sheet-display span.sheet-prepared{margin:0 4px 0 auto}.sheet-spells .sheet-display input[type=number].sheet-prepared{padding:0 4px;position:relative;z-index:2}.sheet-foci-loc[value=left] ~ .sheet-column .sheet-foci-right,.sheet-foci-loc[value=right] ~ .sheet-column .sheet-foci-left{display:none}.sheet-foci .sheet-details-button{position:relative;z-index:2}.sheet-foci .sheet-class-ability{position:relative}.sheet-foci .sheet-class-ability .sheet-edit .sheet-name{font-weight:bold;font-size:1.1em;border-bottom:1px solid #777}.sheet-foci .sheet-class-ability .sheet-name,.sheet-foci .sheet-class-ability .sheet-edit textarea,.sheet-foci .sheet-class-ability .sheet-display{margin-bottom:3px}.sheet-foci .sheet-edit .sheet-name{flex-grow:1}.sheet-foci .sheet-edit .sheet-level{margin-left:3px;width:60px}.sheet-foci .sheet-display .sheet-level{margin-left:auto}.sheet-armor .sheet-total-ac{margin-left:auto;font-weight:bold}.sheet-armor .sheet-armor-grid{grid:auto/40px 1fr 40px 75px 35px 70px}.sheet-readied-stowed{display:grid;align-items:center;grid:auto/1fr 60px 60px 80px 80px;grid-column-gap:7px}.sheet-readied-stowed .sheet-input-gear-over[value="1"] + .sheet-text-input input:first-child{color:red}.sheet-cyberware h3{margin:5px 0}.sheet-cyberware .sheet-edit{flex-wrap:wrap}.sheet-cyberware .sheet-edit input[type=text]{width:0;flex-grow:1}.sheet-cyberware .sheet-edit > span{margin:0 3px}.sheet-equipment .repcontainer[data-groupname=repeating_weapons] + .repcontrol{display:none}.sheet-equipment .sheet-gear-grid{grid:auto/minmax(120px, 1fr) 2fr 35px 70px}.sheet-equipment .sheet-other h3{margin-bottom:5px}.sheet-equipment .sheet-other-gear{height:100px}.sheet-misc .sheet-text-input input{padding-left:2px}.sheet-misc .repitem{margin-bottom:2px}.sheet-misc .sheet-xp{width:50px}.sheet-notes{margin-top:5px}.sheet-ship-class[value=fighter] ~ .sheet-section .sheet-generate-source .sheet-frigate,.sheet-ship-class[value=fighter] ~ .sheet-section .sheet-generate-source .sheet-cruiser,.sheet-ship-class[value=fighter] ~ .sheet-section .sheet-generate-source .sheet-capital{display:none}.sheet-ship-class[value=frigate] ~ .sheet-section .sheet-generate-source .sheet-cruiser,.sheet-ship-class[value=frigate] ~ .sheet-section .sheet-generate-source .sheet-capital{display:none}.sheet-ship-class[value=cruiser] ~ .sheet-section .sheet-generate-source .sheet-capital{display:none}.sheet-ship{margin-top:-20px;grid:auto/repeat(4, 1fr)}.sheet-ship .sheet-menus h3{line-height:1}.sheet-ship .sheet-menus button[type=roll].btn{line-height:1}.sheet-ship .sheet-type{padding:5px 8px}.sheet-ship .sheet-type h3{line-height:1}.sheet-ship .sheet-type select{height:20px;width:80px;background:transparent}.sheet-ship .sheet-info{flex-wrap:wrap}.sheet-ship .sheet-info .sheet-text-input{margin-bottom:3px}.sheet-ship .sheet-data{display:grid;grid:auto/repeat(3, 1fr)}.sheet-ship .sheet-data .sheet-text-input,.sheet-ship .sheet-data .sheet-text-input input[type=number]{text-align:center}.sheet-ship .sheet-stats{display:grid;grid:auto/1fr 1fr}.sheet-ship .sheet-hulltype{position:relative}.sheet-ship .sheet-hulltype .sheet-details{position:absolute;z-index:1;opacity:1;width:250px;top:22px;left:-63px;transition:all .3s;background:#fff;border:1px solid #777;border-radius:8px;padding:5px}.sheet-ship .sheet-hulltype input:not(:focus) ~ .sheet-details{visibility:hidden;opacity:0}.sheet-ship .sheet-input-color-negative[value^="-"] + .sheet-text-input input:first-child{color:red}.sheet-ship .repcontainer{display:grid;grid-row-gap:3px}.sheet-ship .repitem,.sheet-ship .repitem .sheet-edit,.sheet-ship .repitem .sheet-display{width:100%}.sheet-ship .sheet-grey-box-bordered{padding-right:0}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-name{width:calc(100% - 200px)}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-damage{width:65px}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-duo{width:80px}.sheet-ship .sheet-ship-weapons .sheet-edit .sheet-qualities{width:calc(100% - 195px)}.sheet-ship .sheet-ship-weapons .sheet-display{text-indent:-10px;padding-left:14px}.sheet-ship .sheet-ship-defenses .sheet-edit .sheet-name,.sheet-ship .sheet-ship-defenses .sheet-edit .sheet-effect,.sheet-ship .sheet-ship-fitting .sheet-edit .sheet-name,.sheet-ship .sheet-ship-fitting .sheet-edit .sheet-effect{flex:1 1 auto;width:0}.sheet-ship .sheet-ship-defenses .sheet-display,.sheet-ship .sheet-ship-fitting .sheet-display{text-indent:-10px;padding:2px 4px 2px 14px}.sheet-ship .sheet-edit .sheet-broken{width:50px}.sheet-ship .sheet-edit .sheet-number{width:50px}.sheet-ship .sheet-display .sheet-name{font-weight:bold}.sheet-ship .sheet-display .sheet-broken{color:red;text-transform:uppercase}.sheet-ship .sheet-display .sheet-description{font-style:italic}.sheet-ship .sheet-input-type[value=SHIP] ~ div .sheet-vehicle-type:not(.sheet-vehicle-type-ship),.sheet-ship .sheet-input-type[value=MECH] ~ div .sheet-vehicle-type:not(.sheet-vehicle-type-mech),.sheet-ship .sheet-input-type[value=VEHICLE] ~ div .sheet-vehicle-type:not(.sheet-vehicle-type-custom){display:none}.sheet-editmode[value="0"] ~ .sheet-ship .sheet-ship-defenses,.sheet-editmode[value="0"] ~ .sheet-ship .sheet-ship-fitting{background:#f0f0f0;padding:3px 0}.sheet-npc{margin-top:-20px;grid:auto/3fr .8fr 2.2fr}.sheet-npc .sheet-input-individual-hide:not([value="1"]) ~ .sheet-rolls .sheet-individual-hide{display:none}.sheet-npc .sheet-menus h3{line-height:1}.sheet-npc .sheet-menus button[type=roll].btn{line-height:1}.sheet-npc .sheet-info{display:grid;grid:auto/repeat(5, 1fr) 1.3fr}.sheet-npc .sheet-npc-hp{display:grid;grid:auto/40px 1fr}.sheet-npc .sheet-individual-hide input[type=checkbox]{margin-right:2px}.sheet-npc .sheet-npc-rep-header{margin:4px}.sheet-npc .sheet-rolls > :first-child{margin-bottom:5px}.sheet-npc .sheet-npc-checkbox{font-size:.9em}.sheet-npc .sheet-npc-checkbox span{vertical-align:middle;margin-right:4px}.sheet-npc .repcontainer{display:grid;grid-gap:3px}.sheet-npc .sheet-full-attacks{margin:0 6px 0 auto}.sheet-npc .sheet-grey-box-bordered{padding-right:1px}.sheet-npc .sheet-text-input{padding-right:3px}.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-name{width:0;flex-grow:1}.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-attacks,.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-ab{width:50px}.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-burst,.sheet-npc .sheet-npc-attacks .sheet-edit .sheet-damage{width:65px}.sheet-npc .sheet-npc-attacks .sheet-display{font-size:1.1em;font-weight:bold;padding:4px 8px}.sheet-npc .sheet-npc-attacks .sheet-display .sheet-attacks[value="1"] + span{display:none}.sheet-npc .sheet-npc-attacks .sheet-display .sheet-attacks{text-transform:lowercase}.sheet-npc .sheet-npc-abilities .sheet-npc-checkbox{margin-left:auto}.sheet-npc .sheet-npc-abilities .sheet-edit .sheet-name{width:100px}.sheet-npc .sheet-npc-abilities .sheet-edit .sheet-description{width:0;flex-grow:1}.sheet-npc .sheet-npc-abilities .sheet-display{text-indent:-10px;padding:4px 8px 4px 18px}.sheet-npc .sheet-npc-abilities .sheet-display .sheet-name{font-weight:bold}.sheet-npc .sheet-npc-abilities .sheet-display .sheet-description{font-style:italic}.withoutavatars .sheet-rolltemplate-swn-default,.withoutavatars .sheet-rolltemplate-swn-attack,.withoutavatars .sheet-rolltemplate-swn-skill,.withoutavatars .sheet-rolltemplate-swn-save{margin-left:-11px}.sheet-rolltemplate-swn-default,.sheet-rolltemplate-swn-attack,.sheet-rolltemplate-swn-skill,.sheet-rolltemplate-swn-save{margin-left:-41px;width:292px;color:#fff;font-family:"Arial",sans-serif}.sheet-rolltemplate-swn-default div,.sheet-rolltemplate-swn-attack div,.sheet-rolltemplate-swn-skill div,.sheet-rolltemplate-swn-save div{box-sizing:border-box}.sheet-rolltemplate-swn-default .sheet-container .inlinerollresult,.sheet-rolltemplate-swn-attack .sheet-container .inlinerollresult,.sheet-rolltemplate-swn-skill .sheet-container .inlinerollresult,.sheet-rolltemplate-swn-save .sheet-container .inlinerollresult{padding:0;font-family:inherit;background:transparent;border-color:transparent;border:none}.sheet-rolltemplate-swn-default .sheet-container,.sheet-rolltemplate-swn-attack .sheet-container,.sheet-rolltemplate-swn-skill .sheet-container,.sheet-rolltemplate-swn-save .sheet-container{min-height:175px;position:relative;padding:18px 20px;clip-path:polygon(0 7px, 7px 0, 173px 0, 177px 3px, 281px 3px, 289px 11px, 289px 82px, 100% 87px, 100% calc(100% - 6px), calc(100% - 6px) 100%, 22px 100%, 0 calc(100% - 22px))}.sheet-rolltemplate-swn-default .sheet-header,.sheet-rolltemplate-swn-attack .sheet-header,.sheet-rolltemplate-swn-skill .sheet-header,.sheet-rolltemplate-swn-save .sheet-header{width:198px}.sheet-rolltemplate-swn-default .sheet-header .sheet-name,.sheet-rolltemplate-swn-attack .sheet-header .sheet-name,.sheet-rolltemplate-swn-skill .sheet-header .sheet-name,.sheet-rolltemplate-swn-save .sheet-header .sheet-name{margin-bottom:12px;font-size:13px;line-height:1;height:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:"Times New Roman",serif;font-weight:bold}.sheet-rolltemplate-swn-default .sheet-header .sheet-title,.sheet-rolltemplate-swn-attack .sheet-header .sheet-title,.sheet-rolltemplate-swn-skill .sheet-header .sheet-title,.sheet-rolltemplate-swn-save .sheet-header .sheet-title{font-size:14px;height:32px;line-height:16px;overflow:hidden;font-weight:bold;margin-bottom:24px}.sheet-rolltemplate-swn-default .sheet-content,.sheet-rolltemplate-swn-attack .sheet-content,.sheet-rolltemplate-swn-skill .sheet-content,.sheet-rolltemplate-swn-save .sheet-content{position:relative}.sheet-rolltemplate-swn-default .sheet-rolls .inlinerollresult,.sheet-rolltemplate-swn-attack .sheet-rolls .inlinerollresult,.sheet-rolltemplate-swn-skill .sheet-rolls .inlinerollresult,.sheet-rolltemplate-swn-save .sheet-rolls .inlinerollresult{font-size:36px;font-weight:bold;line-height:29px;white-space:nowrap}.sheet-rolltemplate-swn-default .sheet-rolls,.sheet-rolltemplate-swn-attack .sheet-rolls,.sheet-rolltemplate-swn-skill .sheet-rolls,.sheet-rolltemplate-swn-save .sheet-rolls{height:35px;display:flex;align-items:start}.sheet-rolltemplate-swn-default .sheet-rollname,.sheet-rolltemplate-swn-attack .sheet-rollname,.sheet-rolltemplate-swn-skill .sheet-rollname,.sheet-rolltemplate-swn-save .sheet-rollname{font-size:12px;line-height:1}.sheet-rolltemplate-swn-default a,.sheet-rolltemplate-swn-attack a,.sheet-rolltemplate-swn-skill a,.sheet-rolltemplate-swn-save a{color:inherit}.sheet-rolltemplate-swn-default a:hover,.sheet-rolltemplate-swn-attack a:hover,.sheet-rolltemplate-swn-skill a:hover,.sheet-rolltemplate-swn-save a:hover{color:red}.sheet-rolltemplate-swn-default a[href^="~"],.sheet-rolltemplate-swn-attack a[href^="~"],.sheet-rolltemplate-swn-skill a[href^="~"],.sheet-rolltemplate-swn-save a[href^="~"]{padding:0;background:transparent;border:none;line-height:1.4}.sheet-rolltemplate-swn-default .sheet-container{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-black.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat,#0f0f0f}.sheet-rolltemplate-swn-default .sheet-name{color:#bababa}.sheet-rolltemplate-swn-default .sheet-rollname{margin-right:auto}.sheet-rolltemplate-swn-default .sheet-desc,.sheet-rolltemplate-swn-default .sheet-buttons{font-size:12px;line-height:1.4}.sheet-rolltemplate-swn-default .sheet-info{font-style:italic;font-size:10px;line-height:1;margin:-10px 0 5px}.sheet-rolltemplate-swn-default .sheet-info .inlinerollresult{font-size:1em;font-weight:normal}.sheet-rolltemplate-swn-attack .sheet-container{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-purple.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat,#0f0f0f}.sheet-rolltemplate-swn-attack .sheet-name{color:#b291ec}.sheet-rolltemplate-swn-attack .sheet-title .inlinerollresult{font-size:1em;pointer-events:none}.sheet-rolltemplate-swn-attack .sheet-damage{margin-left:auto}.sheet-rolltemplate-swn-attack .sheet-roll{margin-left:10px}.sheet-rolltemplate-swn-attack .sheet-rolls:not(:first-of-type){margin-top:5px}.sheet-rolltemplate-swn-attack .sheet-shock{font-style:italic;margin-top:4px;font-size:12px}.sheet-rolltemplate-swn-attack .sheet-info{font-style:italic;font-size:10px}.sheet-rolltemplate-swn-attack .sheet-info > span:first-child{margin-right:10px}.sheet-rolltemplate-swn-attack .sheet-info .inlinerollresult{font-weight:normal;font-size:1em;margin-left:2px}.sheet-rolltemplate-swn-attack .sheet-desc{font-size:12px;line-height:1.4}.sheet-rolltemplate-swn-skill .sheet-container{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-blue.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat,#0f0f0f}.sheet-rolltemplate-swn-skill .sheet-name{color:#80b0ff}.sheet-rolltemplate-swn-skill .sheet-title .sheet-italic{font-style:italic}.sheet-rolltemplate-swn-skill .sheet-title .inlinerollresult{font-size:1em;pointer-events:none}.sheet-rolltemplate-swn-skill .sheet-rollname{margin-right:auto}.sheet-rolltemplate-swn-save .sheet-container.sheet-success{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-green.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat,#0f0f0f}.sheet-rolltemplate-swn-save .sheet-container.sheet-success .sheet-name{color:#83db53}.sheet-rolltemplate-swn-save .sheet-container.sheet-failure{background:url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-top-red.png") top no-repeat,url("https://raw.githubusercontent.com/roll20/roll20-character-sheets/master/Stars_Without_Number_Revised/Assets/rt-bottom.png") bottom no-repeat,#0f0f0f}.sheet-rolltemplate-swn-save .sheet-container.sheet-failure .sheet-name{color:#ff8080}.sheet-rolltemplate-swn-save .sheet-vs{margin:0 10px}.sheet-rolltemplate-swn-save .sheet-rollname{margin-right:auto} diff --git a/Stars_Without_Number_Revised/Stars_Without_Number_Revised.html b/Stars_Without_Number_Revised/Stars_Without_Number_Revised.html index ea8ddfebda..089c0a865c 100644 --- a/Stars_Without_Number_Revised/Stars_Without_Number_Revised.html +++ b/Stars_Without_Number_Revised/Stars_Without_Number_Revised.html @@ -1,3 +1,3 @@ -

