Files
roll20-character-sheets-tester/GURPS/gurps.html
T
Andreas J 51b9a5a63b [GURPS v1.7.0] clean PR (#5692)
* GURPS: v.1.7 readme & sheet.json changes

* GURPS: v.1.7 Sheet changes, see readme for summary
2019-11-25 12:58:41 -06:00

10885 lines
438 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div class="sheet-wrapper">
<!-- HIDDEN FIELDS -->
<input type="hidden" name="attr_10" value="10" disabled="disabled" />
<input type="hidden" name="attr_VS" value="vs:" disabled="disabled" />
<input type="hidden" name="attr_languages_points" value="0" />
<input type="hidden" name="attr_cf_points" value="0" />
<input type="hidden" name="attr_advantages_points" value="0" />
<input type="hidden" name="attr_disadvantages_points" value="0" />
<input type="hidden" name="attr_racial_points" value="0" />
<input type="hidden" name="attr_skills_points" value="0" />
<input type="hidden" name="attr_techniques_points" value="0" />
<input type="hidden" name="attr_spells_points" value="0" />
<input type="hidden" name="attr_announcements_hide" value="0" />
<input type="hidden" name="attr_inventory_fixed_digits" value="0" />
<!-- /HIDDEN FIELDS -->
<div class="update-alert">
<div class="container">
<input type="checkbox" class="sheet-showarrow sheet-ack-button" name="attr_announcements_show" value="1" title="Click to view announcements" />
<label class="show-content">Announcements <span name="attr_latest_changes"></span></label>
<div class="content">
<h4>GURPS Version <input type="text" name="attr_announcement_version" readonly="readonly" value="0" title="GURPS Sheet Version" /></h4>
<ul>
<li>Repeating skills/spells. Removed checkbox to show success/fail notes. Converted text boxes to multi-line text boxes.</li>
<li>
Repeating melee/ranged attacks. Ability to link weapon to skill or spell. The weapon will show the skill or spell level
and should update when the skill or spell level is updated.
</li>
<li>Reformat minimum damage notes and include page reference.</li>
<li>
Repeating Spells. Moved checkboxes for <b>ON</b> and <b>MT</b> to avoid collision with delete button. Resized some text
boxes to allow more space for delete button. Change Maintained Penalty titles to Concentration Penalty. Thanks to Valter.
</li>
</ul>
<label class="check"><input type="checkbox" name="attr_announcements_hide" value="1">&nbsp;<b><span>Hide until next update</span></b></label>
<button type="action" name="act_view_updates_tab" class="reset" />View All Updates</button>
</div>
</div>
</div>
<!-- ===== ===== ===== ===== TABS ===== ===== ===== ===== -->
<input type="radio" name="attr_tab" value="1" class="sheet-tab sheet-tab1" checked="checked" /><span>General</span>
<input type="radio" name="attr_tab" value="2" class="sheet-tab sheet-tab2" title="Languages, Advantages, Disadvantages, and Cultural Familiarities" /><span>Traits</span>
<input type="radio" name="attr_tab" value="1a" class="sheet-tab sheet-tab-misc" title="Miscellaneous box, Bio Notes, General Notes" /><span>Bio\Misc</span>
<input type="radio" name="attr_tab" value="3" class="sheet-tab sheet-tab3" title="Skills and Techniques" /><span>Skills</span>
<input type="radio" name="attr_tab" value="4" class="sheet-tab sheet-tab4" /><span>Combat</span>
<input type="radio" name="attr_tab" value="5" class="sheet-tab sheet-tab5" /><span>Inventory</span>
<input type="radio" name="attr_tab" value="6" class="sheet-tab sheet-tab6" /><span>Grimoire</span>
<input type="radio" name="attr_tab" value="7" class="sheet-tab sheet-tab7" /><span>Updates</span>
<input type="radio" name="attr_tab" value="0" class="sheet-tab sheet-tab0" /><span title="Sheet Options">y</span>
<div class="sheet-tab-br"></div>
<!-- ===== ===== ===== ===== GENERAL TAB ===== ===== ===== ===== -->
<div class="sheet-tab1">
<!-- _____ _____ ATTRIBUTE BOX _____ _____ -->
<div class="sheet-box sheet-attribute">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Attributes</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">Mod</div>
<span class="sheet-tooltip">
A modifier that will be applied to your
<br />
attribute. All derived attributes draw their<br />
base from your unmodified attributes.<br />
Therefore this MOD will generally only<br />
affect direct attribute rolls and skill rolls.
</span>
</div>
<div class="sheet-cell sheet-col2">Pts</div>
</div> <!-- .sheet-header -->
<div class="sheet-main-attribute">
<div class="sheet-row sheet-row-strength">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">ST</div>
<span class="sheet-tooltip">
Strength
<br />
10pts/level
<br />
Unmodified <span name="attr_strength_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_strength" value="10" readonly="readonly" title="Macro name: strength" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_strength_mod" value="0" step="1" title="Macro name: strength_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_strength_points" value="0" step="10" title="Macro name: strength_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Strength Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{strength} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsST" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-dexterity">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">DX</div>
<span class="sheet-tooltip">
Dexterity
<br />
20pts/level
<br />
Unmodified: <span name="attr_dexterity_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_dexterity" value="10" readonly="readonly" title="Macro name: dexterity" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_dexterity_mod" value="0" step="1" title="Macro name: dexterity_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_dexterity_points" value="0" step="20" title="Macro name: dexterity_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Dexterity Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{dexterity} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsDX" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-intelligence">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">IQ</div>
<span class="sheet-tooltip">
Intelligence
<br />
20pts/level
<br />
Unmodified: <span name="attr_intelligence_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_intelligence" value="10" readonly="readonly" title="Macro name: intelligence" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_intelligence_mod" value="0" step="1" title="Macro name: intelligence_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_intelligence_points" value="0" step="20" title="Macro name: intelligence_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Intelligence Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{intelligence} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsIQ" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-health">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">HT</div>
<span class="sheet-tooltip">
Health
<br />
10pts/level
<br />
Unmodified: <span name="attr_health_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_health" value="10" readonly="readonly" title="Macro name: health" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_health_mod" value="0" step="1" title="Macro name: health_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_health_points" value="0" step="10" title="Macro name: health_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Health Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{health} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsHT" />
</div>
</div> <!-- .sheet-row -->
</div>
<div class="sheet-row sheet-row-perception sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Per</div>
<span class="sheet-tooltip">
Perception
<br />
Based on Intelligence
<br />
5pts/level
<br />
Unmodified: <span name="attr_perception_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_perception" value="10" readonly="readonly" title="Macro name: perception" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_perception_mod" value="0" step="1" title="Macro name: perception_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_perception_points" value="0" step="5" title="Macro name: perception_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Perception Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{perception} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsPer" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-vision">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Vision</div>
<span class="sheet-tooltip">
Visual Perception
<br />
Based on Perception
<br />
2pts/level
<br />
Unmodified: <span name="attr_vision_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_vision" value="10" readonly="readonly" title="Macro name: vision" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_vision_mod" value="0" step="1" title="Macro name: vision_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_vision_points" value="0" step="2" title="Macro name: vision_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Vision Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{vision} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsVision" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-hearing">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Hearing</div>
<span class="sheet-tooltip">
Audio Perception
<br />
Based on Perception
<br />
2pts/level
<br />
Unmodified: <span name="attr_hearing_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_hearing" value="10" readonly="readonly" title="Macro name: hearing" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_hearing_mod" value="0" step="1" title="Macro name: hearing_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_hearing_points" value="0" step="2" title="Macro name: hearing_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Hearing Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{hearing} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsHearing" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-taste-smell">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Smell</div>
<span class="sheet-tooltip">
Taste & Smell Perception
<br />
Based on Perception
<br />
2pts/level
<br />
Unmodified: <span name="attr_taste_smell_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_taste_smell" value="10" readonly="readonly" title="Macro name: taste_smell" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_taste_smell_mod" value="0" step="1" title="Macro name: taste_smell_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_taste_smell_points" value="0" step="2" title="Macro name: taste_smell_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Taste/Smell Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{taste_smell} + @{modifier}]]}} {{useCriticalPlusTen=[[0]]}}" name="roll_vsTasteSmell" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row margin-bottom sheet-row-touch">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Touch</div>
<span class="sheet-tooltip">
Touch Perception
<br />
Based on Perception
<br />
2pts/level
<br />
Unmodified: <span name="attr_touch_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_touch" value="10" readonly="readonly" title="Macro name: touch" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_touch_mod" value="0" step="1" title="Macro name: touch_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_touch_points" value="0" step="2" title="Macro name: touch_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Touch Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{touch} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsTouch" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-willpower sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Will</div>
<span class="sheet-tooltip">
Willpower
<br />
Based on Intelligence
<br />
5pts/level
<br />
Unmodified: <span name="attr_willpower_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_willpower" value="10" readonly="readonly" title="Macro name: willpower" >
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_willpower_mod" value="0" step="1" title="Macro name: willpower_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_willpower_points" value="0" step="5" title="Macro name: willpower_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Will Roll}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{willpower} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsWill" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row margin-bottom sheet-row-fear">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Fright</div>
<span class="sheet-tooltip">
Fright Check Ref: B360
<br />
Based on Willpower
<br />
2pts/level
<br />
See extensive list of Modifiers B360
<br/>
Unmodified: <span name="attr_fear_check_base"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_fear_check" value="10" readonly="readonly" title="Macro name: willpower_fear_check" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_fear_check_mod" value="0" step="1" title="Macro name: willpower_fear_check_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_fear_check_points" value="0" step="2" title="Macro name: willpower_fear_points" />
</div>
<div class="sheet-cell sheet-col4">
<!-- For Fright Check, use "kl1" = Keep Lowest One. [[1d8 ( { 16 , 13 }kl1) ]] = 1d6 + 13 -->
<!-- see: https://wiki.roll20.net/Macros_-_Pathfinder_Examples : Calculated Dice Roll -->
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Attribute Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Fright Check}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[ ( {@{fear_check} + @{modifier}, @{fright_check_threshold}}kl1) ]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{useFrightLabel=[[1]]}} {{showNotes=[[1]]}} {{notes= **On a failure**, Roll 3d6, add your margin of failure on the Fright Check, compare result to the Fright Check Table B360.}}" name="roll_vsFearCheck" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row margin-bottom sheet-row-fear">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Thresh</div>
<span class="sheet-tooltip">
Fright Check Threshold
<br />
If final modified fright check exceeds threshold,
then reduce modified fright check to threshold level.
<br />
Can be modifed by Brave, Rule of 15, etc.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_fright_check_threshold" value="13" readonly="readonly" title="Macro name: fright_check_threshold" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_fright_check_threshold_mod" value="0" step="1" title="Macro name: fright_check_threshold_mod" />
</div>
<div class="sheet-cell sheet-col3-fright-label">
<i>Fright Check</i>
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Unstun</div>
<span class="sheet-tooltip">
Recover from physical stun, based on Health.<br />
Roll at the end of your turn after Do Nothing <br />
High Pain Threshold +3 to check<br />
Low Pain Threshold -3 to check<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_stun_check" value="10" readonly="readonly" title="Macro name: stun_check" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_stun_check_mod" value="0" step="1" title="Macro name: stun_check_mod" />
</div>
<div class="sheet-cell sheet-col3">
&nbsp;
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Condition Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Unstun Check (Recovering from Stun)}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{stun_check} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{showNotes=[[1]]}} {{notes= **On a failure**, you remain stunned; your next maneuver must also be Do Nothing, but you get another roll at the end of that turn . . . and so on, until you recover from stun. You are also -4 to defenses, no retreat.\n<br /> **On a success**, you recover from stun and can act normally on subsequent turns. B420}}" name="roll_vsUnstun" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-condition-knockdown">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">K Down</div>
<span class="sheet-tooltip">
Knockdown & Stunning Check, based on Health.<br />
Roll: <br />
Whenever you suffer a major wound. B420<br />
Whenever you are struck in the head (skull, face, or eye) or<br />
vitals for enough injury to cause a shock penalty,<br />
You must make an immediate HT roll to avoid knockdown and stunning. <br />
**Modifiers:** <br />
-5 for a major wound to the face or vitals (or to the groin, on a humanoid male).<br />
-10 for a major wound to the skull or eye. <br />
+3 High Pain Threshold<br />
-4 Low Pain Threshold<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_knockdown_check" value="10" readonly="readonly" title="Macro name: knockdown_check" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_knockdown_check_mod" value="0" step="1" title="Macro name: knockdown_check_mod" />
</div>
<div class="sheet-cell sheet-col3">
&nbsp;
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Condition Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Knockdown & Stunning Check}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{knockdown_check} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{showNotes=[[1]]}} {{notes= **On a failure**, you’re Physically stunned. You also fall prone (if you weren’t already), and if you were holding anything, you drop it. \n<br />**On a failure by 5 or more, or any critical failure**, you fall unconscious! B420}}" name="roll_vsKnockdown" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-unconscious">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Unc.</div>
<span class="sheet-tooltip">
Unconscious Check, based on Health<br />
If HP zero or less, roll per turn to take an Active Action.<br />
-1 per full multiple of HP below zero.<br />
Hard/Easy to Kill: Gives +/- per level to a Unc. Check<br />
Fit +1 to Unc. Check . Very Fit +2 to Unc. Check<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_unconscious_check" value="10" readonly="readonly" title="Macro name: unconscious_check" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_unconscious_check_mod" value="0" step="1" title="Macro name: unconscious_check_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_unconscious_check_points" value="0" step="2" title="Macro name: unconscious_check_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Condition Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Unconscious Check}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{unconscious_check} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{showNotes=[[1]]}} {{notes=** If you fail:** you fall unconscious. See 'Recovering from Unconsciuness' B423 . \n<br />**Success:** means you can act normally, but must roll again at the begining of every turn to continue functioning (If your HP is 0 or less). Exception: If you choose Do Nothing on your turn, then no roll needed. B419}}" name="roll_vsUnconsciousCheck" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row margin-bottom sheet-row-death">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Death</div>
<span class="sheet-tooltip">
Death Check, based on Health.<br />
On damage taken: Immediately Roll a Death Check if you are<br />
at-1xHP or more.<br />
Roll again each time you suffer injury equal to a further<br />
multiple of your HP. (-2xHP, -3xHP, -4xHP) <br />
Immediate Death at -5xHP<br />
Hard/Easy to Kill: Gives +/- per level to a Death Check<br />
Fit +1 to Death Check . Very Fit +2 to Death Check<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_death_check" value="10" readonly="readonly" title="Macro name: death_check" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_death_check_mod" value="0" step="1" title="Macro name: death_check_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_death_check_points" value="0" step="2" title="Macro name: death_check_points" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Condition Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Death Check}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{unconscious_check} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{showNotes=[[1]]}} {{notes= **On a failure of 1 or 2**, Your receive a Mortal Wound – See Mortal Wounds B423 \n<br /> **On a failure of 3+** ***YOU DIE*** – See Death B423.}}" name="roll_vsDeathCheck" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-speed sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Speed</div>
<span class="sheet-tooltip">
Basic Speed
<br />
Based on Health and Dexterity
<br />
5pts/0.25
<br />
Unmodified: <span name="attr_basic_speed_base" value="10"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_basic_speed" value="" step="0.25" readonly="readonly" title="Macro name: basic_speed" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_basic_speed_mod" value="0" step="0.25" title="Macro name: basic_speed_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_basic_speed_points" value="0" step="5" title="Macro name: basic_speed_points" />
</div>
<div class="sheet-cell sheet-col4">
<button class="sheet-roll-tracker" type="roll" value="@{speed_tracker} [[@{basic_speed} &{tracker}]] &{template:addToTracker} {{characterName=@{character_name}}} {{basicSpeed=@{basic_speed}}}" name="roll_init" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Move</div>
<span class="sheet-tooltip">
Basic Move
<br />
Based on Basic Speed
<br />
5pts/level
<br />
Unmodified: <span name="attr_basic_move_base" value="0"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_basic_move" value="" readonly="readonly" title="Macro name: basic_move" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_basic_move_mod" value="0" step="1" title="Macro name: basic_move_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_basic_move_points" value="0" step="5" title="Macro name: basic_move_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Enhncd</div>
<span class="sheet-tooltip">
Enhanced ground move.
<br />
10pts per half level. Can use up|down arrow keys
<br />
Level: <span name="attr_enhanced_ground_move_multiple" value="0"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_enhanced_ground_move" value="0" readonly="readonly" title="Macro name: enhanced_ground_move" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_enhanced_ground_move_mod" value="0" step=".5" class="editable" title="Macro name: enhanced_ground_move_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_enhanced_ground_move_points" value="0" step="10" class="editable" title="Macro name: enhanced_ground_move_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-dodge">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Dodge</div>
<span class="sheet-tooltip">
Dodge
<br />
Based on Basic Speed
<br />
Unmodified: <span name="attr_dodge_base" value="0"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_dodge" value="" readonly="readonly" title="Macro name: dodge" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_dodge_mod" value="0" step="1" title="Macro name: dodge_mod" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-lift-st sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Lift ST</div>
<span class="sheet-tooltip">
Lifting Strength
<br />
Based on Strength
<br />
3pts/level
<br />
Unmodified: <input class="sheet-inline" type="number" name="attr_lift_st_base" readonly="readonly" >
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_lift_st" value="0" readonly="readonly" title="Macro name: lift_st" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_lift_st_mod" value="0" step="1" title="Macro name: lift_st_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_lift_st_points" value="0" step="3" title="Macro name: lift_st_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-basic-lift">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Lift</div>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_basic_lift" value="0" readonly="readonly" title="Macro name: basic_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-strike-st sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Striking</div>
<span class="sheet-tooltip">
Striking Strength
<br />
Based on Strength
<br />
5pts/level
<br />
Unmodified: <input class="sheet-inline" type="number" name="attr_striking_st_base" readonly="readonly" />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_striking_st" value="0" readonly="readonly" title="Macro name: striking_st" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_striking_st_mod" value="0" step="1" title="Macro name: striking_st_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_striking_st_points" value="0" step="5" title="Macro name: striking_st_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-thrust-damage">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Thrust</div>
<span class="sheet-tooltip">
Thrust Damage
<br />
<div>See page 16 for the complete table.</div>
<table>
<thead><tr><th>Strength</th><th>Thrust</th></tr></thead>
<tbody>
<tr><td>1</td><td>1d6-6</td></tr>
<tr><td>2</td><td>1d6-6</td></tr>
<tr><td>3</td><td>1d6-5</td></tr>
<tr><td>4</td><td>1d6-5</td></tr>
<tr><td>5</td><td>1d6-4</td></tr>
<tr><td>6</td><td>1d6-4</td></tr>
<tr><td>7</td><td>1d6-3</td></tr>
<tr><td>8</td><td>1d6-3</td></tr>
<tr><td>9</td><td>1d6-2</td></tr>
<tr><td>10</td><td>1d6-2</td></tr>
<tr><td>11</td><td>1d6-1</td></tr>
<tr><td>12</td><td>1d6-1</td></tr>
<tr><td>13</td><td>1d6</td></tr>
</tbody>
</table>
<table>
<thead><tr><th>Strength</th><th>Thrust</th></tr></thead>
<tbody>
<tr><td>14</td><td>1d6</td></tr>
<tr><td>15</td><td>1d6+1</td></tr>
<tr><td>16</td><td>1d6+1</td></tr>
<tr><td>17</td><td>1d6+2</td></tr>
<tr><td>18</td><td>1d6+2</td></tr>
<tr><td>19</td><td>2d6-1</td></tr>
<tr><td>20</td><td>2d6-1</td></tr>
<tr><td>21</td><td>2d6</td></tr>
<tr><td>22</td><td>2d6</td></tr>
<tr><td>23</td><td>2d6+1</td></tr>
<tr><td>24</td><td>2d6+1</td></tr>
<tr><td>25</td><td>2d6+2</td></tr>
<tr><td>26</td><td>2d6+2</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_thrust" value="1d6-2" />
</div>
<div class="sheet-cell sheet-col4">
<input type="hidden" name="attr_thrust_damage_dice_icon" class="thrust-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Damage Roll}} {{characterName=@{character_name}}} {{skillName=Thrust Damage}} {{damageRoll=[[@{thrust}]]}} {{minDamageNote=Crush min 0, else min 1}}" name="roll_dmgThrust" class="roll_damage" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-swing-damage">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Swing</div>
<span class="sheet-tooltip">
Swing Damage
<br />
<div>See page 16 for the complete table.</div>
<table>
<thead><tr><th>Strength</th><th>Swing</th></tr></thead>
<tbody>
<tr><td>1</td><td>1d6-5</td></tr>
<tr><td>2</td><td>1d6-5</td></tr>
<tr><td>3</td><td>1d6-4</td></tr>
<tr><td>4</td><td>1d6-4</td></tr>
<tr><td>5</td><td>1d6-3</td></tr>
<tr><td>6</td><td>1d6-3</td></tr>
<tr><td>7</td><td>1d6-2</td></tr>
<tr><td>8</td><td>1d6-2</td></tr>
<tr><td>9</td><td>1d6-1</td></tr>
<tr><td>10</td><td>1d6</td></tr>
<tr><td>11</td><td>1d6+1</td></tr>
<tr><td>12</td><td>1d6+2</td></tr>
<tr><td>13</td><td>2d6-1</td></tr>
</tbody>
</table>
<table>
<thead><tr><th>Strength</th><th>Swing</th></tr></thead>
<tbody>
<tr><td>14</td><td>2d6</td></tr>
<tr><td>15</td><td>2d6+1</td></tr>
<tr><td>16</td><td>2d6+2</td></tr>
<tr><td>17</td><td>3d6-1</td></tr>
<tr><td>18</td><td>3d6</td></tr>
<tr><td>19</td><td>3d6+1</td></tr>
<tr><td>20</td><td>3d6+2</td></tr>
<tr><td>21</td><td>4d6-1</td></tr>
<tr><td>22</td><td>4d6</td></tr>
<tr><td>23</td><td>4d6+1</td></tr>
<tr><td>24</td><td>4d6+2</td></tr>
<tr><td>25</td><td>5d6-1</td></tr>
<tr><td>26</td><td>5d6</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_swing" value="1d6" />
</div>
<div class="sheet-cell sheet-col4">
<input type="hidden" name="attr_swing_damage_dice_icon" class="swing-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Damage Roll}} {{characterName=@{character_name}}} {{skillName=Swing Damage}} {{damageRoll=[[@{swing}]]}} {{minDamageNote=Crush min 0, else min 1}}" name="roll_dmgSwing" class="roll_damage" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-attributes -->
<div class="sheet-box sheet-stats">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Stats</div>
<div class="sheet-cell sheet-col1">Value</div>
<div class="sheet-cell sheet-col2">Mod</div>
<div class="sheet-cell sheet-col3">Pts</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-hit-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Max HP</div>
<span class="sheet-tooltip">
Hit Points
<br />
Based on Strength
<br />
2pts/level
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_hit_points_max" value="10" readonly="readonly" title="Macro name: hit_points_max" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_hit_points_mod" value="0" step="1" title="Macro name: hit_points_max_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_hit_points_points" value="0" step="2" title="Macro name: hit_points_max_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-current-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Current HP</div>
<span class="sheet-tooltip">
Current Hit Points
<br />
When you're hit points are low, you take penalties.
<br />
See Page 419.
<table>
<tbody>
<tr>
<td class="sheet-label">Reeling</td>
<td><input type="text" name="attr_hp_reeling" value="[[floor((@{hit_points|max}) / 3)]]" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- Halve Move, Speed, and Dodge
</td>
</tr>
<tr>
<td class="sheet-label">Verge of Collapse</td>
<td><input type="text" value="Less than 0" readonly="readonly" ></td>
</tr>
<tr>
<td colspan="2">
- Roll every turn @{VS} HT or fall unconscious.
<br />
- Your HT roll is at -1 for every 1xHP you are below 0.
<br />
- If you do nothing, and don't defend, you don't have to roll.
</td>
</tr>
<tr>
<td class="sheet-label">Verge of Death</td>
<td><input type="text" name="attr_hp_verge" value="[[(@{hit_points|max}) * -1]]" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- Roll once @{VS} HT to stay alive.
<br />
- If you fail by 1 or 2 you are mortally wounded, but not dead.
<br />
- Roll again every time you take injury that puts you below<br />
another multiple of your max HP.
</td>
</tr>
<tr>
<td class="sheet-label">Death</td>
<td><input type="text" name="attr_hp_death" value="[[(@{hit_points|max}) * -5]]" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- You are dead.
</td>
</tr>
<tr>
<td class="sheet-label">Total Destruction</td>
<td><input type="text" name="attr_hp_destruction" value="[[(@{hit_points|max}) * -10]]" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- Your body has been destroyed beyond recognition or ressurection.
</td>
</tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_hit_points" value="10" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-fatigue-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Max FP</div>
<span class="sheet-tooltip">
Fatigue Points
<br />
Based on Health
<br />
3pts/level
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_fatigue_points_max" value="10" readonly="readonly" title="Macro name: fatigue_points_max" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_fatigue_points_mod" value="0" step="1" title="Macro name: fatigue_points_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_fatigue_points_points" value="0" step="3" title="Macro name: fatigue_points_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-current-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Current FP</div>
<span class="sheet-tooltip">
Current Fatigue Points
<br />
When you're fatigue points are low you take penalties.
<br />
See Page 426.
<table>
<tbody>
<tr>
<td class="sheet-label">Tired</td>
<td><input type="text" name="attr_fp_tired" value="[[floor((@{fatigue_points|max}) / 3)]]" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- Halve Move, ST, and Dodge
</td>
</tr>
<tr>
<td class="sheet-label">Verge of Collapse</td>
<td><input type="text" value="Less than 0" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- Further FP loss also comes off your HP.
<br />
- Roll against Will to do anything besides rest or talk.
<br />
- If you fail your Will roll, you fall unconscious.
<br />
- On a critical failure, roll @{VS} HT or suffer a heart attack.
</td>
</tr>
<tr>
<td class="sheet-label">Unconscious</td>
<td><input type="text" name="attr_fp_unconscious" value="[[-(@{fatigue_points|max})]]" disabled="disabled"></td>
</tr>
<tr>
<td colspan="2">
- Immediately fall unconscious
<br />
- FP can't drop any lower, but you still lose HP.
<br />
- You regain consciousness at 0 FP
</td>
</tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_fatigue_points" value="10" title="Macro name: fatigue_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-energy-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Max ER</div>
<span class="sheet-tooltip">
Energy Reserve
<br />
See Dungeon Fantasy 3, pg39 - Introduced<br />
See Powers, pg119 – More detailed<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_energy_points_max" title="Macro name: energy_points_max" />
</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_energy_points_points" value="0" step="3" title="Macro name: energy_points_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-current-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Current ER</div>
<span class="sheet-tooltip">
Current Energy Reserve
<br />
See Dungeon Fantasy 3, pg39 - Introduced<br />
See Powers, pg119 – More detailed<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_energy_points" value="0" title="Macro name: energy_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-hr">
<div class="title custom-pools">
<div class="popup">
Custom Pools
</div>
<span class="tooltip">Add additional energy pools. Enter a name of the pool,
max number points, cost in character points, and the current points of pool.</span>
</div>
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_user_pool1_name" title="Macro name: user_pool1_name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_user_pool1_max" title="Macro name: user_pool1_max" />
</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_user_pool1_points" value=0 title="Macro name: user_pool1_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-current-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Current</div>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_user_pool1" value="0" title="Macro name: user_pool1" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_user_pool2_name" title="Macro name: user_pool2_name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_user_pool2_max" title="Macro name: user_pool2_max" />
</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_user_pool2_points" value=0 title="Macro name: user_pool2_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-sub-row sheet-row-current-points">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Current</div>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_user_pool2" value="0" title="Macro name: user_pool2" />
</div>
</div> <!-- .sheet-row -->
</div>
</div>
<!-- _____ _____ MISCELLANEOUS BOX _____ _____ -->
<div class="sheet-box sheet-general-notes-box">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell">Notes</div>
</div>
<div class="sheet-notes">
<div class="sheet-cell-col-100">
<textarea name="attr_general_tab_notes"></textarea>
</div>
</div>
</div>
</div>
<!-- _____ _____ POINT SUMMARY BOX _____ _____ -->
<div class="sheet-box sheet-points">
<div class="sheet-table">
<input type="hidden" name="attr_toggle_unspent_points" class="sheet-toggle-unspoint-points" value="0" />
<div class="sheet-header">
<div class="sheet-popup">Point Sum</div>
<span class="sheet-tooltip">
<strong>Total</strong>: Manual input: Represents total value of the<br />
PC in Character Points (spent & unspent combined).
<br />
<strong>Spent</strong>: Automatic total of Spent points: <br />
Attributes + Traits + Skills + Other.
<br/>
<strong>Unspent</strong>: Has the option of being Manual or<br/>
Automatic, depending on an option selected on the
<br/>
Settings page entitled ‘Enter Unspent Points’.
<br/>
Manual Mode (Blue color): You manually enter your
<br/>
Unspent points.
<br/>
Automatic mode (Black color): It calculates the
<br/>
point total difference between Total and Spent.
</span>
</div> <!-- .sheet-header -->
<div class="sheet-row margin-bottom sheet-row-other">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Total</div>
<span class="sheet-tooltip">
<strong>Total</strong>: Manual input: Represents total value of the<br/>
PC in Character Points (spent and unspent combined).
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_total_points" value="150" title="Macro name: total_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-attributes sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Attributes</div>
<span class="sheet-tooltip">
Point Summary for: <br />
ST, DX, IQ, HT,<br />
HP, FP, Energery Reserve One, Two, and Three,<br />
Per, Vision, Hearing, Smell, Touch,<br />
Will, Fright, Hard to Subdue, Hard to Kill,<br />
Speed, Move, Enhanced Move, Enhanced Dodge,<br />
Lift ST, Striking ST,<br />
Flying, Air Move, Enhanced Air Move, Super Jump
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_att_points" value="@{strength_points} +
@{dexterity_points} +
@{intelligence_points} +
@{health_points} +
@{perception_points} +
@{vision_points} +
@{hearing_points} +
@{taste_smell_points} +
@{touch_points} +
@{willpower_points} +
@{fear_check_points} +
@{hit_points_points} +
@{fatigue_points_points} +
@{energy_points_points} +
@{user_pool1_points} +
@{user_pool2_points} +
@{basic_speed_points} +
@{basic_move_points} +
@{striking_st_points} +
@{lift_st_points} +
@{enhanced_ground_move_points} +
@{flight_points} +
@{basic_air_move_points} +
@{enhanced_air_move_points} +
@{amphibious_points} +
@{basic_water_move_points} +
@{enhanced_water_move_points} +
@{super_jump_points} +
@{unconscious_check_points} +
@{death_check_points}"
disabled="disabled"
title="Macro name: att_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-traits">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Adv.</div>
<span class="sheet-tooltip">
Point Summary for: <br />
Languages, Tech Level, Appearance, Cultural Familiarities,<br />
Advantages & Perks
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_trait_advantages_points" disabled="disabled" value="@{languages_points} +
@{tl_pts} +
@{appearance_pts} +
@{cf_points} +
@{advantages_points}"
title="Macro name: trait_advantages_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-traits">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Disadv.</div>
<span class="sheet-tooltip">
Point Summary for: <br />
Disadvantages & Quirks
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_trait_disadvantages_points" disabled="disabled" value="@{disadvantages_points}" title="Macro name: trait_disadvantages_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-traits">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Racial</div>
<span class="sheet-tooltip">
Point Summary for Racial Traits
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_trait_racial_points" disabled="disabled" value="@{racial_points}" title="Macro name: trait_racial_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-traits" style="display: none;">
<div class="sheet-cell sheet-col0 sheet-label">
Traits
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_trait_points" readonly="readonly" value="0" title="Macro name: trait_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-skills">
<div class="sheet-cell sheet-col0 sheet-label">
Skills
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_skill_points" disabled="disabled" value="@{skills_points}" title="Macro name: skill_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-skills">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Tech.</div>
<span class="sheet-tooltip">
Techniques
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_techniques_total_points" disabled="disabled" value="@{techniques_points}" title="Macro name: techniques_total_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-skills">
<div class="sheet-cell sheet-col0 sheet-label">
Spells
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_spells_total_points" disabled="disabled" value="@{spells_points}" title="Macro name: spell_total_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-other">
<div class="sheet-cell sheet-col0 sheet-label">
Other
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_misc_points" value="0" title="Macro name: misc_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-spent">
<div class="sheet-cell sheet-col0 sheet-label">
Spent
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_point_summary" disabled="disabled" value="@{att_points} + @{trait_points} + @{skill_points} + @{techniques_points} + @{spells_points} + @{misc_points}" title="Macro name: point_summary" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-total sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label">
Unspent
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_point_diff" value="@{total_points} - (@{att_points} + @{trait_points} + @{skill_points} + @{techniques_points} + @{spells_points} + @{misc_points})" disabled="disabled" title="Macro name: point_diff" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-unspent sheet-hr">
<div class="sheet-cell sheet-col0 sheet-label sheet-unspent-points-label">
Unspent
</div>
<div class="sheet-cell sheet-col1 sheet-unspent-points">
<input type="text" name="attr_unspent_points" value="0" title="Macro name: unspent_points" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-points -->
<!-- _____ _____ LIFTING BOX _____ _____ -->
<div class="sheet-box sheet-lift">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Lifting and Moving</div>
<div class="sheet-cell sheet-col1">Weight</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-simple-lift">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Simple Lift</div>
<span class="sheet-tooltip">
The weight the character can lift overhead<br />with one hand in one second.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_simple_lift" value="round(@{basic_lift})" disabled="disabled" title="Macro name: simple_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-one-handed-lift">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">One-Handed Lift</div>
<span class="sheet-tooltip">
The weight the character can lift overhead<br />with one hand in two seconds.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_one_hand_lift" value="round(2 * @{basic_lift})" disabled="disabled" title="Macro name: one_hand_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-two-handed-lift">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Two-Handed Lift</div>
<span class="sheet-tooltip">
The weight the character can lift overhead<br />with both hands in four seconds.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_two_hand_lift" value="round(8 * @{basic_lift})" disabled="disabled" title="Macro name: two_hand_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-shove-knock-over">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Shove &amp; Knock Over</div>
<span class="sheet-tooltip">
The weight of an object the character can<br />shove and knock over.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_shove_lift" value="round(12 * @{basic_lift})" disabled="disabled" title="Macro name: shove_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-running-shove-knock-over">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Running Shove &amp; Knock Over</div>
<span class="sheet-tooltip">
The weight of an object the character can<br />shove and knock over with a running start.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_run_shove_lift" value="round(24 * @{basic_lift})" disabled="disabled" title="Macro name: run_shove_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-carry-on-back">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Carry On Back</div>
<span class="sheet-tooltip">
The weight the character can carry slung<br />over his/her back.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_carry_back_lift" value="round(15 * @{basic_lift})" disabled="disabled" title="Macro name: carry_back_lift" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-shift-slightly">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Shift Slightly</div>
<span class="sheet-tooltip">
The weight of an object that the character<br />can shift slightly on a floor.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_shift_lift" value="round(50 * @{basic_lift})" disabled="disabled" title="Macro name: shift_lift" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-lift -->
<!-- _____ _____ ENCUMBERANCE BOX - Original author(s) misspelled this througout the file_____ _____ -->
<!-- Note: Many of the Move and Dodge calculations were complicated, this was to allow for a Minimum Move of 1 and a Minimum Dodge of 1 -->
<div class="sheet-box sheet-encumberance">
<div class="sheet-table">
<input type="checkbox" name="attr_toggle_encumbrance" class="toggle toggle-encumbrance" />
<div class="sheet-header">
<div class="sheet-cell sheet-col0">
<div class="colToggle">
<input type="checkbox" name="attr_toggle_encumbrance" class="toggle toggle-encumbrance" title="View encumbrance table." />
<span class="checkbox checkbox-encumbrance"></span>
</div>
Encumbrance
</div>
<div class="sheet-cell sheet-colAll">Load</div>
<div class="sheet-cell sheet-colAll">Move</div>
<div class="sheet-cell sheet-colAll">ENH MOVE</div>
<div class="sheet-cell sheet-colAll">Air</div>
<div class="sheet-cell sheet-colAll">Water</div>
<div class="sheet-cell sheet-colAll">Dodge</div>
</div>
<div class="encumbrance-table-body">
<div class="sheet-row sheet-row-encumberance-0">
<div class="sheet-cell sheet-col0 sheet-label">
None (0)
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_lift_0" value="@{basic_lift}" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_move_0" value="@{basic_move}" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_0" value="" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_air_0" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_water_0" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_dodge_0" value="@{dodge}" disabled="disabled" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-encumberance-1">
<div class="sheet-cell sheet-col0 sheet-label">
Light (1)
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_lift_1" value="2 * @{basic_lift}" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_move_1" value="[[((1 + floor((@{basic_move} * 0.8))) + abs(1 - floor((@{basic_move} * 0.8)))) / 2]]" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_1" value="" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_air_1" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_water_1" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_dodge_1" value="[[((1 + (@{dodge} - 1)) + abs(1 - (@{dodge} - 1))) / 2]]" disabled="disabled" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-encumberance-2">
<div class="sheet-cell sheet-col0 sheet-label">
Medium (2)
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_lift_2" value="floor(3 * @{basic_lift}*100)/100" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_move_2" value="[[((1 + floor((@{basic_move} * 0.6))) + abs(1 - floor((@{basic_move} * 0.6)))) / 2]]" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_2" value="" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_air_2" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_water_2" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_dodge_2" value="[[((1 + (@{dodge} - 2)) + abs(1 - (@{dodge} -2))) / 2]]" disabled="disabled" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-encumberance-3">
<div class="sheet-cell sheet-col0 sheet-label">
Heavy (3)
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_lift_3" value="floor(6 * @{basic_lift}*100)/100" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_move_3" value="[[((1 + floor((@{basic_move} * 0.4))) + abs(1 - floor((@{basic_move} * 0.4)))) / 2]]" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_3" value="" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_air_3" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_water_3" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_dodge_3" value="[[((1 + (@{dodge} - 3)) + abs(1 - (@{dodge} -3))) / 2]]" disabled="disabled" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-encumberance-4">
<div class="sheet-cell sheet-col0 sheet-label">
X-Heavy (4)
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_lift_4" value="10 * @{basic_lift}" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_move_4" value="[[((1 + floor((@{basic_move} * 0.2))) + abs(1 - floor((@{basic_move} * 0.2)))) / 2]]" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_4" value="" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_air_4" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_water_4" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_dodge_4" value="[[((1 + (@{dodge} -4)) + abs(1 - (@{dodge} - 4))) / 2]]" disabled="disabled" />
</div>
</div> <!-- .sheet-row -->
<!-- Yes I realize encumbrance is spelled wrong here but the original authors misspelled it throughout the file so I did the same to stay backwards compatible. -->
<div class="sheet-row margin-bottom sheet-row-encumberance-MAX">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">MAX Load*</div>
<span class="sheet-tooltip">
Carry on Back (B353) 15xBL. Thus, you can carry
<br />
more than you can lift by yourself . . . but
<br />
every second that your encumbrance is over 10xBL
<br />
(that is Extra-Heavy encumbrance), you lose 1 FP.
<br />
</span>
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_lift_5" value="15 * @{basic_lift}" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_move_5" value="[[((1 + floor((@{basic_move} * 0.2))) + abs(1 - floor((@{basic_move} * 0.2)))) / 2]]" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_5" value="" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_air_5" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_water_5" value="0" readonly="readonly" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_dodge_5" value="[[((1 + (@{dodge} -4)) + abs(1 - (@{dodge} - 4))) / 2]]"disabled="disabled" />
</div>
</div> <!-- .sheet-row -->
</div>
<input type="checkbox" name="attr_toggle_turn_deceleration" class="toggle toggle-encumbrance" />
<div class="sheet-row sheet-row-load sheet-hr">
<div class="sheet-cell sheet-col0 current-label">
<div class="colToggle">
<input type="checkbox" name="attr_toggle_turn_deceleration" class="toggle toggle-encumbrance" title="View turning and deceleration." />
<span class="checkbox checkbox-encumbrance"></span>
</div>
Current (<span name="attr_encumbrance_level" value=""></span>)
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" step=".001" name="attr_total_weight" value="" readonly="readonly" title="Macro name: total_weight" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_move" value="" readonly="readonly" title="Macro name: current_move" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_current" value="0" readonly="readonly" title="Macro name: enhanced_move_current" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_air" value="0" readonly="readonly" title="Macro name: current_air" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_water" value="0" readonly="readonly" title="Macro name: current_water" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_dodge" value="" readonly="readonly" title="Macro name: current_dodge" />
</div>
</div> <!-- .sheet-row -->
<div class="turn-decelerate-container">
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup" style="text-align:center;">Current Velocity</div>
<span class="sheet-tooltip">
Enter velocity (yards/second) for current turn.
</span>
</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
<div class="sheet-cell sheet-col0">
<div class="sheet-popup">Turn Radius</div>
<span class="sheet-tooltip">
Turn Radius. Minimum number of hexes to move<br />
before making a 60° facing change.<br />
Turn Radius = (Max. Allowed Velocity / Move Score) rounded down.<br />
See B394.<br />
<span style="color:red;font-weight:bold;">NOTE:</span> Turn radius for a move type is limited by maximum velocity.<br />
If Air has 8/16, the maximum velocity is 16.
</span>
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="number" step="1" name="attr_entered_move" value="0" title="Macro name: entered_move" />
</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_move_turn_radius" value="0" readonly="readonly" title="Macro name: current_move_turn_radius" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_current_turn_radius" value="0" readonly="readonly" title="Macro name: enhanced_move_current_turn_radius" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_air_turn_radius" value="0" readonly="readonly" title="Macro name: current_air_turn_radius" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_water_turn_radius" value="0" readonly="readonly" title="Macro name: current_water_turn_radius" />
</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">&nbsp;</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
<div class="sheet-cell sheet-col0">
<div class="sheet-popup">Tight Turn Penalty</div>
<span class="sheet-tooltip">
Skill penalty for a tight turn. Allows you to make an additional facing change.<br />
120° facing change instead of 60°.<br />
Penalty = -1 per full increment of base move which your velocity exceeds your Basic Move.<br />
See B395.<br />
</span>
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">&nbsp;</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_move_turn_radius_penalty" value="0" readonly="readonly" title="Macro name: current_move_turn_radius_penalty" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_current_turn_radius_penalty" value="0" readonly="readonly" title="Macro name: enhanced_move_current_turn_radius_penalty" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_air_turn_radius_penalty" value="0" readonly="readonly" title="Macro name: current_air_turn_radius_penalty" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_water_turn_radius_penalty" value="0" readonly="readonly" title="Macro name: current_water_turn_radius_penalty" />
</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup" style="text-align:center;">Deceleration</div>
<span class="sheet-tooltip">
Difference between start move and final move.<br />
<i>Example:</i> Moving 12/second, need to slow to 5/second, deceleration = 12 - 5 = 7.<br />
Can safely decelerate up to base move, no roll needed.<br />
If over safe deceleration, then make DX+3. If in vehicle, use operation skill + handling statistic.<br />
Apply the appropriate skill penalty from the input forms to the right.<br />
<b>How it works:</b> -1 per two full yards/second beyond Basic Move by which you cut your speed.<br />
<b>NOTE:</b> make an additional roll if you're also turning.<br />
<b>Example:</b> Car with move 3/57 traveling at 16 yards/second, needs to decelerate to 6 yards/second.<br />
Driving Skill: 12, Handling: 0.<br />
Total Deceleration = 16 - 6 = 10.<br />
Can safely decelerate to 16 - 3 (base move) = 13.<br />
Penalty = 13 - 6 (goal speed) / 2 = -3.<br />
Making Driving Skill 12 - 3 to succeed.<br />
see B395.
</span>
</div>
<div class="sheet-cell sheet-colAll">
<div class="sheet-popup" style="text-align:center;">Final</div>
<span class="sheet-tooltip">
Final velocity. Current Velocity - Deceleration.<br />
</span>
</div>
<div class="sheet-cell sheet-col0">
<div class="sheet-popup">Skill Penalty</div>
<span class="sheet-tooltip">
Skill penalty to DX roll or operation skill.<br />
Penalty is limited by max movement rate for the <br />
movement type.
</span>
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="number" step="1" name="attr_deceleration" value="0" title="Macro name: deceleration" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_final_velocity" value="@{entered_move} - @{deceleration}" title="Macro name: final_velocity" disabled="disabled" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_move_deceleration" value="0" readonly="readonly" title="Macro name: current_move_deceleration" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_enhanced_move_current_deceleration" value="0" readonly="readonly" title="Macro name: enhanced_move_current_deceleration" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_air_deceleration" value="0" readonly="readonly" title="Macro name: current_air_deceleration" />
</div>
<div class="sheet-cell sheet-colAll">
<input type="text" name="attr_current_water_deceleration" value="0" readonly="readonly" title="Macro name: current_water_deceleration" />
</div>
<div class="sheet-cell sheet-colAll">&nbsp;</div>
</div> <!-- .sheet-row -->
</div><!-- .sheet-turn-decelerate-container -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-encumberance -->
<!-- _____ _____ MOVEMENT FEATS _____ _____ -->
<div class="box movement-feats">
<div class="table">
<div class="header">
<div class="title">Movement Feats</div>
</div>
</div>
<div class="container-feats">
<!-- Flying Feat -->
<div class="container-flying feats-child">
<div class="sheet-row sheet-row-flight-advantage">
<div class="column-header">Flying</div>
<div class="sheet-cell sheet-col0 sheet-label">
<div class="popup">Flight</div>
<div class="tooltip">
Check the box to add Flight(Ref: B56) to the character. <br />
This will update the Air movement column for the encumbrance table.<br />
Use the text box to enter the numbrer of character points used for Flight<br />
</div>
</div>
<div class="sheet-cell sheet-col1">
<input type="checkbox" name="attr_flight_checked" value="1" class="sheet-boolean" title="Macro name: flight_checked" />
</div>
<div class="sheet-cell sheet-col2">
&nbsp;
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_flight_points" value="0" class="editable" title="Macro name: flight_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Air Mv</div>
<span class="sheet-tooltip">
Base Air Move = Basic Speed * 2 = <input class="sheet-inline" type="number" name="attr_basic_air_move_unmodified" readonly="readonly">
<br />
2pts/level, you can use up and down arrows
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_basic_air_move" value="0" readonly="readonly" title="Macro name: basic_air_move" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_basic_air_move_mod" value="0" step="1" class="editable" title="Macro name: basic_air_move_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_basic_air_move_points" value="0" step="2" class="editable" title="Macro name: basic_air_move_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-enhanced-air">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Enhncd</div>
<span class="sheet-tooltip">
Enhanced Air Move<br />
Modifier box: steps of .5, you can use up and down arrows.<br />
Points box: 10 points per half-level, you can use up and down arrows.<br />
Each level doubles top air move. Half-level is a multiple of 1.5.<br />
Level: <span name="attr_enhanced_air_move_level" value="0"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_enhanced_air_move" value="0" readonly="readonly" title="Macro name: enhanced_air_move" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_enhanced_air_level" value="0" step=".5" class="editable" title="Macro name: enhanced_air_level" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_enhanced_air_move_points" value="0" step="10" class="editable" title="Macro name: enhanced_air_move_points" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .container-swimming -->
<!-- Swimming Feat -->
<div class="container-swimming feats-child">
<div class="sheet-row sheet-row-flight-advantage">
<div class="column-header">Swimming</div>
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Amphib</div>
<div class="tooltip">
Amphibious: Check the box to apply Amphibious (B40) to character<br />
This will update the swimming movement on the encumbrance table.<br />
</div>
</div>
<div class="sheet-cell sheet-col1">
<input type="checkbox" name="attr_amphibious_checked" value="1" class="sheet-boolean" title="Macro name: amphibious_checked" />
</div>
<div class="sheet-cell sheet-col2">
&nbsp;
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_amphibious_points" value="0" class="editable" title="Macro name: amphibious_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Wtr Mv</div>
<span class="sheet-tooltip">
Basic Move = <input class="sheet-inline" type="number" name="attr_basic_water_move_unmodified" readonly="readonly" /><br />
Formula = Basic Move / 5 or Basic Move if amphibious.<br />
5pts/level, you can use up and down arrows.<br />
NOTE: Max +2 water move if you have swimming skill.<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_basic_water_move" value="0" readonly="readonly" title="Macro name: basic_water_move" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_basic_water_move_mod" value="0" step="1" class="editable" title="Macro name: basic_water_move_mod" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_basic_water_move_points" value="0" step="5" class="editable" title="Macro name: basic_water_move_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-enhanced-water">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Enhncd</div>
<span class="sheet-tooltip">
Enhanced Water Move<br />
Modifier box: steps of .5, you can use up and down arrows.<br />
Points box: 10 points per half-level, you can use up and down arrows.<br />
Each level doubles top water move. Half-level is a multiple of 1.5.<br />
Level: <span name="attr_enhanced_water_move_level" value="0"></span>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_enhanced_water_move" value="0" readonly="readonly" title="Macro name: enhanced_water_move" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_enhanced_water_level" value="0" step=".5" class="editable" title="Macro name: enhanced_water_level" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_enhanced_water_move_points" value="0" step="10" class="editable" title="Macro name: enhanced_water_move_points" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .container-swimming -->
<!-- Jumping Feat -->
<div class="container-jumping feats-child">
<div class="sheet-row sheet-row-flight-advantage">
<div class="column-header">Jumping</div>
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Skill</div>
<span class="sheet-tooltip">
Jump Skill. If entered, use Jump skill/2 instead of Basic Move.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_jump_skill" value="" class="editable" title="Macro name: jump_skill" />
</div>
<div class="sheet-cell sheet-col2">
&nbsp;
</div>
<div class="sheet-cell sheet-col3">
&nbsp;
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Use ST</div>
<span class="sheet-tooltip">
If Basic Lift (<input type="text" name="attr_display_jump_basic_lift" value="@{simple_lift}" disabled="disabled" class="textInline" />) > body weight, use ST/4 instead of Move or Jump skill.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="checkbox" name="attr_use_st_for_jump" value="1" class="sheet-boolean" title="Macro name: use_st_for_jump" />
</div>
<div class="sheet-cell sheet-col2">
&nbsp;
</div>
<div class="sheet-cell sheet-col3">
&nbsp;
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-enhanced-air">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Super</div>
<span class="sheet-tooltip">
Super Jump<br />
Modifier box: steps of 1, you can use up and down arrows.<br />
Points box: 10 points per level, you can use up and down arrows.<br />
Each level doubles jump.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_super_jump_level" value="0" readonly="readonly" title="Macro name: super_jump_level" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_super_jump_entered_level" value="0" step="1" class="editable" title="Macro name: super_jump_entered_level" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_super_jump_points" value="0" step="10" class="editable" title="Macro name: super_jump_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Enc</div>
<span class="sheet-tooltip">
Apply encumbrance penalty. See B352<br />
1 for None, 0.8 for Light, 0.6 for Medium, 0.4 for Heavy, and 0.2 for Extra-Heavy.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="checkbox" name="attr_jump_encumbrance" value="1" class="sheet-boolean" />
</div>
<div class="sheet-cell sheet-col2 title">&nbsp;</div>
<div class="sheet-cell sheet-col3 title">&nbsp;</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Prep</div>
<span class="sheet-tooltip">
Concentrate for 2 seconds for full jump distances.<br />
If no concentration, jump distances are halved.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="checkbox" name="attr_jump_concentration" value="1" class="sheet-boolean" title="Macro name: jump_concentration" />
</div>
<div class="sheet-cell sheet-col2 title">
feet
</div>
<div class="sheet-cell sheet-col3 title">
yards
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Broad</div>
<span class="sheet-tooltip">
Standing Broad Jump Distance.<br />
First column is base move stat.<br />
Formula = (2 x Stat To use) - 3 feet<br />
Stat to use: <input type="text" name="attr_standing_broad_jump_stat_to_use" value="" readonly="readonly" class="textInline width-wide" /><br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_broad_jump_base" value="0" readonly="readonly" title="Macro name: broad_jump_base" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_broad_jump_distance_feet" value="0" readonly="readonly" title="Macro name: broad_jump_distance_feet" />
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_broad_jump_distance_yards" value="0" readonly="readonly" title="Macro name: broad_jump_distance_yards" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Run</div>
<span class="sheet-tooltip">
Running Broad Jump.<br />
Formula = (2 x Stat To use) - 3 feet<br />
Stat to use: <input type="text" name="attr_running_broad_jump_stat_to_use" value="" readonly="readonly" class="textInline width-wide" /><br />
Max running broad jump distance is twice standing broad jump distance.<br />
Basic Set Campaigns Page 352.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" step="1" name="attr_running_jump_yards_moved" value="0" class="editable" title="Macro name: running_jump_yards_moved" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_running_jump_distance_feet" value="0" readonly="readonly" title="Macro name: running_jump_distance_feet" />
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_running_jump_distance_yards" value="0" readonly="readonly" title="Macro name: running_jump_distance_yards" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">High</div>
<span class="sheet-tooltip">
High Jump Distance.<br />
First column is base move stat.<br />
Formula = (6 x Stat To use) - 10 inches<br />
Stat to use: <input type="text" name="attr_standing_high_jump_stat_to_use" value="" readonly="readonly" class="textInline width-wide" />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_high_jump_base" value="0" readonly="readonly" title="Macro name: high_jump_base" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_high_jump_distance_feet" value="0" readonly="readonly" title="Macro name: high_jump_distance_feet" />
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_high_jump_distance_yards" value="0" readonly="readonly" title="Macro name: high_jump_distance_yards" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-basic-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Run</div>
<span class="sheet-tooltip">
Running High Jump.<br />
Formula = (6 x Stat To use) - 10 inches<br />
Stat to use: <input type="text" name="attr_running_high_jump_stat_to_use" value="" readonly="readonly" class="textInline width-wide" /><br />
Max running high jump distance is twice standing high jump distance.<br />
Basic Set Campaigns Page 352.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="number" step="1" name="attr_running_high_jump_yards_moved" value="0" class="editable" title="Macro name: running_high_jump_yards_moved" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_running_high_jump_distance_feet" value="0" readonly="readonly" title="Macro name: running_high_jump_distance_feet" />
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_running_high_jump_distance_yards" value="0" readonly="readonly" title="Macro name: running_high_jump_distance_yards" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row margin-bottom sheet-row-jump-move">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">JMP MV</div>
<span class="sheet-tooltip">
Jump move.<br />
Greater of Broad Jump Yards / 5 OR Normal Ground Move.<br />
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_jump_move_speed" value="0" readonly="readonly" title="Macro name: jump_move_speed" />
</div>
<div class="sheet-cell sheet-col2">
&nbsp;
</div>
<div class="sheet-cell sheet-col3">
&nbsp;
</div>
</div> <!-- .sheet-row -->
</div> <!-- .container-jumping -->
</div>
</div>
</div> <!-- .sheet-tab1 -->
<!-- ===== ===== ===== ===== TRAITS TAB ===== ===== ===== ===== -->
<div class="sheet-tab2">
<!-- _____ _____ LANGUAGE BOX _____ _____ -->
<div class="sheet-box sheet-language">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Native Language</div>
<div class="sheet-cell sheet-col1">Spoken</div>
<div class="sheet-cell sheet-col2">Written</div>
<div class="sheet-cell sheet-col3">Pts</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-native-language">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" style="font-weight:bold;" name="attr_name_native_language" placeholder="-Enter Native Language here" title="Macro name: name_native_language" />
</div>
<div class="sheet-cell sheet-col1">
<select name="attr_native_language_spoken" title="Macro name: native_language_spoken">
<option value="0" selected>Native</option>
<option value="-1">Accented</option>
<option value="-2">Broken</option>
<option value="-3">None</option>
</select>
</div>
<div class="sheet-cell sheet-col2">
<select name="attr_native_language_written" title="Macro name: native_language_written">
<option value="0" selected>Native</option>
<option value="-1">Accented</option>
<option value="-2">Broken</option>
<option value="-3">None</option>
</select>
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_native_language_points" value="@{native_language_spoken} + @{native_language_written}" disabled="disabled" title="Macro name: native_language_points" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Learned Languages</div>
<div class="sheet-cell sheet-col1">Spoken</div>
<div class="sheet-cell sheet-col2">Written</div>
<div class="sheet-cell sheet-col3">Pts</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_languages">
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_languages. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<select name="attr_spoken" title="Macro table name: repeating_languages. Field name: spoken">
<option value="3">Native</option>
<option value="2">Accented</option>
<option value="1">Broken</option>
<option value="0" selected>None</option>
</select>
</div>
<div class="sheet-cell sheet-col2">
<select name="attr_written" title="Macro table name: repeating_languages. Field name: written">
<option value="3">Native</option>
<option value="2">Accented</option>
<option value="1">Broken</option>
<option value="0" selected>None</option>
</select>
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_points" value="@{spoken} + @{written}" disabled="disabled" title="Macro table name: repeating_languages. Field name: points" />
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_languages -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-language -->
<!-- _____ _____ MISCELLENEOUS BOX _____ _____ -->
<div class="sheet-box sheet-miscelleneous">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Miscellaneous</div>
<div class="sheet-cell sheet-col1">Pts</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-tech-level">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Tech Level</div>
<span class="sheet-tooltip">
This is the technology level that you character is familiar with.
<br />
It costs 5 points to raise this above or below the campaign"s<br />normal TL.
<div class="sheet-clearfix"></div>
<table style="text-align: left;">
<tbody>
<tr><td>TL0</td><td>Stone Age (Prehistory and later). </td></tr>
<tr><td>TL1</td><td>Bronze Age (3500 B.C.+).</td></tr>
<tr><td>TL2</td><td>Iron Age (1200 B.C.+).</td></tr>
<tr><td>TL3</td><td>Medieval (600 A.D.+).</td></tr>
<tr><td>TL4</td><td>Age of Sail (1450+).</td></tr>
<tr><td>TL5</td><td>Industrial Revolution (1730+).</td></tr>
<tr><td>TL6</td><td>Mechanized Age (1880+).</td></tr>
<tr><td>TL7</td><td>Nuclear Age (1940+).</td></tr>
<tr><td>TL8</td><td>Digital Age (1980+).</td></tr>
<tr><td>TL9</td><td>Microtech Age (2025+?).</td></tr>
<tr><td>TL10</td><td>Robotic Age (2070+?).</td></tr>
<tr><td>TL11</td><td>Age of Exotic Matter.</td></tr>
<tr><td>TL12+</td><td>Whatever the GM likes!</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_tl" title="Macro name: tl" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" step="5" name="attr_tl_pts" value="0" title="Macro name: tl_pts" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-appearance">
<div class="sheet-cell sheet-col0 sheet-label">
Appearance
</div>
<div class="sheet-cell sheet-col1">
<select name="attr_appearance" title="Macro name: appearance">
<option value="-24">Horrific (-6)</option>
<option value="-20">Monstrous (-5)</option>
<option value="-16">Hideous (-4)</option>
<option value="-8">Ugly (-2)</option>
<option value="-4">Unattractive (-1)</option>
<option value="0" selected="selected">Average</option>
<option value="4">Attractive (+1)</option>
<option value="12">Handsome (+4/2)</option>
<option value="16">Very Handsome (+6/2)</option>
<option value="20">Transcendent (+8/2)</option>
</select>
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_appearance_pts" value="@{appearance}" disabled="disabled" title="Macro name: appearance_pts" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-miscelleneous -->
<!-- _____ _____ CULTURE BOX _____ _____ -->
<div class="sheet-box sheet-culture">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Cultural Familiarities</div>
<div class="sheet-cell sheet-col1">Pts</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_cultures">
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_cultures. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_points" title="Macro table name: repeating_cultures. Field name: points" />
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_cultures -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-culture -->
<div class="sheet-clearfix"> </div>
<!-- _____ _____ ADVANTAGES BOX _____ _____ -->
<!-- this box uses the identifier "traits" for backwards compatibility -->
<div class="sheet-box sheet-traits">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Advantages (& Perks)</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">FOA</div>
<span class="sheet-tooltip">
Frequency of Appearance
<br />
<table>
<tbody>
<tr><td>15 or less><td></td>
<tr><td>12 or less><td></td>
<tr><td>9 or less><td></td>
<tr><td>6 or less><td></td>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3">Pts</div>
<div class="sheet-cell sheet-col4">Ref</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_traits">
<input class="sheet-toggle" type="checkbox" title="Click to show/hide more information." name="attr_trait_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_traits. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_foa" title="Macro table name: repeating_traits. Field name: foa" />
</div>
<div class="sheet-cell sheet-col2">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Frequency of Appearance Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{foa} + @{modifier}]]}} {{notes=@{notes}}} {{showNotes=[[@{show_notes}]]}} {{bookReference=@{ref}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsAFOA" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_points" title="Macro table name: repeating_traits. Field name: points" />
</div>
<div class="sheet-cell sheet-col4">
<input type="text" name="attr_ref" title="Macro table name: repeating_traits. Field name: ref" />
</div>
</div> <!-- .sheet-row -->
<div class="row row-details notebox">
<div class="cell col-notebox">
<div class="show-notes">
<input type="checkbox" name="attr_show_notes" value="1" />
<span class="label">Show notes below, in roll template</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_traits. Field name: notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_traits -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-traits -->
<!-- _____ _____ DISADVANTAGES BOX _____ _____ -->
<div class="sheet-box sheet-disadvantages">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Disadvantages (& Quirks)</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">SCN</div>
<span class="sheet-tooltip">
Self-control Number OR
<br />
Frequency of Appearance
<br />
<table>
<tbody>
<tr><td>15 or less</td></tr>
<tr><td>12 or less</td></tr>
<tr><td>9 or less</td></tr>
<tr><td>6 or less</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3">Pts</div>
<div class="sheet-cell sheet-col4">Ref</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_disadvantages">
<input class="sheet-toggle" type="checkbox" title="Click to show/hide more information." name="attr_disadvantage_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_disadvantages. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_control_rating" title="Macro table name: repeating_disadvantages. Field name: control_rating" />
</div>
<div class="sheet-cell sheet-col2">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Self-control Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{control_rating} + @{modifier}]]}} {{notes=@{notes}}} {{showNotes=[[@{show_notes}]]}} {{bookReference=@{ref}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsDSCR" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_points" title="Macro table name: repeating_disadvantages. Field name: points" />
</div>
<div class="sheet-cell sheet-col4">
<input type="text" name="attr_ref" title="Macro table name: repeating_disadvantages. Field name: ref" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-details notebox">
<div class="cell col-notebox">
<div class="show-notes">
<input type="checkbox" name="attr_show_notes" value="1" />
<span class="label">Show notes below, in roll template</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_disadvantages. Field name: notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_disadvantages -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-disadvantages -->
<!-- _____ _____ RACIAL TRAITS BOX _____ _____ -->
<div class="sheet-box sheet-racial">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Racial Traits</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">SCN</div>
<span class="sheet-tooltip">
Self-control Number OR
<br />
Frequency of Appearance
<table>
<tbody>
<tr><td>15 or less</td></tr>
<tr><td>12 or less</td></tr>
<tr><td>9 or less</td></tr>
<tr><td>6 or less</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3">Pts</div>
<div class="sheet-cell sheet-col4">Ref</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_racial">
<input class="sheet-toggle" type="checkbox" title="Click to show/hide more information." name="attr_racial_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_racial. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_control_rating" title="Macro table name: repeating_racial. Field name: control_rating" />
</div>
<div class="sheet-cell sheet-col2">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Self-control Check}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{control_rating} + @{modifier}]]}} {{notes=@{notes}}} {{showNotes=[[@{show_notes}]]}} {{bookReference=@{ref}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsRSCR" />
</div>
<div class="sheet-cell sheet-col3">
<input type="number" name="attr_points" title="Macro table name: repeating_racial. Field name: points" />
</div>
<div class="sheet-cell sheet-col4">
<input type="text" name="attr_ref" title="Macro table name: repeating_racial. Field name: ref" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-details notebox">
<div class="cell col-notebox">
<div class="show-notes">
<input type="checkbox" name="attr_show_notes" value="1" />
<span class="label">Show notes below, in roll template</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_racial. Field name: notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_racial -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-racial -->
</div> <!-- .sheet-tab2 -->
<!-- ===== ===== ===== ===== MISCELLANEOUS TAB ===== ===== ===== ===== -->
<div class="sheet-tab-misc">
<!-- _____ _____ GENERAL BIO BOX _____ _____ -->
<div class="sheet-box sheet-general-bio">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">General Information</div>
</div> <!-- .sheet-header -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Full name
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_fullname" title="Macro name: fullname" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Nickname
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_nickname" title="Macro name: nickname" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Race
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_race" title="Macro name: race" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Gender
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_gender" title="Macro name: gender" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Size Modifier
</div>
<div class="sheet-cell sheet-col1">
<input type="number" name="attr_size" value="0" title="Macro name: size" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Pri Hand
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hand" title="Macro name: hand" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-textarea-reactions">
<div class="sheet-cell sheet-col0 sheet-label">
Reactions
</div>
<div class="sheet-cell sheet-col1">
<textarea name="attr_reactions" title="Macro name: reactions"></textarea>
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-general-bio -->
<!-- _____ _____ DESCRIPTION BOX _____ _____ -->
<div class="sheet-box sheet-bio-description">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Physical Description</div>
</div> <!-- .sheet-header -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Age
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_age" title="Macro name: age" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Height
</div>
<div class="sheet-cell sheet-col-half">
<input type="text" name="attr_height" title="Macro name: height" />
</div>
<div class="sheet-cell sheet-col0 sheet-label">
Weight
</div>
<div class="sheet-cell sheet-col-half">
<input type="text" name="attr_weight" title="Macro name: weight" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Eyes
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_eyes" title="Macro name: eyes" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Build
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_build" title="Macro name: build" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Hair
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hair" title="Macro name: hair" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-textarea">
<div class="sheet-cell sheet-col0 sheet-label">
Appearance
</div>
<div class="sheet-cell sheet-col1">
<textarea name="attr_general_appearance" title="Macro name: appearance"></textarea>
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-textarea-features">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Tattoos, scars, etc.</div>
<span class="sheet-tooltip">
Scars, tattoos, distinguishing marks or features.
</span>
</div>
<div class="sheet-cell sheet-col1 textarea-container">
<textarea name="attr_distinguishing_features" title="Macro name: distinguishing_features"></textarea>
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-bio-description -->
<!-- _____ _____ BACKGROUND INFO BOX _____ _____ -->
<div class="sheet-box sheet-background-info">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Background Information</div>
</div> <!-- .sheet-header -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Birth Date
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_birth_date" title="Macro name: birth_date" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Birth Place
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_birth_place" title="Macro name: birth_place" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Status
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_status" title="Macro name: status" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Wealth
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_wealth" title="Macro name: wealth" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Income
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_income" title="Macro name: income" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Cost of Living
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_cost_of_living" title="Macro name: cost_of_living" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
<div class="sheet-popup">Stash</div>
<span class="sheet-tooltip">
Total available cash stashed in banks,
vaults, mattresses, etc.
</span>
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_stash" title="Macro name: stash" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Affiliations
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_affiliations" value="" title="Macro name: affiliations" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row">
<div class="sheet-cell sheet-col0 sheet-label">
Home Base
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_home_base" title="Macro name: home_base" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-textarea-family">
<div class="sheet-cell sheet-col0 sheet-label">
Family
</div>
<div class="sheet-cell sheet-col1">
<textarea name="attr_family" title="Macro name: family"></textarea>
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-background-info -->
<!-- _____ _____ Background history & Notes INFO BOX _____ _____ -->
<div class="sheet-box sheet-misc-notes">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Background History & Notes</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-textarea">
<div class="sheet-cell sheet-col0">
<textarea name="attr_misc_notes" title="Macro name: misc_notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-misc-notes -->
<!-- _____ _____ TRAINING INFO BOX _____ _____ -->
<div class="sheet-box sheet-training-notes">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Training</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-textarea">
<div class="sheet-cell sheet-col0">
<textarea name="attr_training_notes" title="Macro name: training_notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-misc-notes -->
</div> <!-- .sheet-tab-misc -->
<!-- ===== ===== ===== ===== SKILLS TAB ===== ===== ===== ===== -->
<div class="sheet-tab3">
<!-- _____ _____ SKILLS BOX _____ _____ -->
<div class="sheet-box sheet-skills">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Skills</div>
<div class="sheet-cell sheet-col1"></div>
<div class="sheet-cell sheet-col2">TL</div>
<div class="sheet-cell sheet-col3">Level</div>
<div class="sheet-cell sheet-col4">Attr</div>
<div class="sheet-cell sheet-col5">
<div class="sheet-popup">Diff</div>
<span class="sheet-tooltip">
WC = Wildcard Skill.<br />
PTS = 3, 6, 12, 24, 36, etc.
</span>
</div>
<div class="sheet-cell sheet-col6">Mod</div>
<div class="sheet-cell sheet-col7">Pts</div>
<div class="sheet-cell sheet-col8">Ref</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_skills">
<input class="toggle-highlight" type="checkbox" name="attr_highlight" />
<input class="toggle toggle-notes" type="checkbox" title="Click to show/hide more information." name="attr_skill_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_skills. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Skill Roll}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{level} + @{modifier}]]}} {{notes=@{notes}}} {{showNotes=[[@{show_notes}]]}} {{bookReference=@{ref}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{customSuccessNote=@{skill_success_note}}} {{customCriticalSuccessNote=@{skill_critical_success_note}}} {{customFailNote=@{skill_fail_note}}} {{customCriticalFailNote=@{skill_critical_fail_note}}}" name="roll_vsSL" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_tl" title="Macro table name: repeating_skills. Field name: tl" />
</div>
<div class="sheet-cell sheet-col3">
<input type="hidden" name="attr_level_mirror" value="0" />
<input type="text" name="attr_level" title="Macro table name: repeating_skills. Field name: level" disabled="disabled" value="@{base} + @{difficulty} + @{bonus} + (floor(((@{wildcard_skill_points}*@{use_wildcard_points} + @{points}*@{use_normal_points}) * 0.25) + 2) * ceil( ( ( (@{wildcard_skill_points}*@{use_wildcard_points} + @{points}*@{use_normal_points}) - 2 ) + abs( (@{wildcard_skill_points}*@{use_wildcard_points} + @{points}*@{use_normal_points}) - 2) ) / 256 ) + (@{wildcard_skill_points}*@{use_wildcard_points} + @{points}*@{use_normal_points}) * abs( ceil( ( ( (@{wildcard_skill_points}*@{use_wildcard_points} + @{points}*@{use_normal_points}) - 2 ) + abs( (@{wildcard_skill_points}*@{use_wildcard_points} + @{points}*@{use_normal_points}) - 2) ) / 256 ) - 1 ))"/>
</div>
<div class="sheet-cell sheet-col4">
<select name="attr_base" title="Macro table name: repeating_skills. Field name: base">
<option value="@{strength}">ST</option>
<option value="@{dexterity}">DX</option>
<option value="@{intelligence}">IQ</option>
<option value="@{health}">HT</option>
<option value="@{willpower}">Will</option>
<option value="@{perception}">Per</option>
<option value="10">10</option>
</select>
</div>
<div class="sheet-cell sheet-col5">
<select name="attr_difficulty" title="Macro table name: repeating_skills. Field name: difficulty">
<option value="-1">E</option>
<option value="-2">A</option>
<option value="-3">H</option>
<option value="-4">VH</option>
<option value="-5 + 1">WC</option>
</select>
</div>
<div class="sheet-cell sheet-col6">
<input type="number" name="attr_bonus" value="0" title="Macro table name: repeating_skills. Field name: bonus" />
</div>
<div class="sheet-cell sheet-col7">
<input type="hidden" name="attr_use_wildcard_points" value="0" />
<input type="hidden" name="attr_use_normal_points" value="1" />
<input type="hidden" name="attr_wildcard_skill_points" value="0" />
<input type="number" name="attr_points" value="0" />
</div>
<div class="sheet-cell sheet-col8">
<input type="text" name="attr_ref" title="Macro table name: repeating_skills. Field name: ref" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-details notebox">
<div class="row-misc">
<div class="cell label">
<div class="sheet-popup">Row ID:</div>
<span class="sheet-tooltip">
The row id can be used with macros.<br />
NOTE: Future use for linking to techniques<br />
and combat skills.<br />
Example field name: repeating_skills_[the row id]_level<br />
This example would represent the skill level on that row.
</span>
</div>
<div class="cell">
<input type="text" readonly="readonly" name="attr_row_id" value="" />
</div>
<div class="cell label">
Misc:
</div>
<div class="cell">
<input type="text" name="attr_skill_misc" title="Macro table name: repeating_skills. Field name: skill_misc" />
</div>
</div> <!-- .sheet-row -->
<div class="col-notebox">
<div class="show-notes">
<input type="checkbox" name="attr_show_notes" value="1" />
<span class="label">Show notes below in roll template.</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_skills. Field name: notes"></textarea>
</div>
<div class="rolltable-result-notes">
<div class="note-input">
<div class="note-title">
<div class="sheet-popup">Success Note:</div>
<span class="sheet-tooltip">
Success, critical success, fail, and critical fail<br />
notes will be added to roll results.<br />
You can add macros to these notes.
</span>
</div>
<textarea name="attr_skill_success_note" title="Macro table name: repeating_skills. Field name: skill_success_note"></textarea>
</div>
<div class="note-input">
<div class="note-title">Critical Success Note:</div>
<textarea name="attr_skill_critical_success_note" title="Macro table name: repeating_skills. Field name: skill_critical_success_note"></textarea>
</div>
<div class="note-input">
<div class="note-title">Reason for MOD (Modifier):</div>
<textarea name="attr_skill_mod_notes" title="Macro table name: repeating_skills. Field name: skill_mod_notes"></textarea>
</div>
</div>
<div class="rolltable-result-notes">
<div class="note-input">
<div class="note-title">Fail Note:</div>
<textarea name="attr_skill_fail_note" title="Macro table name: repeating_skills. Field name: skill_fail_note"></textarea>
</div>
<div class="note-input">
<div class="note-title">Critical Fail Note:</div>
<textarea name="attr_skill_critical_fail_note" title="Macro table name: repeating_skills. Field name: skill_critical_fail_note"></textarea>
</div>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_skills -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-skills -->
<!-- _____ _____ TECHNIQUES BOX _____ _____ -->
<div class="sheet-box sheet-techniques">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Techniques</div>
<div class="sheet-cell sheet-col1">Parent</div>
<div class="sheet-cell sheet-col2">Min</div>
<div class="sheet-cell sheet-col3">Max</div>
<div class="sheet-cell sheet-col4">Level</div>
<div class="sheet-cell sheet-col5">Cost</div>
<div class="sheet-cell sheet-col6">Mod</div>
<div class="sheet-cell sheet-col7">Pts</div>
<div class="sheet-cell sheet-col8">Ref</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_techniques">
<input class="sheet-toggle" type="checkbox" title="Click to show/hide more information." name="attr_technique_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_techniques. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_parent" title="Macro table name: repeating_techniques. Field name: parent" />
</div>
<div class="sheet-cell sheet-col2">
<input type="number" name="attr_min" value="0" title="Macro table name: repeating_techniques. Field name: min" />
</div>
<div class="sheet-cell sheet-col3">
---
</div>
<div class="sheet-cell sheet-col4">
<input type="text" name="attr_level" disabled="disabled" title="Macro table name: repeating_techniques. Field name: level" value="@{min} + floor(@{points} / @{points_per_level}) + @{bonus}"/>
</div>
<div class="sheet-cell sheet-col5">
<input type="number" name="attr_points_per_level" value="1" title="Macro table name: repeating_techniques. Field name: points_per_level" />
</div>
<div class="sheet-cell sheet-col6">
<input type="number" name="attr_bonus" value="0" title="Macro table name: repeating_techniques. Field name: bonus" />
</div>
<div class="sheet-cell sheet-col7">
<input type="number" name="attr_points" value="0" title="Macro table name: repeating_techniques. Field name: points" />
</div>
<div class="sheet-cell sheet-col8">
<input type="text" name="attr_ref" title="Macro table name: repeating_techniques. Field name: ref" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-details notebox">
<div class="cell col-notebox">
<div class="show-notes">
<input type="checkbox" name="attr_show_notes" value="1" />
<span class="label">Show notes below, in roll template</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_techniques. Field name: notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_techniques -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-techniques -->
</div> <!-- .sheet-tab3 -->
<!-- ===== ===== ===== ===== COMBAT TAB ===== ===== ===== ===== -->
<div class="sheet-tab4">
<!-- _____ _____ HIT LOCATION BOX _____ _____ -->
<div class="sheet-box sheet-damage-reduction">
<div class="sheet-table">
<div class="sheet-header sheet-row-title">
<div class="sheet-cell sheet-col0">
Hit Location
</div>
</div> <!-- .sheet-header -->
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Where</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">Pen</div>
<span class="sheet-tooltip">
This is the <strong>Penalty</strong> <br />
applied to attack the <br />
specific location.
</span>
</div>
<div class="sheet-cell sheet-col2">DR</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-skull">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_skull" value="Skull" title="Macro name: name_skull" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_skull" value="-7" title="Macro name: hit_penalty_skull" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_skull_dr_max" value="2" title="Macro name: skull_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-face">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_face" value="Face" title="Macro name: name_face" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_face" value="-5" title="Macro name: hit_penalty_face" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_face_dr_max" value="0" title="Macro name: face_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-eyes">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_eyes" value="Eyes" title="Macro name: name_eyes" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_eyes" value="-9" title="Macro name: hit_penalty_eyes" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_eyes_dr_max" value="0" title="Macro name: eyes_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-neck">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_neck" value="Neck" title="Macro name: name_neck" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_neck" value="-5" title="Macro name: hit_penalty_neck" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_neck_dr_max" value="0" title="Macro name: neck_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-arms">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_arms" value="Arms" title="Macro name: name_arms" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_arms" value="-2" title="Macro name: hit_penalty_arms" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_arms_dr_max" value="0" title="Macro name: arms_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-hands">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_hands" value="Hands" title="Macro name: name_hands" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_hands" value="-4" title="Macro name: hit_penalty_hands" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_hands_dr_max" value="0" title="Macro name: hands_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-torso">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_torso" value="Torso" title="Macro name: name_torso" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_torso" value="0" title="Macro name: hit_penalty_torso" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_torso_dr_max" value="0" title="Macro name: torso_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-vitals">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_vitals" value="Vitals" title="Macro name: name_vitals" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_vitals" value="-3" title="Macro name: hit_penalty_vitals" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_vitals_dr_max" value="0" title="Macro name: vitals_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-groin">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_groin" value="Groin" title="Macro name: name_groin" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_groin" value="-3" title="Macro name: hit_penalty_groin" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_groind_dr_max" value="0" title="Macro name: groind_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-legs">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_legs" value="Legs" title="Macro name: name_legs" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_legs" value="-2" title="Macro name: hit_penalty_legs" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_legs_dr_max" value="0" title="Macro name: legs_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-feet">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_feet" value="Feet" title="Macro name: name_feet" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_feet" value="-4" title="Macro name: hit_penalty_feet" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_feet_dr_max" value="0" title="Macro name: feet_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-area">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name_area" value="Area" title="Macro name: name_area" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty_area" value="n/a" title="Macro name: hit_penalty_area" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_area_dr_max" value="0" title="Macro name: area_dr_max" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-header sheet-row-title">
<div class="sheet-cell sheet-col0">
User Created
</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_location">
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0 sheet-label">
<input type="text" name="attr_name" title="Macro table name: repeating_location. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_hit_penalty" value="0" title="Macro table name: repeating_location. Field name: hit_penalty" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_dr_max" value="0" title="Macro table name: repeating_location. Field name: dr_max" />
</div>
</div> <!-- .sheet-row -->
</fieldset>
</div> <!-- .sheet-table -->
<div class="rapid-fire-table">
<img src="https://raw.githubusercontent.com/Roll20/roll20-character-sheets/master/GURPS/Images/Rapid_Fire_Table.png" title="Rapid Fire Table" alt="Rapid Fire Table" />
</div>
<div class="speed-range-table"> <!-- .speed-range-table image-->
<img src="https://raw.githubusercontent.com/Roll20/roll20-character-sheets/master/GURPS/Images/Speed_Range_Table.PNG" title="Speed/Range Table" alt="GURPS Speed/Range Table" />
</div> <!-- .speed-range-table image-->
</div> <!-- .sheet-box .sheet-damage-reduction -->
<!-- _____ _____ ACTIVE DEFENSE BOX _____ _____ -->
<div class="sheet-box sheet-active-defense">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Active Defenses</div>
<div class="sheet-cell sheet-col1">Type</div>
<div class="sheet-cell sheet-col2">
<div class="sheet-popup">Info</div>
<span class="sheet-tooltip">
<strong>F</strong>: this is a fencing weapon.
<br />
<strong>U</strong>: the weapon is unbalanced. You cannot use it to<br />
parry if you've already attacked with it this turn<br /> (and vice versa).
</span>
</div>
<div class="sheet-cell sheet-col3">Skill</div>
</div> <!-- .sheet-header -->
<div class="sheet-row sheet-row-stats sheet-row-standard">
<div class="sheet-cell sheet-col0">
<div class="sheet-popup">[Optional] Apply Combat Reflexes to Dodge and Fright Modifiers</div>
<span class="sheet-tooltip sheet-ad-col0-tooltip">
Quickly add +1 Dodge modifier and
+2 Fright modifier on the General tab.
</span>
</div>
<div class="sheet-cell sheet-col1">&nbsp;</div>
<div class="sheet-cell sheet-col2">&nbsp;</div>
<div class="sheet-cell sheet-col3">
<input type="checkbox" class="sheet-boolean" name="attr_combat_reflexes" value="1" />
</div>
<div class="sheet-cell sheet-col4">&nbsp;</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-stats sheet-row-standard">
<div class="sheet-cell sheet-col0">Dodge</div>
<div class="sheet-cell sheet-col1">Dodge</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3"><input type="text" name="attr_ad_dodge_skill" value="@{current_dodge}" disabled="disabled" title="Macro name: ad_dodge_skill" /></div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Defense Roll}} {{defenseType=[[1]]}} {{activeDefense=[[1]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Dodge}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{current_dodge} + @{modifier}]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsDodge" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-stats sheet-row-standard">
<div class="sheet-cell sheet-col0">Dodge and Retreat</div>
<div class="sheet-cell sheet-col1">Dodge</div>
<div class="sheet-cell sheet-col2"></div>
<div class="sheet-cell sheet-col3"><input type="text" name="attr_ad_dodge_retreat_skill" value="@{current_dodge} + 3" disabled="disabled" title="Macro name: ad_dodge_retreat_skill" /></div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Defense Roll}} {{defenseType=[[1]]}} {{activeDefense=[[1]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Dodge and Retreat}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{current_dodge} + @{modifier} + 3]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsDodgeRetreat" />
</div>
</div> <!-- .sheet-row -->
<fieldset class="repeating_defense">
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_defense. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="hidden" name="attr_defense_type" value="0" />
<select name="attr_type" title="Macro table name: repeating_defense. Field name: type">
<option>Dodge</option>
<option>Parry</option>
<option>Block</option>
<option>Magic</option>
<option>Other</option>
</select>
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_info" title="Macro table name: repeating_defense. Field name: info" />
<input type="hidden" name="attr_info_description" />
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_skill" title="Macro table name: repeating_defense. Field name: skill" />
</div>
<div class="sheet-cell sheet-col4">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Defense Roll (@{type})}} {{defenseType=[[@{defense_type}]]}} {{activeDefense=[[1]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{skill} + @{modifier}]]}} {{showNotes=[[1]]}} {{notes=@{info_description}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsSL" />
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_defense -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-active-defense -->
<!-- _____ _____ MELEE ATTACKS BOX _____ _____ -->
<div class="sheet-box sheet-melee-attacks">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Melee Attacks</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">Damage</div>
<span class="sheet-tooltip">
<strong>Armor Divisor</strong>: A number in parenthesis after<br />
the damage - eg. (2) - is an armor divisor.
<br />
Enter this number as AD(#) or as
<br />
Armor Divisor(#) in the Damage Notes.
<br />
<strong>ex</strong>: indicates the attack causes an explosion.<br />
See page 269. Enter in the Damage Notes
</span>
</div>
<div class="sheet-cell sheet-col2">
<div class="sheet-popup"> </div>
<span class="sheet-tooltip">
Damage Macro
</span>
</div>
<div class="sheet-cell sheet-col3">
<div class="sheet-popup">Type</div>
<span class="sheet-tooltip">
<table>
<thead>
<tr>
<th>Abbr</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr><td>aff</td> <td>Affliction</td></tr>
<tr><td>burn</td><td>Burning</td></tr>
<tr><td>cor</td> <td>Corrosion</td></tr>
<tr><td>cr</td> <td>Crushing</td></tr>
<tr><td>cut</td> <td>Cutting</td></tr>
<tr><td>fat</td> <td>Fatigue</td></tr>
<tr><td>imp</td> <td>Impaling</td></tr>
<tr><td>pi-</td> <td>Small Piercing</td></tr>
<tr><td>pi</td> <td>Piercing</td></tr>
<tr><td>pi+</td> <td>Large Piercing</td></tr>
<tr><td>pi++</td><td>Huge Piercing</td></tr>
<tr><td>spec</td><td>Special</td></tr>
<tr><td>tox</td> <td>Toxic</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col4">
<div class="sheet-popup">Reach</div>
<span class="sheet-tooltip">
The distance in yards that the weapon can reach.
<br />
<strong>C</strong>: this weapon can be used in close combat.
<br />
<strong>*</strong>: the weapon is awkward, and requires a Ready<br />
maneuver to switch between different reaches.
</span>
</div>
<div class="sheet-cell sheet-col5">
<span style="background-color: #87CEFA">| skill |</span>
</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_melee">
<input class="toggle-highlight" type="checkbox" name="attr_highlight" />
<input class="sheet-toggle toggle-notes" type="checkbox" title="Click to show/hide more information." name="attr_melee_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_melee. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_damage" title="Macro table name: repeating_melee. Field name: damage" />
</div>
<div class="sheet-cell sheet-col2">
<input type="hidden" name="attr_damage_dice_icon" class="melee-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Melee Damage}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{damageRoll=[[@{damage}]]}} {{minDamageNote=@{minimum_damage_note}}} {{damageType=@{type}}} {{useDamageTypeNotes=[[@{use_damage_type_notes}]]}} {{damageTypeNote=@{damage_type_note}}} {{showNotes=[[1]]}} {{notes=@{damage_notes}}}" name="roll_damage" class="roll_damage" />
</div>
<div class="sheet-cell sheet-col3">
<select name="attr_type" title="Macro table name: repeating_melee. Field name: type">
<option value="Affliction (aff)">aff</option>
<option value="Burning (burn)">burn</option>
<option value="Corrosion (cor)">cor</option>
<option value="Crushing (cr)">cr</option>
<option value="Cutting (cut)">cut</option>
<option value="Fatigue (fat)">fat</option>
<option value="Impaling (imp)">imp</option>
<option value="Small Piercing (pi-)">pi-</option>
<option value="Piercing (pi)">pi</option>
<option value="Large Piercing (pi+)">pi+</option>
<option value="Huge Piercing (pi++)">pi++</option>
<option value="Special (spec)">spec</option>
<option value="Toxic (tox)">tox</option>
</select>
<input type="hidden" name="attr_damage_type_note" value="@{damage_type_note_aff}" />
<input type="hidden" name="attr_minimum_damage_note" value="Min 1" />
</div>
<div class="sheet-cell sheet-col4">
<input type="text" name="attr_reach" title="Macro table name: repeating_melee. Field name: reach" />
</div>
<div class="sheet-cell sheet-col5">
<input type="text" name="attr_skill" title="Macro table name: repeating_melee. Field name: skill" />
</div>
<div class="sheet-cell sheet-col6">
<button type="roll" class="template-attack-roll" value="@{roll}&{template:skillRoll} {{type=Melee Attack}} {{activeDefense=[[0]]}} {{showHitLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{skill} + @{modifier}]]}} {{reach=@{reach}}} {{notes=@{notes}}} {{showNotes=[[1]]}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsSL" />
</div>
</div> <!-- .sheet-row -->
<div class="ranged-notebox">
<div class="row">
<div class="cell">
<select name="attr_melee_row_type">
<option>Skill</option>
<option>Spell</option>
</select>
</div>
<div class="cell col-normal label">
<div class="popup">Row ID</div>
<span class="tooltip">
Copy/paste the Skill or Spell Row ID to link that skill to this attack.<br />
When the skill/spell is updated, the weapon attack will also be updated.<br />
Use the Modifier column to account for unfamiliar weapon, weapon bond, quality, etc.
</span>
</div>
<div class="cell col-input-medium">
<input type="hidden" name="attr_melee_skill_row_id_toggle" value="0" />
<input type="text" name="attr_melee_skill_row_id" title="Macro table name: repeating_melee. Field name: melee_skill_row_id" />
</div>
<div class="cell custom-checkbox">
<label>
Mod:
<input type="number" value="0" name="attr_melee_skill_row_id_modifier" class="inline" title="Macro table name: repeating_melee. Field name: melee_skill_row_id_modifier" />
</label>
</div>
<div class="cell col-wide">
<input type="hidden" name="attr_melee_skill_row_id_message" value="" />
<span name="attr_melee_skill_row_id_message"></span>
</div>
</div> <!-- .sheet-row -->
<div class="row">
<div class="cell col-normal label">
<div class="popup">Weapon Notes</div>
<span class="tooltip">
<strong>Hint:</strong> Enter inline rolls for additional results.<br />
To show the selected arrow.<br />
Example: Select Location: ?{Location|Head|Torso}
</span>
</div>
<div class="cell col-auto">
<input type="text" class="text-left" name="attr_notes" title="Macro table name: repeating_melee. Field name: notes" />
</div>
<div class="cell col-normal label">
<div class="popup">Damage Notes</div>
<span class="sheet-tooltip">
<strong>Hint:</strong> Enter inline rolls for additional results.<br />
Example: Does an additional [[1d6]] fire damage.
</span>
</div>
<div class="cell col-wide">
<input type="text" class="text-left" name="attr_damage_notes" title="Macro table name: repeating_melee. Field name: damage_notes" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-ranged-notebox -->
</fieldset> <!-- .repeating_melee -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-melee-attacks -->
<!-- _____ _____ RANGED ATTACKS BOX _____ _____ -->
<div class="sheet-box sheet-ranged-attacks">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Ranged Attacks</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">Damage</div>
<span class="sheet-tooltip">
<strong>Armor Divisor</strong>: A number in parenthesis after<br />
the damage - eg. (2) - is an armor divisor.<br />
Enter this number as AD(#) or as<br />
Armor Divisor(#) in the Damage Notes.
<br />
<strong>ex</strong>: indicates the attack causes an explosion.<br />
<strong>[#d]</strong>: indicates the attack causes fragmentation.<br />
See page 269.
</span>
</div>
<div class="sheet-cell sheet-col2"> </div>
<div class="sheet-cell sheet-col3">
<div class="sheet-popup">Type</div>
<span class="sheet-tooltip">
<table>
<thead>
<tr>
<th>Abbr</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr><td>aff</td> <td>Affliction</td></tr>
<tr><td>burn</td><td>Burning</td></tr>
<tr><td>cor</td> <td>Corrosion</td></tr>
<tr><td>cr</td> <td>Crushing</td></tr>
<tr><td>cut</td> <td>Cutting</td></tr>
<tr><td>fat</td> <td>Fatigue</td></tr>
<tr><td>imp</td> <td>Impaling</td></tr>
<tr><td>pi-</td> <td>Small Piercing</td></tr>
<tr><td>pi</td> <td>Piercing</td></tr>
<tr><td>pi+</td> <td>Large Piercing</td></tr>
<tr><td>pi++</td><td>Huge Piercing</td></tr>
<tr><td>spec</td><td>Special</td></tr>
<tr><td>tox</td> <td>Toxic</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col4">Acc</div>
<div class="sheet-cell sheet-col5">
<div class="sheet-popup">RNG</div>
<span class="sheet-tooltip">
See page 269.
</span>
</div>
<div class="sheet-cell sheet-col6">
<div class="sheet-popup">RoF</div>
<span class="sheet-tooltip">
Rate of Fire
<br />
The maximum number of shots that can be fired in <br />
one turn (by a regular person).
<br />
The minimum number of shots is 1.
<br /><br />
<strong>!</strong>: minimum RoF is 1/4 of the maximum, rounded up.
<br />
<strong>mxn</strong>: fires the first number of shots, which each then<br />
split into the second number (eg. shotguns)
<br />
<strong>Jet</strong>: shoots a continuous stream of fliud. See page 106.
</span>
</div>
<div class="sheet-cell sheet-col7">
<div class="sheet-popup">Shots</div>
<span class="sheet-tooltip">
The number of shots that can be fired before the<br />
weapon must be reloaded.<br />
The parenthetical number indicates the number of 1<br />
second ready maneuvers required to reload the<br />
weapon.<br />
<strong>T</strong>: the weapon is thrown. To "reload" it, pick it up.<br />
<strong>i</strong>: you must load the shots individually. the listed<br />
time is for each shot.
</span>
</div>
<div class="sheet-cell sheet-col8">
<div class="sheet-popup">BULK</div>
<span class="sheet-tooltip">
Subtract bulk penalty to Move and Attack or -2, whatever is worse.<br />
Subtract bulk penalty to Holdout skill.<br />
See B270<br />
</span>
</div>
<div class="sheet-cell sheet-col9">
<div class="sheet-popup">RCL</div>
<span class="sheet-tooltip">
When firing at RoF 2+, every full multiple of Rcl<br />
by which you make your attack roll means you score<br />
one extra hit, to a maximum number of hits equal<br />
to total shots fired. See page 373.
</span>
</div>
<div class="sheet-cell sheet-col10">
<span style="background-color: #87CEFA">| skill |</span>
</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_ranged">
<input class="toggle-highlight" type="checkbox" name="attr_highlight" />
<input class="sheet-toggle toggle-notes" type="checkbox" title="Click to show/hide more information." name="attr_ranged_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_ranged. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_damage" title="Macro table name: repeating_ranged. Field name: damage" />
</div>
<div class="sheet-cell sheet-col2">
<input type="hidden" name="attr_damage_dice_icon" class="range-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Ranged Damage}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{damageRoll=[[@{damage}]]}} {{minDamageNote=@{minimum_damage_note}}} {{damageType=@{type}}} {{useDamageTypeNotes=[[@{use_damage_type_notes}]]}} {{damageTypeNote=@{damage_type_note}}} {{showNotes=[[1]]}} {{notes=@{damage_notes}}}" name="roll_damage" class="roll_damage" />
</div>
<div class="sheet-cell sheet-col3">
<select name="attr_type" title="Macro table name: repeating_ranged. Field name: type">
<option value="Affliction (aff)">aff</option>
<option value="Burning (burn)">burn</option>
<option value="Corrosion (cor)">cor</option>
<option value="Crushing (cr)">cr</option>
<option value="Cutting (cut)">cut</option>
<option value="Fatigue (fat)">fat</option>
<option value="Impaling (imp)">imp</option>
<option value="Small Piercing (pi-)">pi-</option>
<option value="Piercing (pi)">pi</option>
<option value="Large Piercing (pi+)">pi+</option>
<option value="Huge Piercing (pi++)">pi++</option>
<option value="Special (spec)">spec</option>
<option value="Toxic (tox)">tox</option>
</select>
<input type="hidden" name="attr_damage_type_note" value="@{damage_type_note_aff}" />
<input type="hidden" name="attr_minimum_damage_note" value="Min 1" />
</div>
<div class="sheet-cell sheet-col4">
<input type="text" name="attr_acc" title="Macro table name: repeating_ranged. Field name: acc" />
</div>
<div class="sheet-cell sheet-col5">
<input type="text" name="attr_range" title="Macro table name: repeating_ranged. Field name: range" />
</div>
<div class="sheet-cell sheet-col6">
<input type="text" name="attr_rof" title="Macro table name: repeating_ranged. Field name: rof" />
</div>
<div class="sheet-cell sheet-col7">
<input type="text" name="attr_shots" title="Macro table name: repeating_ranged. Field name: shots" />
</div>
<div class="sheet-cell sheet-col8">
<input type="text" name="attr_bulk" title="Macro table name: repeating_ranged. Field name: bulk" />
</div>
<div class="sheet-cell sheet-col9">
<input type="text" name="attr_recoil" title="Macro table name: repeating_ranged. Field name: recoil" />
</div>
<div class="sheet-cell sheet-col10">
<input type="text" name="attr_skill" title="Macro table name: repeating_ranged. Field name: skill" />
</div>
<div class="sheet-cell sheet-col11">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Ranged Attack}} {{activeDefense=[[0]]}} {{showHitLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{skill} + @{modifier}]]}} {{notes=@{notes}}} {{showNotes=[[1]]}} {{rof=@{rof}}} {{recoil=@{recoil}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{useMalfunction=[[@{use_malfunction}]]}} {{malfunction=[[@{malfunction}]]}} {{verifyMalfunction=[[ @{malfunction_verify} ]]}}" name="roll_vsSL" />
</div>
</div> <!-- .sheet-row -->
<div class="ranged-notebox">
<div class="row">
<div class="cell">
<select name="attr_ranged_row_type">
<option>Skill</option>
<option>Spell</option>
</select>
</div>
<div class="cell col-normal label">
<div class="popup">Row ID</div>
<span class="tooltip">
Copy/paste the Skill or Spell Row ID to link that skill to this attack.<br />
When the skill/spell is updated, the weapon attack will also be updated.<br />
Use the Modifier column to account for unfamiliar weapon, weapon bond, quality, etc.
</span>
</div>
<div class="cell col-input-medium">
<input type="hidden" name="attr_ranged_skill_row_id_toggle" value="0" />
<input type="text" name="attr_ranged_skill_row_id" title="Macro table name: repeating_ranged. Field name: ranged_skill_row_id" />
</div>
<div class="cell custom-checkbox">
<label>
Mod:
<input type="number" value="0" name="attr_ranged_skill_row_id_modifier" class="inline" title="Macro table name: repeating_ranged. Field name: ranged_skill_row_id_modifier" />
</label>
</div>
<div class="cell col-wide">
<input type="hidden" name="attr_ranged_skill_row_id_message" value="" />
<span name="attr_ranged_skill_row_id_message"></span>
</div>
</div> <!-- .sheet-row -->
<div class="row">
<div class="cell col-normal label">
<div class="popup">Malfunction</div>
<span class="tooltip">
Malfunction chance.<br />
If the option <i>Use Malfunction</i> is checked, <br />
the roll results will check for weapon malfunction.<br />
Malfunction levels:<br />
TL3: 12, TL:4: 14, TL5: 16, TL6+: 17<br />
For more info and malfunction table See B407.<br />
High Tech (HT79): If verify is checked, then roll again to verify the malfunction.<br />
<b style="color:red;">NOTE:</b> Malfunction has "priority" over a critical miss: if both would occur, <br />
only the malfunction takes place. Critical Misses, Basic Set, page 382.
</span>
</div>
<div class="cell col-input">
<input type="number" default="0" name="attr_malfunction" value="0" title="Macro table name: repeating_ranged. Field name: malfunction" />
</div>
<div class="cell col-verify custom-checkbox">
<label>
Verify:
<input type="checkbox" name="attr_malfunction_verify" value="1" class="inline" title="Macro table name: repeating_ranged. Field name: malfunction_verify" />
</label>
</div>
</div> <!-- .sheet-row -->
<div class="row">
<div class="cell col-normal label">
<div class="popup">Weapon Notes</div>
<span class="tooltip">
<strong>Hint:</strong> Enter inline rolls for additional results.<br />
To show the selected arrow.<br />
Example: Arrow: ?{Arrow Type|Bodkin|Normal}
</span>
</div>
<div class="cell col-auto">
<input type="text" class="text-left" name="attr_notes" title="Macro table name: repeating_ranged. Field name: notes" />
</div>
<div class="cell col-normal label">
<div class="popup">Damage Notes</div>
<span class="sheet-tooltip">
<strong>Hint:</strong> Enter inline rolls for additional results.<br />
Example: [[1d6]] fire damage.
</span>
</div>
<div class="cell col-wide">
<input type="text" class="text-left" name="attr_damage_notes" title="Macro table name: repeating_ranged. Field name: notes" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-note-box -->
</fieldset> <!-- .repeating_ranged -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-ranged-attacks -->
<!-- combat tools heading -->
<div class="section-heading combat-tools">
<div class="header">Combat Tools</div>
</div>
<!-- _____ _____ THROWING _____ _____ -->
<div class="sheet-box sheet-ranged-attacks sheet-thrown-object">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0-st">Thrown (lbs)</div>
<div class="sheet-cell sheet-col8">
<div class="sheet-popup">ST</div>
<div class="sheet-tooltip">
Based on Striking ST<br />
<i>Note:</i> future versions will add ability to choose ST source or enter ST.
</div>
</div>
<div class="sheet-cell sheet-col8">
<div class="sheet-popup">MOD</div>
<div class="sheet-tooltip">
Strength Modifier to distance only<br />
Throwing or Throwing Art at DX Level = +1 ST<br />
Throwing or Throwing Art at DX+1 Level = +2 ST<br />
</div>
</div>
<div class="sheet-cell sheet-col8">
<div class="sheet-popup">SUPER</div>
<div class="sheet-tooltip">
Super Throw Level<br />
Each level of Super Throw, double range.<br />
Each level of Super Throw increases damage by +2 per die.
</div>
</div>
<div class="sheet-cell sheet-col1">
<div class="sheet-popup">Damage</div>
<div class="sheet-tooltip">
Final damage based on ST, super throw,
and damage modifier.
</div>
</div>
<div class="sheet-cell sheet-col8">
<div class="sheet-popup">Mod</div>
<div class="sheet-tooltip">
Bonus or penalty per die<br />
Throwing Art at DX Level = +1 per die<br />
Throwing Art at DX+1 Level = +2 per die<br />
</div>
</div>
<div class="sheet-cell sheet-col2"> </div>
<div class="sheet-cell sheet-col3">
<div class="sheet-popup">Type</div>
<span class="sheet-tooltip">
<table>
<thead>
<tr>
<th>Abbr</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr><td>aff</td> <td>Affliction</td></tr>
<tr><td>burn</td><td>Burning</td></tr>
<tr><td>cor</td> <td>Corrosion</td></tr>
<tr><td>cr</td> <td>Crushing</td></tr>
<tr><td>cut</td> <td>Cutting</td></tr>
<tr><td>fat</td> <td>Fatigue</td></tr>
<tr><td>imp</td> <td>Impaling</td></tr>
<tr><td>pi-</td> <td>Small Piercing</td></tr>
<tr><td>pi</td> <td>Piercing</td></tr>
<tr><td>pi+</td> <td>Large Piercing</td></tr>
<tr><td>pi++</td><td>Huge Piercing</td></tr>
<tr><td>spec</td><td>Special</td></tr>
<tr><td>tox</td> <td>Toxic</td></tr>
</tbody>
</table>
</span>
</div>
<div class="sheet-cell sheet-col4">Acc</div>
<div class="sheet-cell sheet-col5">
<div class="sheet-popup">RNG</div>
<span class="sheet-tooltip">
See GURPS Campaigns Page 355 for formula
</span>
</div>
<div class="sheet-cell sheet-col6">
<div class="sheet-popup">RoF</div>
<span class="sheet-tooltip">
Rate of Fire
<br />
The maximum number of shots that can be fired in <br />
one turn (by a regular person).
<br />
The minimum number of shots is 1.
<br /><br />
<strong>!</strong>: minimum RoF is 1/4 of the maximum, rounded up.
<br />
<strong>mxn</strong>: fires the first number of shots, which each then<br />
split into the second number (eg. shotguns)
<br />
<strong>Jet</strong>: shoots a continuous stream of fliud. See page 106.
</span>
</div>
<div class="sheet-cell sheet-col7">
<div class="sheet-popup">Shots</div>
<span class="sheet-tooltip">
The number of shots that can be fired before the<br />
weapon must be reloaded.<br />
The parenthetical number indicates the number of 1<br />
second ready maneuvers required to reload the<br />
weapon.<br />
<strong>T</strong>: the weapon is thrown. To "reload" it, pick it up.<br />
<strong>i</strong>: you must load the shots individually. the listed<br />
time is for each shot.
</span>
</div>
<div class="sheet-cell sheet-col9">
<div class="sheet-popup">RCL</div>
<span class="sheet-tooltip">
When firing at RoF 2+, every full multiple of Rcl<br />
by which you make your attack roll means you score<br />
one extra hit, to a maximum number of hits equal<br />
to total shots fired. See page 373.
</span>
</div>
<div class="sheet-cell sheet-col10">
<span style="background-color: #87CEFA">| skill |</span>
</div>
</div> <!-- .sheet-header -->
<div class="repcontainer">
<div class="repitem">
<input class="sheet-toggle" type="checkbox" title="Click to show/hide more information." name="attr_thrown_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats row-thrown-object">
<div class="sheet-cell sheet-col0-st">
<input type="number" step="1" value="1" min="1" name="attr_thrown_object_weight" title="Macro name: thrown_object_weight" />
</div>
<div class="sheet-cell sheet-col8">
<input type="text" name="attr_thrown_object_strength" readonly="readonly" value="10" title="Macro name: thrown_object_strength" />
</div>
<div class="sheet-cell sheet-col8">
<input type="number" name="attr_thrown_object_strength_mod" value="0" step="1" title="Macro name: thrown_object_strength_mod" />
</div>
<div class="sheet-cell sheet-col8">
<input type="number" name="attr_super_throw_level" value="0" step="1" title="Macro name: super_throw_level" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_thrown_object_damage" readonly="readonly" value="@{thrust}" title="Macro name: thrown_object_damage" />
</div>
<div class="sheet-cell sheet-col8">
<input type="number" step="1" name="attr_thrown_object_damage_mod" value="0" title="Macro name: thrown_object_damage_mod" />
</div>
<div class="sheet-cell sheet-col2">
<input type="hidden" name="attr_damage_dice_icon" class="range-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Ranged Damage}} {{characterName=@{character_name}}} {{skillName=Thrown Object @{thrown_object_weight} lbs.}} {{damageRoll=[[@{thrown_object_damage}]]}} {{minDamageNote=@{thrown_minimum_damage_note}}} {{damageType=@{thrown_object_damage_type}}} {{useDamageTypeNotes=[[@{use_damage_type_notes}]]}} {{damageTypeNote=@{thrown_object_damage_type_note}}} {{showNotes=[[1]]}} {{notes=@{thrown_object_damage_notes}}}" name="roll_damage" class="roll_damage" />
</div>
<div class="sheet-cell sheet-col3">
<select name="attr_thrown_object_damage_type" title="Macro name: thrown_object_damage_type">
<option value="Cutting (cut)">cut</option>
<option value="Impaling (imp)">imp</option>
<option value="Crushing (cr)">cr</option>
<option value="Small Piercing (pi-)">pi-</option>
<option value="Piercing (pi)">pi</option>
<option value="Large Piercing (pi+)">pi+</option>
<option value="Huge Piercing (pi++)">pi++</option>
<option value="Affliction (aff)">aff</option>
<option value="Burning (burn)">burn</option>
<option value="Corrosion (cor)">cor</option>
<option value="Fatigue (fat)">fat</option>
<option value="Toxic (tox)">tox</option>
<option value="Special (spec)">spec</option>
</select>
<input type="hidden" name="attr_thrown_object_damage_type_note" value="@{damage_type_note_cut}" />
<input type="hidden" name="attr_thrown_minimum_damage_note" value="Min 1" />
</div>
<div class="sheet-cell sheet-col4">
<input type="number" step="1" name="attr_thrown_object_acc" value="0" title="Macro name: thrown_object_acc" />
</div>
<div class="sheet-cell sheet-col5 thrown-object-input">
<input type="text" name="attr_thrown_object_range" readonly="readonly" value="10" title="Macro name: thrown_object_range" />
</div>
<div class="sheet-cell sheet-col6">
<input type="text" name="attr_thrown_object_rof" value="1" title="Macro name: thrown_object_rof" />
</div>
<div class="sheet-cell sheet-col7">
<input type="text" name="attr_thrown_object_shots" value="1" title="Macro name: thrown_object_shots" />
</div>
<div class="sheet-cell sheet-col9">
<input type="text" name="attr_thrown_object_recoil" value="-1" title="Macro name: thrown_object_recoil" />
</div>
<div class="sheet-cell sheet-col10">
<input type="text" name="attr_thrown_object_skill" value="10" title="Macro name: thrown_object_skill" />
</div>
<div class="sheet-cell sheet-col11">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Ranged Attack}} {{activeDefense=[[0]]}} {{showHitLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=Thrown Object @{thrown_object_weight} lbs.}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{thrown_object_skill} + @{modifier}]]}} {{showNotes=[[1]]}} {{notes=@{thrown_object_notes}}} {{rof=@{thrown_object_rof}}} {{recoil=@{thrown_object_recoil}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}}" name="roll_vsSL" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-details2">
<div class="sheet-cell sheet-col0 sheet-label">
Weapon Notes
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_thrown_object_notes" title="Macro name: thrown_object_notes" />
</div>
<div class="sheet-cell sheet-col2 sheet-label">
<div class="sheet-popup">Damage Notes</div>
<span class="sheet-tooltip">
<strong>Hint:</strong> Enter inline rolls for additional results.<br />
Example: [[1d6]] fire damage.
</span>
</div>
<div class="sheet-cell sheet-col3">
<input type="text" name="attr_thrown_object_damage_notes" title="Macro name: thrown_object_damage_notes" />
</div>
</div>
</div> <!-- .sheet-row -->
</div>
<!-- .end repcontainer -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-ranged-attacks -->
<!-- _____ _____ Firing Up or Down _____ _____ -->
<div class="box firing-up-down">
<div class="table">
<div class="row title">
<div class="cell">
Range Calculator for Ranged Attacks only
</div>
</div>
<div class="header">
<div class="cell linear-range">
<div class="popup">Range</div>
<div class="tooltip">
Distance between shooter and target.<br />
</div>
</div>
<div class="cell speed">
<div class="popup">Speed</div>
<div class="tooltip">
(2 mph = 1 yard/second).<br />
Ignore if human like target moving 10 yards or less.
</div>
</div>
<div class="cell size">
Size Mod
</div>
<div class="cell fire-direction">
<div class="popup">Direction</div>
<div class="tooltip">
Ignore up/down for beam type weapons like lasers.
</div>
</div>
<div class="cell fire-up-dwn-distance">
Elevation
</div>
<div class="cell new-range">
Speed/Range
</div>
<div class="cell hit-mod">
Hit Mod
</div>
<div class="cell reset">
&nbsp;
</div>
</div> <!-- .sheet-header -->
<div class="container">
<div class="row">
<div class="cell linear-range">
<input type="number" step="1" value="0" min="0" name="attr_firing_distance" title="Macro name: firing_distance" />
</div>
<div class="cell speed">
<input type="number" step="1" value="0" min="0" name="attr_firing_speed_difference" title="Macro name: firing_speed_difference" />
</div>
<div class="cell size">
<input type="number" step="1" value="0" name="attr_firing_size_mod" title="Macro name: firing_size_mod" />
</div>
<div class="cell fire-direction">
<select name="attr_firing_direction" title="Macro name: firing_direction">
<option value="linear">Normal</option>
<option value="up">Elev. Up</option>
<option value="dn">Elev. Down</option>
</select>
</div>
<div class="cell fire-up-dwn-distance">
<input type="number" step="1" value="0" min="0" name="attr_firing_up_dwn_distance" title="Macro name: firing_up_dwn_distance" />
</div>
<div class="cell new-range">
<input type="number" step="1" value="0" min="0" name="attr_firing_new_range" readonly="readonly" title="Macro name: firing_new_range" />
</div>
<div class="cell new-range">
<input type="number" step="1" value="0" name="attr_firing_hit_mod" readonly="readonly" title="Macro name: firing_hit_mod" />
</div>
<div class="cell reset">
<button type="action" name="act_range_calc_reset" class="reset" />Reset</button>
</div>
</div>
</div> <!-- .container -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-ranged-attacks firing-up-or-down -->
<!-- _____ _____ Falling and Collision _____ _____ -->
<div class="box falling-collision">
<div class="table">
<div class="row title">
<div class="cell">
Falling and Collision
</div>
</div>
<div class="header">
<div class="cell row-title">
&nbsp;
</div>
<div class="cell yards-fallen">
Yds Fallen
</div>
<div class="cell gravity">
Gravity
</div>
<div class="cell atmosphere">
<div class="popup">Atm.</div>
<div class="tooltip">
Atmosphere
</div>
</div>
<div class="cell velocity">
<div class="popup">Velocity</div>
<span class="tooltip">
If collision, use relative velocity.<br />
Headon collision = Add velocity of both objects<br />
Reared collisioin = Faster object - slower object<br />
Side collision = Speed of object causing collision<br />
</span>
</div>
<div class="cell hit-points">
<div class="popup">HP</div>
<div class="tooltip">
Hit Points of falling object or object initiating <br />
collision.<br />
If hitting immovable object, use HP*2<br />
NOTE: If collision, if the other object is moving<br />
it will inflict its own damage to object that initiated<br />
the collision.<br />
See B430
</div>
</div>
<div class="cell damage">
Damage
</div>
<div class="cell roll-damage">
&nbsp;
</div>
<div class="cell reset">
&nbsp;
</div>
</div> <!-- .sheet-header -->
<div class="container">
<div class="row">
<div class="cell row-title">
Falling
</div>
<div class="cell yards-fallen">
<input type="number" step="1" value="1" min="1" name="attr_yards_fallen" title="Macro name: yards_fallen" />
</div>
<div class="cell gravity">
<input type="number" value="1" min="0" name="attr_gravity" title="Macro name: gravity" />
</div>
<div class="cell atmosphere">
<input type="number" value="1" min="0" name="attr_atmosphere" title="Macro name: atmosphere" />
</div>
<div class="cell velocity">
<input type="number" value="5" readonly="readonly" name="attr_falling_velocity" title="Macro name: velocity" />
</div>
<div class="cell hit-points">
<input type="number" step="1" value="10" min="1" name="attr_falling_hit_points" title="Macro name: falling_hit_points" />
</div>
<div class="cell damage">
<input type="text" value="1d6-2" name="attr_falling_damage" readonly="readonly" title="Macro name: falling_damage" />
</div>
<div class="cell roll-damage">
<input type="hidden" name="attr_thrust_damage_dice_icon" class="thrust-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Damage Roll}} {{characterName=@{character_name}}} {{skillName=Falling Damage}} {{damageRoll=[[@{falling_damage}]]}} {{minDamageNote=Crush min 0, else min 1}} {{showNotes=[[1]]}} {{notes=@{falling_collision_damage_notes}}}" name="roll_dmgFalling" class="roll_damage" />
</div>
<div class="cell reset">
<button type="action" name="act_falling_reset" class="reset" />Reset</button>
</div>
</div>
<div class="row">
<div class="cell row-title">
Collision
</div>
<div class="cell yards-fallen">
&nbsp;
</div>
<div class="cell gravity">
&nbsp;
</div>
<div class="cell atmosphere">
&nbsp;
</div>
<div class="cell velocity">
<input type="number" value="1" step="1" min="1" name="attr_collision_velocity" title="Macro name: collision_velocity" />
</div>
<div class="cell hit-points">
<input type="number" step="1" value="10" min="1" name="attr_collision_hit_points" title="Macro name: collision_hit_points" />
</div>
<div class="cell damage">
<input type="text" value="1d6-3" name="attr_collision_damage" readonly="readonly" title="Macro name: collision_damage" />
</div>
<div class="cell roll-damage">
<input type="hidden" name="attr_thrust_damage_dice_icon" class="thrust-damage-dice-icon" value="explode" />
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Damage Roll}} {{characterName=@{character_name}}} {{skillName=Collision Damage}} {{damageRoll=[[@{collision_damage}]]}} {{minDamageNote=Crush min 0, else min 1}} {{showNotes=[[1]]}} {{notes=@{falling_collision_damage_notes}}}" name="roll_dmgFalling" class="roll_damage" />
</div>
<div class="cell reset">
<button type="action" name="act_collision_reset" class="reset" />Reset</button>
</div>
</div>
</div> <!-- .container -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-ranged-attacks -->
</div> <!-- .sheet-tab4 -->
<!-- ===== ===== ===== ===== ITEMS TAB ===== ===== ===== ===== -->
<div class="sheet-tab5">
<!-- _____ _____ QUICK INVENTORY BOX _____ _____ -->
<div class="sheet-box sheet-quick-inventory sheet-textarea">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Quick Inventory & Wealth</div>
</div>
<div class="quick-inventory-textarea">
<textarea name="attr_quick_inventory" title="Macro name: quick_inventory"></textarea>
</div>
</div>
<!-- _____ _____ INVENTORY BOX _____ _____ -->
<div class="sheet-box sheet-items">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">Possessions</div>
<div class="sheet-cell sheet-col1">TL</div>
<div class="sheet-cell sheet-col2">Ref</div>
<div class="sheet-cell sheet-col3">
<div class="sheet-popup">On</div>
<span class="sheet-tooltip">
Carried
<br />
Is the item being carried at the moment?
</span>
</div>
<div class="sheet-cell sheet-col4">#</div>
<div class="sheet-cell sheet-col5">$</div>
<div class="sheet-cell sheet-col6">W</div>
<div class="sheet-cell sheet-col7">$+</div>
<div class="sheet-cell sheet-col8">W+</div>
</div>
<fieldset class="repeating_item">
<input class="toggle-highlight" type="checkbox" name="attr_highlight" />
<input class="sheet-toggle toggle-notes" type="checkbox" title="Click to show/hide more information." name="attr_item_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_item. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<input type="text" name="attr_tl" title="Macro table name: repeating_item. Field name: tl" />
</div>
<div class="sheet-cell sheet-col2">
<input type="text" name="attr_ref" title="Macro table name: repeating_item. Field name: ref" />
</div>
<div class="sheet-cell sheet-col3">
<input class="sheet-boolean" type="checkbox" name="attr_carried" value="1" checked title="Macro table name: repeating_item. Field name: carried" />
</div>
<div class="sheet-cell sheet-col4">
<input type="number" name="attr_count" value="1" title="Macro table name: repeating_item. Field name: count" />
</div>
<div class="sheet-cell sheet-col5">
<input type="number" name="attr_cost" value="0.00" step="0.01" title="Macro table name: repeating_item. Field name: cost" />
</div>
<div class="sheet-cell sheet-col6">
<input type="number" name="attr_weight" value="0.000" step="0.001" title="Macro table name: repeating_item. Field name: weight" />
</div>
<div class="sheet-cell sheet-col7" style="text-align: right;background-color: #c9c9c9;border-bottom: 1px solid white;border-right: 1px solid white;">
<span name="attr_costtotal" value="0.00" title="Macro table name: repeating_item. Field name: costtotal" />
</div>
<div class="sheet-cell sheet-col8" style="text-align: right;background-color: #c9c9c9;border-bottom: 1px solid white;border-right: 1px solid white;">
<input type="hidden" name="attr_inventory_item_carried" />
<span name="attr_weighttotal" value="0.000" class="item-weight-total" title="Macro table name: repeating_item. Field name: weighttotal" />
</div>
</div> <!-- .sheet-row -->
<div class="sheet-row sheet-row-details notebox">
<div class="cell col-notebox">
<div class="show-notes">
<span class="label">Notes</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_item. Field name: notes"></textarea>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_item -->
<div class="sheet-row sheet-row-totals">
<div class="sheet-cell sheet-col0 sheet-label">
Total Value:
</div>
<div class="sheet-cell sheet-col1">
<input type="number" style="font-weight: bold;" step=".01" name="attr_total_value" value="0" readonly="readonly" title="Macro name: total_value" />
</div>
<div class="sheet-cell sheet-col2 sheet-label">
Total Weight:
</div>
<div class="sheet-cell sheet-col3">
<input type="number" style="font-weight: bold; text-align: center;" step=".001" name="attr_total_weight" value="0" readonly="readonly" title="Macro name: total_weight" />
</div>
</div> <!-- .sheet-row -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-items -->
</div> <!-- .sheet-tab5 -->
<!-- ===== ===== ===== ===== GRIMOIRE TAB ===== ===== ===== ===== -->
<div class="sheet-tab6">
<!-- _____ _____ SPELLS SETUP _____ _____ -->
<div class="box spells spell-stats">
<div class="table">
<div class="header spell-stats-header">
<div class="cell"> Spells Based on: </div>
<div class="cell margin-right">
<select name="attr_spell_base" title="Macro name: spell_base">
<option value="@{strength}">ST</option>
<option value="@{dexterity}">DX</option>
<option value="@{intelligence}" selected>IQ</option>
<option value="@{health}">HT</option>
<option value="@{willpower}">Will</option>
<option value="@{perception}">Per</option>
<option value="10">10</option>
</select>
</div>
<div class="cell"> Magery/PI/Bonus Level: </div>
<div class="cell margin-right">
<input type="number" name="attr_spell_bonus" value="0" title="Macro name: spell_bonus" />
</div>
<div class="cell">
<div class="popup">On Penalty</div>
<div class="tooltip">
Spell skill penalty based on number of <b>ON</b> spells.<br />
<input type="hidden" name="attr_spell_on_count" value="0" />
Number of spells <b>ON:</b> <span name="attr_spell_on_count"></span>.<br />
<i>NOTE:</i> Use the options tab to adjust the penalty per spell <b>ON</b>.
</div>
</div>
<div class="cell margin-right">
<input type="number" name="attr_spell_on_penalty_total" value="0" title="Macro name: spell_on_penalty_total" readonly="readonly" />
</div>
<div class="cell">
<div class="popup">Concentration Penalty</div>
<div class="tooltip">
<b>Concentration</b> spell penalty<br />
<input type="hidden" name="attr_spell_maintained_count" value="0" />
Number of spells: <span name="attr_spell_maintained_count"></span>.<br />
<i>NOTE:</i> Use options tab to adjust the penalty.
</div>
</div>
<div class="cell margin-right">
<input type="number" name="attr_spell_maintained_penalty_total" value="0" title="Macro name: spell_maintained_penalty_total" readonly="readonly" />
</div>
</div>
</div>
</div>
<!-- _____ _____ SPELLS BOX _____ _____ -->
<div class="sheet-box sheet-spells">
<div class="sheet-table">
<div class="sheet-header">
<div class="sheet-cell sheet-col0">
<div class="popup">Spell</div>
<div class="tooltip">
Name of spell
</div>
</div>
<div class="sheet-cell sheet-col1"></div>
<div class="sheet-cell sheet-col2">
<div class="popup">LVL</div>
<div class="tooltip">
Skill level with spell<br />
</div>
</div>
<div class="sheet-cell sheet-col3">
<div class="popup">Diff</div>
<div class="tooltip">
Difficulty
</div>
</div>
<div class="sheet-cell sheet-col4">
<div class="popup">Mod</div>
<div class="tooltip">
Modifier
</div>
</div>
<div class="sheet-cell sheet-col5">
<div class="popup">Pts</div>
<div class="tooltip">
Points
</div>
</div>
<div class="sheet-cell sheet-col12">
<div class="popup">ON</div>
<div class="tooltip">
Mark the spell as <b>ON</b><br />
-1 skill penalty for each spell that is <b>ON</b>.<br />
See B238 or M10.
</div>
</div>
<div class="sheet-cell sheet-col12">
<div class="popup">CT</div>
<div class="tooltip">
Mark the spell as <b>Under Concentration</b>.<br />
-3 skill penalty for each spell.<br />
See B238 or M10.
</div>
</div>
<div class="sheet-cell sheet-col6">
<div class="popup">Class</div>
<div class="tooltip">
Spell class; Area, Blocking, Information, Melee,<br />
Missile, Regular, Regular (Jet), Resisted, Special
</div>
</div>
<div class="sheet-cell sheet-col7">
<div class="popup">RESIST</div>
<div class="tooltip">
Resisted By
</div>
</div>
<div class="sheet-cell sheet-col8">
<div class="popup">Duration</div>
<div class="tooltip">
Duration of Spell
</div>
</div>
<div class="sheet-cell sheet-col9">
<div class="popup">Cost</div>
<div class="tooltip">
Energy cost for casting the spell.
</div>
</div>
<div class="sheet-cell sheet-col10">
<div class="popup">Time</div>
<div class="tooltip tooltip-spell-time">
Amount of time to cast the spell.
</div>
</div>
<div class="sheet-cell sheet-col11">
<div class="popup">Maintain</div>
<div class="tooltip">
Energy cost to maintain the spell.
</div>
</div>
</div> <!-- .sheet-header -->
<fieldset class="repeating_spells">
<input class="toggle-highlight" type="checkbox" name="attr_highlight" />
<input class="toggle toggle-notes" type="checkbox" title="Click to show/hide more information." name="attr_spell_toggle_notes" />
<span class="sheet-checkbox"></span>
<div class="sheet-row sheet-row-stats">
<div class="sheet-cell sheet-col0">
<input type="text" name="attr_name" title="Macro table name: repeating_spells. Field name: name" />
</div>
<div class="sheet-cell sheet-col1">
<button type="roll" value="@{roll}&{template:skillRoll} {{type=Spell Skill Roll}} {{activeDefense=[[0]]}} {{showSuccessLabel=[[1]]}} {{characterName=@{character_name}}} {{skillName=@{name}}} {{rollResult=[[3d6]]}} {{effectiveSkill=[[@{level} + @{modifier}]]}} {{notes=@{notes}}} {{showNotes=[[@{show_notes}]]}} {{castingTime=@{casttime}}} {{castingDuration=@{duration}}} {{castingCost=@{cost}}} {{castingMaintain=@{maintain}}} {{castingResist=@{spell_resisted_by}}} {{castingClass=@{spell_class}}} {{bookReference=@{ref}}} {{useCriticalPlusTen=[[@{use_critical_plus_10}]]}} {{customSuccessNote=@{spell_success_note}}} {{customCriticalSuccessNote=@{spell_critical_success_note}}} {{customFailNote=@{spell_fail_note}}} {{customCriticalFailNote=@{spell_critical_fail_note}}} " name="roll_vsSL" />
</div>
<div class="sheet-cell sheet-col2">
<input type="hidden" name="attr_level_mirror" value="0" />
<input type="text" name="attr_level" title="Macro table name: repeating_spells. Field name: level" disabled="disabled" value="@{spell_base} + @{difficulty} +@{spell_modifier} + @{spell_bonus} + (floor((@{points} * 0.25) + 2) * ceil( ( ( @{points} - 2 ) + abs( @{points} - 2) ) / 256 ) + @{points} * abs( ceil( ( ( @{points} - 2 ) + abs( @{points} - 2) ) / 256 ) - 1 ))"/>
</div>
<div class="sheet-cell sheet-col3">
<select name="attr_difficulty" title="Macro table name: repeating_spells. Field name: difficulty">
<option value="-3">H</option>
<option value="-4">VH</option>
</select>
</div>
<div class="sheet-cell sheet-col4">
<input type="number" name="attr_spell_modifier" value="0" title="Macro table name: repeating_spells. Field name: spell_modifier" />
</div>
<div class="sheet-cell sheet-col5">
<input type="number" name="attr_points" value="0" title="Macro table name: repeating_spells. Field name: points" />
</div>
<div class="sheet-cell sheet-col12">
<input type="checkbox" class="checkbox" title="Check to mark spell as on." name="attr_spell_on_checked" value="1" />
</div>
<div class="sheet-cell sheet-col12">
<input type="checkbox" class="checkbox" title="Check to mark spell as on." name="attr_spell_maintained_checked" value="1" />
</div>
<div class="sheet-cell sheet-col6">
<input type="text" name="attr_spell_class" placeholder="Class" title="Macro table name: repeating_spells. Field name: spell_class" />
</div>
<div class="sheet-cell sheet-col7">
<input type="text" name="attr_spell_resisted_by" placeholder="Resist" title="Macro table name: repeating_spells. Field name: spell_resisted_by" />
</div>
<div class="sheet-cell sheet-col8">
<input type="text" name="attr_duration" placeholder="Duration" title="Macro table name: repeating_spells. Field name: duration" />
</div>
<div class="sheet-cell sheet-col9">
<input type="text" name="attr_cost" placeholder="Cost to Cast" title="Macro table name: repeating_spells. Field name: cost" />
</div>
<div class="sheet-cell sheet-col10">
<input type="text" name="attr_casttime" placeholder="Casting Time" title="Macro table name: repeating_spells. Field name: casttime" />
</div>
<div class="sheet-cell sheet-col11">
<input type="text" name="attr_maintain" placeholder="Cost to Maintain" title="Macro table name: repeating_spells. Field name: maintain" />
</div>
</div> <!-- .sheet-row -->
<div class="row row-details notebox">
<div class="row-misc row-college">
<div class="cell label">
<div class="sheet-popup">Row ID:</div>
<span class="sheet-tooltip">
The row id can be used with macros.<br />
NOTE: Future use for linking to techniques<br />
and combat skills.<br />
Example field name: repeating_spells_[the row id]_level<br />
This example would represent the spell level on that row.
</span>
</div>
<div class="cell">
<input type="text" readonly="readonly" name="attr_row_id" value="" />
</div>
<div class="cell label">
College(s):
</div>
<div class="cell">
<input type="text" name="attr_spell_college" title="Macro table name: repeating_spells. Field name: spell_college" />
</div>
<div class="cell label">
<div class="popup">Ref</div>
<div class="tooltip alt-indent">
Reference to book and page numbers.<br />
Examples:<br />
B238 = GURPS Basic, Page 238<br />
PU2:126 = Power-Ups 2. Page 126<br />
</div>
</div>
<div class="cell">
<input type="text" name="attr_ref" placeholder="Ref" title="Macro table name: repeating_spells. Field name: ref" />
</div>
</div> <!-- .sheet-row -->
<div class="col-notebox">
<div class="show-notes">
<input type="checkbox" name="attr_show_notes" value="1" />
<span class="label">Show notes below, in roll template</span>
</div>
<textarea name="attr_notes" title="Macro table name: repeating_spells. Field name: notes"></textarea>
</div>
<div class="rolltable-result-notes">
<div class="note-input">
<div class="note-title">
<div class="sheet-popup">Success Note:</div>
<span class="sheet-tooltip">
Success, critical success, fail, and critical fail<br />
notes will be added to roll results.<br />
You can add macros to these notes.
</span>
</div>
<textarea name="attr_spell_success_note" title="Macro table name: repeating_spells. Field name: spell_success_note"></textarea>
</div>
<div class="note-input">
<div class="note-title">Critical Success Note:</div>
<textarea name="attr_spell_critical_success_note" title="Macro table name: repeating_spells. Field name: spell_critical_success_note"></textarea>
</div>
<div class="note-input">
<div class="note-title">Reason for MOD (Modifier):</div>
<textarea name="attr_spell_mod_notes" title="Macro table name: repeating_spells. Field name: spell_mod_notes"></textarea>
</div>
</div>
<div class="rolltable-result-notes">
<div class="note-input">
<div class="note-title">Fail Note:</div>
<textarea name="attr_spell_fail_note" title="Macro table name: repeating_spells. Field name: spell_fail_note"></textarea>
</div>
<div class="note-input">
<div class="note-title">Critical Fail Note:</div>
<textarea name="attr_spell_critical_fail_note" title="Macro table name: repeating_spells. Field name: spell_critical_fail_note"></textarea>
</div>
</div>
</div> <!-- .sheet-row -->
</fieldset> <!-- .repeating_spells -->
</div> <!-- .sheet-table -->
</div> <!-- .sheet-box .sheet-spells -->
</div> <!-- .sheet-tab6 -->
<!-- ===== ===== ===== ===== Revision History TAB ===== ===== ===== ===== -->
<div class="sheet-tab7">
<div>
<h3>Latest Changes: Updated
<!-- NOTE: set value by using var latestChangesDate = "DATE"; -->
<input type="text" style="font-size: 20px; font-weight: bold; border-style: none;" name="attr_latest_changes" readonly="readonly"/>
</h3>
<h3>Known Issues</h3>
<ul>
<li>Unable to delete a Technique - UPDATE</li>
<li>
The issue is the 'Max' value for the Technique. If any value was placed in there, the row will not delete.
So I have blocked values from being placed there so that new Techniques can be deleted if need be.
Existing Techniques that you are unable to delete - the Devs are looking into that issue and will advise me.
</li>
<li>NOTE: Techniques, as it is now on the character sheet, does not really work well - that section will most likely be completely rewritten (I plan on doing it when I get some time and my skills at HTML improve).</li>
</ul>
<h3>Note to authors</h3>
<ul>
<p>I need to mention that the original author(s) misspelled the words Miscellaneous (as Miscellwneous) and Encumbrance (as Encumberance) in both the CSS and HTML files. Rather than write extensive code to fix this, I just corrected the cosmetic portions only. Also note that the original author(s) use the word Fear in place of Fright although the proper word to use is Fright. As with the misspelled words, I changed no code other than the cosmetic side. This seemed simpler then spending hours writing code, transferring values from the attributes in question, and making sure it still functions. It also avoids having to explain it to the users in case they used those misspelled attributes in homemade macros.</p>
</ul>
<h3>Revision History</h3>
<ul>
<p>Please note: I, Mike W, am not one of the original authors of this sheet. All I have done is to fix a number of small issues, changed some formatting, and implemeted some suggested changes. The basic functionality of the sheet has remained the same.</p>
<p>To report any Issues or a Suggestion, please use the Roll20 forum under Character Sheets & Compendium. I have created a thread named: [GURPS] - Sheet #1 - Thread 1 (that seems to be similar to the naming convention used by other sheets).</p>
<p>https://app.roll20.net/forum/post/6616836/gurps-sheet-number-1-thread-1/</p>
<p>In your post, please specify if it is an Issue or Suggestion with as much detail information as possible. Screen shots help a lot! I am just learning to work with HTML and CSS so I may not be able to do everything requested. I make no promises on how fast I may be able to implement a Fix or a Suggestion - so please be patient. -Thanks, Mike W.</p>
<p>If there are others that are working on or wish to work on this sheet, lets coordinate using the Roll20 forum for now - perhaps later we can use GitHub.</p>
</ul>
<h4>Version: <span name="attr_announcement_version"></span></h4>
<p>Pull Request: <span name="attr_latest_changes"></span></p>
<ul>
<li>Repeating skills/spells. Removed checkbox to show success/fail notes. Converted text boxes to multi-line text boxes.</li>
<li>
Repeating melee/ranged attacks. Ability to link weapon to skill or spell. The weapon will show the skill or spell level
and should update when the skill or spell level is updated.
</li>
<li>Reformat minimum damage notes and include page reference.</li>
<li>
Repeating Spells. Moved checkboxes for <b>ON</b> and <b>MT</b> to avoid collision with delete button. Resized some text
boxes to allow more space for delete button. Change Maintained Penalty titles to Concentration Penalty. Thanks to Valter.
</li>
</ul>
<h4>Version: 1.6.9</h4>
<ul>
<li>Roll template. Add malfunction number next to recoil.</li>
<li>Skills tab. Fix Success Note bug, not showing on success results correctly.</li>
<li>Repeating skills and spells. Added checkbox to show success/fail notes on rolltable.</li>
<li>If critical fail on skill roll, show both associated fail and critical fail notes.</li>
<li>
Grimoire Tab - Repeating Spells table. Move <b>REF</b> field to expanded notes area, replace with <b>ON</b> checkbox.
resize Resisted by to add Being Maintained checkbox.
</li>
</ul>
<h4>Version: 1.6.8</h4>
<ul>
<li>Combat Tab - Ranged Attacks. Added Malfunction field.</li>
<li>New Option - Use Malfunction. If checked, roll result will check for malfunction.</li>
<li>Character Sheet Default Options. Added Use Malfunction default option.</li>
<li>General Tab - Added turning and deceleration movement. Expand <b>Current</b> move row to view.</li>
</ul>
<h4>Version: 1.6.7</h4>
<p>Pull Request: 10/22/2019</p>
<ul>
<li>Combat Tab - Defense Roll. If parry, new notes for parrying heavier weapon. Will not display if wound modifier notes is turned off.</li>
<li>Options tab - added field to edit defensive parry notes.</li>
<li>Added Success/Fail notes for skills.</li>
<li>Added Success/Fail notes for spells.</li>
<li>Skills Tab - Expanding the skill box now shows the Row ID. The Row ID is useful for macros and for future linking to combat table.</li>
<li>Grimoire Tab - Expanding the spell box now shows the Row ID. The Row ID is useful for macros and for future linking to combat table.</li>
<li>Add notes for minimum damage amount.</li>
<li>Tooltips to view macro field names. Hover mouse over input box to see tooltip.</li>
</ul>
<h4>Version: 1.6.6</h4>
<p>Pull Request: 09/23/2019</p>
<ul>
<li>If a Wound Modifier Note is updated, each combat attack with the same modifier will get updated.</li>
<li>Jumping - Add check box to factor in encumbrance level.</li>
<li>Critical Successes Option: If Turn Off is selected, fixed bug where the critical success text is displayed for active defenses.</li>
<li>Combat Tab - Active Defense. If U or F is entered for INFO, the appropriate description will be added. New Feature.</li>
<li>Added date to announcements tip.</li>
<li>Inventory Tab: If Item is marked as "ON" the weight will be bolded. NOTE: Please toggle the ON field to see the bolded text.</li>
<li>Added tooltips to open/close arrows. Changed the style slightly to more of a button feel.</li>
</ul>
<h4>Version: 1.6.5</h4>
<p>Pull Request: 09/10/2019</p>
<ul>
<li>Changes, Fixes, and Adds made by Mike W (UserID: 1414610)</li>
<li>Updated ToolTips for Fright Check, Knockdown and Stunning, Death, Unc. Check (Unconsciousness), ER, and Unstun - Cosmetic Only</li>
<li>Updated Knockdown and Stunning Roll Template - Cosmetic Only </li>
<li>Updated Unstun (Recovering from Physical Stun) Roll Template - Cosmetic Only</li>
<li>Updated Death Check Roll Template - Cosmetic Only</li>
<li>Updated Unc. Check (Unconsciousness) Roll Template - Cosmetic Only</li>
<li>Change the basic format of all ToolTips - Cosmetic Only</li>
<li>Corrected Wound Modifier Notes for imp, pi+, and pi++. - Cosmetic Only</li>
</ul>
<h4>Version: 1.6.4</h4>
<p>Pull Request: 08/20/2019</p>
<ul>
<li>Changes, Fixes, and Adds made by Mike W (UserID: 1414610)</li>
<li>Change Placeholder Opacity (Cosmetic Only)</li>
<li>Added Placeholders for Grimoire repeating section (Cosmetic Only)</li>
<li>Updated some ToolTips for the Grimoire (Cosmetic Only)</li>
</ul>
<h4>Version: 1.6.3</h4>
<p>Pull Request: 08/06/2019</p>
<ul>
<li>Rolltemplate: If Target is too low, show warning message. If Defense roll, lowest Target is 1. All other rolls, lowest Target is 3.</li>
<li>General Tab: Fix bug for totalling amounts in summary point table. Reported by Raymond G and Elaxter.</li>
<li>General Tab: Fixed movement feats box alignment when Encrumbance table is expanded.</li>
</ul>
<h4>Version: 1.6.2</h4>
<p>Pull Request: 07/30/2019</p>
<ul>
<li>Rolltemplate text. On critical failure for dodge, added additional notes. Suggested by Mike W.</li>
<li>Rolltemplate text. On critical failure for parry, added additional notes. Suggested by Mike W.</li>
<li>Rolltemplate text. On critical failure for block, added additional notes. Suggested by Mike W.</li>
<li>Rolltemplate text. On critical success for any active defense, added additional notes. Suggested by Mike W.</li>
<li>Bio\Misc. Tab. Added Training textarea below Background history & notes. Suggested by Mike W.</li>
<li>General Tab. Added toggle to show/hide encumbrance table. Suggested by Mike W.</li>
<li>General Tab: Revamped Point summary to show more details.</li>
<li>Grimoire Tab: Added tool tips to headers. Additional information will be added later. Suggested by Mike W.</li>
<li>General Tab: Added tooltips to Flying and Swimming sections. Moved movement feats below the encumbrance table.</li>
<li>General Tab: Changed spacing in box for containing Hit Points and Energy Reserve.</li>
<li>General Tab: Tweaked spacing to main stats section. Added Custom Pools heading and tooltip.</li>
</ul>
<h4>Version: 1.6.1</h4>
<p>Pull Request: 07/09/2019</p>
<ul>
<li>Changes, Fixes, and Adds made by Mike W (UserID: 1414610)</li>
<li>Fixed wording from roll table to roll template. (Cosmetic Only)</li>
<li>Fixed Spell Macro roll to include Modifier, if any.</li>
<li>Fixed the Spell Effective Skill level to include the Spell MOD, if any</li>
<li>Fixed columns for MOD, Pts, Duration, and Maintains. (Cosmetic Only)</li>
<li>Reordered column layout to match GURPS Magic format. (Cosmetic Only)</li>
<li>Added the attributes for Class and Resisted By for the Grimoire.</li>
<li>Fixed Spells ‘Based On’ header to show the attribute chosen. (Cosmetic Only)</li>
<li>Reduced the attribute size for Diff, MOD and Pts and increased size for Cost and Time. (Cosmetic Only)</li>
<li>Added the attributes for Latest Changes date. (Cosmetic Only)</li>
<li>Added the attributes for College and Modifier Notes for the Grimoire.</li>
<li>Added Attributes Misc and Modifier Notes for Skills. </li>
<li>Fixed Inventory totals for Value and Weight totals to show trailing zeros.</li>
<li>Fixed issue with Inventory Total Weight not rounding properly and not showing to 3 decimal places.</li>
<li>Made some format changes for Total Value and Total Weight under Inventory. (Cosmetic Only)</li>
</ul>
<h4>Version 1.6.0</h4>
<ul>
<li>Roll template update: Move "Ref" to the right of roll type to save space. Suggested by Mike W.</li>
<li>Grimoire tab: Added checkbox to highlight spells. Added a spell level modifier column.</li>
<li>Fallling/Collision notes: Revised the default notes when the falling damage is rolled.
However, these notes are only visible on new characters sheets, since the those notes can be edited on the options page.
</li>Bug fix: Racial Traits Self-control roll. Success/Fail text was missing, fixed.</li>
</ul>
<h4>Version: 1.5.9</h4>
<ul>
<li>
Notes boxes for advantages, disadvantages, racial traits, skills, techniques, inventory items, and spells
were converted to a text area, allowing you to enter more notes easily. There's also an option to include
the notes on the roll template.
</li>
<li>Roll results table. Removed "Notes" label to provide more space to notes.</li>
<li>Skills tab: changed column heading from BONUS to MOD. MOD can be positive or negative numbers. Suggested by Mike W.</li>
<li>Removed powered by GURPS logo. Suggested by Mike W.</li>
</ul>
<h4>Version: 1.5.8</h4>
<ul>
<li>Added button links to GURPS Wiki and Forum Thread</li>
<li>Skills Tab. Added Wildcard! Skill level option</li>
<li>Roll Results. Refactored logic to show text for hit/miss or success/fail, and handle critical rolls better.</li>
<li>
Added names to a few roll buttons. if you drag the button to the macro quick bar, then a useful name will show.
For example; drag the die for ST to the quick macro bar and it will be called ST Roll
</li>
</ul>
<h4>Version: 1.5.7</h4>
<p>Pull Request: 4/23/2019</p>
<ul>
<li>Added new method for showing announcements and updates. Inspired by Pathfinder Community Character Sheet</li>
<li>Combat Tab: Added Falling and collision combat tool</li>
</ul>
<h4>Version: 1.5.6</h4>
<p>Pull Request: 4/9/2019</p>
<ul>
<li>Updated all 3d6 rolls to use the option "Critical Successes: Use rules as written", instead of just skill and combat rolls. Reported by Mike W</li>
<li>All tables: When modifying tables, delete button fits on row and the move button is more accessible and easier to use.</li>
<li>
Skill, Melee Attacks, Range Attacks, and Inventory tables: Added checkbox to highlight the row.
Requested by Larry R. NOTE: Future updates will allow ability to select color.
</li>
<li>
By default, Wound Modifier Notes have been turned off by default. This can be changed by editing your character sheets default settings
on the campaign page.
</li>
<li>Combat Tab: Added Combat Tools Heading</li>
<li>Combat Tab: Added Range Calculator</li>
<li>General Tab: Fright check threshold wasn't showing the final modified total. Fixed. Reported by Ray G</li>
</ul>
<h4>Version: 1.5.5
</h4>
<p>Pull Request: 4/2/2019</p>
<ul>
<li>Changed title of Damage Type Notes to Wound Modifier Notes.</li>
<li>Rolltemplates: Remove RoF. and Reach. Style updates</li>
<li>Corrected a spelling error for encumbrance. Spotted by Larry R</li>
<li>Combat tab: Added Rapid Fire Table, image provided by Mike W.</li>
<li>Updated the default character sheet options to use drop-down lists.</li>
</ul>
<h4>Version: 1.5.4
</h4>
<p>Pull Request: 3/26/2019</p>
<ul>
<li>Changed title of Damage Type Notes to Wound Modifier Notes.</li>
<li>Changed Speed Add To Tracker to use rolltemplates.</li>
<li>Added Thrown Object based on weight on combat tab below Ranged Attacks.</li>
<li>Added Bio tab. For Misc. Information, Physical Description, Background information.</li>
<li>Updated General tab. Replaced Miscellaneous box with a notes text box</li>
<li>Inventory tab. Cosmetic update to text box to remove scroll bar.</li>
<li>Options tab. Reduced font-size for Wound Modifier Notes text boxes.</li>
<li>Roll templates. Reduced font-size for results.</li>
<li>Delete old update notices</li>
<li>Updates tab. Highlight "mark updates as read" checkbox</li>
<li>Grimoire Tab. Tweak Spells based on: heading area. Added spacing</li>
</ul>
<h4>Version: 1.5.3</h4>
<p>Pull Request: 03/12/2019</p>
<ul>
<li>Changes, Fixes, and Adds made by Mike W (UserID: 1414610)</li>
<li>Changed Damage Type into alphabetical select order for Melee and Ranged Attacks in the ToolTips aand Dropdown – Cosmetic Only</li>
<li>Changed the term Fear Check to Fright Check in the Fright Check Roll Template and the ToolTip – Cosmetic Only</li>
<li>Changed the tern Fear to Fright under Active Defenses for the Combat Reflexes option – Cosmetic Only</li>
</ul>
<h4>Version: 1.5.2</h4>
<p>Pull Request: 02/20/2019</p>
<ul>
<li>Fixed rounding bug with flight move. Updated Air move column to hide enhanced move if there's no enhanced move.</li>
<li>Added condition rolls: Unstun, Knockdown, Unconscious, and Death Checks.</li>
<li>Added ability to turn off damage type notes.</li>
<li>Added ability to edit damage type notes.</li>
<li>Added Critical Successes option: Turn off</li>
<li>[Experimental] Added default sheet options. Can only be tested after deployment.</li>
<li>Tweak some spacing</li>
</ul>
<h4>Version: 1.5.1</h4>
<p>Pull Request: 02/11/2019</p>
<ul>
<li>Added attributes for enhanced ground movement, flying, swimming, and jumping</li>
<li>Added encumbrance columsn for enhanced ground movement, flying, and swimming</li>
<li>Added roll template templates. Shows success/error on rolls. Shows critical success or fail.</li>
<li>Modified option for private/public rolls. NOTE: Roll templates do not support showing just skill.</li>
<li>
Added option for private/public speed button. NOTE: If token is not selected,
it show an error to select token in order to add character to the order tracker
</li>
<li>Added option to use Skill+10 for critical success or just use 3 or 4 for critical success</li>
<li>Added option to mark updates as read. If marked, last tab visited will be opened instead of the updates tab.</li>
</ul>
<h4>Version: 1.5.0</h4>
<p>Pull Request: 02/05/2019</p>
<ul>
<li>Changes, Fixes, and Adds made by Mike W (UserID: 1414610)</li>
<li>Fixed alert indicating to use a valid 3 decimal Weight value for the Inventory weight attribute, which in fact can up to 4 decimal places, Reported by Ray G (@raymond-g) (UserID: 1600355</li>
<li>Fixed Inventory header alignment – Cosmetic Only</li>
<li>Fixed Inventory calculations color bacground – Cosetic Only</li>
</ul>
</div>
</div> <!-- .sheet-tab7 -->
<div class="sheet-tab0">
<div class="sheet-options">
<div class="sheet-box">
<input type="radio" name="attr_modifier" value="0" />
<span class="sheet-popup">No Modifier Prompt</span>
<span class="sheet-tooltip">
Rolls will be made immediately with no prompt.
</span>
<br /><input type="radio" name="attr_modifier" value="[[?{Modifier|0}]]" checked="true" />
<span class="sheet-popup">Single Modifier Prompt</span>
<span class="sheet-tooltip">
Ask for a bonus or penalty to be added to dice rolls.
<br />
This will not affect damage rolls.
</span>
<br />
<input type="radio" name="attr_modifier" value="[[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]]" />
<span class="sheet-popup">Extended Modifier Prompts</span>
<span class="sheet-tooltip">
Instead of a single modifier, rolls will ask for a series of modifiers,<br />
to remind you about potential bonuses/penalties.
<br />
This will not affect damage rolls.
</span>
</div>
<div>
<div class="sheet-box">
<input type="radio" name="attr_roll" value="" checked="true" />
<span class="sheet-popup">Public Rolls</span>
<span class="sheet-tooltip">
All players will be able to see<br />
your skill level, roll and results.
</span>
<br />
<input type="radio" name="attr_roll" value="/w gm --l " />
<span class="sheet-popup">Private Skill Levels <em>deprecated</em></span>
<span class="sheet-tooltip">
Only the GM will be able to see<br />
your skill level, but all players<br />
will see the result.<br />
<b>NOTE:</b> This now behaves just like Private Rolls
</span>
<br />
<input type="radio" name="attr_roll" value="/w gm " />
<span class="sheet-popup">Private Rolls</span>
<span class="sheet-tooltip">
Only the GM will see your skill<br />
level and the result.
</span>
</div>
<div class="sheet-box">
<input type="radio" name="attr_speed_tracker" value="/em" checked="true" />
<span class="sheet-popup">Public Speed Tracker</span>
<span class="sheet-tooltip">
Show basic speed and add to Chat message to public.
</span>
<br />
<input type="radio" name="attr_speed_tracker" value="/w gm" />
<span class="sheet-popup">Private Speed Tracker</span>
<span class="sheet-tooltip">
Show basic speed and add to Chat message to GM.
</span>
</div>
</div>
<div class="sheet-box">
<div>
<input type="checkbox" name="attr_use_unspent_box" class="sheet-manual-unspent-box" value="1" />
<span class="sheet-popup">Enter Unspent Points</span>
<span class="sheet-tooltip">Check if you would like to manually track your unspent points</span>
</div>
<div>
<input type="checkbox" name="attr_use_malfunction" class="sheet-manual-unspent-box" value="1" />
<span class="sheet-popup">Use Malfunction</span>
<span class="sheet-tooltip">If checked, roll results will check for malfunction.</span>
</div>
</div>
<div class="sheet-box">
Damage Dice Icon
<div>
<input type="radio" name="attr_damage_dice_type" value="explode" checked="true" />
<button type="roll" value="0" name="btn_damage_dice_explode" class="roll_explode btn" disabled="disabled" />
</div>
<div>
<input type="radio" name="attr_damage_dice_type" value="d6black" />
<button type="roll" value="0" name="btn_damage_dice_d6black" class="btn" disabled="disabled" />
</div>
<div>
<input type="radio" name="attr_damage_dice_type" value="d20blank" />
<button type="roll" value="0" name="btn_damage_dice_d20blank" class="btn roll_d20blank" disabled="disabled" />
</div>
<div>
<input type="radio" name="attr_damage_dice_type" value="d4skull" />
<button type="roll" value="0" name="btn_damage_dice_d4skull" class="btn roll_d4skull" disabled="disabled" />
</div>
</div>
<hr />
<div class="sheet-box">
<input type="radio" name="attr_mod_cascade" value="all" checked="true" />
<span class="sheet-popup">Mods to attributes increase all derived stats (including HP, FP)</span>
<br />
<input type="radio" name="attr_mod_cascade" value="some" />
<span class="sheet-popup">Mods to attributes increase most derived stats (not HP, FP)</span>
<br />
<input type="radio" name="attr_mod_cascade" value="none" />
<span class="sheet-popup">Mods to attributes do not increase derived stats</span>
</div>
<div class="sheet-box">
<table>
<tr>
<td>
Penalty for each spell <b>ON:</b>
</td>
<td>
<input type="number" step="1" value="-1" name="attr_penalty_per_spell_on"></input>
</td>
</tr>
<tr>
<td>
Penalty for each spell <b>Maintained:</b>
</td>
<td>
<input type="number" step="1" value="-3" name="attr_penalty_per_spell_maintained"></input>
</td>
</tr>
</table>
</div>
<div class="sheet-box">
<span><b>Critical Successes:</b></span><br />
<input type="radio" name="attr_use_critical_plus_10" value="1" checked="checked" />
<span class="sheet-popup">Use rules as written</span>
<br />
<input type="radio" name="attr_use_critical_plus_10" value="0" />
<span class="sheet-popup">Only on a 3 or 4</span>
<br />
<input type="radio" name="attr_use_critical_plus_10" value="2" />
<span class="sheet-popup">Turn Off</span>
</div>
<div class="box collision-falling-options">
<span class="label">Falling & Collision Damage Notes</span><br />
<textarea name="attr_falling_collision_damage_notes">Collisions: If an object is bullet-shaped, sharp, or spiked, it does half damage, but this damage is piercing, cutting, or impaling, rather than crushing.
Falling Damage: If using hit locations, roll randomly for the hit location damaged in a fall. If the injury is to an extremity or a limb, do not ignore injury in excess of that required to cripple it. Instead, subtract the full amount from HP! If the fall would cripple a limb, roll 1d. On 5-6, all limbs of that type are crippled, although there is no extra injury. B431</textarea>
</div>
<hr />
<div>
<h2>Editable Notes</h2>
<div class="toggle-notes">
<input type="checkbox" name="attr_use_damage_type_notes" class="sheet-manual-unspent-box" value="1" />
<span class="sheet-popup">Show notes in roll template</span>
</div>
</div>
<div class="box damage-type-notes">
<h3>Editable Wound Modifier Notes</h3>
<div>Initial wound modifier notes based on GURPS 4th Edition - Campaigns</div>
<table>
<tr>
<th>Type</th>
<th>Notes</th>
</tr>
<tr>
<td>Cutting</td>
<td>
<textarea name="attr_damage_type_note_cut">CUTTING
Damage x1.5
Neck Damage x2
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>Impaling</td>
<td>
<textarea name="attr_damage_type_note_imp">IMPALING
Damage x2
Arm, Leg, Foot, or Hand x1 (B399)
Vitals Damage x3
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>Crushing</td>
<td>
<textarea name="attr_damage_type_note_cr">Damage x1
Neck Damage x1.5
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>PI-</td>
<td>
<textarea name="attr_damage_type_note_pi_minus">Damage x .5
Vitals Damage x3
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>PI</td>
<td>
<textarea name="attr_damage_type_note_pi">Damage x1
Vitals Damage x3
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>PI+</td>
<td>
<textarea name="attr_damage_type_note_pi_plus">Damage x1.5
Arm, Leg, Foot, or Hand x1 (B399)
Vitals Damage x3
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>PI++</td>
<td>
<textarea name="attr_damage_type_note_pi_plus_plus">Damage x2
Arm, Leg, Foot, or Hand x1 (B399)
Vitals Damage x3
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>Affliction</td>
<td>
<textarea name="attr_damage_type_note_aff">special damage and affects based on affliction description</textarea>
</td>
</tr>
<tr>
<td>Burn</td>
<td>
<textarea name="attr_damage_type_note_burn">Damage x1
Skull Damage x4</textarea>
</td>
</tr>
<tr>
<td>Corrosion</td>
<td>
<textarea name="attr_damage_type_note_cor">Damage x1
Face Damage x1.5, blind eye if major wound, both eyes if full HP
Neck Damage x1.5
Skull Damage x4
-1 DR per 5 of points damage</textarea>
</td>
</tr>
<tr>
<td>Fatigue</td>
<td>
<textarea name="attr_damage_type_note_fat">Damage x1</textarea>
</td>
</tr>
<tr>
<td>Toxic</td>
<td>
<textarea name="attr_damage_type_note_tox">Damage x1</textarea>
</td>
</tr>
<tr>
<td>Special</td>
<td>
<textarea name="attr_damage_type_note_spec">See notes for weapon.</textarea>
</td>
</tr>
</table>
</div>
<div class="box damage-type-notes">
<h3>Defensive Notes</h3>
<div>
<h4>Parry</h4>
<textarea class="defensive-notes" name="attr_defensive_parry_notes">Parrying heavy weapon, see B376<br />
Attack weapon's weight is...<br />
3X heavier: 2 in 6 break<br />
4X heavier: 3 in 6 break<br />
5X heavier: 4 in 6 break<br />
6X heavier: 5 in 6 break<br />
7X heavier: 6 in 6 break<br />
8X+ heavier: 7 in 6 break & parry fails<br />
Unarmed Weight = 1/10 ST score<br />
Slam/Flying tackle/Pounce/Shield Rush = ST Score<br />
Cheap Weapon: +2 break<br />
Fine Weapon: -1 break<br />
Very Fine: -2 break<br />
<hr class="border" />
No Parry allowed if weapon weight is...<br />
> Basic Lift and parry is 1-handed/unarmed<br />
> 2X Basic Lift and parry is 2-handed<br />
If weapon doesn't break, it is knocked away<br />
If unarmed, knockback 1-yard, DX save<br />
<hr class="border" />
Unarmed parry...<br />
Judo/Karate no penalty<br />
Otherwise -3 to parry, except thrust<br />
If fail, attacker can opt to hit limb<br /></textarea>
</div>
</div>
</div>
</div>
<!-- ===== ===== ===== ===== LOGO ===== ===== ===== ===== -->
<div class="logo">
<hr />
<div class="control">
<button type="roll" class="no-decoration" name="roll_blank" value="https://wiki.roll20.net/GURPS_4th_Edition" title="Show link in chat. NOTE: Right-click to open in new window">
GURPS 4th Edition Roll20 Wiki Page
</button>
</div>
<h3> Your feedback is most welcomed! See link below.</h3>
<div class="control">
<button type="roll" class="no-decoration" name="roll_blank" value="https://app.roll20.net/forum/post/6616836/gurps-sheet-number-1-thread-1/" title="Show link in chat. NOTE: Right-click to open in new window">
Roll20 Forum - [GURPS] - Sheet #1 - Thread 1
</button>
</div>
</div>
</div>
<!-- ROLL TEMPLATES -->
<div class="rolltemplates">
<rolltemplate class="sheet-rolltemplate-addToTracker">
<div class="container">
<table class="result">
<tr>
<th colspan="2">{{characterName}}</th>
</tr>
<tr>
<td colspan="2" class="subhead">{{skillName}}</td>
</tr>
<tr>
<td class="label">Speed:</td>
<td>{{basicSpeed}}</td>
</tr>
</table>
</div>
</rolltemplate>
<rolltemplate class="sheet-rolltemplate-skillRoll">
<div class="container">
<table class="result">
<tr>
<th colspan="2">{{characterName}}</th>
</tr>
<tr>
<td colspan="2" class="subhead">{{skillName}}</td>
</tr>
{{#type}}
<tr>
<td class="label">Type:</td>
<td>
{{type}}
{{#bookReference}}
<span class="ref-label"><b>Ref:</b> {{bookReference}}</span>
{{/bookReference}}
</td>
</tr>
{{/type}}
{{#rollResult}}
<tr>
<td class="label">Roll:</td>
<td>
<!-- WARNING THIS IS GOING TO GET GET UGLY AND HARD TO FOLLOW -->
<!-- NOTE: Regardless of the score you are rolling against, -->
<!-- a roll of 3 or 4 is always a success, while a roll of 17 or 18 is always a failure. -->
<!-- Roll of 18 is always critical failure -->
{{#rollTotal() rollResult 18}}
<span class="failure">
{{rollResult}}
<span class="failure-text">
{{#showHitLabel}}Critical Miss{{/showHitLabel}}
{{#showSuccessLabel}}Critical Failure{{/showSuccessLabel}}
</span>
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>If you get a critical miss on a parry, roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical failure note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
</span>
{{/rollTotal() rollResult 18}}
<!-- Roll of 17 is always a failure -->
{{#rollTotal() rollResult 17}}
<span class="failure">
{{rollResult}}
<span class="failure-text">
<!-- skill of 15 or less is critical -->
{{#rollLess() effectiveSkill 16}}Critical{{/rollLess() effectiveSkill 16}}
{{#showHitLabel}}Miss{{/showHitLabel}}
{{#showSuccessLabel}}Failure{{/showSuccessLabel}}
</span>
<!-- skill of 16 or higher is normal failure, add helper text -->
{{#rollGreater() effectiveSkill 15}}
<!-- block custom failure note -->
{{#customFailNote}}
<p>{{customFailNote}}</p>
{{/customFailNote}}
{{/rollGreater() effectiveSkill 15}}
<!-- skill of 15 or less is critical, add helper text -->
{{#rollLess() effectiveSkill 16}}
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>Roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical failure note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
{{/rollLess() effectiveSkill 16}}
</span>
{{/rollTotal() rollResult 17}}
<!-- A roll of 3 or 4 always succeeds -->
{{#rollBetween() rollResult 3 4}}
<span class="success">
{{rollResult}}
<span class="success-text">
<!-- if critical success is turned on, show text -->
{{#rollLess() useCriticalPlusTen 2}}Critical{{/rollLess() useCriticalPlusTen 2}}
{{#showHitLabel}}Hit{{/showHitLabel}}
{{#showSuccessLabel}}Success{{/showSuccessLabel}}
</span>
<!-- normal success area -->
{{#rollTotal() useCriticalPlusTen 2}}
<!-- block custom success note -->
{{#customSuccessNote}}
<p>{{customSuccessNote}}</p>
{{/customSuccessNote}}
{{/rollTotal() useCriticalPlusTen 2}}
<!-- Check if Critical Success was turned on -->
<!-- attr_use_critical_plus_10: 0 = only on 3 or 4, 1 = rules as written, 2 = turn off -->
{{#rollLess() useCriticalPlusTen 2}}
<!-- show notes for critical success on active defense -->
{{#rollTotal() activeDefense 1}}
<p>If defending against a melee attack, then your foe goes immediately to the Critical Miss Table (B556). (B381)</p>
{{/rollTotal() activeDefense 1}}
<!-- block custom critical success note -->
{{#customCriticalSuccessNote}}
<p>{{customCriticalSuccessNote}}</p>
{{/customCriticalSuccessNote}}
{{/rollLess() useCriticalPlusTen 2}}
</span>
{{/rollBetween() rollResult 3 4}}
<!-- Roll from 5 to 16 means we have a chance at hit or miss -->
<!-- NOTE: A roll of 3 or 4 always succeeds, handled above -->
{{#rollBetween() rollResult 5 16}}
<!-- Check for failure, where roll is greaten than effective skill -->
{{#rollGreater() rollResult effectiveSkill}}
<span class="failure">
{{rollResult}}
<span class="failure-text">
<!-- if effective skill is 3 or less, critical failure is 13 or higher -->
{{#rollLess() effectiveSkill 4}}
{{#rollGreater() rollResult 12}}Critical{{/rollGreater() rollResult 12}}
{{/rollLess() effectiveSkill 4}}
<!-- if effective skill is 4, critical failure is 14 or higher -->
{{#rollTotal() effectiveSkill 4}}
{{#rollGreater() rollResult 13}}Critical{{/rollGreater() rollResult 13}}
{{/rollTotal() effectiveSkill 4}}
<!-- if effective skill is 5, critical failure is 15 or higher -->
{{#rollTotal() effectiveSkill 5}}
{{#rollGreater() rollResult 14}}Critical{{/rollGreater() rollResult 14}}
{{/rollTotal() effectiveSkill 5}}
<!-- if effective skill is 6, critical failure is 16 or higher -->
{{#rollTotal() effectiveSkill 6}}
{{#rollGreater() rollResult 15}}Critical{{/rollGreater() rollResult 15}}
{{/rollTotal() effectiveSkill 6}}
<!-- if effective skill is 7 to 15, critical failure is 17 or 18 -->
{{#rollBetween() effectiveSkill 7 15}}
{{#rollGreater() rollResult 16}}Critical{{/rollGreater() rollResult 16}}
{{/rollBetween() effectiveSkill 7 15}}
<!-- NOTE: Roll of 18 check has already been made -->
{{#showHitLabel}}Miss{{/showHitLabel}}
{{#showSuccessLabel}}Fail{{/showSuccessLabel}}
</span>
<!-- additional critical failure text -->
<!-- if effective skill is 3 or less, critical failure is 13 or higher -->
{{#rollLess() effectiveSkill 4}}
<!-- normal failure -->
{{#rollLess() rollResult 13}}
<!-- block custom fail note -->
{{#customFailNote}}
<p>{{customFailNote}}</p>
{{/customFailNote}}
{{/rollLess() rollResult 13}}
<!-- critical failure -->
{{#rollGreater() rollResult 12}}
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>Roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical fail note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
{{/rollGreater() rollResult 12}}
{{/rollLess() effectiveSkill 4}}
<!-- if effective skill is 4, critical failure is 14 or higher -->
{{#rollTotal() effectiveSkill 4}}
<!-- normal failure -->
{{#rollLess() rollResult 15}}
<!-- block custom fail note -->
{{#customFailNote}}
<p>{{customFailNote}}</p>
{{/customFailNote}}
{{/rollLess() rollResult 15}}
<!-- critical failure -->
{{#rollGreater() rollResult 13}}
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>Roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical fail note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
{{/rollGreater() rollResult 13}}
{{/rollTotal() effectiveSkill 4}}
<!-- if effective skill is 5, critical failure is 15 or higher -->
{{#rollTotal() effectiveSkill 5}}
<!-- normal failure -->
{{#rollLess() rollResult 15}}
<!-- block custom fail note -->
{{#customFailNote}}
<p>{{customFailNote}}</p>
{{/customFailNote}}
{{/rollLess() rollResult 15}}
<!-- critical failure -->
{{#rollGreater() rollResult 14}}
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>Roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical fail note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
{{/rollGreater() rollResult 14}}
{{/rollTotal() effectiveSkill 5}}
<!-- if effective skill is 6, critical failure is 16 or higher -->
{{#rollTotal() effectiveSkill 6}}
<!-- normal failure -->
{{#rollLess() rollResult 16}}
<!-- block custom fail note -->
{{#customFailNote}}
<p>{{customFailNote}}</p>
{{/customFailNote}}
{{/rollLess() rollResult 16}}
<!-- critical failure -->
{{#rollGreater() rollResult 15}}
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>Roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical fail note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
{{/rollGreater() rollResult 15}}
{{/rollTotal() effectiveSkill 6}}
<!-- if effective skill is 7 to 15, critical failure is 17 or 18 -->
{{#rollBetween() effectiveSkill 7 15}}
<!-- normal failure -->
{{#rollLess() rollResult 17}}
<!-- block custom fail note -->
{{#customFailNote}}
<p>{{customFailNote}}</p>
{{/customFailNote}}
{{/rollLess() rollResult 17}}
<!-- critical failure -->
{{#rollGreater() rollResult 16}}
<!-- dodge critical failure -->
{{#rollTotal() defenseType 1}}
<p>Lose your footing and fall prone. (B382)</p>
{{/rollTotal() defenseType 1}}
<!-- parry critical failure -->
{{#rollTotal() defenseType 2}}
<p>Roll on the appropriate Critical Miss Table B556. (B382). Apply the result immediately.</p>
{{/rollTotal() defenseType 2}}
<!-- block critical failure -->
{{#rollTotal() defenseType 3}}
<p>You lose your grip on whatever you were Blocking with and must take a turn to ready it before you can use it to block again. (B382)</p>
{{/rollTotal() defenseType 3}}
<!-- block custom critical fail note -->
{{#customFailNote}}
<p><span class="failure-note-label">Fail:</span> {{customFailNote}}</p>
{{/customFailNote}}
{{#customCriticalFailNote}}
<p><span class="failure-note-label">Crit:</span> {{customCriticalFailNote}}</p>
{{/customCriticalFailNote}}
{{/rollGreater() rollResult 16}}
{{/rollBetween() effectiveSkill 7 15}}
</span>
{{/rollGreater() rollResult effectiveSkill}}
<!-- check for success, roll from 5 to effective skill -->
<!-- NOTE: roll 3 or 4 has already been handled -->
{{#rollBetween() rollResult 5 effectiveSkill}}
<span class="success">
{{rollResult}}
<span class="success-text">
<!-- Check if Critical Success was turned on -->
<!-- attr_use_critical_plus_10: 0 = only on 3 or 4, 1 = rules as written, 2 = turn off -->
{{#rollLess() useCriticalPlusTen 2}}
<!-- If rules as written -->
{{#rollTotal() useCriticalPlusTen 1}}
<!-- if effective sKill is 16 or higher, check for critical success on a 6 -->
{{#rollGreater() effectiveSkill 15}}
{{#rollTotal() rollResult 6}}Critical{{/rollTotal() rollResult 6}}
{{#rollTotal() rollResult 5}}Critical{{/rollTotal() rollResult 5}}
{{/rollGreater() effectiveSkill 15}}
<!-- If rules as written and if effectiveSKill is 15, check for critical success on a 5 -->
{{#rollTotal() effectiveSkill 15}}
{{#rollTotal() rollResult 5}}Critical{{/rollTotal() rollResult 5}}
{{/rollTotal() effectiveSkill 15}}
{{/rollTotal() useCriticalPlusTen 1}}
{{/rollLess() useCriticalPlusTen 2}}
{{#showHitLabel}}Hit{{/showHitLabel}}
{{#showSuccessLabel}}Success{{/showSuccessLabel}}
</span>
<!-- check if critical success is off -->
<!-- attr_use_critical_plus_10: 0 = only on 3 or 4, 1 = rules as written, 2 = turn off -->
{{#rollTotal() useCriticalPlusTen 2}}
<!-- block custom success note -->
{{#customSuccessNote}}
<p>{{customSuccessNote}}</p>
{{/customSuccessNote}}
{{/rollTotal() useCriticalPlusTen 2}}
<!-- Check if Critical Success was turned on -->
<!-- attr_use_critical_plus_10: 0 = only on 3 or 4, 1 = rules as written, 2 = turn off -->
<!-- show additional notes -->
{{#rollLess() useCriticalPlusTen 2}}
<!-- If rules as written -->
{{#rollTotal() useCriticalPlusTen 1}}
<!-- if effective skill is less than 15, then show success note -->
{{#rollLess() effectiveSkill 15}}
<!-- block custom success note -->
{{#customSuccessNote}}
<p>{{customSuccessNote}}</p>
{{/customSuccessNote}}
{{/rollLess() effectiveSkill 15}}
<!-- if effective sKill is 16 or higher, check for critical success on a 6 -->
{{#rollGreater() effectiveSkill 15}}
<!-- normal success -->
{{#rollGreater() rollResult 6}}
<!-- block custom success note -->
{{#customSuccessNote}}
<p>{{customSuccessNote}}</p>
{{/customSuccessNote}}
{{/rollGreater() rollResult 6}}
<!-- critical success -->
{{#rollBetween() rollResult 5 6}}
<!-- show notes for critical success on active defense -->
{{#rollTotal() activeDefense 1}}
<p>If defending against a melee attack, then your foe goes immediately to the Critical Miss Table (B556). (B381)</p>
{{/rollTotal() activeDefense 1}}
<!-- block custom critical success note -->
{{#customCriticalSuccessNote}}
<p>{{customCriticalSuccessNote}}</p>
{{/customCriticalSuccessNote}}
{{/rollBetween() rollResult 5 6}}
{{/rollGreater() effectiveSkill 15}}
<!-- If rules as written and if effectiveSKill is 15, check for critical success on a 5 -->
{{#rollTotal() effectiveSkill 15}}
<!-- normal success -->
{{#rollGreater() rollResult 5}}
<!-- block custom success note -->
{{#customSuccessNote}}
<p>{{customSuccessNote}}</p>
{{/customSuccessNote}}
{{/rollGreater() rollResult 5}}
<!-- critical success -->
{{#rollTotal() rollResult 5}}
<!-- show notes for critical success on active defense -->
{{#rollTotal() activeDefense 1}}
<p>If defending against a melee attack, then your foe goes immediately to the Critical Miss Table (B556). (B381)</p>
{{/rollTotal() activeDefense 1}}
<!-- block custom critical success note -->
{{#customCriticalSuccessNote}}
<p>{{customCriticalSuccessNote}}</p>
{{/customCriticalSuccessNote}}
{{/rollTotal() rollResult 5}}
{{/rollTotal() effectiveSkill 15}}
{{/rollTotal() useCriticalPlusTen 1}}
{{/rollLess() useCriticalPlusTen 2}}
</span>
{{/rollBetween() rollResult 5 effectiveSkill}}
{{/rollBetween() rollResult 5 16}}
</td>
</tr>
{{/rollResult}}
{{#effectiveSkill}}
<tr>
<td class="label">Target:</td>
<td class="effective-skill">
{{effectiveSkill}}
{{#useFrightLabel}}
<i>Fright Threshold</i>
{{/useFrightLabel}}
<!-- If defense roll, check for effective skill below 1 -->
{{#rollTotal() activeDefense 1}}
{{#rollLess() effectiveSkill 1}}
<div style="color: red; margin-top: 6px;">WARNING: Final Target is less than 1. Defense roll is not possible. Ref B345</div>
{{/rollLess() effectiveSkill 1}}
{{/rollTotal() activeDefense 1}}
<!-- For other rolls, check for effective skill below 3 -->
{{#rollTotal() activeDefense 0}}
{{#rollLess() effectiveSkill 3}}
<div style="color: red; margin-top: 6px;">WARNING: Final Target is less than 3. Roll is not possible. Ref B374</div>
{{/rollLess() effectiveSkill 3}}
{{/rollTotal() activeDefense 0}}
</td>
</tr>
{{/effectiveSkill}}
{{#useMalfunction}}
{{#rollGreater() malfunction 0}}
{{#rollBetween() rollResult malfunction 18}}
<tr>
<td colspan="2">
<span style="color: red; font-weight:bold;">Malfunction!</span><br />
{{#rollTotal() verifyMalfunction 1}}
<span style="color: red; font-weight:bold;">Verify!</span> roll 3d6 again to verify the results. See HT79.<br />
{{/rollTotal() verifyMalfunction 1}}
For effect, Roll 3d6 and see table on B407 or use custom table.<br />
<b style="color:red;">NOTE:</b> Malfunction has "priority" over a critical miss: if both would occur,
only the malfunction takes place. Critical Misses, Basic Set, page 382.
</td>
</tr>
{{/rollBetween() rollResult malfunction 18}}
{{/rollGreater() malfunction 0}}
{{/useMalfunction}}
{{#damageRoll}}
<tr>
<td class="label">Damage:</td>
<td class="damage-roll">
{{damageRoll}} <span class="damageType">{{damageType}}</span>
</td>
</tr>
{{#minDamageNote}}
<tr>
<td class="label">Minimum:</td>
<td class="damage-roll">
{{minDamageNote}}<br />
See B378 <b>Damage Roll</b>
</td>
</tr>
{{/minDamageNote}}
{{/damageRoll}}
{{#rollTotal() useDamageTypeNotes 1}}
{{#damageTypeNote}}
<tr>
<td colspan="2"><span>{{damageTypeNote}}</span></td>
</tr>
{{/damageTypeNote}}
{{/rollTotal() useDamageTypeNotes 1}}
{{#rollTotal() showNotes 1}}
{{#notes}}
<tr>
<td colspan="2">{{notes}}</td>
</tr>
{{/notes}}
{{/rollTotal() showNotes 1}}
{{#rollTotal() defenseType 2}}
{{#notes}}
<tr>
<td colspan="2">
<span name="attr_defensive_parry_notes"></span>
</td>
</tr>
{{/notes}}
{{/rollTotal() defenseType 2}}
{{#castingTime}}
<tr>
<td class="label">Time:</td>
<td>{{castingTime}}</td>
</tr>
{{/castingTime}}
{{#castingDuration}}
<tr>
<td class="label">Duration:</td>
<td>{{castingDuration}}</td>
</tr>
{{/castingDuration}}
{{#castingCost}}
<tr>
<td class="label">Cost:</td>
<td>{{castingCost}}</td>
</tr>
{{/castingCost}}
{{#castingMaintain}}
<tr>
<td class="label">Maintain:</td>
<td>{{castingMaintain}}</td>
</tr>
{{/castingMaintain}}
{{#castingResist}}
<tr>
<td class="label">Resisted by:</td>
<td>{{castingResist}}</td>
</tr>
{{/castingResist}}
{{#castingClass}}
<tr>
<td class="label">Class:</td>
<td>{{castingClass}}</td>
</tr>
{{/castingClass}}
{{#recoil}}
<tr>
<td colspan="2">
<span class="title">Recoil: </span>{{recoil}}
{{#rollGreater() malfunction 0}}
<span class="title">Malf: </span>{{malfunction}}
{{/rollGreater() malfunction 0}}
</td>
</tr>
{{/recoil}}
</table>
</div>
</rolltemplate>
</div>
<script type="text/worker">
var noop = function () {}; // do nothing.
var version = "1.7.0";
var latestChangesDate = "11/19/2019";
var modCascade = true;
var modCascadeAll = true;
// add global variable
var damageTable = [];
// caching technique. Store skill row ids and attack rows ids,
// avoids looping through repeating tables to get matching row.
var skillRowIds = [];
var weaponRowIds = [];
const decelerationDivisor = 2;
// see: https://app.roll20.net/forum/post/7251390/slug%7D
const modBySpeedRange = [
{r:1, m:0},
{r:2, m:0},
{r:3, m:-1},
{r:5, m:-2},
{r:7, m:-3},
{r:10, m:-4},
{r:15, m:-5},
{r:20, m:-6},
{r:30, m:-7},
{r:50, m:-8},
{r:70, m:-9},
{r:100, m:-10},
{r:150, m:-11},
{r:200, m:-12},
{r:300, m:-13},
{r:500, m:-14},
{r:700, m:-15},
{r:1000, m:-16},
{r:1500, m:-17},
{r:2000, m:-18},
{r:3000, m:-19},
{r:5000, m:-20},
{r:7000, m:-21},
{r:10000, m:-22},
{r:15000, m:-23},
{r:20000, m:-24}
];
/**
* Create global function
* use: var mod = getModBySpeedRange(14);
* Uses the array of json object objects
* to get the modifier based on speed/range
**/
const getModBySpeedRange = (d) => {
// find first matching entry where range is greater than distance
// Distance = 4, first entry where range is greater than 4.
// Range = 5, which is greater than 4. return that object. Modifier = -2
const entry = modBySpeedRange.find((o)=>o.r>=d );
// if no matches, return -24.
return (entry != undefined ? entry.m : -24);
};
/* Due to the change from auto-calc fields to helper scrips,
* I'm running a "on open" to set various fields. At some point
* in the future this might no longer be needed.
*/
on('sheet:opened', function() {
console.log('********* Sheet Opened *********');
setSkillRowIds();
setWeaponRowIds();
setAttrs({inventory_fixed_digits: 1});
sumRepeating('repeating_item', 'weighttotal', function(v) {
setAttrs({ total_weight: Number(Math.round(v * 1000) / 1000).toFixed(3) });
});
sumRepeating('repeating_item', 'costtotal', function(v) {
setAttrs({ total_value: Number((v * 100) / 100).toFixed(2) });
});
getAttrs(['modifier'], function(v){
const setObj = {};
if(v.modifier==='?{Modifier|0}'){
setObj.modifier = '[[?{Modifier|0}]]'
}else if(v.modifier==='?{Modifier|0} + ?{Shock|0} + ?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0}'){
setObj.modifier = '[[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]]'
}
setAttrs(setObj,{silent:true});
});
getAttrs(['sheet_version', 'mod_cascade', 'modCascade', 'modCascadeAll'], function(v) {
if (v.modCascade && v.modCascadeAll) {
modCascade = v.modCascade;
modCascadeAll = v.modCascadeAll;
}
if (!v.sheet_version || v.sheet_version != version) {
// Set sheet version:
// show announcements div
setAttrs({
sheet_version: version,
announcement_version: version,
latest_changes: latestChangesDate,
announcements_hide: 0,
announcements_show: 0
});
// initialize any empty fields in repeating sections since the default values were removed.
loadRepeating('repeating_languages', 'spoken', 0);
loadRepeating('repeating_languages', 'written', 0);
loadRepeating('repeating_skills', 'points', 1);
loadRepeating('repeating_cultures', 'points', 1);
loadRepeating('repeating_techniques', 'points', 1);
loadRepeating('repeating_spells', 'points', 1);
// initalize all calculated stats
resetAll(v.mod_cascade);
}
});
damageTable = generateDamageTable();
});
on('change:mod_cascade', function (e) {
getAttrs(['mod_cascade'], function (v) {
resetAll(v.mod_cascade);
})
});
function resetAll(mod_cascade) {
switch(mod_cascade) {
case 'all':
modCascade = true;
modCascadeAll = true;
break;
case 'some':
modCascade = true;
modCascadeAll = false;
break;
default:
modCascade = false;
modCascadeAll = false;
}
setAttrs({
modCascade: modCascade,
modCascadeAll: modCascadeAll
});
// last thing to update is movement
var thenMovementStats = _.after(1, function () {
// last thing to update is movement tables
updateToggleUnspentCheckBox();
updateDiceDamageIcons();
updateEnhancedMove();
updateFlightValues();
updateWaterMoveValues();
updateJumpDistanceValues();
// update conditions
updateHealthConditionChecks();
});
// After move, dodge, encumbrance, HP, and FP
var thenCurrentMoveDodge = _.after(2, function () {
updateMoveDodge(thenMovementStats);
});
// After DX and HT
var thenSpeedMoveDodge = _.after(2, function () {
updateBasicSpeed(function () {
// After Basic Speed...
updateBasicMove(thenCurrentMoveDodge);
updateDodge(thenCurrentMoveDodge);
});
});
// After Lift and weight...
var thenEncumbrance = _.after(2, function () {
updateEncLevel(thenCurrentMoveDodge);
});
// After Striking st damage
var thenUpdateThrownObjectStats = _.after(1, function() {
updateThrownObjectStats();
});
sumRepeating('repeating_item', 'weighttotal', function (v) {
setAttrs({ total_weight: Math.round(v * 1000) / 1000 }, {silent: false}, thenEncumbrance);
});
// Update attributes, then secondary characteristics, and so on...
updateST(function () {
// After ST...
updateHP(thenCurrentMoveDodge);
updateLift(thenEncumbrance);
updateStrikingST();
// updateStrikingST damage rolls
// after completed, then update thrown object
updateStrikingStrengthDamage(thenUpdateThrownObjectStats);
});
updateDX(thenSpeedMoveDodge);
updateIQ(function () {
// After IQ...
updateWill();
updatePer(function () {
// After Per...
updateSense();
});
});
updateHT(function () {
updateFP(thenCurrentMoveDodge);
thenSpeedMoveDodge();
});
updateDamageNotes();
updateFrightCheckThreshold();
updateRepeatingDefenseTypes();
updateRepeatingDefenseNotes();
updateRepeatingSkillLevels();
updateRepeatingSpellLevels();
}
// Sum values, used in reduce
function getSum(total, num) {
return (+total || 0) + (+num || 0);
}
// function to sum a field from a repeating section
function sumRepeating(sectionName, fieldName, callback) {
getSectionIDs(sectionName, function (ids) {
if (ids.length === 0 ) {
callback(0);
return;
}
var fieldArray = [];
for (var i = 0; i < ids.length; i++) {
fieldArray.push(sectionName + '_' + ids[i] + '_' + fieldName);
}
getAttrs(fieldArray, function (fieldValues) {
var vals = Object.values(fieldValues);
vals.push(0);
var total = vals.reduce(getSum);
callback(total);
});
});
}
// load values of a repeating section
function loadRepeating(sectionName, fieldName, defaultValue) {
console.log('********* loadRepeating ' + sectionName + '.' + fieldName + '*********');
getSectionIDs(sectionName, function (ids) {
if (ids.length === 0 ) {
return;
}
var fieldArray = [];
var update = {};
for (var i = 0; i < ids.length; i++) {
var propName = sectionName + '_' + ids[i] + '_' + fieldName;
fieldArray.push(propName);
update[propName] = defaultValue;
}
getAttrs(fieldArray, function (fieldValues) {
Object.assign(update, fieldValues);
setAttrs(update);
});
});
}
// Strength Change
on('change:strength_points change:strength_mod', function (e) {
updateST();
});
// Update Strength
function updateST(callback) {
callback = callback || noop;
console.log('********* updateST *********');
getAttrs(['strength_points', 'strength_mod'], function(v) {
var base = 10 + ((+v.strength_points || 0) / 10 | 0);
var mod = +v.strength_mod || 0;
setAttrs({
strength_base: base,
strength: base + mod
}, {silent: false}, callback);
});
}
// Dexterity Change
on('change:dexterity_points change:dexterity_mod', function (e) {
updateDX();
});
// Update Dexterity
function updateDX(callback) {
callback = callback || noop;
console.log('********* updateDX *********');
getAttrs(['dexterity_points', 'dexterity_mod'], function(v) {
var base = 10 + ((+v.dexterity_points || 0) / 20 | 0);
var mod = +v.dexterity_mod || 0;
setAttrs({
dexterity_base: base,
dexterity: base + mod
}, {silent: false}, callback);
});
}
// Intelligence
on('change:intelligence_points change:intelligence_mod', function (e) {
updateIQ();
});
// Update Intelligence
function updateIQ(callback) {
callback = callback || noop;
console.log('********* updateIQ *********');
getAttrs(['intelligence_points', 'intelligence_mod'], function(v) {
var base = 10 + ((+v.intelligence_points || 0) / 20 | 0);
var mod = +v.intelligence_mod || 0;
setAttrs({
intelligence_base: base,
intelligence: base + mod
}, {silent: false}, callback);
});
}
// Health
on('change:health_points change:health_mod', function (e) {
updateHT();
});
// Update Health
function updateHT(callback) {
callback = callback || noop;
console.log('********* updateHT *********');
getAttrs(['health_points', 'health_mod'], function(v) {
var base = 10 + ((+v.health_points || 0) / 10 | 0);
var mod = +v.health_mod || 0;
setAttrs({
health_base: base,
health: base + mod
}, {silent: false}, callback);
});
}
// HP
on('change:strength change:hit_points_points change:hit_points_mod', function (e) {
updateHP();
});
// Update HP
function updateHP(callback) {
console.log('********* updateHP *********');
callback = callback || noop;
getAttrs(['strength', 'strength_base', 'hit_points_points', 'hit_points_mod'], function(v) {
var base = (modCascadeAll ? +v.strength : +v.strength_base) +
((+v.hit_points_points || 0) / 2 | 0);
var mod = +v.hit_points_mod;
setAttrs({
hit_points_max: base + mod
}, {silent: false}, callback);
});
}
// FP
on('change:health change:fatigue_points_points change:fatigue_points_mod', function (e) {
updateFP();
});
// Update FP
function updateFP(callback) {
console.log('********* updateFP *********');
callback = callback || noop;
getAttrs(['health', 'health_base', 'fatigue_points_points', 'fatigue_points_mod'], function(v) {
var base = (modCascadeAll ? +v.health : +v.health_base) +
((+v.fatigue_points_points || 0) / 3 | 0);
var mod = +v.fatigue_points_mod;
setAttrs({
fatigue_points_max: base + mod
}, {silent: false}, callback);
});
}
// Perception
on('change:intelligence change:perception_points change:perception_mod', function (e) {
updatePer();
});
// Update Perception
function updatePer(callback) {
console.log('********* updatePer *********');
callback = callback || noop;
getAttrs(['intelligence', 'intelligence_base', 'perception_points', 'perception_mod'], function(v) {
var base = (modCascade ? +v.intelligence : +v.intelligence_base) +
((+v.perception_points || 0) / 5 | 0);
var mod = +v.perception_mod || 0;
setAttrs({
perception_base: base,
perception: base + mod
}, {silent: false}, callback);
});
}
// Vision, Hearing, Smell, Touch
on('change:perception change:vision_points change:vision_mod change:hearing_points change:hearing_mod change:taste_smell_points change:taste_smell_mod change:touch_points change:touch_mod', function (e) {
updateSense();
});
// Update Vision, Hearing, Smell, Touch
function updateSense() {
console.log('********* updateSense *********');
getAttrs(['perception', 'perception_base', 'vision_points', 'vision_mod', 'hearing_points', 'hearing_mod', 'taste_smell_points', 'taste_smell_mod', 'touch_points', 'touch_mod'], function(v) {
var base = (modCascade ? +v.perception : +v.perception_base);
var visionBase = base + ((+v.vision_points || 0) / 2 | 0);
var visionMod = +v.vision_mod || 0;
var hearingBase = base + ((+v.hearing_points || 0) / 2 | 0);
var hearingMod = +v.hearing_mod || 0;
var tasteSmellBase = base + ((+v.taste_smell_points || 0) / 2 | 0);
var tasteSmellMod = +v.taste_smell_mod || 0;
var touchBase = base + ((+v.touch_points || 0) / 2 | 0);
var touchMod = +v.touch_mod || 0;
setAttrs({
vision_base: visionBase,
vision: visionBase + visionMod,
hearing_base: hearingBase,
hearing: hearingBase + hearingMod,
taste_smell_base: tasteSmellBase,
taste_smell: tasteSmellBase + tasteSmellMod,
touch_base: touchBase,
touch: touchBase + touchMod
});
});
}
// Updage Willpower, Fear (This is actually called Fright Check - the General page reflects this)
on('change:intelligence change:willpower_points change:willpower_mod change:fear_check_points change:fear_check_mod', function (e) {
updateWill();
});
// Updage Willpower, Fear (This is actually called Fright Check - the General page reflects this)
function updateWill() {
console.log('********* updateWill *********');
getAttrs(['intelligence', 'intelligence_base', 'willpower_points', 'willpower_mod', 'fear_check_points', 'fear_check_mod'], function(v) {
var wBase = (modCascade ? +v.intelligence : +v.intelligence_base) +
((+v.willpower_points || 0) / 5 | 0);
var wMod = +v.willpower_mod || 0;
var fBase = wBase + (modCascade ? +wMod : 0) +
((+v.fear_check_points || 0) / 2 | 0);
var fMod = +v.fear_check_mod || 0;
setAttrs({
willpower_base: wBase,
willpower: wBase + wMod,
fear_check_base: fBase,
fear_check: fBase + fMod
});
});
}
// Check for conditions to HT and conditions
on('change:health change:stun_check_mod change:knockdown_check_mod change:unconscious_check_mod change:unconscious_check_points change:death_check_mod change:death_check_points', function (e) {
updateHealthConditionChecks();
});
// Update HT, update Stun, Knockdown, Unconscious, and Death Checks
function updateHealthConditionChecks() {
console.log('********* updateHealthConditionChecks *********');
getAttrs(['health', 'health_base', 'stun_check_mod', 'knockdown_check_mod', 'unconscious_check_mod', 'unconscious_check_points', 'death_check_mod', 'death_check_points'], function(v) {
var healthBase = (modCascade ? +v.health : +v.health_base);
// stun
var stunMod = +v.stun_check_mod || 0;
var stunCheck = healthBase + stunMod;
// knockdown
var knockDownMod = +v.knockdown_check_mod || 0;
var knockDownCheck = healthBase + knockDownMod;
// unconscious
var unconsciousMod = +v.unconscious_check_mod || 0;
var unconsciousCheck = healthBase + (modCascade ? +unconsciousMod : 0) + ((+v.unconscious_check_points || 0) / 2 | 0);
// death
var deathMod = +v.death_check_mod || 0;
var deathCheck = healthBase + (modCascade ? +deathMod : 0) + ((+v.death_check_points || 0) / 2 | 0);
setAttrs({
stun_check: stunCheck,
knockdown_check: knockDownCheck,
unconscious_check: unconsciousCheck,
death_check: deathCheck
});
});
}
// Speed
on('change:dexterity change:health change:basic_speed_points change:basic_speed_mod', function (e) {
updateBasicSpeed();
});
// Update Speed
function updateBasicSpeed(callback) {
console.log('********* updateBasicSpeed *********');
callback = callback || noop;
getAttrs(['dexterity', 'dexterity_base', 'health', 'health_base', 'basic_speed_points', 'basic_speed_mod'], function(v) {
var dx = (modCascade ? +v.dexterity : +v.dexterity_base);
var ht = (modCascade ? +v.health : +v.health_base);
var base = (dx + ht) / 4 + (((+v.basic_speed_points || 0) / 5 | 0) * 0.25);
var mod = +v.basic_speed_mod || 0;
setAttrs({
basic_speed_base: base,
basic_speed: base + mod
}, {silent: false}, callback);
});
}
// Move
on('change:basic_speed change:basic_move_points change:basic_move_mod', function (e) {
updateBasicMove();
});
// Update Move
function updateBasicMove(callback) {
console.log('********* updateBasicMove *********');
callback = callback || noop;
getAttrs(['basic_speed', 'basic_speed_base', 'basic_move_points', 'basic_move_mod'], function(v) {
var speed = (modCascade ? +v.basic_speed : +v.basic_speed_base);
var base = Math.floor(speed) + ((+v.basic_move_points || 0) / 5 | 0);
var mod = +v.basic_move_mod || 0;
setAttrs({
basic_move_base: base,
basic_move: base + mod
}, {silent: false}, callback);
});
}
// Dodge
on('change:basic_speed change:dodge_mod', function (e) {
updateDodge();
});
// Update Dodge
function updateDodge(callback) {
console.log('********* updateDodge *********');
callback = callback || noop;
getAttrs(['basic_speed', 'basic_speed_base', 'dodge_mod'], function(v) {
var speed = (modCascade ? +v.basic_speed : +v.basic_speed_base);
var base = Math.floor(speed) + 3;
var mod = +v.dodge_mod || 0;
setAttrs({
dodge_base: base,
dodge: base + mod
}, {silent: false}, callback);
});
}
// Encumbered/injured move and dodge
on('change:encumbrance_level change:dodge change:basic_move change:hit_points change:fatigue_points', function (e) {
updateMoveDodge();
});
// Update encumbered/injured move and dodge
function updateMoveDodge(callback) {
console.log('***** UPDATE MOVE/DODGE *****');
callback = callback || noop;
getAttrs(['encumbrance_level', 'dodge', 'basic_move', 'hit_points', 'hit_points_max', 'fatigue_points', 'fatigue_points_max', 'strength_base', 'strength_mod'], function(v) {
var dodge = +v.dodge;
var move = +v.basic_move;
var strength = +v.strength_base + +v.strength_mod;
if (v.encumbrance_level === 5) {
dodge = 1;
move = 1;
} else {
dodge = dodge - +v.encumbrance_level;
// There is some math error when calculating Encumbrance which requires the modifier of 1.01 instead of 1 below
move = Math.floor(+v.basic_move * (1.01 - (0.2 * +v.encumbrance_level)));
dodge = dodge < 1 ? 1 : dodge;
move = move < 1 ? 1 : move;
}
if (+v.hit_points < +v.hit_points_max / 3) {
dodge = Math.ceil(dodge / 2);
move = Math.ceil(move / 2);
}
if (+v.fatigue_points < +v.fatigue_points_max / 3 ) {
dodge = Math.ceil(dodge / 2);
move = Math.ceil(move / 2);
strength = Math.ceil(strength / 2);
}
setAttrs({
current_move: move,
current_dodge: dodge,
strength: strength
}, {silent: false}, callback);
});
}
// Lifting ST
on('change:strength change:lift_st_points change:lift_st_mod', function (e) {
updateLift();
});
// Update Lift
function updateLift(callback) {
console.log('********* updateLift *********');
callback = callback || noop;
getAttrs(['strength', 'strength_base', 'lift_st_points', 'lift_st_mod'], function(v) {
var base = (modCascade ? +v.strength : +v.strength_base) +
((+v.lift_st_points || 0) / 3 | 0);
var modded = base + +v.lift_st_mod;
var basicLift = (modded * modded) / 5;
if (basicLift >= 10) {
basicLift = Math.round(basicLift);
}
setAttrs({
lift_st_base: base,
lift_st: modded,
basic_lift: basicLift
}, {silent: false}, callback);
});
}
// Striking ST
on('change:strength change:striking_st_points change:striking_st_mod', function (e) {
updateStrikingST();
});
// Update Striking
function updateStrikingST() {
console.log('********* updateStrikingST *********');
getAttrs(['strength', 'strength_base', 'striking_st_points', 'striking_st_mod'], function(v) {
var base = (modCascade ? +v.strength : +v.strength_base) +
((+v.striking_st_points || 0) / 5 | 0);
var mod = +v.striking_st_mod;
setAttrs({
striking_st_base: base,
striking_st: base + mod
});
});
}
// Update the total cost of Languages
on('change:native_language_spoken change:native_language_written change:repeating_languages:spoken change:repeating_languages:written remove:repeating_languages', function (e) {
console.log('**** Languages Changed ****');
var total = 0;
var tally = _.after(2, function () {
setAttrs({ languages_points: total });
});
getAttrs(['native_language_spoken', 'native_language_written'], function(v) {
total += +v.native_language_spoken;
total += +v.native_language_written;
tally();
});
sumRepeating('repeating_languages', 'spoken', function(v) {
total += +v;
tally();
});
sumRepeating('repeating_languages', 'written', function(v) {
total += +v;
tally();
});
});
// Update the total cost of Cultural Familiarities
on('change:repeating_cultures:points remove:repeating_cultures', function (e) {
sumRepeating('repeating_cultures', 'points', function(v) {
setAttrs({ cf_points: v });
});
});
// Update the total cost of Advantages
on('change:repeating_traits:points remove:repeating_traits', function (e) {
sumRepeating('repeating_traits', 'points', function(v) {
setAttrs({ advantages_points: v });
});
});
// Update the total cost of Disadvantages
on('change:repeating_disadvantages:points remove:repeating_disadvantages', function (e) {
sumRepeating('repeating_disadvantages', 'points', function(v) {
setAttrs({ disadvantages_points: v });
});
});
// Update the total cost of Racial Traits
on('change:repeating_racial:points remove:repeating_racial', function (e) {
sumRepeating('repeating_racial', 'points', function(v) {
setAttrs({ racial_points: v });
});
});
// Update the total cost of Skills
on('change:repeating_skills:points change:repeating_skills:difficulty remove:repeating_skills', function (e) {
// checkForWildCardSkill(e);
getAttrs(['repeating_skills_points', 'repeating_skills_difficulty'], function (skill) {
var skill_points = +skill.repeating_skills_points;
var adjusted_points = 0;
var use_wildcard_points = 0;
var use_normal_skill = 0;
if (String(skill.repeating_skills_difficulty) == "-5 + 1") {
use_wildcard_points = 1;
use_normal_points = 0;
// minimum point cost is 3
if (skill_points < 3) {
wildcard_skill_points = 0;
} else {
wildcard_skill_points = Math.floor(skill_points/3);
}
} else {
use_wildcard_points = 0;
use_normal_points = 1;
wildcard_skill_points = skill.repeating_skills_points;
}
setAttrs({
repeating_skills_wildcard_skill_points: wildcard_skill_points,
repeating_skills_use_wildcard_points: use_wildcard_points,
repeating_skills_use_normal_points: use_normal_points
});
sumRepeating('repeating_skills', 'points', function(v) {
setAttrs({ skills_points: v });
});
});
});
// update row ids when repeating row is updated
on("change:repeating_skills", function(event) {
get_update_row_ids("repeating_skills", function(ids) {
updateSkillLevel("repeating_skills", ids);
});
});
// if skill was removed, make sure to remove it from cache
on("remove:repeating_skills", function(event) {
var rowId = getRowIdFromEventInfo(event, "repeating_skills");
// remove from array
skillRowIds = skillRowIds.remove(rowId);
});
// update row ids when repeating row is updated
on("change:repeating_spells", function(event) {
var sectionName = "repeating_spells";
get_update_row_ids(sectionName, function(ids) {
// get the base spell level and bonus
getAttrs(["spell_base", "spell_bonus"], function(values) {
var spellBase = values.spell_base;
var spellBonus = parseInt(values.spell_bonus);
if ( isNaN(spellBonus) ) {
spellBonus = 0;
}
updateSpellLevel( sectionName, ids, spellBase, spellBonus );
});
});
});
// if spell was removed, make sure to remove it from cache
on("remove:repeating_spells", function(event) {
var rowId = getRowIdFromEventInfo(event, "repeating_spells");
// remove from array
skillRowIds = skillRowIds.remove(rowId);
});
/**
* get rows ids and update display field
*
* @param string sectionId Repeating section id
*/
function get_update_row_ids(sectionId, callback) {
getSectionIDs(sectionId, function(ids) {
if (ids.length === 0) return;
const items = {}; // initialise an object to hold fields to update.
for(var i=0; i < ids.length; i++) {
//Do something with the IDs
var rowId = ids[i];
// set the field value
items[`${sectionId}_${rowId}_row_id`] = rowId;
updateSkillIdsArrayCache(rowId);
}
// update the field values
// callback returns the row ids to function that made the call
setAttrs(items, '', callback(ids));
});
}
/**
* If missing in cache, add this row id
*
* @param string rowId Row ID to add to cache
*/
function updateSkillIdsArrayCache(rowId) {
if (skillRowIds.includes(rowId) === false ) {
skillRowIds.push(rowId);
}
}
// Update the total cost of Techniques
on('change:repeating_techniques:points remove:repeating_techniques', function (e) {
sumRepeating('repeating_techniques', 'points', function(v) {
setAttrs({ techniques_points: v });
});
});
// Update the total cost of Spells
on('change:repeating_spells:points remove:repeating_spells', function (e) {
sumRepeating('repeating_spells', 'points', function(v) {
setAttrs({ spells_points: v });
});
});
// Update Summery
on('change:tl_pts change:appearance change:languages_points change:cf_points change:advantages_points change:disadvantages_points change:racial_points', function (e) {
getAttrs(['tl_pts', 'appearance', 'languages_points', 'cf_points', 'advantages_points', 'disadvantages_points', 'racial_points'], function(v) {
var vals = Object.values(v);
vals.push(0);
setAttrs({ trait_points: vals.reduce(getSum) });
});
});
// Update the line total weight and cost
on('change:repeating_item:count change:repeating_item:cost change:repeating_item:carried change:repeating_item:weight', function (e) {
getAttrs(['repeating_item_count', 'repeating_item_cost', 'repeating_item_weight', 'repeating_item_carried'], function (item) {
setAttrs({
repeating_item_weighttotal: Number(Math.round(item.repeating_item_count * item.repeating_item_weight * item.repeating_item_carried * 1000) / 1000).toFixed(3),
repeating_item_costtotal: Number(Math.round(item.repeating_item_count * item.repeating_item_cost * 100) / 100).toFixed(2)
});
});
});
// Update the total weight of all carried items.
on('change:repeating_item:weighttotal remove:repeating_item', function (e) {
sumRepeating('repeating_item', 'weighttotal', function(v) {
setAttrs({ total_weight: Number(Math.round(v * 1000) / 1000).toFixed(3) });
});
});
// Update the line Format for existing inventory weight and cost - Script provided by GiGs ID:157788 (Roll20)
on('change:inventory_fixed_digits',function() {
// getSectionIDs gives an array of all the row ids.
getSectionIDs('item', function (ids) {
if (ids.length === 0) return;
// need to get an array of all the attributes used in the repeating_items calculations, for getAttrs
const fieldArray = [];
ids.forEach(id => fieldArray.push(
`repeating_item_${id}_count`, `repeating_item_${id}_cost`, `repeating_item_${id}_weight`, `repeating_item_${id}_carried`
));
getAttrs(fieldArray, function (item) {
const items = {}; // initialise an object to hold the total weights and costs.
ids.forEach(id => {
// for each row of the table, calculate the total weight and cost
const weight = (+item[`repeating_item_${id}_count`]||0) * (+item[`repeating_item_${id}_weight`]||0) * (+item[`repeating_item_${id}_carried`]||0);
const cost = (+item[`repeating_item_${id}_count`]||0) * (+item[`repeating_item_${id}_cost`]||0);
// save the totals, in the correct format
items[`repeating_item_${id}_weighttotal`] = Number(Math.round(weight * 1000)/1000).toFixed(3);
items[`repeating_item_${id}_costtotal`] = Number(Math.round(cost * 100)/100).toFixed(2);
});
setAttrs(items);
});
});
});
// Get Encumbrance Level:
on('change:total_weight change:basic_lift', function (e) {
updateEncLevel();
});
function updateEncLevel(callback) {
getAttrs(['basic_lift', 'total_weight'], function(v) {
callback = callback || noop;
var basicLift = +v.basic_lift;
var encumbranceLevel = Math.floor(v.total_weight / basicLift);
if (encumbranceLevel > 0 && (v.total_weight % basicLift) === 0) {
encumbranceLevel--;
}
if (encumbranceLevel >= 10) {
encumbranceLevel = 4;
} else if (encumbranceLevel >= 6) {
encumbranceLevel = 4;
} else if (encumbranceLevel >= 3) {
encumbranceLevel = 3;
}
setAttrs(
{ encumbrance_level: encumbranceLevel },
{silent: false},
callback
);
});
}
// Update the total cost of all items.
on('change:repeating_item:costtotal remove:repeating_item', function (e) {
sumRepeating('repeating_item', 'costtotal', function(v) {
setAttrs({ total_value: Number((v * 100) / 100).toFixed(2) });
});
});
// Update thrust and swing when striking st is updated
on('change:striking_st', function(e){
updateStrikingStrengthDamage();
});
/**
* Get the striking ST value and then get the damage type
* update Thrust and Swing
*/
function updateStrikingStrengthDamage(callback) {
console.log("******** updateStrikingStrengthDamage ********");
// get Strking strength
getAttrs(['striking_st'], function(values) {
callback = callback || noop;
// + means to convert variable to number
var strikingST = +values.striking_st;
// get the damageType object (strength, thrust, swing)
var damageType = getDamageType(strikingST);
// set thrust and swing
setAttrs({
thrust: damageType.thrust,
swing: damageType.swing
}, {silent: false}, callback);
});
}
/**
* Returns the damage type object
* based on ST
* damageType {strength, thrust, swing}
*
* @param int strikingST ST of attack
*
* @return object
*/
function getDamageType(strikingST) {
// return value
var damgeType = null;
var modifier = 0;
var baseThrust = 11;
var baseSwing = 13;
// prevent bad ST from causing issue
if (isNaN(strikingST) || strikingST < 0) {
strikingST = 1;
}
if (strikingST < 110) {
// get damageType from table
damageType = damageTable[strikingST];
} else {
// calculate the total
// Add 1d6 to thrust and swing for every full 10 points over 100
modifier = Math.floor((strikingST - 100) / 10);
baseThrust = baseThrust + modifier;
baseSwing = baseSwing = modifier;
damageType = {strength:strikingST, thrust:baseThrust + "d6", swing:baseSwing + "d6"};
}
return damageType;
}
/**
* Populates the global variable damageTable
*/
function generateDamageTable() {
var damageTable = [];
damageTable[0] = {strength:"0", thrust:"1d6-6", swing:"1d6-6"};
damageTable[1] = {strength:"1", thrust:"1d6-6", swing:"1d6-5"};
damageTable[2] = {strength:"2", thrust:"1d6-6", swing:"1d6-5"};
damageTable[3] = {strength:"3", thrust:"1d6-5", swing:"1d6-4"};
damageTable[4] = {strength:"4", thrust:"1d6-5", swing:"1d6-4"};
damageTable[5] = {strength:"5", thrust:"1d6-4", swing:"1d6-3"};
damageTable[6] = {strength:"6", thrust:"1d6-4", swing:"1d6-3"};
damageTable[7] = {strength:"7", thrust:"1d6-3", swing:"1d6-2"};
damageTable[8] = {strength:"8", thrust:"1d6-3", swing:"1d6-2"};
damageTable[9] = {strength:"9", thrust:"1d6-2", swing:"1d6-1"};
damageTable[10] = {strength:"10", thrust:"1d6-2", swing:"1d6"};
damageTable[11] = {strength:"11", thrust:"1d6-1", swing:"1d6+1"};
damageTable[12] = {strength:"12", thrust:"1d6-1", swing:"1d6+2"};
damageTable[13] = {strength:"13", thrust:"1d6", swing:"2d6-1"};
damageTable[14] = {strength:"14", thrust:"1d6", swing:"2d6"};
damageTable[15] = {strength:"15", thrust:"1d6+1", swing:"2d6+1"};
damageTable[16] = {strength:"16", thrust:"1d6+1", swing:"2d6+2"};
damageTable[17] = {strength:"17", thrust:"1d6+2", swing:"3d6-1"};
damageTable[18] = {strength:"18", thrust:"1d6+2", swing:"3d6"};
damageTable[19] = {strength:"19", thrust:"2d6-1", swing:"3d6+1"};
damageTable[20] = {strength:"20", thrust:"2d6-1", swing:"3d6+2"};
damageTable[21] = {strength:"21", thrust:"2d6", swing:"4d6-1"};
damageTable[22] = {strength:"22", thrust:"2d6", swing:"4d6"};
damageTable[23] = {strength:"23", thrust:"2d6+1", swing:"4d6+1"};
damageTable[24] = {strength:"24", thrust:"2d6+1", swing:"4d6+2"};
damageTable[25] = {strength:"25", thrust:"2d6+2", swing:"5d6-1"};
damageTable[26] = {strength:"26", thrust:"2d6+2", swing:"5d6"};
damageTable[27] = {strength:"27", thrust:"3d6-1", swing:"5d6+1"};
damageTable[28] = {strength:"28", thrust:"3d6-1", swing:"5d6+1"};
damageTable[29] = {strength:"29", thrust:"3d6", swing:"5d6+2"};
damageTable[30] = {strength:"30", thrust:"3d6", swing:"5d6+2"};
damageTable[31] = {strength:"31", thrust:"3d6+1", swing:"6d6-1"};
damageTable[32] = {strength:"32", thrust:"3d6+1", swing:"6d6-1"};
damageTable[33] = {strength:"33", thrust:"3d6+2", swing:"6d6"};
damageTable[34] = {strength:"34", thrust:"3d6+2", swing:"6d6"};
damageTable[35] = {strength:"35", thrust:"4d6-1", swing:"6d6+1"};
damageTable[36] = {strength:"36", thrust:"4d6-1", swing:"6d6+1"};
damageTable[37] = {strength:"37", thrust:"4d6", swing:"6d6+2"};
damageTable[38] = {strength:"38", thrust:"4d6", swing:"6d6+2"};
damageTable[39] = {strength:"39", thrust:"4d6+1", swing:"7d6-1"};
damageTable[40] = {strength:"40", thrust:"4d6+1", swing:"7d6-1"};
damageTable[41] = {strength:"41", thrust:"4d6+1", swing:"7d6-1"};
damageTable[42] = {strength:"42", thrust:"4d6+1", swing:"7d6-1"};
damageTable[43] = {strength:"43", thrust:"4d6+1", swing:"7d6-1"};
damageTable[44] = {strength:"44", thrust:"4d6+1", swing:"7d6-1"};
damageTable[45] = {strength:"45", thrust:"5d6", swing:"7d6+1"};
damageTable[46] = {strength:"46", thrust:"5d6", swing:"7d6+1"};
damageTable[47] = {strength:"47", thrust:"5d6", swing:"7d6+1"};
damageTable[48] = {strength:"48", thrust:"5d6", swing:"7d6+1"};
damageTable[49] = {strength:"49", thrust:"5d6", swing:"7d6+1"};
damageTable[50] = {strength:"50", thrust:"5d6+2", swing:"8d6-1"};
damageTable[51] = {strength:"51", thrust:"5d6+2", swing:"8d6-1"};
damageTable[52] = {strength:"52", thrust:"5d6+2", swing:"8d6-1"};
damageTable[53] = {strength:"53", thrust:"5d6+2", swing:"8d6-1"};
damageTable[54] = {strength:"54", thrust:"5d6+2", swing:"8d6-1"};
damageTable[55] = {strength:"55", thrust:"6d6", swing:"8d6+1"};
damageTable[56] = {strength:"56", thrust:"6d6", swing:"8d6+1"};
damageTable[57] = {strength:"57", thrust:"6d6", swing:"8d6+1"};
damageTable[58] = {strength:"58", thrust:"6d6", swing:"8d6+1"};
damageTable[59] = {strength:"59", thrust:"6d6", swing:"8d6+1"};
damageTable[60] = {strength:"60", thrust:"7d6-1", swing:"9d6"};
damageTable[61] = {strength:"61", thrust:"7d6-1", swing:"9d6"};
damageTable[62] = {strength:"62", thrust:"7d6-1", swing:"9d6"};
damageTable[63] = {strength:"63", thrust:"7d6-1", swing:"9d6"};
damageTable[64] = {strength:"64", thrust:"7d6-1", swing:"9d6"};
damageTable[65] = {strength:"65", thrust:"7d6+1", swing:"9d6+2"};
damageTable[66] = {strength:"66", thrust:"7d6+1", swing:"9d6+2"};
damageTable[67] = {strength:"67", thrust:"7d6+1", swing:"9d6+2"};
damageTable[68] = {strength:"68", thrust:"7d6+1", swing:"9d6+2"};
damageTable[69] = {strength:"69", thrust:"7d6+1", swing:"9d6+2"};
damageTable[70] = {strength:"70", thrust:"8d6", swing:"10d6"};
damageTable[71] = {strength:"71", thrust:"8d6", swing:"10d6"};
damageTable[72] = {strength:"72", thrust:"8d6", swing:"10d6"};
damageTable[73] = {strength:"73", thrust:"8d6", swing:"10d6"};
damageTable[74] = {strength:"74", thrust:"8d6", swing:"10d6"};
damageTable[75] = {strength:"75", thrust:"8d6+2", swing:"10d6+2"};
damageTable[76] = {strength:"76", thrust:"8d6+2", swing:"10d6+2"};
damageTable[77] = {strength:"77", thrust:"8d6+2", swing:"10d6+2"};
damageTable[78] = {strength:"78", thrust:"8d6+2", swing:"10d6+2"};
damageTable[79] = {strength:"79", thrust:"8d6+2", swing:"10d6+2"};
damageTable[80] = {strength:"80", thrust:"9d6", swing:"11d6"};
damageTable[81] = {strength:"81", thrust:"9d6", swing:"11d6"};
damageTable[82] = {strength:"82", thrust:"9d6", swing:"11d6"};
damageTable[83] = {strength:"83", thrust:"9d6", swing:"11d6"};
damageTable[84] = {strength:"84", thrust:"9d6", swing:"11d6"};
damageTable[85] = {strength:"85", thrust:"9d6+2", swing:"11d6+2"};
damageTable[86] = {strength:"86", thrust:"9d6+2", swing:"11d6+2"};
damageTable[87] = {strength:"87", thrust:"9d6+2", swing:"11d6+2"};
damageTable[88] = {strength:"88", thrust:"9d6+2", swing:"11d6+2"};
damageTable[89] = {strength:"89", thrust:"9d6+2", swing:"11d6+2"};
damageTable[90] = {strength:"90", thrust:"10d6", swing:"12d6"};
damageTable[91] = {strength:"91", thrust:"10d6", swing:"12d6"};
damageTable[92] = {strength:"92", thrust:"10d6", swing:"12d6"};
damageTable[93] = {strength:"93", thrust:"10d6", swing:"12d6"};
damageTable[94] = {strength:"94", thrust:"10d6", swing:"12d6"};
damageTable[95] = {strength:"95", thrust:"10d6+2", swing:"12d6+2"};
damageTable[96] = {strength:"96", thrust:"10d6+2", swing:"12d6+2"};
damageTable[97] = {strength:"97", thrust:"10d6+2", swing:"12d6+2"};
damageTable[98] = {strength:"98", thrust:"10d6+2", swing:"12d6+2"};
damageTable[99] = {strength:"99", thrust:"10d6+2", swing:"12d6+2"};
damageTable[100] = {strength:"100", thrust:"11d6", swing:"13d6"};
return damageTable;
}
// check for combat reflexes toggle box
on('change:combat_reflexes', function(e){
updateActiveDefenses();
});
/**
* Get combat reflexes. Update active defenses
*/
function updateActiveDefenses(callback) {
// get the defense values
getAttrs(['combat_reflexes', 'dodge_mod', 'fear_check_mod'], function(values) {
callback = callback || noop;
// + means to convert variable to number
var chkCombatReflexes = +values.combat_reflexes;
var modDodge = 0;
var modFear = 0;
if (chkCombatReflexes == 1) {
modDodge = 1;
modFear = 2;
} else {
modDodge = -1;
modFear = -2;
}
// update dodge modifier
var orig_dodge_mod = 0;
if (isNaN(values.dodge_mod)) {
orig_dodge_mod = 0;
} else {
orig_dodge_mod = +values.dodge_mod;
}
var new_dodge_mod = orig_dodge_mod + modDodge;
// update fear check
var orig_fear_check_mod = 0;
if (isNaN(values.fear_check_mod)) {
orig_fear_check_mod = 0;
} else {
orig_fear_check_mod = +values.fear_check_mod;
}
var new_fear_check_mod = orig_fear_check_mod + modFear;
// update
// set thrust and swing
setAttrs({
dodge_mod: new_dodge_mod,
fear_check_mod: new_fear_check_mod
});
});
}
// check for manual or calculated option
on("change:use_unspent_box", function (e) {
updateToggleUnspentCheckBox();
});
/**
* Updates the hidden toggle_unspent_points. Used by
* css to show/hide unspent boxes
* see: gurps.css -> input.sheet-toggle-unspoint-points[value="1"]
*
*/
function updateToggleUnspentCheckBox() {
console.log('***** TOGGLE UNSPENT BOX *****');
getAttrs(['use_unspent_box'], function(values) {
setAttrs({
toggle_unspent_points: values.use_unspent_box
});
});
}
// check for selected damage dice change
on("change:damage_dice_type", function (e) {
updateDiceDamageIcons();
});
/**
* Controller function to update each section of
* damage dice icons
*/
function updateDiceDamageIcons() {
console.log('***** UPDATE DICE DAMAGE *****');
updateThrustSwingDamageIcons();
updateRepeatingDamageDice("repeating_melee");
updateRepeatingDamageDice("repeating_ranged");
}
/**
* Update the Thrust and Swing Damage Icons
* on the general tab by setting the hidden inputs
*/
function updateThrustSwingDamageIcons() {
getAttrs(['damage_dice_type'], function(values) {
setAttrs({
thrust_damage_dice_icon: values.damage_dice_type,
swing_damage_dice_icon: values.damage_dice_type
});
});
}
/**
* Gets the repeating sections ids. loop through
* each id, must use getAttrs() inside the loop,
* then set the hidden input for dice damge icon
*
* @param string sectionID Repeating section id
*/
function updateRepeatingDamageDice(sectionID) {
// get all the ids for each repeating section
getSectionIDs(sectionID, function (ids) {
// loop though each ids using underscores
// see: https://underscorejs.org/#each
_.each(ids,function(id) {
getAttrs(['damage_dice_type'], function(values) {
// set the hidden input attribute
setAttrs({
[sectionID + "_" + id + "_damage_dice_icon"]: values.damage_dice_type
});
});
});
});
}
// check to see if ground move mod or move points changed
on("change:enhanced_ground_move_mod change:enhanced_ground_move_points change:basic_move change:encumbrance_level change:hit_points change:fatigue_points", function(e) {
updateEnhancedMove();
});
/**
* Get the attributes for enhanced ground move modifier and points spent
* Update the fields for ground multiple and ground move based on mod and points
*/
function updateEnhancedMove() {
console.log('***** UPDATE ENHANCED MOVE *****');
getAttrs(["enhanced_ground_move_mod", "enhanced_ground_move_points", "basic_move", "encumbrance_level", "hit_points", "hit_points_max", "fatigue_points", "fatigue_points_max"], function(values) {
// + sign converts value to a number
var groundModifier = +values.enhanced_ground_move_mod;
var groundPoints = +values.enhanced_ground_move_points;
var groundModifierFromPoints = 0;
var totalModifier = 0;
var basicMove = +values.basic_move;
var enhancedMove = 0;
// encumbrance levels
var enhancedMove0 = "";
var enhancedMove1 = "";
var enhancedMove2 = "";
var enhancedMove3 = "";
var enhancedMove4 = "";
var enhancedMove5 = "";
var encumberedEnhancedMove1 = 0;
var encumberedEnhancedMove2 = 0;
var encumberedEnhancedMove3 = 0;
var encumberedEnhancedMove4 = 0;
// current speed based on encumbrance and pain/fatigue
var currentEnhancedMove = "";
var injuryFatigueMoveModifier = 1;
// validate groundModifer
if (groundModifier < 0) {
groundModifier = 0;
}
// make sure groundModifier is multiple of .5
// https://stackoverflow.com/questions/25209849/javascript-round-up-to-nearest-5
groundModifier = Math.ceil(groundModifier * 2) / 2;
// validate groundPoints
if (groundPoints < 0) {
groundPoints = 0;
}
// make sure groundPoints is multiple of 10
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
groundPoints = Math.ceil(groundPoints / 10) * 10;
groundModifierFromPoints = groundPoints / 20;
totalModifier = groundModifier + groundModifierFromPoints;
enhancedMove = getEnhancedValue(basicMove, totalModifier);
if (totalModifier == 0) {
enhancedMove0 = "";
enhancedMove1 = "";
enhancedMove2 = "";
enhancedMove3 = "";
enhancedMove4 = "";
enhancedMove5 = "";
currentBasicMove = "";
currentEnhancedMove = "";
} else {
enhancedMove0 = basicMove + "/" + enhancedMove;
move1 = getEncumberedMove(basicMove, 1);
encumberedEnhancedMove1 = getEncumberedMove(enhancedMove, 1);
enhancedMove1 = move1 + "/" + encumberedEnhancedMove1;
move2 = getEncumberedMove(basicMove, 2);
encumberedEnhancedMove2 = getEncumberedMove(enhancedMove, 2);
enhancedMove2 = move2 + "/" + encumberedEnhancedMove2;
move3 = getEncumberedMove(basicMove, 3);
encumberedEnhancedMove3 = getEncumberedMove(enhancedMove, 3);
enhancedMove3 = move3 + "/" + encumberedEnhancedMove3;
move4 = getEncumberedMove(basicMove, 4);
encumberedEnhancedMove4 = getEncumberedMove(enhancedMove, 4);
enhancedMove4 = move4 + "/" + encumberedEnhancedMove4;
enhancedMove5 = enhancedMove4;
// check for half move
injuryFatigueMoveModifier = getInjuryFatigueModifier(values.hit_points, values.hit_points_max, values.fatigue_points, values.fatigue_points_max);
// determine the current encumbrance move
switch(values.encumbrance_level) {
case 0:
currentEnhancedMove = Math.floor(+basicMove * injuryFatigueMoveModifier) + "/" + Math.floor(+enhancedMove * injuryFatigueMoveModifier);
break;
case 1:
currentEnhancedMove = Math.floor(+move1 * injuryFatigueMoveModifier) + "/" + Math.floor(+encumberedEnhancedMove1 * injuryFatigueMoveModifier);
break;
case 2:
currentEnhancedMove = Math.floor(+move2 * injuryFatigueMoveModifier) + "/" + Math.floor(+encumberedEnhancedMove2 * injuryFatigueMoveModifier);
break;
case 3:
currentEnhancedMove = Math.floor(+move3 * injuryFatigueMoveModifier) + "/" + Math.floor(+encumberedEnhancedMove3 * injuryFatigueMoveModifier);
break;
case 4:
case 5:
default:
currentEnhancedMove = Math.floor(+move4 * injuryFatigueMoveModifier) + "/" + Math.floor(+encumberedEnhancedMove4 * injuryFatigueMoveModifier);
break;
}
}
// set values and making sure modifiers are correct multiples
setAttrs({
"enhanced_ground_move_mod": groundModifier,
"enhanced_ground_move_points": groundPoints,
"enhanced_ground_move_multiple": totalModifier,
"enhanced_ground_move": enhancedMove,
"enhanced_move_0": enhancedMove0,
"enhanced_move_1": enhancedMove1,
"enhanced_move_2": enhancedMove2,
"enhanced_move_3": enhancedMove3,
"enhanced_move_4": enhancedMove4,
"enhanced_move_5": enhancedMove5,
"enhanced_move_current": currentEnhancedMove
});
});
}
/**
* Calculates move based on encumbrance level
* encumbrance level 1-4. 5 is the same as 4, just costs fatigue
*
* @param int basicMove Starting basic move
* @param string encumbranceLevel Encumbrance level 1-4
*
* @return int
*/
function getEncumberedMove(basicMove, encumbranceLevel) {
var newMove = 0;
var encumbranceModifier = 0;
// make sure we have a good value
if (encumbranceLevel < 1) {
encumbranceLevel = 1;
} else if (encumbranceLevel > 4) {
encumbranceLevel = 4;
}
encumbranceModifier = 1 - ((encumbranceLevel*2)/10);
// fix floating point bug
// see: https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary
encumbranceModifier = Math.round(encumbranceModifier * 100) / 100;
newMove = Math.floor(basicMove * encumbranceModifier);
// minimum move is 1
if (newMove <= 0) {
newMove = 1;
}
return newMove;
}
/**
* Calculate the enhanced value for multiples of 2.
* If .5 value, then multiply by 1.5
* see GURPS Basic Set, page 52 enhanced move
*
* @param int baseValue Value to multiply
* @param decimal level Level of enhanced move to apply to baseValue
*
* @return int
*/
function getEnhancedValue(baseValue, level) {
var enhancedValue = 0;
// check for formula to use
if (level == 0) {
enhancedValue = 0;
} else if (level % 1 == 0) {
// if no remainder, use this formula
enhancedValue = baseValue * Math.pow(2, level);
} else {
// if there is a remainder, use this formula
// remove the .5 and then multiply by 1.5
enhancedValue = (baseValue * Math.pow(2, Math.floor(level))) * 1.5;
enhancedValue = Math.floor(enhancedValue);
}
return enhancedValue;
}
/**
* Checks for 1/3 HP and 1/3 FP.
* Apply move modifies
*
* @param int hit_points Current hit points of character
* @param int hit_points_max Max HP of character
* @param int fatigue_points Current FP of character
* @param int fatigue_points_max Max FP of character
*
* @return decimal
*/
function getInjuryFatigueModifier(hit_points, hit_points_max, fatigue_points, fatigue_points_max) {
var modifier = 1;
if (+hit_points < +hit_points_max / 3) {
modifier = modifier / 2;
}
if (+fatigue_points < +fatigue_points_max / 3 ) {
modifier = modifier / 2;
}
return modifier;
}
// check for changes that affect flight speed
on("change:flight_checked change:basic_speed change:basic_air_move_points change:basic_air_move_mod change:enhanced_air_level change:enhanced_air_move_points change:encumbrance_level change:hit_points change:fatigue_points", function(e) {
updateFlightValues();
});
/**
* Update flight values, including encumbered and current speed
*
* @return void
*/
function updateFlightValues() {
console.log('***** UPDATE FLIGHT VALUES *****');
getAttrs(["flight_checked", "basic_speed", "enhanced_air_level", "basic_air_move", "basic_air_move_mod",
"basic_air_move_points", "enhanced_air_level", "enhanced_air_move_points",
"encumbrance_level", "hit_points", "hit_points_max", "fatigue_points", "fatigue_points_max"], function(values) {
// + sign converts value to a number
var airMovePoints = +values.basic_air_move_points;
// ensure valid airMovePoints
if (airMovePoints < 0) {
airMovePoints = 0;
}
var basicAirMoveMod = +values.basic_air_move_mod;
// ensure valid basicAirMoveMod
if (basicAirMoveMod < 0) {
basicAirMoveMod = 0;
}
var airMoveUnmodified = 0;
var airMove = 0;
var airModifierFromPoints = 0;
var baseEnhancedAirMove = "";
var enhancedAirLevel = 0;
var enhancedEnteredLevel = +values.enhanced_air_level;
var encumberedDisplayMove0 = "";
var encumberedDisplayMove1 = "";
var encumberedDisplayMove2 = "";
var encumberedDisplayMove3 = "";
var encumberedDisplayMove4 = "";
var encumberedDisplayMove5 = "";
var currentAirMove = "";
// ensure valid enhancedEnteredLevel
if (enhancedEnteredLevel < 0) {
enhancedEnteredLevel = 0;
}
var enhancedEnteredPoints = +values.enhanced_air_move_points;
// ensure valid enhancedEnteredPoints
if (enhancedEnteredPoints < 0) {
enhancedEnteredPoints = 0;
}
var enhancedAirLevelFromPoints = 0;
var totalEnhancedLevel = 0;
var injuryFatigueMoveModifier = 1;
// if flight is checked, calculate the values
if (values.flight_checked == 1) {
//----------------
// calculate air move
airMoveUnmodified = Math.floor(+values.basic_speed * 2);
// base is basis_speed * 2
airMove = Math.floor(+values.basic_speed * 2);
// add air move modifier
airMove = airMove + basicAirMoveMod;
// make sure airMovePoints is multiple of 2
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
airMovePoints = Math.ceil(airMovePoints / 2) * 2;
airModifierFromPoints = airMovePoints/2;
// add in the air move from spent points
airMove = airMove + airModifierFromPoints;
//-----------------
// calculate top air speed
// make sure groundPoints is multiple of 10
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
enhancedEnteredPoints = Math.ceil(enhancedEnteredPoints / 10) * 10;
enhancedAirLevelFromPoints = enhancedEnteredPoints / 20;
// make sure enhancedEnteredLevel is multiple of .5
// https://stackoverflow.com/questions/25209849/javascript-round-up-to-nearest-5
enhancedEnteredLevel = Math.ceil(enhancedEnteredLevel * 2) / 2;
totalEnhancedLevel = enhancedEnteredLevel + enhancedAirLevelFromPoints;
baseEnhancedAirMove = getEnhancedValue(airMove, totalEnhancedLevel);
// get the encumbered levels
if (baseEnhancedAirMove > 0) {
// show the enhanced move
encumberedDisplayMove0 = airMove + "/" + baseEnhancedAirMove;
encumberedDisplayMove1 = getEncumberedMove(airMove, 1) + "/" + getEncumberedMove(baseEnhancedAirMove, 1);
encumberedDisplayMove2 = getEncumberedMove(airMove, 2) + "/" + getEncumberedMove(baseEnhancedAirMove, 2);
encumberedDisplayMove3 = getEncumberedMove(airMove, 3) + "/" + getEncumberedMove(baseEnhancedAirMove, 3);
encumberedDisplayMove4 = getEncumberedMove(airMove, 4) + "/" + getEncumberedMove(baseEnhancedAirMove, 4);
encumberedDisplayMove5 = encumberedDisplayMove4;
} else {
// don't need the enhanced move
encumberedDisplayMove0 = airMove;
encumberedDisplayMove1 = getEncumberedMove(airMove, 1);
encumberedDisplayMove2 = getEncumberedMove(airMove, 2);
encumberedDisplayMove3 = getEncumberedMove(airMove, 3);
encumberedDisplayMove4 = getEncumberedMove(airMove, 4);
encumberedDisplayMove5 = encumberedDisplayMove4;
}
// check for half move
injuryFatigueMoveModifier = getInjuryFatigueModifier(values.hit_points, values.hit_points_max, values.fatigue_points, values.fatigue_points_max);
// determine the current encumbrance move
switch(values.encumbrance_level) {
case 0:
currentAirMove = (airMove * injuryFatigueMoveModifier);
if (baseEnhancedAirMove > 0) {
currentAirMove = currentAirMove + "/" + (baseEnhancedAirMove * injuryFatigueMoveModifier);
}
break;
case 1:
currentAirMove = (getEncumberedMove(airMove, 1) * injuryFatigueMoveModifier);
if (baseEnhancedAirMove > 0) {
currentAirMove = currentAirMove + "/" + (getEncumberedMove(baseEnhancedAirMove, 1) * injuryFatigueMoveModifier);
}
break;
case 2:
currentAirMove = (getEncumberedMove(airMove, 2) * injuryFatigueMoveModifier);
if (baseEnhancedAirMove > 0) {
currentAirMove = currentAirMove + "/" + (getEncumberedMove(baseEnhancedAirMove, 2) * injuryFatigueMoveModifier);
}
break;
case 3:
currentAirMove = (getEncumberedMove(airMove, 3) * injuryFatigueMoveModifier);
if (baseEnhancedAirMove > 0) {
currentAirMove = currentAirMove + "/" + (getEncumberedMove(baseEnhancedAirMove, 3) * injuryFatigueMoveModifier);
}
break;
case 4:
case 5:
default:
currentAirMove = (getEncumberedMove(airMove, 4) * injuryFatigueMoveModifier);
if (baseEnhancedAirMove > 0) {
currentAirMove = currentAirMove + "/" + (getEncumberedMove(baseEnhancedAirMove, 4) * injuryFatigueMoveModifier);
}
break;
}
} else {
airMove = 0;
baseEnhancedAirMove = 0;
currentAirMove = 0;
}
// set air moves
setAttrs({
"basic_air_move": airMove,
"basic_air_move_unmodified": airMoveUnmodified,
"enhanced_air_move": baseEnhancedAirMove,
"enhanced_air_move_level": totalEnhancedLevel,
"basic_air_move_points": airMovePoints,
"enhanced_air_move_points": enhancedEnteredPoints,
"air_0": encumberedDisplayMove0,
"air_1": encumberedDisplayMove1,
"air_2": encumberedDisplayMove2,
"air_3": encumberedDisplayMove3,
"air_4": encumberedDisplayMove4,
"air_5": encumberedDisplayMove5,
"current_air": currentAirMove
});
});
}
// check for changes that affect water speed
on("change:amphibious_checked change:basic_move change:basic_water_move_points change:basic_water_move_mod change:enhanced_water_level change:enhanced_water_move_points change:encumbrance_level change:hit_points change:fatigue_points", function(e) {
updateWaterMoveValues();
});
/**
* Update water move values, including encumbered and current speed
*
* @return void
*/
function updateWaterMoveValues() {
console.log('***** UPDATE WATER MOVE VALUES *****');
getAttrs(["amphibious_checked", "basic_move", "enhanced_water_level", "basic_water_move", "basic_water_move_mod",
"basic_water_move_points", "enhanced_water_level", "enhanced_water_move_points",
"encumbrance_level", "hit_points", "hit_points_max", "fatigue_points", "fatigue_points_max"], function(values) {
// + sign converts value to a number
var waterMovePoints = +values.basic_water_move_points;
// ensure valid waterMovePoints
if (waterMovePoints < 0) {
waterMovePoints = 0;
}
var basicWaterMoveMod = +values.basic_water_move_mod;
// ensure valid basicWaterMoveMod
if (basicWaterMoveMod < 0) {
basicWaterMoveMod = 0;
}
var waterMoveUnmodified = 0;
var waterMove = 0;
var waterModifierFromPoints = 0;
var baseEnhancedWaterMove = "";
var enhancedWaterLevel = 0;
var enhancedEnteredLevel = +values.enhanced_water_level;
var encumberedDisplayMove0 = "";
var encumberedDisplayMove1 = "";
var encumberedDisplayMove2 = "";
var encumberedDisplayMove3 = "";
var encumberedDisplayMove4 = "";
var encumberedDisplayMove5 = "";
var currentWaterMove = "";
// ensure valid enhancedEnteredLevel
if (enhancedEnteredLevel < 0) {
enhancedEnteredLevel = 0;
}
var enhancedEnteredPoints = +values.enhanced_water_move_points;
// ensure valid enhancedEnteredPoints
if (enhancedEnteredPoints < 0) {
enhancedEnteredPoints = 0;
}
var enhancedWaterLevelFromPoints = 0;
var totalEnhancedLevel = 0;
var injuryFatigueMoveModifier = 1;
// if flight is checked, calculate the values
if (values.amphibious_checked == 1 && (enhancedEnteredPoints > 0 || enhancedEnteredLevel > 0)) {
//----------------
// calculate water move
waterMoveUnmodified = +values.basic_move;
// determine move
if (values.amphibious_checked == 1) {
// base is basis_move
waterMove = +values.basic_move;
} else {
// base is basis_move / 5
waterMove = +values.basic_move / 5;
}
// add water move modifier
waterMove = waterMove + basicWaterMoveMod;
// make sure waterMovePoints is multiple of 5
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
waterMovePoints = Math.ceil(waterMovePoints / 5) * 5;
waterModifierFromPoints = waterMovePoints/5;
// add in the water move from spent points
waterMove = waterMove + waterModifierFromPoints;
waterMove = Math.floor(waterMove);
// make sure it's a minimum of 1.
if (waterMove <= 0) {
waterMove = 1;
}
//-----------------
// calculate top water speed
// make sure groundPoints is multiple of 10
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
enhancedEnteredPoints = Math.ceil(enhancedEnteredPoints / 10) * 10;
enhancedWaterLevelFromPoints = enhancedEnteredPoints / 20;
// make sure enhancedEnteredLevel is multiple of .5
// https://stackoverflow.com/questions/25209849/javascript-round-up-to-nearest-5
enhancedEnteredLevel = Math.ceil(enhancedEnteredLevel * 2) / 2;
totalEnhancedLevel = enhancedEnteredLevel + enhancedWaterLevelFromPoints;
baseEnhancedWaterMove = getEnhancedValue(waterMove, totalEnhancedLevel);
// get the encumbered levels
encumberedDisplayMove0 = waterMove + "/" + baseEnhancedWaterMove;
encumberedDisplayMove1 = getEncumberedMove(waterMove, 1) + "/" + getEncumberedMove(baseEnhancedWaterMove, 1);
encumberedDisplayMove2 = getEncumberedMove(waterMove, 2) + "/" + getEncumberedMove(baseEnhancedWaterMove, 2);
encumberedDisplayMove3 = getEncumberedMove(waterMove, 3) + "/" + getEncumberedMove(baseEnhancedWaterMove, 3);
encumberedDisplayMove4 = getEncumberedMove(waterMove, 4) + "/" + getEncumberedMove(baseEnhancedWaterMove, 4);
encumberedDisplayMove5 = encumberedDisplayMove4;
// check for half move
injuryFatigueMoveModifier = getInjuryFatigueModifier(values.hit_points, values.hit_points_max, values.fatigue_points, values.fatigue_points_max);
// determine the current encumbrance move
switch(values.encumbrance_level) {
case 0:
currentWaterMove = (waterMove * injuryFatigueMoveModifier) + "/" + (baseEnhancedWaterMove * injuryFatigueMoveModifier);
break;
case 1:
currentWaterMove = (getEncumberedMove(waterMove, 1) * injuryFatigueMoveModifier) + "/" + (getEncumberedMove(baseEnhancedWaterMove, 1) * injuryFatigueMoveModifier);
break;
case 2:
currentWaterMove = (getEncumberedMove(waterMove, 2) * injuryFatigueMoveModifier) + "/" + (getEncumberedMove(baseEnhancedWaterMove, 2) * injuryFatigueMoveModifier);
break;
case 3:
currentWaterMove = (getEncumberedMove(waterMove, 3) * injuryFatigueMoveModifier) + "/" + (getEncumberedMove(baseEnhancedWaterMove, 3) * injuryFatigueMoveModifier);
break;
case 4:
case 5:
default:
currentWaterMove = (getEncumberedMove(waterMove, 4) * injuryFatigueMoveModifier) + "/" + (getEncumberedMove(baseEnhancedWaterMove, 4) * injuryFatigueMoveModifier);
break;
}
} else {
//----------------
// calculate water move
waterMoveUnmodified = +values.basic_move;
// determine move
if (values.amphibious_checked == 1) {
// base is basis_move
waterMove = +values.basic_move;
} else {
// base is basis_move / 5
waterMove = +values.basic_move / 5;
}
// add water move modifier
waterMove = waterMove + basicWaterMoveMod;
waterMove = Math.floor(waterMove);
// make sure it's a minimum of 1.
if (waterMove <= 0) {
waterMove = 1;
}
// make sure waterMovePoints is multiple of 5
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
waterMovePoints = Math.ceil(waterMovePoints / 5) * 5;
waterModifierFromPoints = waterMovePoints/5;
// add in the water move from spent points
waterMove = waterMove + waterModifierFromPoints;
baseEnhancedWaterMove = 0;
currentWaterMove = 0;
// get the encumbered levels
encumberedDisplayMove0 = waterMove;
encumberedDisplayMove1 = getEncumberedMove(waterMove, 1);
encumberedDisplayMove2 = getEncumberedMove(waterMove, 2);
encumberedDisplayMove3 = getEncumberedMove(waterMove, 3);
encumberedDisplayMove4 = getEncumberedMove(waterMove, 4);
encumberedDisplayMove5 = encumberedDisplayMove4;
// check for half move
injuryFatigueMoveModifier = getInjuryFatigueModifier(values.hit_points, values.hit_points_max, values.fatigue_points, values.fatigue_points_max);
// determine the current encumbrance move
switch(values.encumbrance_level) {
case 0:
currentWaterMove = (waterMove * injuryFatigueMoveModifier);
break;
case 1:
currentWaterMove = (getEncumberedMove(waterMove, 1) * injuryFatigueMoveModifier);
break;
case 2:
currentWaterMove = (getEncumberedMove(waterMove, 2) * injuryFatigueMoveModifier);
break;
case 3:
currentWaterMove = (getEncumberedMove(waterMove, 3) * injuryFatigueMoveModifier);
break;
case 4:
case 5:
default:
currentWaterMove = (getEncumberedMove(waterMove, 4) * injuryFatigueMoveModifier);
break;
}
}
// set water moves
setAttrs({
"basic_water_move": waterMove,
"basic_water_move_unmodified": waterMoveUnmodified,
"enhanced_water_move": baseEnhancedWaterMove,
"enhanced_water_move_level": totalEnhancedLevel,
"basic_water_move_points": waterMovePoints,
"enhanced_water_move_points": enhancedEnteredPoints,
"water_0": encumberedDisplayMove0,
"water_1": encumberedDisplayMove1,
"water_2": encumberedDisplayMove2,
"water_3": encumberedDisplayMove3,
"water_4": encumberedDisplayMove4,
"water_5": encumberedDisplayMove5,
"current_water": currentWaterMove
});
});
}
// check for changes that affect jump distance
on("change:use_st_for_jump change:jump_skill change:basic_move change:enhanced_ground_move change:super_jump_entered_level change:super_jump_points change:jump_encumbrance change:encumbrance_level change:jump_concentration change:running_jump_yards_moved change:running_high_jump_yards_moved change:strength change:encumbrance_level change:hit_points change:fatigue_points", function(e) {
updateJumpDistanceValues();
});
/**
* Update jump distance values
*/
function updateJumpDistanceValues() {
console.log('***** UPDATE JUMP VALUES *****');
getAttrs(["use_st_for_jump", "jump_skill", "basic_move", "enhanced_ground_move", "super_jump_entered_level",
"super_jump_points", "strength", "jump_concentration", "running_jump_yards_moved", "running_high_jump_yards_moved",
"encumbrance_level", "hit_points", "hit_points_max", "fatigue_points", "fatigue_points_max", "jump_encumbrance", "encumbrance_level"], function(values) {
var jumpSkill = +values.jump_skill;
if (jumpSkill < 0) {
jumpSkill = 0;
}
var jumpST = +values.strength;
if (jumpST < 0) {
jumpST = 0;
}
// + sign converts value to a number
var superJumpPoints = +values.super_jump_points;
// ensure valid superJumpPoints
if (superJumpPoints < 0) {
superJumpPoints = 0;
}
var superJumpEnteredLevel = +values.super_jump_entered_level;
if (superJumpEnteredLevel < 0) {
superJumpEnteredLevel = 0;
}
var basicMove = +values.basic_move;
// ensure valid basicWaterMoveMod
if (basicMove < 0) {
basicMove = 0;
}
// check for super move
var enhancedGroundMove = +values.enhanced_ground_move;
if (enhancedGroundMove < 0) {
enhancedGroundMove = 0;
}
// check for running jump
var runningJumpYardsMoved = +values.running_jump_yards_moved;
runningJumpYardsMoved = Math.floor(runningJumpYardsMoved);
var runningHighJumpYardsMoved = +values.running_high_jump_yards_moved;
runningHighJumpYardsMoved = Math.floor(runningHighJumpYardsMoved);
var runningMoveToUse = 0;
var runningHighMoveToUse = 0;
var jumpBroadFeet = 0;
var jumpBroadYards = 0;
var runningBroadJumpFeet = 0;
var runningBroadJumpYards = 0;
var jumpHighFeet = 0;
var jumpHighYards = 0;
var runningHighJumpFeet = 0;
var runningHighJumpYards = 0;
var superJumpLevelFromPoints = 0;
var totalSuperJumpLevel = 0;
var encumberedDisplayMove0 = "";
var encumberedDisplayMove1 = "";
var encumberedDisplayMove2 = "";
var encumberedDisplayMove3 = "";
var encumberedDisplayMove4 = "";
var encumberedDisplayMove5 = "";
var totalSuperJumpLevel = 0;
var injuryFatigueMoveModifier = 1;
var jumpMoveSpeed = 0;
var finalJumpMoveSpeed = 0;
var statUsedForJump = "";
var statUsedForRunningJump = "";
var baseJumpMove = "";
// calculate broad and high jump
if (jumpSkill > 0) {
// -------------
// USE JUMP SKILL
baseJumpMove = Math.floor(jumpSkill/2);
// calc. standing broad jump
jumpBroadFeet = baseJumpMove;
if (jumpBroadFeet <= 0) {
jumpBroadFeet = 1;
}
statUsedForJump = "Jump Skill/2 = " + jumpBroadFeet;
jumpBroadFeet = (jumpBroadFeet * 2) - 3;
if (jumpBroadFeet <= 0) {
jumpBroadFeet = 1;
}
// calc. running broad jump
if (enhancedGroundMove > Math.floor(jumpSkill/2)) {
// use enhanced move instead of jump skill
statUsedForRunningJump = "Basic Move * (2 ^ Enh MV Mod)";
runningMoveToUse = enhancedGroundMove;
runningHighMoveToUse = enhancedGroundMove;
} else {
// use jump skill for running jump
statUsedForRunningJump = statUsedForJump + " + Yards Run";
runningMoveToUse = Math.floor(jumpSkill/2) + runningJumpYardsMoved;
runningHighMoveToUse = Math.floor(jumpSkill/2) + runningHighJumpYardsMoved;
}
runningBroadJumpFeet = (runningMoveToUse * 2) - 3;
if (runningBroadJumpFeet <= 0) {
runningBroadJumpFeet = 1;
}
// calc. standing high jump
jumpHighFeet = Math.floor(jumpSkill/2);
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
jumpHighFeet = (6 * jumpHighFeet) - 10;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
// convert to feet
// round to 2 decimals
// https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary
jumpHighFeet = Math.round( (jumpHighFeet / 12) * 100) / 100;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
// calc. running high jump
runningHighJumpFeet = (6 * runningHighMoveToUse) - 10;
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
}
// convert to feet
runningHighJumpFeet = Math.floor(runningHighJumpFeet / 12);
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
} else if (runningHighJumpFeet > jumpHighFeet * 2) {
// can't be greater than twice standing broad jump
runningHighJumpFeet = jumpHighFeet * 2;
}
} else if (values.use_st_for_jump == "1") {
//-------------------------------
// USE Strength to determine jump
baseJumpMove = Math.floor(jumpST/4);
// calc. standing broad jump
jumpBroadFeet = baseJumpMove;
if (jumpBroadFeet <= 0) {
jumpBroadFeet = 1;
}
statUsedForJump = "ST / 4 = " + jumpBroadFeet;
jumpBroadFeet = (jumpBroadFeet * 2) - 3;
if (jumpBroadFeet <= 0) {
jumpBroadFeet = 1;
}
// calc. running broad jump
if (enhancedGroundMove > Math.floor(jumpST/4)) {
// use enhanced move instead of strength
statUsedForRunningJump = "Basic Move * (2 ^ Enh MV Mod)";
runningMoveToUse = enhancedGroundMove;
runningHighMoveToUse = enhancedGroundMove;
} else {
statUsedForRunningJump = statUsedForJump + " + Yards Run";
runningMoveToUse = Math.floor(jumpST/4) + runningJumpYardsMoved;
runningHighMoveToUse = Math.floor(jumpST/2) + runningHighJumpYardsMoved;
}
runningBroadJumpFeet = (runningMoveToUse * 2) - 3;
if (runningBroadJumpFeet <= 0) {
runningBroadJumpFeet = 1;
}
// calc. standing high jump
jumpHighFeet = Math.floor(jumpST/4);
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
jumpHighFeet = (6 * jumpHighFeet) - 10;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
// convert to feet
// round to 2 decimals
// https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary
jumpHighFeet = Math.round( (jumpHighFeet / 12) * 100) / 100;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
// calc. running high jump
runningHighJumpFeet = (6 * runningHighMoveToUse) - 10;
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
}
// convert to feet
runningHighJumpFeet = Math.floor(runningHighJumpFeet / 12);
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
} else if (runningHighJumpFeet > jumpHighFeet * 2) {
// can't be greater than twice standing broad jump
runningHighJumpFeet = jumpHighFeet * 2;
}
} else {
//---------------
// USE Basic Move
baseJumpMove = basicMove;
statUsedForJump = "Basic Move = " + basicMove;
// calc. standing broad jump
jumpBroadFeet = (basicMove * 2) - 3;
if (jumpBroadFeet <= 0) {
jumpBroadFeet = 1;
}
// calc. running broad jump
if (enhancedGroundMove > basicMove) {
// use enhanced move instead of strength
statUsedForRunningJump = "Basic Move * (2 ^ Enh MV Mod)";
runningMoveToUse = enhancedGroundMove;
runningHighMoveToUse = enhancedGroundMove;
} else {
statUsedForRunningJump = statUsedForJump + " + Yards Run";
runningMoveToUse = basicMove + runningJumpYardsMoved;
runningHighMoveToUse = basicMove + runningHighJumpYardsMoved;
}
runningBroadJumpFeet = (runningMoveToUse * 2) - 3;
if (runningBroadJumpFeet <= 0) {
runningBroadJumpFeet = 1;
} else if (runningBroadJumpFeet > jumpBroadFeet * 2) {
// can't be greater than twice standing broad jump
runningBroadJumpFeet = jumpBroadFeet * 2;
}
// calc. high jump
jumpHighFeet = (6 * basicMove) - 10;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
// convert to feet
// round to 2 decimals
// https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary
jumpHighFeet = Math.round( (jumpHighFeet / 12) * 100) / 100;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
// calc. running high jump
runningHighJumpFeet = (6 * runningHighMoveToUse) - 10;
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
}
// convert to feet
runningHighJumpFeet = Math.floor(runningHighJumpFeet / 12);
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
} else if (runningHighJumpFeet > jumpHighFeet * 2) {
// can't be greater than twice standing broad jump
runningHighJumpFeet = jumpHighFeet * 2;
}
}
// If no concentration, divide distance by 2
if (values.jump_concentration != "1") {
jumpBroadFeet = Math.floor(jumpBroadFeet / 2);
if (jumpBroadFeet <= 0) {
jumpBroadFeet = 1;
}
runningBroadJumpFeet = Math.floor(runningBroadJumpFeet / 2);
if (runningBroadJumpFeet <= 0 ) {
runningBroadJumpFeet = 1;
}
// reduce in half
// round to 2 decimals
// https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary
jumpHighFeet = Math.round( (jumpHighFeet / 2) * 100) / 100;
if (jumpHighFeet <= 0) {
jumpHighFeet = 1;
}
runningHighJumpFeet = Math.floor(runningHighJumpFeet / 2);
if (runningHighJumpFeet <= 0) {
runningHighJumpFeet = 1;
}
}
// check for super jump
if (superJumpPoints > 0 || superJumpEnteredLevel > 0) {
//-----------------
// calculate super jump
// make sure points is multiple of 10
// https://stackoverflow.com/questions/18953384/javascript-round-up-to-the-next-multiple-of-5
superJumpPoints = Math.ceil(superJumpPoints / 10) * 10;
superJumpLevelFromPoints = superJumpPoints / 10;
// -------
// make sure entered super jump level is an integer, min of 1
superJumpEnteredLevel = Math.floor(superJumpEnteredLevel);
if (superJumpEnteredLevel < 0) {
superJumpEnteredLevel = 0;
}
totalSuperJumpLevel = superJumpEnteredLevel + superJumpLevelFromPoints;
// get the new jump feet values based on super level
jumpBroadFeet = getEnhancedValue(jumpBroadFeet, totalSuperJumpLevel);
runningBroadJumpFeet = getEnhancedValue(runningBroadJumpFeet, totalSuperJumpLevel);
jumpHighFeet = getEnhancedValue(jumpHighFeet, totalSuperJumpLevel);
runningHighJumpFeet = getEnhancedValue(runningHighJumpFeet, totalSuperJumpLevel);
}
// check for encumbrance
if (+values.jump_encumbrance === 1) {
switch(+values.encumbrance_level) {
default:
case 0:
// do nothing
break;
case 1:
// Light
jumpBroadFeet = Math.round( (jumpBroadFeet * .8) * 100) / 100;
runningBroadJumpFeet = Math.round( (runningBroadJumpFeet * .8) * 100) / 100;
jumpHighFeet = Math.round( (jumpHighFeet * .8) * 100) / 100;
runningHighJumpFeet = Math.round( (runningHighJumpFeet * .8) * 100) / 100;
break;
case 2:
// Medium
jumpBroadFeet = Math.round( (jumpBroadFeet * .6) * 100) / 100;
runningBroadJumpFeet = Math.round( (runningBroadJumpFeet * .6) * 100) / 100;
jumpHighFeet = Math.round( (jumpHighFeet * .6) * 100) / 100;
runningHighJumpFeet = Math.round( (runningHighJumpFeet * .6) * 100) / 100;
break;
case 3:
// Heavy
jumpBroadFeet = Math.round( (jumpBroadFeet * .4) * 100) / 100;
runningBroadJumpFeet = Math.round( (runningBroadJumpFeet * .4) * 100) / 100;
jumpHighFeet = Math.round( (jumpHighFeet * .4) * 100) / 100;
runningHighJumpFeet = Math.round( (runningHighJumpFeet * .4) * 100) / 100;
break;
case 4:
// Extra-Heavy
jumpBroadFeet = Math.round( (jumpBroadFeet * .2) * 100) / 100;
runningBroadJumpFeet = Math.round( (runningBroadJumpFeet * .2) * 100) / 100;
jumpHighFeet = Math.round( (jumpHighFeet * .2) * 100) / 100;
runningHighJumpFeet = Math.round( (runningHighJumpFeet * .2) * 100) / 100;
break;
}
}
// get broad jump in yards. Minimum of 1
jumpBroadYards = Math.round( (jumpBroadFeet / 3) * 100) / 100;
// get running jump in yards. Min of 1
runningBroadJumpYards = Math.round( (runningBroadJumpFeet / 3) * 100) / 100;
// get high jump in yards
jumpHighYards = Math.round( (jumpHighFeet / 3) * 100) / 100;
// get running high in yards
runningHighJumpYards = Math.round( (runningHighJumpFeet / 3) * 100) / 100;
// calculate jump move speed
jumpMoveSpeed = Math.floor(jumpBroadYards / 5);
if (jumpMoveSpeed <= 0) {
jumpMoveSpeed = 1;
}
// determine which one to use
if (jumpMoveSpeed > basicMove) {
finalJumpMoveSpeed = jumpMoveSpeed;
} else {
finalJumpMoveSpeed = basicMove;
}
// set jump distances
setAttrs({
"broad_jump_distance_feet": jumpBroadFeet,
"broad_jump_distance_yards": jumpBroadYards,
"high_jump_distance_feet": jumpHighFeet,
"high_jump_distance_yards": jumpHighYards,
"super_jump_level": totalSuperJumpLevel,
"super_jump_entered_level": superJumpEnteredLevel,
"super_jump_points": superJumpPoints,
"running_jump_distance_feet": runningBroadJumpFeet,
"running_jump_distance_yards": runningBroadJumpYards,
"running_high_jump_distance_feet": runningHighJumpFeet,
"running_high_jump_distance_yards": runningHighJumpYards,
"broad_jump_base": baseJumpMove,
"standing_broad_jump_stat_to_use": statUsedForJump,
"running_broad_jump_stat_to_use": statUsedForRunningJump,
"high_jump_base": baseJumpMove,
"standing_high_jump_stat_to_use": statUsedForJump,
"running_high_jump_stat_to_use": statUsedForRunningJump,
"jump_move_speed": finalJumpMoveSpeed
});
});
}
// set note values for damage types
// Update thrust and swing when striking st is updated
on('change:repeating_melee:type', function(event){
getAttrs(['repeating_melee_type',
'damage_type_note_cut',
'damage_type_note_imp',
'damage_type_note_cr',
'damage_type_note_pi_minus',
'damage_type_note_pi',
'damage_type_note_pi_plus',
'damage_type_note_pi_plus_plus',
'damage_type_note_aff',
'damage_type_note_burn',
'damage_type_note_cor',
'damage_type_note_fat',
'damage_type_note_tox',
'damage_type_note_spec'
], function(values) {
var typeNote = getDamageTypeNote(values.repeating_melee_type, values);
var minDamageNote = getMinimumDamageNote(values.repeating_melee_type);
setAttrs({
"repeating_melee_damage_type_note": typeNote,
"repeating_melee_minimum_damage_note": minDamageNote,
});
});
});
// set note values for damage types
// Update thrust and swing when striking st is updated
on('change:repeating_ranged:type', function(event){
getAttrs(['repeating_ranged_type',
'damage_type_note_cut',
'damage_type_note_imp',
'damage_type_note_cr',
'damage_type_note_pi_minus',
'damage_type_note_pi',
'damage_type_note_pi_plus',
'damage_type_note_pi_plus_plus',
'damage_type_note_aff',
'damage_type_note_burn',
'damage_type_note_cor',
'damage_type_note_fat',
'damage_type_note_tox',
'damage_type_note_spec'
], function(values) {
var typeNote = getDamageTypeNote(values.repeating_ranged_type, values);
var minDamageNote = getMinimumDamageNote(values.repeating_ranged_type);
setAttrs({
"repeating_ranged_damage_type_note": typeNote,
"repeating_ranged_minimum_damage_note": minDamageNote,
});
});
});
// update damage notes for thrown object
on('change:thrown_object_damage_type', function(event) {
updateThrownObject();
});
/*
* Update the thrown object weight damage notes
*/
function updateThrownObject() {
getAttrs(['thrown_object_damage_type',
'damage_type_note_cut',
'damage_type_note_imp',
'damage_type_note_cr',
'damage_type_note_pi_minus',
'damage_type_note_pi',
'damage_type_note_pi_plus',
'damage_type_note_pi_plus_plus',
'damage_type_note_aff',
'damage_type_note_burn',
'damage_type_note_cor',
'damage_type_note_fat',
'damage_type_note_tox',
'damage_type_note_spec'
], function(values) {
var typeNote = getDamageTypeNote(values.thrown_object_damage_type, values);
var minDamageNote = getMinimumDamageNote(values.thrown_object_damage_type);
setAttrs({
"thrown_object_damage_type_note": typeNote,
"thrown_minimum_damage_note": minDamageNote,
});
} );
}
/**
* Get Damage Type Note for damage type string
* Used for adding custom notes to rolltemplates
*/
function getDamageTypeNote(damageType, values) {
var typeNote = "";
switch(damageType) {
case "Cutting (cut)":
typeNote = values.damage_type_note_cut;
break;
case "Impaling (imp)":
typeNote = values.damage_type_note_imp;
break;
case "Crushing (cr)":
typeNote = values.damage_type_note_cr;
break;
case "Small Piercing (pi-)":
typeNote = values.damage_type_note_pi_minus;
break;
case "Piercing (pi)":
typeNote = values.damage_type_note_pi;
break;
case "Large Piercing (pi+)":
typeNote = values.damage_type_note_pi_plus;
break;
case "Huge Piercing (pi++)":
typeNote = values.damage_type_note_pi_plus_plus;
break;
case "Affliction (aff)":
typeNote = values.damage_type_note_aff;
break;
case "Burning (burn)":
typeNote = values.damage_type_note_burn;
break;
case "Corrosion (cor)":
typeNote = values.damage_type_note_cor;
break;
case "Fatigue (fat)":
typeNote = values.damage_type_note_fat;
break;
case "Toxic (tox)":
typeNote = values.damage_type_note_tox;
break;
case "Special (spec)":
typeNote = values.damage_type_note_spec;
break;
default:
typeNote = values.damage_type_note_cut;
}
return typeNote;
}
/*
* Loop through each repeating section
* for melee and ranged and update
* damage notes to match damage type
*
*/
function updateDamageNotes() {
// note field values
var noteFields = ['damage_type_note_cut',
'damage_type_note_imp',
'damage_type_note_cr',
'damage_type_note_pi_minus',
'damage_type_note_pi',
'damage_type_note_pi_plus',
'damage_type_note_pi_plus_plus',
'damage_type_note_aff',
'damage_type_note_burn',
'damage_type_note_cor',
'damage_type_note_fat',
'damage_type_note_tox',
'damage_type_note_spec'
];
getAttrs(noteFields, function(noteFieldValues) {
updateDamageNotesBySection("melee", noteFieldValues);
updateDamageNotesBySection("ranged", noteFieldValues);
});
}
/*
* Update damage notes for a section
*
* @param string sectionName melee | ranged
* @param object noteFieldValues Note Content for each damage type
*/
function updateDamageNotesBySection(sectionName, noteFieldValues) {
console.log('********* updateDamageNotesBySection ' + sectionName + '*********');
getSectionIDs(sectionName, function (ids) {
if (ids.length === 0 ) {
return;
}
var getFields = [];
// loop through the rows
for (var i = 0; i < ids.length; i++) {
// field that determines note
var damageTypeField = "repeating_" + sectionName + '_' + ids[i] + '_type';
getFields.push(damageTypeField);
}
getAttrs(getFields, function (values) {
var updateFields = {};
// loop through the row ids again so we can get the values
// and fill array of note values to update
_.each(ids, function(id) {
var damageTypeField = "repeating_" + sectionName + '_' + id + '_type';
// field we need to update
var damageTypeNoteField = "repeating_" + sectionName + '_' + id + '_damage_type_note';
var type = values[damageTypeField];
var note = getDamageTypeNote(type, noteFieldValues);
var minDamageNote = getMinimumDamageNote(type);
var minDamageNoteField = `repeating_${sectionName}_${id}_minimum_damage_note`;
updateFields[damageTypeNoteField] = note;
updateFields[minDamageNoteField] = minDamageNote;
});
setAttrs(updateFields);
});
});
}
// check for changes that affect thrown object stats
on('change:thrown_object_weight change:striking_st change:basic_lift change:super_throw_level change:thrown_object_strength_mod change:thrown_object_damage_mod', function(event) {
updateThrownObjectStats();
});
/**
* Update thrown objects stats
* Damage, range, etc.
*/
function updateThrownObjectStats() {
console.log("*********** Updating Thrown Object Stats ***********");
var fields = ['thrown_object_weight',
'striking_st',
'thrown_object_strength_mod',
'super_throw_level',
'thrust',
'basic_lift',
'thrown_object_damage_mod'
];
getAttrs(fields, function (values) {
var weight = +values.thrown_object_weight;
var basicLift = +values.basic_lift;
var throwingST = +values.striking_st;
var throwingStMod = parseInt(values.thrown_object_strength_mod);
var superThrowLvl = parseInt(values.super_throw_level);
var enteredDamageMod = parseInt(values.thrown_object_damage_mod);
var damageMod = 0;
throwingST = throwingST + throwingStMod;
if (weight < 1) {
weight = 0;
}
if (basicLift < 0) {
basicLift = 1;
}
if (superThrowLvl < 0) {
superThrowLvl = 0;
}
var weightRatio = weight/basicLift;
var distanceMod = distanceModifier(weightRatio);
var distance = throwingST * distanceMod;
var damageMod = getThrownDamageModifier(basicLift, weight);
// check for super throw
if (superThrowLvl > 0) {
distance = distance * Math.pow(2,superThrowLvl);
damageMod = damageMod + (superThrowLvl * 2);
}
// check to see if they entered a modifier
if (enteredDamageMod != 0) {
damageMod = damageMod + enteredDamageMod;
}
distance = Math.floor(distance);
var finalDamage = getModifiedDamage(values.thrust, damageMod);
//
setAttrs({
'thrown_object_strength': throwingST,
'thrown_object_range': distance,
'thrown_object_damage': finalDamage
});
});
}
/*
* Get damage modifier
*
* @param int basicLift In pounds
* @param int weight Weight of thrown object
*
* @return int
*/
function getThrownDamageModifier(basicLift, weight) {
var damageMod = 0;
if (weight <= Math.floor(basicLift/8)) {
damageMod = -2;
} else if (Math.floor(basicLift/8) < weight && weight <= Math.floor(basicLift/4)) {
damageMod = -1;
} else if (Math.floor(basicLift/4) < weight && weight <= Math.floor(basicLift/2)) {
damageMod = 0;
} else if (Math.floor(basicLift/2) < weight && weight <= Math.floor(basicLift)) {
damageMod = 1;
} else if (Math.floor(basicLift) < weight && weight <= Math.floor(basicLift*2)) {
damageMod = 0;
} else if (Math.floor(basicLift*2) < weight && weight <= Math.floor(basicLift*4)) {
damageMod = -.5;
} else if (Math.floor(basicLift*4) < weight && weight <= Math.floor(basicLift*8)) {
damageMod = -1;
} else {
damageMod = -10;
}
return damageMod;
}
/*
* Get distance modifier based on ratio
*
* @param decimal weightRatio Object Weight/Basic Lift
*
* @return decimal
*/
function distanceModifier(weightRatio) {
var distanceMod = 0;
if (weightRatio <= .05) {
distanceMod = 3.5;
} else if (.05 < weightRatio && weightRatio <= .10) {
distanceMod = 2.5;
} else if (.10 < weightRatio && weightRatio <= .15) {
distanceMod = 2.0;
} else if (.15 < weightRatio && weightRatio <= .20) {
distanceMod = 1.5;
} else if (.20 < weightRatio && weightRatio <= .25) {
distanceMod = 1.2;
} else if (.25 < weightRatio && weightRatio <= .30) {
distanceMod = 1.1;
} else if (.30 < weightRatio && weightRatio <= .40) {
distanceMod = 1.0;
} else if (.40 < weightRatio && weightRatio <= .50) {
distanceMod = .8;
} else if (.50 < weightRatio && weightRatio <= .75) {
distanceMod = .7;
} else if (.75 < weightRatio && weightRatio <= 1.00) {
distanceMod = .6;
} else if (1.00 < weightRatio && weightRatio <= 1.50) {
distanceMod = .4;
} else if (1.50 < weightRatio && weightRatio <= 2.0) {
distanceMod = .30;
} else if (2.0 < weightRatio && weightRatio <= 2.5) {
distanceMod = .25;
} else if (2.5 < weightRatio && weightRatio <= 3.0) {
distanceMod = .20;
} else if (3.0 < weightRatio && weightRatio <= 4.0) {
distanceMod = .15;
} else if (4.0 < weightRatio && weightRatio <= 5.0) {
distanceMod = .12;
} else if (5.0 < weightRatio && weightRatio <= 6.0) {
distanceMod = .10;
} else if (6.0 < weightRatio && weightRatio <= 7.0) {
distanceMod = .09;
} else if (7.0 < weightRatio && weightRatio <= 8.0) {
distanceMod = .08;
} else if (8.0 < weightRatio && weightRatio <= 9.0) {
distanceMod = .07;
} else if (9.0 < weightRatio && weightRatio <= 10.0) {
distanceMod = .06;
} else if (10.0 < weightRatio && weightRatio <= 12.0) {
distanceMod = .05;
} else {
distanceMod = 0;
}
return distanceMod;
}
/**
* Determines the final damage dice + modifier
*
* @param string damageDice Original damage dice; 3d6
* @param int damageMod Damage modifier per dice; +1 per dice
*
* @return string Modified damge dice
*/
function getModifiedDamage(damageDice, damageMod) {
var newDamageDice = damageDice;
damageDice = damageDice.toLowerCase();
// split into array.
// 3d6 = [3,6]
var arrDice = damageDice.split("d");
if (arrDice.length == 2) {
var diceCount = parseInt(arrDice[0]);
var diceType = arrDice[1];
var arrDiceTypeModifier = [];
var diceModifier = "";
if (diceCount < 1) {
diceCount = 1;
}
// check for dice modifier
// 3d6+1; diceType = 6+1; diceType=6; diceModifier=1;
if (diceType.includes("+")) {
arrDiceTypeModifier = diceType.split("+");
diceType = arrDiceTypeModifier[0];
diceModifier = parseInt(arrDiceTypeModifier[1]);
} else if (diceType.includes("-")) {
arrDiceTypeModifier = diceType.split("-");
diceType = arrDiceTypeModifier[0];
diceModifier = -1 * parseInt(arrDiceTypeModifier[1]);
} else {
diceModifier = 0;
}
newDamageDice = diceCount + "d" + diceType;
// get the final damage modifier
damageMod = Math.floor(damageMod + diceModifier);
if (damageMod < 0) {
damageMod = Math.abs(damageMod) * diceCount;
newDamageDice = newDamageDice + "-" + damageMod;
} else if (damageMod > 0) {
damageMod = Math.abs(damageMod) * diceCount;
newDamageDice = newDamageDice + "+" + damageMod;
}
}
return newDamageDice;
}
on("clicked:range_calc_reset", function() {
resetRangeCalculator();
});
function resetRangeCalculator() {
setAttrs(
{
"firing_distance": 0,
"firing_speed_difference": 0,
"firing_size_mod": 0,
"firing_direction": "linear",
"firing_up_dwn_distance": 0
});
}
// Range Calculator
on('change:firing_distance change:firing_speed_difference change:firing_size_mod change:firing_direction change:firing_up_dwn_distance', function(event) {
updateRangeModifier();
});
/**
* Determine new range based on fields
* and then get the final to hit modifier
*/
function updateRangeModifier() {
var fields = [
"firing_distance",
"firing_speed_difference",
"firing_size_mod",
"firing_direction",
"firing_up_dwn_distance"
];
getAttrs(fields, function(values) {
var linearDistance = +values.firing_distance;
var sizeMod = +values.firing_size_mod;
var speed = +values.firing_speed_difference;
var elevation = +values.firing_up_dwn_distance;
var elevationDown = 0;
var rangeToTarget = 0;
var speedRangeValue = 0;
var finalSpeedRangeValue = 0;
// make sure value is valid
if (linearDistance < 0)
linearDistance = 0;
if (elevation > 0 && values.firing_direction == "up") {
rangeToTarget = linearDistance + elevation;
} else if (elevation > 0 && values.firing_direction == "dn") {
elevationDown = Math.floor(elevation/2);
// max elevation is half of ground distance
if (elevationDown > Math.floor(linearDistance/2)) {
elevationDown = Math.floor(linearDistance/2);
}
rangeToTarget = linearDistance - elevationDown;
} else {
rangeToTarget = linearDistance;
}
finalSpeedRangeValue = rangeToTarget + speed;
var hitModifier = getModBySpeedRange(finalSpeedRangeValue);
// add in size modifier
hitModifier = hitModifier + sizeMod;
setAttrs({
'firing_new_range': finalSpeedRangeValue,
'firing_hit_mod': hitModifier
});
});
}
// check to see if modifier for fright check threshold changed
on("change:fright_check_threshold_mod", function(event) {
updateFrightCheckThreshold();
});
function updateFrightCheckThreshold() {
var fields = [
"fright_check_threshold_mod"
];
getAttrs(fields, function(values) {
var base = 13;
var mod = +values.fright_check_threshold_mod;
var final = base + mod;
setAttrs({
"fright_check_threshold": final
});
});
}
// when button is clicked, show the updates tab
on("clicked:view_updates_tab", function() {
setAttrs({
"tab": 7
});
});
on("change:yards_fallen change:gravity change:atmosphere", function() {
var fields = [
"yards_fallen",
"gravity",
"atmosphere"
];
getAttrs(fields, function(values) {
var yards = Math.floor(+values.yards_fallen);
var gravity = +values.gravity;
var atmosphere = +values.atmosphere;
if (yards <= 0)
yards = 1;
if (gravity < 0)
gravity = 1;
if (atmosphere < 0)
atmosphere = 1;
var velocity = (Math.sqrt(gravity * 21.4 * yards) / Math.sqrt(atmosphere));
velocity = Math.round(velocity);
setAttrs({
falling_velocity: velocity
});
});
});
// handle falling/collision damage
on("change:falling_velocity change:falling_hit_points", function() {
var strDmg = "";
getAttrs(["falling_velocity", "falling_hit_points"], function(values) {
strDmg = getCollisionDamage(values.falling_velocity, values.falling_hit_points);
setAttrs({
"falling_damage": strDmg
});
});
});
on("change:collision_velocity change:collision_hit_points", function() {
var strDmg = "";
getAttrs(["collision_velocity", "collision_hit_points"], function(values) {
strDmg = getCollisionDamage(values.collision_velocity, values.collision_hit_points);
setAttrs({
"collision_damage": strDmg
});
});
});
function getCollisionDamage(velocity, hit_points) {
var strDmg = "1d6-3";
var remainder = 0;
velocity = +velocity;
if (velocity <= 0) {
velocity = 1;
}
hit_points = +hit_points;
if (hit_points <= 0) {
hit_points = 1;
}
var ratio = (hit_points*velocity)/100;
if (ratio <= .25) {
strDmg = "1d6-3";
} else if (ratio <= .5) {
strDmg = "1d6-2";
} else if (ratio < 1) {
strDmg = "1d6-1";
} else {
remainder = ratio % 1;
if (remainder < .5) {
strDmg = Math.floor(ratio) + "d6";
} else {
strDmg = Math.ceil(ratio) + "d6";
}
}
return strDmg;
}
on("clicked:falling_reset", function() {
setAttrs({
"yards_fallen": 1,
"gravity": 1,
"atmosphere": 1,
"falling_hit_points": 10
});
});
on("clicked:collision_reset", function() {
setAttrs({
"collision_velocity": 1,
"collision_hit_points": 10
});
});
// If defense type changed, update hidden defense type
on('change:repeating_defense:type', function(event){
getAttrs(['repeating_defense_type'], function(v) {
var defenseTypeName = v.repeating_defense_type;
var defenseTypeId = 1;
// <option>Dodge</option> = 1
// <option>Parry</option> = 2
// <option>Block</option> = 3
// <option>Magic</option> = 4
// <option>Other</option> = 5
defenseTypeName = defenseTypeName.toLowerCase();
switch(defenseTypeName) {
case "parry":
defenseTypeId = 2;
break;
case "block":
defenseTypeId = 3;
break;
case "magic":
defenseTypeId = 4;
break;
case "block":
defenseTypeId = 5;
break;
default:
case "dodge":
defenseTypeId = 1;
break;
}
// set the hidden value
setAttrs({
repeating_defense_defense_type: defenseTypeId
});
});
});
/**
* When loading a new version, make sure defense_type is updated
* for each item in the row.
*/
function updateRepeatingDefenseTypes() {
console.log('********* updateRepeatingDefenseTypes *********');
var sectionName = "repeating_defense";
getSectionIDs(sectionName, function (ids) {
if (ids.length === 0 ) {
return;
}
var getFields = [];
// loop through the rows
for (var i = 0; i < ids.length; i++) {
// field that determines defense type
var damageTypeField = "repeating_defense_" + ids[i] + '_type';
getFields.push(damageTypeField);
}
getAttrs(getFields, function (values) {
var updateFields = {};
// loop through the row ids again so we can get the values
// and fill array of defense_type id numbers
_.each(ids, function(id) {
var defenseTypeField = "repeating_defense_" + id + '_type';
// field we need to update
var defenseTypeIdField = "repeating_defense_" + id + '_defense_type';
var defenseName = values[defenseTypeField];
// determine id based on defense type name
var defenseTypeId = 0;
switch (defenseName.toLowerCase()) {
case "parry":
defenseTypeId = 2;
break;
case "block":
defenseTypeId = 3;
break;
case "magic":
defenseTypeId = 4;
break;
case "block":
defenseTypeId = 5;
break;
default:
case "dodge":
defenseTypeId = 1;
break;
}
// update the defense type id number
updateFields[defenseTypeIdField] = defenseTypeId;
});
setAttrs(updateFields);
});
});
}
on("change:damage_type_note_cut", function() {
getAttrs(["damage_type_note_cut"], function(values) {
updateMeleeCombatWoundNotes("Cutting (cut)", values.damage_type_note_cut);
updateRangedCombatWoundNotes("Cutting (cut)", values.damage_type_note_cut);
updateCombatToolThrownDamageType("Cutting (cut)", values.damage_type_note_cut);
});
});
on("change:damage_type_note_imp", function() {
getAttrs(["damage_type_note_imp"], function(values) {
updateMeleeCombatWoundNotes("Impaling (imp)", values.damage_type_note_imp);
updateRangedCombatWoundNotes("Impaling (imp)", values.damage_type_note_imp);
updateCombatToolThrownDamageType("Impaling (imp)", values.damage_type_note_imp);
});
});
on("change:damage_type_note_cr", function() {
getAttrs(["damage_type_note_cr"], function(values) {
updateMeleeCombatWoundNotes("Crushing (cr)", values.damage_type_note_cr);
updateRangedCombatWoundNotes("Crushing (cr)", values.damage_type_note_cr);
updateCombatToolThrownDamageType("Crushing (cr)", values.damage_type_note_cr);
});
});
on("change:damage_type_note_pi_minus", function() {
getAttrs(["damage_type_note_pi_minus"], function(values) {
updateMeleeCombatWoundNotes("Small Piercing (pi-)", values.damage_type_note_pi_minus);
updateRangedCombatWoundNotes("Small Piercing (pi-)", values.damage_type_note_pi_minus);
updateCombatToolThrownDamageType("Small Piercing (pi-)", values.damage_type_note_pi_minus);
});
});
on("change:damage_type_note_pi", function() {
getAttrs(["damage_type_note_pi"], function(values) {
updateMeleeCombatWoundNotes("Piercing (pi)", values.damage_type_note_pi);
updateRangedCombatWoundNotes("Piercing (pi)", values.damage_type_note_pi);
updateCombatToolThrownDamageType("Piercing (pi)", values.damage_type_note_pi);
});
});
on("change:damage_type_note_pi_plus", function() {
getAttrs(["damage_type_note_pi_plus"], function(values) {
updateMeleeCombatWoundNotes("Large Piercing (pi+)", values.damage_type_note_pi_plus);
updateRangedCombatWoundNotes("Large Piercing (pi+)", values.damage_type_note_pi_plus);
updateCombatToolThrownDamageType("Large Piercing (pi+)", values.damage_type_note_pi_plus);
});
});
on("change:damage_type_note_pi_plus_plus", function() {
getAttrs(["damage_type_note_pi_plus_plus"], function(values) {
updateMeleeCombatWoundNotes("Huge Piercing (pi++)", values.damage_type_note_pi_plus_plus);
updateRangedCombatWoundNotes("Huge Piercing (pi++)", values.damage_type_note_pi_plus_plus);
updateCombatToolThrownDamageType("Huge Piercing (pi++)", values.damage_type_note_pi_plus_plus);
});
});
on("change:damage_type_note_aff", function() {
getAttrs(["damage_type_note_aff"], function(values) {
updateMeleeCombatWoundNotes("Affliction (aff)", values.damage_type_note_aff);
updateRangedCombatWoundNotes("Affliction (aff)", values.damage_type_note_aff);
updateCombatToolThrownDamageType("Affliction (aff)", values.damage_type_note_aff);
});
});
on("change:damage_type_note_burn", function() {
getAttrs(["damage_type_note_burn"], function(values) {
updateMeleeCombatWoundNotes("Burning (burn)", values.damage_type_note_burn);
updateRangedCombatWoundNotes("Burning (burn)", values.damage_type_note_burn);
updateCombatToolThrownDamageType("Burning (burn)", values.damage_type_note_burn);
});
});
on("change:damage_type_note_cor", function() {
getAttrs(["damage_type_note_cor"], function(values) {
updateMeleeCombatWoundNotes("Corrosion (cor)", values.damage_type_note_cor);
updateRangedCombatWoundNotes("Corrosion (cor)", values.damage_type_note_cor);
updateCombatToolThrownDamageType("Corrosion (cor)", values.damage_type_note_cor);
});
});
on("change:damage_type_note_fat", function() {
getAttrs(["damage_type_note_fat"], function(values) {
updateMeleeCombatWoundNotes("Fatigue (fat)", values.damage_type_note_fat);
updateRangedCombatWoundNotes("Fatigue (fat)", values.damage_type_note_fat);
updateCombatToolThrownDamageType("Fatigue (fat)", values.damage_type_note_fat);
});
});
on("change:damage_type_note_tox", function() {
getAttrs(["damage_type_note_tox"], function(values) {
updateMeleeCombatWoundNotes("Toxic (tox)", values.damage_type_note_tox);
updateRangedCombatWoundNotes("Toxic (tox)", values.damage_type_note_tox);
updateCombatToolThrownDamageType("Toxic (tox)", values.damage_type_note_tox);
});
});
on("change:damage_type_note_spec", function() {
getAttrs(["damage_type_note_spec"], function(values) {
updateMeleeCombatWoundNotes("Special (spec)", values.damage_type_note_spec);
updateRangedCombatWoundNotes("Special (spec)", values.damage_type_note_spec);
updateCombatToolThrownDamageType("Special (spec)", values.damage_type_note_spec);
});
});
/**
* Update the damage types for repeating tables
* Find damage types that match the one that was updated.
* Replace the note with the new note.
*
* @param damageType Type of damage to update
* @param damageNote Damage note to use
*/
function updateMeleeCombatWoundNotes(damageType, damageNote) {
var updateAttrs = {};
// repeating_melee | repeating_ranged
getSectionIDs("repeating_melee", function (ids) {
if (ids.length === 0 ) {
return;
}
var getFields = [];
// loop through the rows
for (var i = 0; i < ids.length; i++) {
// field that determines defense type
var damageTypeField = "repeating_melee_" + ids[i] + '_type';
getFields.push(damageTypeField);
}
getAttrs(getFields, function (values) {
var updateFields = {};
// loop through the row ids again so we can get the values
// and fill array of defense_type id numbers
_.each(ids, function(id) {
var damageTypeField = "repeating_melee_" + id + '_type';
// field we need to update
var fieldToUpdate = "repeating_melee_" + id + '_damage_type_note';
var damageTypeValue = values[damageTypeField];
if (damageTypeValue === damageType) {
// update the defense type id number
updateFields[fieldToUpdate] = damageNote;
}
});
setAttrs(updateFields);
});
});
}
/**
* Update the damage types for repeating tables
* Find damage types that match the one that was updated.
* Replace the note with the new note.
*
* @param damageType Type of damage to update
* @param damageNote Damage not to use
*/
function updateRangedCombatWoundNotes(damageType, damageNote) {
var updateAttrs = {};
getSectionIDs("repeating_ranged", function (ids) {
if (ids.length === 0 ) {
return;
}
var getFields = [];
// loop through the rows
for (var i = 0; i < ids.length; i++) {
// field that determines defense type
var damageTypeField = "repeating_ranged_" + ids[i] + '_type';
getFields.push(damageTypeField);
}
getAttrs(getFields, function (values) {
var updateFields = {};
// loop through the row ids again so we can get the values
// and fill array of defense_type id numbers
_.each(ids, function(id) {
var damageTypeField = "repeating_ranged_" + id + '_type';
// field we need to update
var fieldToUpdate = "repeating_ranged_" + id + '_damage_type_note';
var damageTypeValue = values[damageTypeField];
if (damageTypeValue === damageType) {
// update the defense type id number
updateFields[fieldToUpdate] = damageNote;
}
});
setAttrs(updateFields);
});
});
}
/**
* Update the damage type now for the combat tool thrown damage
*
* @param damageType
* @param damageNote
*/
function updateCombatToolThrownDamageType(damageType, damageNote) {
getAttrs(["thrown_object_damage_type"], function (values) {
if (damageType === values.thrown_object_damage_type) {
setAttrs({
"thrown_object_damage_type_note": damageNote,
});
}
});
}
on("change:repeating_defense:info", function(event) {
updateDefenseNote();
});
/**
* Update the defense note.
*/
function updateDefenseNote() {
getAttrs(['repeating_defense_info'], function(values) {
var note = getDefenseNote(values.repeating_defense_info);
// update the note
setAttrs({
repeating_defense_info_description: note
});
});
}
/**
* Get defense note based on initial defense info field
*
* @param defenseInfo
*
* @return string
*/
function getDefenseNote(defenseInfo) {
var note = "";
switch(defenseInfo.toLowerCase()) {
case "u":
note = "Info: U\nThe weapon is unbalanced. You cannot use it to parry if you've already attacked with it this turn.\nSee B208";
break;
case "f":
note = "Info: F\nThis is a fencing weapon. +3 to retreat, instead of +1. -2 for each additional parry for the round.\nSee B208";
break;
case "":
note = "";
break;
default:
note = "Info: " + values.repeating_defense_info;
break;
}
return note;
}
/**
* If new version, make sure to update the
* defensive notes.
*/
function updateRepeatingDefenseNotes() {
getSectionIDs("repeating_defense", function (ids) {
if (ids.length === 0 ) {
return;
}
var getFields = [];
// loop through the rows
for (var i = 0; i < ids.length; i++) {
// field that determines defense type
var damageTypeField = "repeating_defense_" + ids[i] + '_info';
getFields.push(damageTypeField);
}
getAttrs(getFields, function (values) {
var updateFields = {};
// loop through the row ids again so we can get the values
// and fill array of defense_type id numbers
_.each(ids, function(id) {
var infoField = "repeating_defense_" + id + '_info';
// field we need to update
var fieldToUpdate = "repeating_defense_" + id + '_info_description';
var infoValue = values[infoField];
// update the defense type id number
updateFields[fieldToUpdate] = getDefenseNote(infoValue);
});
setAttrs(updateFields);
});
});
}
on("change:repeating_item:carried", function(event) {
markItemRowAsCarried();
});
/**
* Update the hidden input field on/off
* If ON, the row will bold the weight text.
*
*/
function markItemRowAsCarried() {
getAttrs(["repeating_item_carried"], function(values) {
setAttrs({
"repeating_item_inventory_item_carried": values.repeating_item_carried
});
});
}
/**
* Returns min. damage note based on damage type
* Crush = min. of 0
* others = min. of 1
*
* @param string damageTypeValue
*
* @return string
*/
function getMinimumDamageNote(damageTypeValue) {
var minDamageNote = "";
if (damageTypeValue === "Crushing (cr)") {
minDamageNote = "Min 0";
} else {
minDamageNote = "Min 1";
}
return minDamageNote;
}
on("change:entered_move change:current_move change:enhanced_move_current change:current_air change:current_water change:deceleration", function(event) {
updateTurnRadiusMovements();
});
/**
* Updates the turn radius for different move types
* based on velocity.
*
*/
function updateTurnRadiusMovements() {
getAttrs(["entered_move", "current_move", "enhanced_move_current", "current_air", "current_water", "deceleration"], function(values) {
var deceleration = +values.deceleration;
var enteredMove = +values.entered_move;
var enhancedGroundMove = values.enhanced_move_current;
var arrEnhancedGroundMove;
var maxGroundVelocity = 0;
var baseMove = +values.current_move;
var baseMoveTurnRadius = 0;
var groundTightTurnPenalty = 0;
var groundDecelerationPenalty = 0;
var maxAirVelocity = 0;
var baseAirMove = values.current_air;
var arrAirMove;
var baseAirMoveTurnRadius = 0;
var airTightTurnPenalty = 0;
var airDecelerationPenalty = 0;
var maxWaterVelocity = 0;
var baseWaterMove = values.current_water;
var baseWaterMoveTurnRadius = 0;
var arrWaterMove;
var waterTightTurnPenalty = 0;
var waterDecelerationPenalty = 0;
if (enteredMove < 0) {
enteredMove = 0;
}
// --
// get ground move and turn radius
if ( enhancedGroundMove === "0" ) {
// if no super move, then use normal base move
maxGroundVelocity = getMaxVelocity(values.current_move, enteredMove);
groundTightTurnPenalty = 0;
} else {
// use super move
maxGroundVelocity = getMaxVelocity(enhancedGroundMove, enteredMove);
groundTightTurnPenalty = getTightTurnPenalty(maxGroundVelocity, values.enhanced_move_current);
}
if (maxGroundVelocity && baseMove) {
baseMoveTurnRadius = maxGroundVelocity/baseMove;
// round down, but min. is 1.
if (baseMoveTurnRadius <= 1) {
baseMoveTurnRadius = 1;
} else {
baseMoveTurnRadius = Math.floor(baseMoveTurnRadius);
}
}
groundDecelerationPenalty = getDecelerationPenalty(deceleration, values.current_move, maxGroundVelocity);
// --
// get base air move and turn radius
// check for slash
maxAirVelocity = getMaxVelocity(baseAirMove, enteredMove);
baseAirMove = getBaseMove(baseAirMove);
if ( baseAirMove === 0 ) {
baseAirMoveTurnRadius = 0;
} else if ( maxAirVelocity && baseAirMove ) {
baseAirMoveTurnRadius = maxAirVelocity/baseAirMove;
// round down, but min. is 1.
if (baseAirMoveTurnRadius <= 1) {
baseAirMoveTurnRadius = 1;
} else {
baseAirMoveTurnRadius = Math.floor(baseAirMoveTurnRadius);
}
airTightTurnPenalty = getTightTurnPenalty(maxAirVelocity, values.current_air);
}
airDecelerationPenalty = getDecelerationPenalty(deceleration, baseAirMove, maxAirVelocity);
// --
// get base water move and turn radius
maxWaterVelocity = getMaxVelocity(baseWaterMove, enteredMove);
baseWaterMove = getBaseMove(baseWaterMove);
if (maxWaterVelocity && baseWaterMove ) {
baseWaterMoveTurnRadius = maxWaterVelocity/baseWaterMove;
// round down, but min. is 1.
if (baseWaterMoveTurnRadius <= 1) {
baseWaterMoveTurnRadius = 1;
} else {
baseWaterMoveTurnRadius = Math.floor(baseWaterMoveTurnRadius);
}
waterTightTurnPenalty = getTightTurnPenalty(maxWaterVelocity, values.current_water);
}
waterDecelerationPenalty = getDecelerationPenalty(deceleration, baseWaterMove, maxWaterVelocity);
setAttrs({
"current_move_turn_radius": baseMoveTurnRadius,
"current_move_turn_radius_penalty": groundTightTurnPenalty,
"enhanced_move_current_turn_radius": baseMoveTurnRadius,
"enhanced_move_current_turn_radius_penalty": groundTightTurnPenalty,
"current_air_turn_radius": baseAirMoveTurnRadius,
"current_air_turn_radius_penalty": airTightTurnPenalty,
"current_water_turn_radius": baseWaterMoveTurnRadius,
"current_water_turn_radius_penalty": waterTightTurnPenalty,
"current_move_deceleration": groundDecelerationPenalty,
"enhanced_move_current_deceleration": groundDecelerationPenalty,
"current_air_deceleration": airDecelerationPenalty,
"current_water_deceleration": waterDecelerationPenalty,
});
});
}
/**
* Calculate deceleration penalty
* example: deceleration = 10, baseMove = 3
* removesafe = 10 - 3 = 7
* penalty = -1 * (7/2) = -3
*
* @param int deceleration How much is thing/vehicle slows down by
* @param int baseMove base move.
* @param int maxMove Deceleration can't more than maxMove
*
* @return int
*/
function getDecelerationPenalty(deceleration, baseMove, maxMove) {
var safeDeceleration = 0;
var maxDeceleration = 0;
var penalty = 0;
// make sure we don't exceed max move
if (deceleration < maxMove) {
maxDeceleration = deceleration;
} else {
maxDeceleration = maxMove;
}
if (maxDeceleration == 0 ||
baseMove == 0 ||
maxDeceleration <= baseMove) {
return 0;
}
// example: deceleration = 10, baseMove = 3
// removesafe = 10 - 3 = 7
// penalty = 7/2 = -3
safeDeceleration = maxDeceleration - baseMove;
// note: decelerationDivisor is a constant declared at top of javascript
penalty = -1 * Math.floor(safeDeceleration/decelerationDivisor);
return penalty;
}
/**
* Gets base move from a number or two values.
* If move = 8/16, basemove = 8.
* If move = 8, basemove = 8
*/
function getBaseMove(moveValue) {
var move = 0;
if ( moveValue.toString().includes("/") ) {
// split the value
// move = 8/16
// 8 = base move
// 16 = max move
arrMoveValue = moveValue.split("/");
// get second part, convert to number
move = +arrMoveValue[0];
} else {
move = +moveValue;
}
return move;
}
/**
* Determines max velocity for a movement type.
* Entered move can't exceed move value.
* Example moveValue = 8/16
* if enteredMove = 8, then use it
* if enteredMove = 20, then use 16
* @param string moveValue Example: 8/16 or 8
* @param string enteredMove Velocity entered by user
*
* @return int
*/
function getMaxVelocity(moveValue, enteredMove) {
var maxVelocity = 0;
var move = 0;
var arrMoveValue;
if ( moveValue.toString().includes("/") ) {
// split the value
// move = 8/16
// 8 = base move
// 16 = max move
arrMoveValue = moveValue.split("/");
// get second part, convert to number
move = +arrMoveValue[1];
} else {
move = +moveValue;
}
// i.e. entered move = 20, top speed = 16
// if 20 > 16, then use 16
if (enteredMove > move ) {
maxVelocity = move;
} else {
maxVelocity = enteredMove;
}
return maxVelocity;
}
/**
* Determines the tight turn penalty
*
* @param int velocity Current velocity
* @param string moveValue Base move used to determine turn penalty
*
* @return int
*/
function getTightTurnPenalty(velocity, moveValue) {
var penalty = 0;
var arrMoveValue;
var baseMove = 0;
var maxMove = 0;
var temp = 0;
if ( moveValue.toString().includes("/") ) {
// split the value
// move = 8/16
// 8 = base move
// 16 = max move
arrMoveValue = moveValue.split("/");
baseMove = +arrMoveValue[0];
maxMove = +arrMoveValue[1];
} else {
baseMove = +moveValue;
maxMove = +moveValue;
}
if ( baseMove === maxMove ) {
penalty = 0;
} else {
temp = velocity - baseMove;
penalty = Math.floor(temp/baseMove) * -1;
}
return penalty;
}
function setSkillRowIds() {
getSectionIDs("repeating_skills", function(ids) {
skillRowIds = ids;
});
}
function setWeaponRowIds() {
setWeaponRowIdsBySection("repeating_melee", "melee");
setWeaponRowIdsBySection("repeating_ranged", "ranged");
}
function setWeaponRowIdsBySection(sectionName, prefixValue) {
getSectionIDs(sectionName, function(ids) {
// loop through each row, find ones that have skill row id
// see: https://underscorejs.org/#each
_.each(ids,function(id) {
var fieldName = `${sectionName}_${id}_${prefixValue}_skill_row_id`;
getAttrs([fieldName], function(values) {
var rowId = values[fieldName];
// if theres rowId, add it
if (rowId) {
var skillData = {
skillRowId: values[fieldName], // use values.[var name]. can't use values.field_name
sectionName: sectionName,
rowId: id,
prefix: prefixValue
};
// add to global variable
weaponRowIds.push(skillData);
}
});
});
});
}
// check if skill level mirror changed
on("change:repeating_skills:level_mirror", function(event) {
var rowId = getRowIdFromEventInfo(event, "repeating_skills");
// if the weapon rowId is being used by a skill, update the toggles
weapons = getMatchinWeaponsFromSkillId(rowId);
// through could be more than one weapon tied to a skill
if (weapons.length) {
var updateFields = {};
weapons.forEach( function(weaponRow) {
var toggleFieldName = `${weaponRow.sectionName}_${weaponRow.rowId}_${weaponRow.prefix}_skill_row_id_toggle`;
updateFields[toggleFieldName] = 1;
});
setAttrs(updateFields);
}
});
// check if spell level mirror changed
on("change:repeating_spells:level_mirror", function(event) {
var rowId = getRowIdFromEventInfo(event, "repeating_spells");
// if the weapon rowId is being used by a skill, update the toggles
weapons = getMatchinWeaponsFromSkillId(rowId);
console.log("update spell level mirror");
console.log("rowId", rowId);
console.log(weapons);
// could be more than one weapon tied to a skill/spell
if (weapons.length) {
var updateFields = {};
weapons.forEach( function(weaponRow) {
var toggleFieldName = `${weaponRow.sectionName}_${weaponRow.rowId}_${weaponRow.prefix}_skill_row_id_toggle`;
updateFields[toggleFieldName] = 1;
});
setAttrs(updateFields);
}
});
/**
* Searches for matching weapon row data based on skill row id
* returns array of matching weapon objects: {skillRowId, sectionName, rowId, prefix}
* skillRowId = Skill Row that weapon is linked to.
* sectionName = The name of the repeating section; repeating_melee or repeating_ranged
* rowId = Row id for the weapon in the repeating section
* prefix is used for labeling fields in a section to avoid the rule of re-using attr names
*
* @param string rowId Row ID of skill that might be linked to a weapon
*
* @return array
*/
function getMatchinWeaponsFromSkillId(rowId) {
var matchingWeapons = [];
// loop through each cached weapon data
weaponRowIds.forEach( function(weaponRow) {
if (weaponRow.skillRowId === rowId) {
matchingWeapons.push(weaponRow);
}
});
return matchingWeapons;
}
function getRowIdFromEventInfo(event, sectionName) {
var rowId = "";
// example: repeating_skills_-l6zk36zhcjhsyvc-kax_level_mirror
var sourceAttr = event.sourceAttribute;
// remove the sectionname
var regReplace = new RegExp(sectionName+ '_', "ig");
// example: -l6zk36zhcjhsyvc-kax_level_mirror
sourceAttr = sourceAttr.replace(regReplace, "");
// now split by the _
var arrSource = sourceAttr.split("_");
// first element should be rowId
rowId = arrSource[0];
return rowId.toLowerCase();
}
// set note values for damage types
// Update thrust and swing when striking st is updated
on('change:repeating_ranged:ranged_row_type change:repeating_ranged:ranged_skill_row_id change:repeating_ranged:ranged_skill_row_id_modifier change:repeating_ranged:ranged_skill_row_id_toggle', function(event){
getAttrs(["repeating_ranged_ranged_row_type"], function(values) {
updateLinkedWeaponSkill("repeating_ranged", "ranged", values.repeating_ranged_ranged_row_type, function() {
//make sure we update the cache
setWeaponRowIdsBySection("repeating_ranged", "ranged");
});
});
});
// set note values for damage types
// Update thrust and swing when striking st is updated
on('change:repeating_melee:melee_row_type change:repeating_melee:melee_skill_row_id change:repeating_melee:melee_skill_row_id_modifier change:repeating_melee:melee_skill_row_id_toggle', function(event){
getAttrs(["repeating_melee_melee_row_type"], function(values) {
updateLinkedWeaponSkill("repeating_melee", "melee", values.repeating_melee_melee_row_type, function() {
//make sure we update the cache
setWeaponRowIdsBySection("repeating_melee", "melee");
});
});
});
/**
* Update the weapon skill associated with the skill row id
*
* @param string sectionName Should be either repeating_melee or repeating_ranged
* @param string prefix Placed before skill attribute names to follow rules for unique names, even inside repeating sections.
* @param string rowType Where to get the level. Skill | Spell
* @param object callback A function to run after everything is done
*/
function updateLinkedWeaponSkill(sectionName, prefix, rowType, callback) {
var repeatingTableToUse = "";
switch (rowType) {
case "Spell":
repeatingTableToUse = "repeating_spells";
break;
case "Skill":
default:
repeatingTableToUse = "repeating_skills";
break;
}
var skillRowIdFieldName = `${sectionName}_${prefix}_skill_row_id`;
var skillRowModFieldName = `${sectionName}_${prefix}_skill_row_id_modifier`;
var skillMessageFieldName = `${sectionName}_${prefix}_skill_row_id_message`;
var weaponSkillFieldName = `${sectionName}_skill`;
// if this gets changed, then the update linked weapon skill gets triggered
var skillRowIdToggleFieldName = `${sectionName}_${prefix}_skill_row_id_toggle`;
getAttrs([skillRowIdFieldName,
skillRowModFieldName
], function(values) {
var skillRowId = values[skillRowIdFieldName];
var skillMod = +values[skillRowModFieldName];
// exit if there's no value
if (skillRowId.length === 0) {
// clear the field
var updateFields = {};
updateFields[skillMessageFieldName] = ``;
setAttrs(updateFields);
} else if ( validSkillRowId(skillRowId) ) {
// if it's a good row id, let's update stuff
var skillFieldName = `${repeatingTableToUse}_${skillRowId}_level_mirror`;
// update the skill level for weapon.
getAttrs([skillFieldName], function(values) {
var skillLevel = +values[skillFieldName];
var skillLevelFinal = skillLevel + skillMod;
var updateFields = {};
updateFields[weaponSkillFieldName] = skillLevelFinal;
updateFields[skillMessageFieldName] = `Found: ${skillLevel}. Mod: ${skillMod}.`;
// reset toggle to zero
updateFields[skillRowIdToggleFieldName] = 0;
setAttrs(updateFields, '', callback());
});
} else {
// show an error message
var updateFields = {};
updateFields[skillMessageFieldName] = `Could not find ${rowType}.`;
setAttrs(updateFields);
}
});
}
function validSkillRowId( rowIdToFind ) {
var blnValid = skillRowIds.includes(rowIdToFind);
return blnValid;
}
/**
* This function is used to make sure the repeating
* skill levels are updated when the version has changed
*/
function updateRepeatingSkillLevels() {
var sectionName = "repeating_skills";
getSectionIDs(sectionName, function(ids) {
updateSkillLevel(sectionName, ids);
});
}
function updateSkillLevel(sectionName, ids) {
_.each(ids,function(id) {
var rowId = id;
var baseFieldName = `${sectionName}_${id}_base`;
var difficultyFieldName = `${sectionName}_${id}_difficulty`;
var bonusFieldName = `${sectionName}_${id}_bonus`;
var wildcardSkillPointsFieldName = `${sectionName}_${id}_wildcard_skill_points`;
var useWildcardPointsFieldName = `${sectionName}_${id}_use_wildcard_points`;
var pointsFieldName = `${sectionName}_${id}_points`;
var useNormalPointsFieldName = `${sectionName}_${id}_use_normal_points`;
fields = [
baseFieldName,
difficultyFieldName,
bonusFieldName,
wildcardSkillPointsFieldName,
useWildcardPointsFieldName,
pointsFieldName,
useNormalPointsFieldName,
"strength",
"dexterity",
"intelligence",
"health",
"perception",
"willpower"
];
getAttrs(fields, function(values) {
var base = getBaseSkillLevel(values[baseFieldName], values);
var difficulty = values[difficultyFieldName];
var bonus = +values[bonusFieldName];
var wildcardSkillPoints = +values[wildcardSkillPointsFieldName];
var useWildcardSkillPoints = +values[useWildcardPointsFieldName];
var points = +values[pointsFieldName];
var useNormalPoints = +values[useNormalPointsFieldName];
// check for wildcard
if ( String(difficulty) === "-5 + 1") {
difficulty = -4;
} else {
difficulty = +difficulty;
}
var skillLevel = getSkillLevelUsingRaw(base, difficulty, bonus, wildcardSkillPoints, useWildcardSkillPoints, points, useNormalPoints);
var fieldToUpdate = `${sectionName}_${rowId}_level_mirror`;
var updateFields = {};
updateFields[fieldToUpdate] = skillLevel;
setAttrs(updateFields);
});
});
}
function getBaseSkillLevel(baseFieldName, values) {
var baseLevel = 10;
switch(baseFieldName) {
case "@{strength}":
baseLevel = +values.strength;
break;
case "@{dexterity}":
baseLevel = +values.dexterity;
break;
case "@{intelligence}":
baseLevel = +values.intelligence;
break;
case "@{health}":
baseLevel = +values.health;
break;
case "@{willpower}":
baseLevel = +values.willpower;
break;
case "@{perception}":
baseLevel = +values.perception;
break;
default:
baseLevel = 10;
break;
}
return baseLevel;
}
/**
* This function is used to make sure the repeating
* skill levels are updated when the version has changed
*/
function updateRepeatingSpellLevels() {
var sectionName = "repeating_spells";
// get the base spell level and bonus
getAttrs(["spell_base", "spell_bonus"], function(values) {
var spellBase = values.spell_base;
var spellBonus = parseInt(values.spell_bonus);
if ( isNaN(spellBonus) ) {
spellBonus = 0;
}
getSectionIDs(sectionName, function(ids) {
updateSpellLevel( sectionName, ids, spellBase, spellBonus );
});
});
}
function updateSpellLevel(sectionName, ids, spellBase, spellBonus) {
_.each(ids,function(id) {
var rowId = id;
var difficultyFieldName = `${sectionName}_${id}_difficulty`;
var bonusFieldName = `${sectionName}_${id}_spell_modifier`;
var pointsFieldName = `${sectionName}_${id}_points`;
fields = [
difficultyFieldName,
bonusFieldName,
pointsFieldName,
"strength",
"dexterity",
"intelligence",
"health",
"perception",
"willpower"
];
getAttrs(fields, function(values) {
var base = getBaseSkillLevel(spellBase, values);
var difficulty = +values[difficultyFieldName];
var bonus = +values[bonusFieldName] + spellBonus;
var points = +values[pointsFieldName];
var skillLevel = getSkillLevelUsingRaw(base, difficulty, bonus, 0, false, points, true);
var fieldToUpdate = `${sectionName}_${rowId}_level_mirror`;
var updateFields = {};
updateFields[fieldToUpdate] = skillLevel;
setAttrs(updateFields);
});
});
}
/**
* Calculate skill level using GURPS rules as written
*
* @param int base Base skill level
* @param int difficulty Modifier selected from drop-down
* @param int bonus Modifier entered by user
* @param int
*
*/
function getSkillLevelUsingRaw(base, difficulty, bonus, wildcardSkillPoints, useWildcardSkillPoints, points, useNormalPoints) {
var skill = 10;
var skillPoints = 0;
// determine which points to use
if (useNormalPoints) {
skillPoints = points;
} else {
skillPoints = wildcardSkillPoints;
}
var levelFromPoints = Math.floor((skillPoints * 0.25) + 2)
* Math.ceil( ( ( skillPoints - 2 ) + Math.abs( skillPoints - 2) ) / 256 )
+ skillPoints
* Math.abs( Math.ceil( ( ( skillPoints - 2 ) + Math.abs( skillPoints - 2) ) / 256 ) - 1 );
skill = base + difficulty + bonus + levelFromPoints;
return skill;
}
// see: https://stackoverflow.com/questions/3954438/how-to-remove-item-from-array-by-value
Array.prototype.remove = function() {
var what, a = arguments, L = a.length, ax;
while (L && this.length) {
what = a[--L];
while ((ax = this.indexOf(what)) !== -1) {
this.splice(ax, 1);
}
}
return this;
};
function removeArray(arr) {
var what, a = arguments, L = a.length, ax;
while (L > 1 && arr.length) {
what = a[--L];
while ((ax= arr.indexOf(what)) !== -1) {
arr.splice(ax, 1);
}
}
return arr;
}
on("change:repeating_spells:spell_on_checked", function(event) {
var fields = [
"repeating_spells_spell_on_checked",
"penalty_per_spell_on",
"spell_on_penalty_total"
];
getAttrs( fields, function(values) {
var currentPenalty = +values.spell_on_penalty_total;
var perSpellPenalty = +values.penalty_per_spell_on;
var checked = +values.repeating_spells_spell_on_checked;
var newTotalPenalty = getSpellPenaltyForOnOrMaintained(checked, currentPenalty, perSpellPenalty);
setAttrs({
spell_on_penalty_total: newTotalPenalty
})
});
});
on("change:repeating_spells:spell_maintained_checked", function(event) {
var fields = [
"repeating_spells_spell_maintained_checked",
"penalty_per_spell_maintained",
"spell_maintained_penalty_total"
];
getAttrs( fields, function(values) {
var currentPenalty = +values.spell_maintained_penalty_total;
var perSpellPenalty = +values.penalty_per_spell_maintained;
var checked = +values.repeating_spells_spell_maintained_checked;
var newTotalPenalty = getSpellPenaltyForOnOrMaintained(checked, currentPenalty, perSpellPenalty);
setAttrs({
spell_maintained_penalty_total: newTotalPenalty
})
});
});
function getSpellPenaltyForOnOrMaintained(checked, currentPenalty, perSpellPenalty) {
var newTotalPenalty = 0;
if (checked) {
newTotalPenalty = currentPenalty + perSpellPenalty;
} else {
newTotalPenalty = currentPenalty - perSpellPenalty;
}
return newTotalPenalty;
}
</script>