Files
roll20-character-sheets/The One Ring 2e/sheet.html
T

3423 lines
188 KiB
HTML

<input type="hidden" name="attr_version" value="03-14-00" />
<input type="hidden" class="sheet-tabstoggle" name="attr_sheetTab" />
<input type="checkbox" name="attr_parsedrolls" value="1" class="hidden config-parsed-rolls" checked="checked" hidden
readonly />
<input type="checkbox" name="attr_darktoggle" value="1" class="hidden user-darkmode" checked="checked" hidden
readonly />
<div class="sheet-pc">
<div id="content">
<div id="character">
<h1 data-i18n="general">General</h1>
<div id="character-nested">
<div class="onecol">
<label data-i18n="character-name">Name</label><input type="text" name="attr_character_name">
</div>
<div class="twocols">
<label data-i18n="culture">Heroic Culture</label><input type="text" name="attr_culture">
<label data-i18n="calling">Calling</label><input type="text" name="attr_calling">
<label data-i18n="standard-of-living">Living standard</label><input type="text"
name="attr_standard_of_living">
<label data-i18n="shadow-weakness">Shadow Weakness</label><input type="text"
name="attr_shadow_weakness">
</div>
<div class="threecols">
<label data-i18n="patron">Patron</label>
<input type="text" name="attr_patron">
<label data-i18n="fellowship-focus">Fellow</label>
<input type="text" name="attr_fellowship_focus">
<label data-i18n="age">Age</label><input type="text" name="attr_age">
</div>
<div class="onecol">
<label data-i18n="cultural-blessing">Cultural Blessing</label><input type="text"
name="attr_cultural_blessing">
<label data-i18n="distinctive-features">Dist. Features</label><input type="text"
name="attr_distinctive_features" />
<label data-i18n="flaws">Flaws</label><input type="text" name="attr_flaws">
</div>
</div>
</div>
<div id="virtues">
<h2 data-i18n="virtues">Virtues</h2>
<div>
<span>
<button type="roll" class="table-rolls" value="@{wisdom_roll}" name="roll_wisdomcheck"></button>
<button type="action" class="parsed-rolls" name="act_wisdom" id="roll_wisdom"></button>
<input type="checkbox" name="attr_wisdom_favoured">
<label data-i18n="wisdom">Wisdom</label>
<div class="sheet-hover-info" data-i18n="wisdom-description"></div>
</span>
<span class="diamond-small-red"><span>
<input name="attr_wisdom" value="1" type="number" min=1 max=6 />
</div>
<textarea name="attr_virtues" />
</div>
<div id="rewards">
<h2 data-i18n="rewards">Rewards</h2>
<div>
<span>
<button type="roll" class="table-rolls" value="@{valour_roll}" name="roll_valourcheck"></button>
<button type="action" class="parsed-rolls" name="act_valour" id="roll_valour"></button>
<input type="checkbox" name="attr_valour_favoured">
<label data-i18n="valour">Valour</label>
<div class="sheet-hover-info" data-i18n="valour-description"></div>
</span>
<span class="diamond-small-red"><span>
<input name="attr_valour" value="1" type="number" min=1 max=6 />
</div>
&nbsp; &nbsp;
<textarea name="attr_rewards" />
</div>
<div id="gear">
<select id="gearoritems_toggle" name="attr_gearoritems">
<option data-i18n="gear" value="1" select="selected"></option>
<option data-i18n="useful-items" value="2"></option>
</select>
<input type="hidden" name="attr_gearoritems_toggle" class="gearoritems_toggle" value="1" />
<div id="items-nested">
<div id="items-row">
<label data-i18n="name"></label>
<label class="center" data-i18n-title="item-bonus" data-i18n="item-bonus-short"></label>
<label class="center" data-i18n-title="blessing1" data-i18n="blessing1-short"></label>
<label class="center" data-i18n-title="blessing2" data-i18n="blessing2-short"></label>
</div>
<fieldset class="repeating_items">
<div id="items-row">
<input name="attr_items_desc" type="text" />
<select name="attr_items_bonus" class="center">
<option value="0" selected="selected" title="-">-</option>
<option value="1" data-i18n-title="marvelous-item" data-i18n="marvelous-item-bonus">
</option>
<option value="2" data-i18n-title="wondrous-item" data-i18n="wondrous-item-bonus"></option>
</select>
<select name="attr_items_blessing1" class="center">
<option value="0" selected="selected" title="-">-</option>
<option value="1" data-i18n-title="awe" data-i18n="awe-short"></option>
<option value="2" data-i18n-title="enhearten" data-i18n="enhearten-short"></option>
<option value="3" data-i18n-title="persuade" data-i18n="persuade-short"></option>
<option value="4" data-i18n-title="athletics" data-i18n="athletics-short"></option>
<option value="5" data-i18n-title="travel" data-i18n="travel-short"></option>
<option value="6" data-i18n-title="stealth" data-i18n="stealth-short"></option>
<option value="7" data-i18n-title="awareness" data-i18n="awareness-short"></option>
<option value="8" data-i18n-title="insight" data-i18n="insight-short"></option>
<option value="9" data-i18n-title="scan" data-i18n="scan-short"></option>
<option value="10" data-i18n-title="hunting" data-i18n="hunting-short"></option>
<option value="11" data-i18n-title="healing" data-i18n="healing-short"></option>
<option value="12" data-i18n-title="explore" data-i18n="explore-short"></option>
<option value="13" data-i18n-title="courtesy" data-i18n="courtesy-short"></option>
<option value="14" data-i18n-title="song" data-i18n="song-short"></option>
<option value="15" data-i18n-title="riddle" data-i18n="riddle-short"></option>
<option value="16" data-i18n-title="craft" data-i18n="craft-short"></option>
<option value="17" data-i18n-title="battle" data-i18n="battle-short"></option>
<option value="18" data-i18n-title="lore" data-i18n="lore-short"></option>
</select>
<select name="attr_items_blessing2" class="center">
<option value="0" selected="selected" title="-">-</option>
<option value="1" data-i18n-title="awe" data-i18n="awe-short"></option>
<option value="2" data-i18n-title="enhearten" data-i18n="enhearten-short"></option>
<option value="3" data-i18n-title="persuade" data-i18n="persuade-short"></option>
<option value="4" data-i18n-title="athletics" data-i18n="athletics-short"></option>
<option value="5" data-i18n-title="travel" data-i18n="travel-short"></option>
<option value="6" data-i18n-title="stealth" data-i18n="stealth-short"></option>
<option value="7" data-i18n-title="awareness" data-i18n="awareness-short"></option>
<option value="8" data-i18n-title="insight" data-i18n="insight-short"></option>
<option value="9" data-i18n-title="scan" data-i18n="scan-short"></option>
<option value="10" data-i18n-title="hunting" data-i18n="hunting-short"></option>
<option value="11" data-i18n-title="healing" data-i18n="healing-short"></option>
<option value="12" data-i18n-title="explore" data-i18n="explore-short"></option>
<option value="13" data-i18n-title="courtesy" data-i18n="courtesy-short"></option>
<option value="14" data-i18n-title="song" data-i18n="song-short"></option>
<option value="15" data-i18n-title="riddle" data-i18n="riddle-short"></option>
<option value="16" data-i18n-title="craft" data-i18n="craft-short"></option>
<option value="17" data-i18n-title="battle" data-i18n="battle-short"></option>
<option value="18" data-i18n-title="lore" data-i18n="lore-short"></option>
</select>
</select>
</div>
</fieldset>
</div>
<div id="gear-nested">
<textarea name="attr_travellinggear" />
</div>
</div>
<div id="experience">
<h2 data-i18n="experience" data-i18n-title="experience-description">Experience</h2>
<div id="experience-nested">
<span class="diamond-small">
<span><input name="attr_adventurepoints" value="0" type="number"></span></span>
<span class="diamond-small">
<span><input name="attr_skillpoints" value="0" type="number"></span></span>
<span class="diamond-small">
<span><input name="attr_fellowship" value="0" type="number"></span></span>
<span><label data-i18n="adventure-points">Adv. Points</label></span>
<span><label data-i18n="skill-points">Skill Points</label></span>
<span><label data-i18n="fellowship-pool">Fellowship</label></span>
<span class="diamond-small">
<span><input name="attr_totaladventurepoints" value="0" type="number"></span></span>
<span class="diamond-small">
<span><input name="attr_totalskillpoints" value="0" type="number"></span></span>
<span class="diamond-small">
<span><input name="attr_treasure" value="0" type="number"></span></span>
<span><label data-i18n="adventure-points-total">Adv. Total</label></span>
<span><label data-i18n="skill-points-total">Skill Total</label></span>
<span><label data-i18n="treasure-rating">Treasure<br />Rating</label></span>
</div>
</div>
<div id="strength">
<h1 data-i18n="strength" data-i18n-title="strength-description">Strength</h1>
<div id="attribute-strength" class="attribute">
<div id="strength-row1" class="attribute-row1">
<label data-i18n="rating" class="right">Rating</label>
<span class="diamond-small">
<span><input class="" name="attr_strength" value="0" type="number"></span></span>
<span></span>
<span class="diamond-small">
<span><input class="" name="attr_endurance_max" value="1" type="number"></span></span>
<label data-i18n="endurance-short" data-i18n-title="endurance" class="left">Endur.</label>
</div>
<div id="strength-row2" class="attribute-row2">
<label data-i18n="tn-strength" data-i18n-title="target-number" class="right">TN</label>
<span class="diamond-red center">
<span><input class="strong" name="attr_strengthtn" value="0" type="number"></span></span>
<span></span>
<span class="diamond-red">
<span><input class="strong" name="attr_endurance" value="1" type="number"></span></span>
<label data-i18n="current-endurance" data-i18n-title="current-endurance" class="left">Current
Endurance</label>
<span></span>
</div>
<div id="strength-row3" class="attribute-row3">
<label data-i18n="load" class="right">Load</label>
<span class="diamond-small">
<span><input name="attr_load" value="0" type="number" readonly="readonly"></span></span>
<div class="center">
<span class="diamond-small">
<span><input name="attr_treasureload" value="0" type="number"></span></span>
<label data-i18n="treasure" data-i18n-title="treasure-load" class="center">Treasure</label>
</div>
<span class="diamond-small">
<span><input name="attr_fatigue" value="0" type="number"></span></span>
<label data-i18n="fatigue" class="left">Fatigue</label>
</div>
</div>
</div>
<div id="heart">
<h1 data-i18n="heart" data-i18n-title="heart-description">Heart</h1>
<div id="attribute-heart" class="attribute">
<div id="heart-row1" class="attribute-row1">
<label data-i18n="rating" class="right">Rating</label>
<span class="diamond-small">
<span><input name="attr_heart" value="0" type="number"></span></span>
<span></span>
<span class="diamond-small">
<span><input class="" name="attr_hope_max" value="1" type="number"></span></span>
<label data-i18n="hope" class="left">Hope</label>
</div>
<div id="heart-row2" class="attribute-row2">
<label data-i18n="tn-heart" class="right">TN</label>
<span class="diamond-red">
<span><input class="strong" name="attr_hearttn" value="0" type="number"></span></span>
<span></span>
<span class="diamond-red">
<input type="hidden" class="sheet-hopetoggle" name="attr_hopetoggle" />
<span id="hope_readonly" data-i18n-title="daunted-title"><input class="strong" name="attr_hope"
value="1" type="number" readonly="readonly"></span>
<span id="hope"><input class="strong" name="attr_hope" value="1" type="number"></span>
</span>
<label data-i18n="current-hope" class="left">Current Hope</label>
</div>
<div id="heart-row3" class="attribute-row3">
<label data-i18n="shadow" class="right">Shadow</label>
<span class="diamond-small">
<span><input name="attr_shadow" value="0" type="number"></span></span>
<div class="center">
<span class="diamond-small">
<span><input name="attr_taint" value="0" type="number"></span></span>
<label data-i18n="taint" data-i18n-title="taint-title" class="center">Taint</label>
</div>
<span class="diamond-small">
<span><input name="attr_shadowscar" value="0" type="number"></span></span>
<label data-i18n="scars" class="left">Scars</label>
</div>
</div>
</div>
<div id="wits">
<h1 data-i18n="wits" data-i18n-title="wits-description">Wits</h1>
<div id="attribute-wits" class="attribute">
<div id="wits-row1" class="attribute-row1">
<label data-i18n="rating" class="right">Rating</label>
<span class="diamond-small">
<span><input class="" name="attr_wits" value="0" type="number"></span></span>
<span></span>
<span class="diamond-small">
<span><input name="attr_parry" value="0" type="number"></span></span>
<label data-i18n="parry" class="left">Parry</label>
</div>
<div id="wits-row2" class="attribute-row2">
<label data-i18n="tn-wits" data-i18n-title="target-number" class="right">TN</label>
<span class="diamond-red center">
<span><input class="strong" name="attr_witstn" value="0" type="number"></span></span>
<span></span>
<span class="diamond-red">
<span><input class="strong" name="attr_totalparry" value="0" type="number"
readonly="readonly"></span></span>
<label data-i18n="total-parry" data-i18n-title="total-parry" class="left">Total Parry</label>
<span></span>
</div>
<div id="wits-row3" class="attribute-row3">
<div class="right">
<span>
<input type="checkbox" name="attr_shieldparry_active" value=1 checked="checked">
<label data-i18n="shield"></label>
</span>
</div>
<span class="diamond-small">
<span>
<input name="attr_shieldparry_total" value="0" type="number" readonly="readonly">
</span>
</span>
<div class="center">
<span class="diamond-small">
<span>
<input name="attr_otherparry" value="0" type="number">
</span>
</span>
<span class="center">
<input type="checkbox" name="attr_otherparry_active" value=1 checked="checked">
<label data-i18n="other"></label>
</span>
</div>
<span class="diamond-small">
<span>
<input name="attr_stanceparry" value="0" type="number">
</span>
</span>
<div class="left">
<span>
<input type="checkbox" name="attr_stanceparry_active" value=1 checked="checked">
<label data-i18n="stance"></label>
</span>
</div>
</div>
</div>
</div>
<div id="conditions">
<h2 data-i18n="conditions-modifiers">Conditions / Modifiers</h2>
<div id="conditions-nested">
<label>
<input name="attr_favorill" type="radio" value="{1t[feat]}" checked="checked">
<span data-i18n="normal">Normal</span>
</label>
<label>
<input name="attr_favorill" type="radio" value="{2t[feat]}kh1">
<span data-i18n="favoured">Favoured</span>
</label>
<label>
<input name="attr_favorill" type="radio" value="{2t[feat]}kl1">
<span data-i18n="illfavoured">Ill. Fav.</span>
</label>
<label><input name="attr_weary" type="checkbox" value=1>
<span data-i18n="weary-weary">Weary</span></label>
<label><input name="attr_miserable" type="checkbox" value=1>
<span data-i18n="miserable">Miserable</span></label>
<label><input name="attr_wounded" type="checkbox" value=1>
<span data-i18n="wounded">Wounded</span></label>
<div />
<label><input name="attr_daunted" type="checkbox" value=1>
<span data-i18n="daunted" data-i18n-title="daunted-title">Daunted</span></label>
<div />
</div>
<div class="center">
<label data-i18n="injury" /><input name="attr_injury" type="text">
</div>
<div id="custom-diceroller">
<div class="onecols">
<h2 data-i18n="custom-roll">Custom Dice Roller</h3>
</div>
<div class="twocols">
<label data-i18n="custom-rollname" />
<input class="center" type="text" data-i18n-placeholder="custom-rollname-placeholder"
name="attr_customrollname">
</div>
<div class="twocols">
<label data-i18n="whisper" />
<input class="center" type="text" data-i18n-placeholder="whisper-placeholder" name="attr_whisper">
</div>
<div class="twocols">
<label data-i18n="custom-featdie" />
<select name="attr_customfeatdie" class="center">
<option value="-1">None</option>
<option value="1" selected="selected">Normal</option>
<option value="2">Favoured</option>
<option value="0">Ill-favoured</option>
</select>
</div>
<div class="threecols">
<span>
<label data-i18n="custom-successdice" />
<input class="center" type="number" value="0" name="attr_customsuccessdice">
</span>
<span>
<label data-i18n="custom-tn" />
<input class="center" type="number" value="14" name="attr_customtn">
</span>
<button type="action" style="display: inline-block" class="parsed-rolls" name="act_customroll"
id="roll_custom" />
</div>
</div>
<div class="center">
<label data-i18n="parsed-rolls">Parsed rolls</label>
<div class="sheet-hover-info" data-i18n="parsedroll-description">When enabled the dice rolls will be
parsed and calculated, with output displayed in a rolltemplate. This removes the need for roll
tables. </div>
<span class="toggle">
<input type="checkbox" name="attr_parsedrolls" value="1" checked="checked"
id="config_parsedrolls" />
&nbsp;
<input type="checkbox" name="attr_parsedrolls" value="0" id="config_tablerolls" />
</span>
<label data-i18n="table-rolls">Table rolls</label>
<br />
<div class="sheet-hover-info" data-i18n="tableroll-description">When enabled the dice rolls will be
using preconfigured rollable tables according to instructions for The One Ring 1st Edition, with
output displayed in a rolltemplate.</div>
</div>
<button class="btn-labeled" type="action" name="act_notestoggle" data-i18n="notes">Notes</button>
<span id="darkmode-toggle">&nbsp;&nbsp;
<label data-i18n="darkmode">Darkmode</label>
<input name="attr_darktoggle" type="checkbox" value=1 checked="checked">
</span>
</div>
<div id="combat">
<h1 class="center" data-i18n="combat">Combat</h1>
<div class="sheet-row">
<input type="hidden" name="attr_axes_roll1" />
<button type="roll" class="table-rolls" name="roll_axescheck1" value="@{axes_roll1}"></button>
<input type="hidden" name="attr_axes_roll2" />
<button type="roll" class="table-rolls crosshair" name="roll_axescheck2" value="@{axes_roll2}"></button>
<!--
<span class="parsed-rolls">
<input type='hidden' name='attr_axes_action' value=''>
<button type='action' name='act_axes_action' style="display: none;"></button>
<button type='roll' name='roll_axes' class="parsed-rolls" value='@{axes_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_axes_target_action' value=''>
<button type='action' name='act_axes_target_action' style="display: none;"></button>
<button type='roll' name='roll_axes_target' class="parsed-rolls crosshair"
value='@{axes_target_action}'
title="Use this button when you have an adversary token to target."></button>
</span>
-->
&nbsp;
<input type="checkbox" value="1" name="attr_axes_favoured" title="Toggle favoured" />
<label data-i18n="axes">Axes</label>
<div class="sheet-hover-info" data-i18n="axes-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_axes" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_axes" value="1" /><span></span>
<input type="radio" name="attr_axes" value="2" /><span></span>
<input type="radio" name="attr_axes" value="3" /><span></span>
<input type="radio" name="attr_axes" value="4" /><span></span>
<input type="radio" name="attr_axes" value="5" /><span></span>
<input type="radio" name="attr_axes" value="6" /><span></span>
</div>
</div>
<div class="sheet-row">
<input type="hidden" name="attr_bows_roll1" />
<button type="roll" class="table-rolls" name="roll_bowscheck1" value="@{bows_roll1}"></button>
<input type="hidden" name="attr_bows_roll2" />
<button type="roll" class="table-rolls crosshair" name="roll_bowscheck2" value="@{bows_roll2}"></button>
<!--
<span class="parsed-rolls">
<input type='hidden' name='attr_bows_action' value=''>
<button type='action' name='act_bows_action' style="display: none;"></button>
<button type='roll' name='roll_bows' class="parsed-rolls" value='@{bows_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_bows_target_action' value=''>
<button type='action' name='act_bows_target_action' style="display: none;"></button>
<button type='roll' name='roll_bows_target' class="parsed-rolls crosshair"
value='@{bows_target_action}'
title="Use this button when you have an adversary token to target."></button>
</span>
-->
&nbsp;
<input type="checkbox" value="1" name="attr_bows_favoured" title="Toggle favoured" />
<label data-i18n="bows">Bows</label>
<div class="sheet-hover-info" data-i18n="bows-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_bows" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_bows" value="1" /><span></span>
<input type="radio" name="attr_bows" value="2" /><span></span>
<input type="radio" name="attr_bows" value="3" /><span></span>
<input type="radio" name="attr_bows" value="4" /><span></span>
<input type="radio" name="attr_bows" value="5" /><span></span>
<input type="radio" name="attr_bows" value="6" /><span></span>
</div>
</div>
<div class="sheet-row">
<input type="hidden" name="attr_spears_roll1" />
<button type="roll" class="table-rolls" name="roll_spearscheck1" value="@{spears_roll1}"></button>
<input type="hidden" name="attr_spears_roll2" />
<button type="roll" class="table-rolls crosshair" name="roll_spearscheck2"
value="@{spears_roll2}"></button>
<!--
<span class="parsed-rolls">
<input type='hidden' name='attr_spears_action' value=''>
<button type='action' name='act_spears_action' style="display: none;"></button>
<button type='roll' name='roll_spears' class="parsed-rolls" value='@{spears_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_spears_target_action' value=''>
<button type='action' name='act_spears_target_action' style="display: none;"></button>
<button type='roll' name='roll_spears_target' class="parsed-rolls crosshair"
value='@{spears_target_action}'
title="Use this button when you have an adversary token to target."></button>
</span>
-->
&nbsp;
<input type="checkbox" value="1" name="attr_spears_favoured" title="Toggle favoured" />
<label data-i18n="spears">Spears</label>
<div class="sheet-hover-info" data-i18n="spears-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_spears" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_spears" value="1" /><span></span>
<input type="radio" name="attr_spears" value="2" /><span></span>
<input type="radio" name="attr_spears" value="3" /><span></span>
<input type="radio" name="attr_spears" value="4" /><span></span>
<input type="radio" name="attr_spears" value="5" /><span></span>
<input type="radio" name="attr_spears" value="6" /><span></span>
</div>
</div>
<div class="sheet-row">
<input type="hidden" name="attr_swords_roll1" />
<button type="roll" class="table-rolls" name="roll_swordscheck1" value="@{swords_roll1}"></button>
<input type="hidden" name="attr_swords_roll2" />
<button type="roll" class="table-rolls crosshair" name="roll_swordscheck2"
value="@{swords_roll2}"></button>
<!--
<span class="parsed-rolls">
<input type='hidden' name='attr_swords_action' value=''>
<button type='action' name='act_swords_action' style="display: none;"></button>
<button type='roll' name='roll_swords' class="parsed-rolls" value='@{swords_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_swords_target_action' value=''>
<button type='action' name='act_swords_target_action' style="display: none;"></button>
<button type='roll' name='roll_swords_target' class="parsed-rolls crosshair"
value='@{swords_target_action}'
title="Use this button when you have an adversary token to target."></button>
</span>
-->
&nbsp;
<input type="checkbox" value="1" name="attr_swords_favoured" title="Toggle favoured" />
<label data-i18n="swords">Swords</label>
<div class="sheet-hover-info" data-i18n="swords-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_swords" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_swords" value="1" /><span></span>
<input type="radio" name="attr_swords" value="2" /><span></span>
<input type="radio" name="attr_swords" value="3" /><span></span>
<input type="radio" name="attr_swords" value="4" /><span></span>
<input type="radio" name="attr_swords" value="5" /><span></span>
<input type="radio" name="attr_swords" value="6" /><span></span>
</div>
</div>
<div class="sheet-row">
<input type="hidden" name="attr_brawl_roll1" />
<button type="roll" class="table-rolls" name="roll_brawlcheck1" value="@{brawl_roll1}"></button>
<input type="hidden" name="attr_brawl_roll2" />
<button type="roll" class="table-rolls crosshair" name="roll_brawlcheck2"
value="@{brawl_roll2}"></button>
&nbsp;
<input type="checkbox" value="1" name="attr_brawl_favoured" title="Toggle favoured" />
<label data-i18n="brawling">Brawling</label>
<div class="sheet-hover-info" data-i18n="brawling-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_brawl" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_brawl" value="1" /><span></span>
<input type="radio" name="attr_brawl" value="2" /><span></span>
<input type="radio" name="attr_brawl" value="3" /><span></span>
<input type="radio" name="attr_brawl" value="4" /><span></span>
<input type="radio" name="attr_brawl" value="5" /><span></span>
<input type="radio" name="attr_brawl" value="6" /><span></span>
</div>
</div>
<div class="center sheet-row">
<label data-i18n="stance">Stance</label>
<label><input name="attr_stance" type="radio" value="1"> <span data-i18n="stance-forward">Forw.</span>
</label>
<label><input name="attr_stance" type="radio" value="2" checked="checked"> <span
data-i18n="stance-open">Open</span> </label>
<label><input name="attr_stance" type="radio" value="3"> <span data-i18n="stance-defensive">Def.</span>
</label>
<label><input name="attr_stance" type="radio" value="4"> <span data-i18n="stance-rearward">Rear</span>
</label>
</div>
<div class="sheet-row">
<div class="center">
<label>
<span data-i18n="stance-attack-modifier"
data-i18n-title="stance-attack-modifier-description">Attack Mod.:</span></label>
<input name="attr_stanceattackbonus" value="0" type="number" readonly>
<label>
<input name="attr_stanceattack_active" type="checkbox" value="1">
<span data-i18n="stance-damage">Stance Damage:</span>
</label>
<input name="attr_stancedamagebonus" value="0" type="number">
</div>
</div>
</div>
<div id="skill-strength">
<h1>&nbsp;</h1>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{awe_roll}" name="roll_awecheck"></button>
<button type="action" class="parsed-rolls" name="act_awe" id="roll_awe"></button>
<input type="checkbox" name="attr_awe_favoured">
<label data-i18n="awe">Awe</label>
<div class="sheet-hover-info" data-i18n="awe-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_awe" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_awe" value="1" /><span></span>
<input type="radio" name="attr_awe" value="2" /><span></span>
<input type="radio" name="attr_awe" value="3" /><span></span>
<input type="radio" name="attr_awe" value="4" /><span></span>
<input type="radio" name="attr_awe" value="5" /><span></span>
<input type="radio" name="attr_awe" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{athletics_roll}" name="roll_athleticscheck"></button>
<button type="action" class="parsed-rolls" name="act_athletics" id="roll_athletics"></button>
<input type="checkbox" name="attr_athletics_favoured">
<label data-i18n="athletics">Athletics</label>
<div class="sheet-hover-info" data-i18n="athletics-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_athletics" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_athletics" value="1" /><span></span>
<input type="radio" name="attr_athletics" value="2" /><span></span>
<input type="radio" name="attr_athletics" value="3" /><span></span>
<input type="radio" name="attr_athletics" value="4" /><span></span>
<input type="radio" name="attr_athletics" value="5" /><span></span>
<input type="radio" name="attr_athletics" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{awareness_roll}" name="roll_awarenesscheck"></button>
<button type="action" class="parsed-rolls" name="act_awareness" id="roll_awareness"></button>
<input type="checkbox" name="attr_awareness_favoured">
<label data-i18n="awareness">Awareness</label>
<div class="sheet-hover-info" data-i18n="awareness-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_awareness" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_awareness" value="1" /><span></span>
<input type="radio" name="attr_awareness" value="2" /><span></span>
<input type="radio" name="attr_awareness" value="3" /><span></span>
<input type="radio" name="attr_awareness" value="4" /><span></span>
<input type="radio" name="attr_awareness" value="5" /><span></span>
<input type="radio" name="attr_awareness" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{hunting_roll}" name="roll_huntingcheck"></button>
<button type="action" class="parsed-rolls" name="act_hunting" id="roll_hunting"></button>
<input type="checkbox" name="attr_hunting_favoured">
<label data-i18n="hunting">Hunting</label>
<div class="sheet-hover-info" data-i18n="hunting-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_hunting" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_hunting" value="1" /><span></span>
<input type="radio" name="attr_hunting" value="2" /><span></span>
<input type="radio" name="attr_hunting" value="3" /><span></span>
<input type="radio" name="attr_hunting" value="4" /><span></span>
<input type="radio" name="attr_hunting" value="5" /><span></span>
<input type="radio" name="attr_hunting" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{song_roll}" name="roll_songcheck"></button>
<button type="action" class="parsed-rolls" name="act_song" id="roll_song"></button>
<input type="checkbox" name="attr_song_favoured">
<label data-i18n="song">Song</label>
<div class="sheet-hover-info" data-i18n="song-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_song" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_song" value="1" /><span></span>
<input type="radio" name="attr_song" value="2" /><span></span>
<input type="radio" name="attr_song" value="3" /><span></span>
<input type="radio" name="attr_song" value="4" /><span></span>
<input type="radio" name="attr_song" value="5" /><span></span>
<input type="radio" name="attr_song" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{craft_roll}" name="roll_craftcheck"></button>
<button type="action" class="parsed-rolls" name="act_craft" id="roll_craft"></button>
<input type="checkbox" name="attr_craft_favoured">
<label data-i18n="craft">Craft</label>
<div class="sheet-hover-info" data-i18n="craft-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_craft" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_craft" value="1" /><span></span>
<input type="radio" name="attr_craft" value="2" /><span></span>
<input type="radio" name="attr_craft" value="3" /><span></span>
<input type="radio" name="attr_craft" value="4" /><span></span>
<input type="radio" name="attr_craft" value="5" /><span></span>
<input type="radio" name="attr_craft" value="6" /><span></span>
</div>
</div>
</div>
<div id="skill-heart">
<h1 data-i18n="skills" class="center"></h1>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{enhearten_roll}" name="roll_enheartencheck"></button>
<button type="action" class="parsed-rolls" name="act_enhearten" id="roll_enhearten"></button>
<input type="checkbox" name="attr_enhearten_favoured">
<label data-i18n="enhearten">Enhearten</label>
<div class="sheet-hover-info" data-i18n="enhearten-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_enhearten" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_enhearten" value="1" /><span></span>
<input type="radio" name="attr_enhearten" value="2" /><span></span>
<input type="radio" name="attr_enhearten" value="3" /><span></span>
<input type="radio" name="attr_enhearten" value="4" /><span></span>
<input type="radio" name="attr_enhearten" value="5" /><span></span>
<input type="radio" name="attr_enhearten" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{travel_roll}" name="roll_travelcheck"></button>
<button type="action" class="parsed-rolls" name="act_travel" id="roll_travel"></button>
<input type="checkbox" name="attr_travel_favoured">
<label data-i18n="travel">Travel</label>
<div class="sheet-hover-info" data-i18n="travel-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_travel" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_travel" value="1" /><span></span>
<input type="radio" name="attr_travel" value="2" /><span></span>
<input type="radio" name="attr_travel" value="3" /><span></span>
<input type="radio" name="attr_travel" value="4" /><span></span>
<input type="radio" name="attr_travel" value="5" /><span></span>
<input type="radio" name="attr_travel" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{insight_roll}" name="roll_insightcheck"></button>
<button type="action" class="parsed-rolls" name="act_insight" id="roll_insight"></button>
<input type="checkbox" name="attr_insight_favoured">
<label data-i18n="insight">Insight</label>
<div class="sheet-hover-info" data-i18n="insight-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_insight" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_insight" value="1" /><span></span>
<input type="radio" name="attr_insight" value="2" /><span></span>
<input type="radio" name="attr_insight" value="3" /><span></span>
<input type="radio" name="attr_insight" value="4" /><span></span>
<input type="radio" name="attr_insight" value="5" /><span></span>
<input type="radio" name="attr_insight" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{healing_roll}" name="roll_healingcheck"></button>
<button type="action" class="parsed-rolls" name="act_healing" id="roll_healing"></button>
<input type="checkbox" name="attr_healing_favoured">
<label data-i18n="healing">Healing</label>
<div class="sheet-hover-info" data-i18n="healing-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_healing" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_healing" value="1" /><span></span>
<input type="radio" name="attr_healing" value="2" /><span></span>
<input type="radio" name="attr_healing" value="3" /><span></span>
<input type="radio" name="attr_healing" value="4" /><span></span>
<input type="radio" name="attr_healing" value="5" /><span></span>
<input type="radio" name="attr_healing" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{courtesy_roll}" name="roll_courtesycheck"></button>
<button type="action" class="parsed-rolls" name="act_courtesy" id="roll_courtesy"></button>
<input type="checkbox" name="attr_courtesy_favoured">
<label data-i18n="courtesy">Courtesy</label>
<div class="sheet-hover-info" data-i18n="courtesy-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_courtesy" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_courtesy" value="1" /><span></span>
<input type="radio" name="attr_courtesy" value="2" /><span></span>
<input type="radio" name="attr_courtesy" value="3" /><span></span>
<input type="radio" name="attr_courtesy" value="4" /><span></span>
<input type="radio" name="attr_courtesy" value="5" /><span></span>
<input type="radio" name="attr_courtesy" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{battle_roll}" name="roll_battlecheck"></button>
<button type="action" class="parsed-rolls" name="act_battle" id="roll_battle"></button>
<input type="checkbox" name="attr_battle_favoured">
<label data-i18n="battle">Battle</label>
<div class="sheet-hover-info" data-i18n="battle-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_battle" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_battle" value="1" /><span></span>
<input type="radio" name="attr_battle" value="2" /><span></span>
<input type="radio" name="attr_battle" value="3" /><span></span>
<input type="radio" name="attr_battle" value="4" /><span></span>
<input type="radio" name="attr_battle" value="5" /><span></span>
<input type="radio" name="attr_battle" value="6" /><span></span>
</div>
</div>
</div>
<div id="skill-wits">
<h1>&nbsp;</h1>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{persuade_roll}" name="roll_persuadecheck"></button>
<button type="action" class="parsed-rolls" name="act_persuade" id="roll_persuade"></button>
<input type="checkbox" name="attr_persuade_favoured">
<label data-i18n="persuade">Persuade</label>
<div class="sheet-hover-info" data-i18n="persuade-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_persuade" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_persuade" value="1" /><span></span>
<input type="radio" name="attr_persuade" value="2" /><span></span>
<input type="radio" name="attr_persuade" value="3" /><span></span>
<input type="radio" name="attr_persuade" value="4" /><span></span>
<input type="radio" name="attr_persuade" value="5" /><span></span>
<input type="radio" name="attr_persuade" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{stealth_roll}" name="roll_stealthcheck"></button>
<button type="action" class="parsed-rolls" name="act_stealth" id="roll_stealth"></button>
<input type="checkbox" name="attr_stealth_favoured">
<label data-i18n="stealth">Stealth</label>
<div class="sheet-hover-info" data-i18n="stealth-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_stealth" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_stealth" value="1" /><span></span>
<input type="radio" name="attr_stealth" value="2" /><span></span>
<input type="radio" name="attr_stealth" value="3" /><span></span>
<input type="radio" name="attr_stealth" value="4" /><span></span>
<input type="radio" name="attr_stealth" value="5" /><span></span>
<input type="radio" name="attr_stealth" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{scan_roll}" name="roll_scancheck"></button>
<button type="action" class="parsed-rolls" name="act_scan" id="roll_scan"></button>
<input type="checkbox" name="attr_scan_favoured">
<label data-i18n="scan">Scan</label>
<div class="sheet-hover-info" data-i18n="scan-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_scan" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_scan" value="1" /><span></span>
<input type="radio" name="attr_scan" value="2" /><span></span>
<input type="radio" name="attr_scan" value="3" /><span></span>
<input type="radio" name="attr_scan" value="4" /><span></span>
<input type="radio" name="attr_scan" value="5" /><span></span>
<input type="radio" name="attr_scan" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{explore_roll}" name="roll_explorecheck"></button>
<button type="action" class="parsed-rolls" name="act_explore" id="roll_explore"></button>
<input type="checkbox" name="attr_explore_favoured">
<label data-i18n="explore">Explore</label>
<div class="sheet-hover-info" data-i18n="explore-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_explore" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_explore" value="1" /><span></span>
<input type="radio" name="attr_explore" value="2" /><span></span>
<input type="radio" name="attr_explore" value="3" /><span></span>
<input type="radio" name="attr_explore" value="4" /><span></span>
<input type="radio" name="attr_explore" value="5" /><span></span>
<input type="radio" name="attr_explore" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{riddle_roll}" name="roll_riddlecheck"></button>
<button type="action" class="parsed-rolls" name="act_riddle" id="roll_riddle"></button>
<input type="checkbox" name="attr_riddle_favoured">
<label data-i18n="riddle">Riddle</label>
<div class="sheet-hover-info" data-i18n="riddle-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_riddle" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_riddle" value="1" /><span></span>
<input type="radio" name="attr_riddle" value="2" /><span></span>
<input type="radio" name="attr_riddle" value="3" /><span></span>
<input type="radio" name="attr_riddle" value="4" /><span></span>
<input type="radio" name="attr_riddle" value="5" /><span></span>
<input type="radio" name="attr_riddle" value="6" /><span></span>
</div>
</div>
<div class=sheet-row>
<button type="roll" class="table-rolls" value="@{lore_roll}" name="roll_lorecheck"></button>
<button type="action" class="parsed-rolls" name="act_lore" id="roll_lore"></button>
<input type="checkbox" name="attr_lore_favoured">
<label data-i18n="lore">Lore</label>
<div class="sheet-hover-info" data-i18n="lore-description"></div>
<div class="sheet-dots">
<input type="radio" name="attr_lore" value="0" checked="checked" /><span></span>
<input type="radio" name="attr_lore" value="1" /><span></span>
<input type="radio" name="attr_lore" value="2" /><span></span>
<input type="radio" name="attr_lore" value="3" /><span></span>
<input type="radio" name="attr_lore" value="4" /><span></span>
<input type="radio" name="attr_lore" value="5" /><span></span>
<input type="radio" name="attr_lore" value="6" /><span></span>
</div>
</div>
</div>
<div id="war-gear">
<!-- <h2>War Gear</h2> -->
<div id="war-gear-nested">
<span />
<h2 data-i18n="weapon">Weapon</h2>
<label data-i18n="weapon-type">Type</label>
<label class="center" data-i18n="weapon-damage">Dmg.</label>
<label class="center" data-i18n="weapon-injury">Inj.</label>
<label class="center" data-i18n="weapon-load">Load</label>
<label class="center" data-i18n="weapon-fell" data-i18n-title="weapon-fell-description">F</label>
<label class="center" data-i18n="weapon-grievous"
data-i18n-title="weapon-grievous-description">G</label>
<label class="center" data-i18n="weapon-keen" data-i18n-title="weapon-keen-description">K</label>
<label data-i18n="notes">Notes</label>
<span class="table-rolls" />
<span class="parsed-rolls">
<input type='hidden' name='attr_weapon_1_action' value=''>
<button type='action' name='act_weapon_1_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_1' class="parsed-rolls" value='@{weapon_1_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_weapon_1_target_action' value=''>
<button type='action' name='act_weapon_1_target_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_1_target' class="parsed-rolls crosshair"
value='@{weapon_1_target_action}'
title="Use this button when you have an adversary token to target."></button>
&nbsp;
<input type="checkbox" value="1" name="attr_weapon_active_1" checked="checked" title="Toggle weapon is equipped on/off.">
&nbsp;
</span>
<input name="attr_weapon_skill_name_1" type="text" />
<select name="attr_weapon_combat_prof_1">
<option value="" selected default></option>
<option value="axes" data-i18n="axes">Axes</option>
<option value="bows" data-i18n="bows">Bows</option>
<option value="spears" data-i18n="spears">Spears</option>
<option value="swords" data-i18n="swords">Swords</option>
<option value="brawl" data-i18n="brawling">Brawling</option>
</select>
<input name="attr_weapon_damage_1" value="0" class="center number" type="number">
<input name="attr_weapon_injury_1" value="0" class="center number" type="number">
<input name="attr_weapon_load_1" value="0" class="center number" type="number">
<select name="attr_weapon_fell_val_1">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="4">+4</option>
</select>
<select name="attr_weapon_grievous_val_1">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_weapon_keen_val_1">
<option value="10" selected default></option>
<option value="9">9+</option>
<option value="8">8+</option>
</select>
<input name="attr_weapon_note_1" type="text">
<span class="table-rolls" />
<span class="parsed-rolls">
<input type='hidden' name='attr_weapon_2_action' value=''>
<button type='action' name='act_weapon_2_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_2' class="parsed-rolls" value='@{weapon_2_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_weapon_2_target_action' value=''>
<button type='action' name='act_weapon_2_target_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_2_target' class="parsed-rolls crosshair"
value='@{weapon_2_target_action}'
title="Use this button when you have an adversary token to target."></button>
&nbsp;
<input type="checkbox" value="1" name="attr_weapon_active_2" checked="checked" title="Toggle weapon is equipped on/off.">
&nbsp;
</span>
<input name="attr_weapon_skill_name_2" type="text" />
<select name="attr_weapon_combat_prof_2">
<option value="" selected default></option>
<option value="axes" data-i18n="axes">Axes</option>
<option value="bows" data-i18n="bows">Bows</option>
<option value="spears" data-i18n="spears">Spears</option>
<option value="swords" data-i18n="swords">Swords</option>
<option value="brawl" data-i18n="brawling">Brawling</option>
</select>
<input name="attr_weapon_damage_2" value="0" class="center number" type="number">
<input name="attr_weapon_injury_2" value="0" class="center number" type="number">
<input name="attr_weapon_load_2" value="0" class="center number" type="number">
<select name="attr_weapon_fell_val_2">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="4">+4</option>
</select>
<select name="attr_weapon_grievous_val_2">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_weapon_keen_val_2">
<option value="10" selected default></option>
<option value="9">9+</option>
<option value="8">8+</option>
</select>
<input name="attr_weapon_note_2" type="text">
<span class="table-rolls" />
<span class="parsed-rolls">
<input type='hidden' name='attr_weapon_3_action' value=''>
<button type='action' name='act_weapon_3_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_3' class="parsed-rolls" value='@{weapon_3_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_weapon_3_target_action' value=''>
<button type='action' name='act_weapon_3_target_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_3_target' class="parsed-rolls crosshair"
value='@{weapon_3_target_action}'
title="Use this button when you have an adversary token to target."></button>
&nbsp;
<input type="checkbox" value="1" name="attr_weapon_active_3" checked="checked" title="Toggle weapon is equipped on/off.">
&nbsp;
</span>
<input name="attr_weapon_skill_name_3" type="text" />
<select name="attr_weapon_combat_prof_3">
<option value="" selected default></option>
<option value="axes" data-i18n="axes">Axes</option>
<option value="bows" data-i18n="bows">Bows</option>
<option value="spears" data-i18n="spears">Spears</option>
<option value="swords" data-i18n="swords">Swords</option>
<option value="brawl" data-i18n="brawling">Brawling</option>
</select>
<input name="attr_weapon_damage_3" value="0" class="center number" type="number">
<input name="attr_weapon_injury_3" value="0" class="center number" type="number">
<input name="attr_weapon_load_3" value="0" class="center number" type="number">
<select name="attr_weapon_fell_val_3">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="4">+4</option>
</select>
<select name="attr_weapon_grievous_val_3">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_weapon_keen_val_3">
<option value="10" selected default></option>
<option value="9">9+</option>
<option value="8">8+</option>
</select>
<input name="attr_weapon_note_3" type="text">
<span class="table-rolls" />
<span class="parsed-rolls">
<input type='hidden' name='attr_weapon_4_action' value='' />
<button type='action' name='act_weapon_4_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_4' class="parsed-rolls" value='@{weapon_4_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_weapon_4_target_action' value=''>
<button type='action' name='act_weapon_4_target_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_4_target' class="parsed-rolls crosshair"
value='@{weapon_4_target_action}'
title="Use this button when you have an adversary token to target."></button>
&nbsp;
<input type="checkbox" value="1" name="attr_weapon_active_4" checked="checked" title="Toggle weapon is equipped on/off.">
&nbsp;
</span>
<input name="attr_weapon_skill_name_4" type="text" />
<select name="attr_weapon_combat_prof_4">
<option value="" selected default></option>
<option value="axes" data-i18n="axes">Axes</option>
<option value="bows" data-i18n="bows">Bows</option>
<option value="spears" data-i18n="spears">Spears</option>
<option value="swords" data-i18n="swords">Swords</option>
<option value="brawl" data-i18n="brawling">Brawling</option>
</select>
<input name="attr_weapon_damage_4" value="0" class="center number" type="number">
<input name="attr_weapon_injury_4" value="0" class="center number" type="number">
<input name="attr_weapon_load_4" value="0" class="center number" type="number">
<select name="attr_weapon_fell_val_4">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="4">+4</option>
</select>
<select name="attr_weapon_grievous_val_4">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_weapon_keen_val_4">
<option value="10" selected default></option>
<option value="9">9+</option>
<option value="8">8+</option>
</select>
<input name="attr_weapon_note_4" type="text">
<span class="table-rolls" />
<span class="parsed-rolls">
<input type='hidden' name='attr_weapon_5_action' value=''>
<button type='action' name='act_weapon_5_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_5' class="parsed-rolls" value='@{weapon_5_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_weapon_5_target_action' value=''>
<button type='action' name='act_weapon_5_target_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_5_target' class="parsed-rolls crosshair"
value='@{weapon_5_target_action}'
title="Use this button when you have an adversary token to target."></button>
&nbsp;
<input type="checkbox" value="1" name="attr_weapon_active_5" checked="checked" title="Toggle weapon is equipped on/off.">
&nbsp;
</span>
<input name="attr_weapon_skill_name_5" type="text" />
<select name="attr_weapon_combat_prof_5">
<option value="" selected default></option>
<option value="axes" data-i18n="axes">Axes</option>
<option value="bows" data-i18n="bows">Bows</option>
<option value="spears" data-i18n="spears">Spears</option>
<option value="swords" data-i18n="swords">Swords</option>
<option value="brawl" data-i18n="brawling">Brawling</option>
</select>
<input name="attr_weapon_damage_5" value="0" class="center number" type="number">
<input name="attr_weapon_injury_5" value="0" class="center number" type="number">
<input name="attr_weapon_load_5" value="0" class="center number" type="number">
<select name="attr_weapon_fell_val_5">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="4">+4</option>
</select>
<select name="attr_weapon_grievous_val_5">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_weapon_keen_val_5">
<option value="10" selected default></option>
<option value="9">9+</option>
<option value="8">8+</option>
</select>
<input name="attr_weapon_note_5" type="text" />
<span class="table-rolls" />
<span class="parsed-rolls">
<input type='hidden' name='attr_weapon_6_action' value=''>
<button type='action' name='act_weapon_6_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_6' class="parsed-rolls" value='@{weapon_6_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_weapon_6_target_action' value=''>
<button type='action' name='act_weapon_6_target_action' style="display: none;"></button>
<button type='roll' name='roll_weapon_6_target' class="parsed-rolls crosshair"
value='@{weapon_6_target_action}'
title="Use this button when you have an adversary token to target."></button>
&nbsp;
<input type="checkbox" value="1" name="attr_weapon_active_6" checked="checked" title="Toggle weapon is equipped on/off.">
&nbsp;
</span>
<input name="attr_weapon_skill_name_6" type="text" />
<select name="attr_weapon_combat_prof_6">
<option value="" selected default></option>
<option value="axes" data-i18n="axes">Axes</option>
<option value="bows" data-i18n="bows">Bows</option>
<option value="spears" data-i18n="spears">Spears</option>
<option value="swords" data-i18n="swords">Swords</option>
<option value="brawl" data-i18n="brawling">Brawling</option>
</select>
<input name="attr_weapon_damage_6" value="0" class="center number" type="number">
<input name="attr_weapon_injury_6" value="0" class="center number" type="number">
<input name="attr_weapon_load_6" value="0" class="center number" type="number">
<select name="attr_weapon_fell_val_6">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="4">+4</option>
</select>
<select name="attr_weapon_grievous_val_6">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_weapon_keen_val_6">
<option value="10" selected default></option>
<option value="9">9+</option>
<option value="8">8+</option>
</select>
<input name="attr_weapon_note_6" type="text">
</div>
</div>
<div id="armour">
<!-- <h2>Armour</h2> -->
<div id="armour-nested">
<span></span>
<h2 data-i18n="armour">Armour</h2>
<label class="center" data-i18n="protection-abbr" data-i18n-title="protection">Prot.</label>
<label class="center" data-i18n="load">Load</label>
<label class="center" data-i18n="close-fitting">CF</label>
<div class="sheet-hover-info" data-i18n="close-fitting-description"></div>
<label class="center" data-i18n="cunning-make">CM</label>
<div class="sheet-hover-info" data-i18n="cunning-make-description"></div>
<input type="checkbox" name="attr_armourprot_active" value=1 checked="checked" title="Toggle armour is equipped on/off.">
<input class="text" type="text" placeholder="Armour" title="Armour" data-i18n-title="armour"
data-i18n-placeholder="armour-placeholder" name="attr_armour">
<input class="center number" type="number" name="attr_armourprot" value="0">
<input class="center number" type="number" name="attr_armourload" value="0">
<select name="attr_armourcf_val" class="center gridcol4">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="3">+3</option>
</select>
<select name="attr_armourcm_val" class="center gridcol5">
<option value="0" selected default></option>
<option value="-2">-2</option>
<option value="-3">-3</option>
</select>
<input type="checkbox" name="attr_helmprot_active" value=1 checked="checked" title="Toggle armour is equipped on/off.">
<input class="text" type="text" placeholder="Helm" title="Helm" data-i18n-title="helm"
data-i18n-placeholder="helm-placeholder" name="attr_helm">
<input class="center number" type="number" name="attr_helmprot" value="0">
<input class="center number" type="number" name="attr_helmload" value="0">
<select name="attr_helmetcf_val" class="center gridcol4">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="3">+3</option>
</select>
<select name="attr_helmetcm_val" class="center gridcol5">
<option value="0" selected default></option>
<option value="-2">-2</option>
<option value="-3">-3</option>
</select>
<input type="checkbox" name="attr_otherprot_active" value=1 checked="checked" title="Toggle armour is equipped on/off.">
<input type="text" class="text" name="attr_otherprot_name" placeholder="Other"
title="Other modifiers for Protection" data-i18n-title="Other-protection"
data-i18n-placeholder="other-placeholder">
<input class="center number" type="number" name="attr_otherprot" value="0">
<input class="center number" type="number" name="attr_otherload" value="0">
<select name="attr_othercf_val" class="center gridcol4">
<option value="0" selected default></option>
<option value="2">+2</option>
<option value="3">+3</option>
</select>
<select name="attr_othercm_val" class="center gridcol5">
<option value="0" selected default></option>
<option value="-2">-2</option>
<option value="-3">-3</option>
</select>
<span></span>
<label data-i18n="shield">Shield</label>
<label class="center" data-i18n="parry">Parry</label>
<label class="center" data-i18n="load">Load</label>
<label class="center" data-i18n="reinforced">RI</label>
<div class="sheet-hover-info" data-i18n="reinforced-description"></div>
<label class="center" data-i18n="cunning-make">CM</label>
<div class="sheet-hover-info" data-i18n="cunning-make-description"></div>
<input type="checkbox" name="attr_shieldparry_active" value="1" checked="checked" title="Toggle shield is equipped on/off.">
<input class="text" type="text" placeholder="Shield" data-i18n-title="shield"
data-i18n-placeholder="shield-placeholder" name="attr_shield">
<input class="center number" type="number" name="attr_shieldparry" value="0">
<input class="center number" type="number" name="attr_shieldload" value="0">
<select name="attr_shieldreinf_val" class="center gridcol4">
<option value="0" selected default></option>
<option value="1">+1</option>
<option value="2">+2</option>
</select>
<select name="attr_shieldcm_val" class="center gridcol5">
<option value="0" selected default></option>
<option value="-2">-2</option>
<option value="-3">-3</option>
</select>
</div>
</div>
<div id="mount">
<h2 class="center" data-i18n="mount">Mount</h2>
<div id="mount-nested">
<!-- <label>Quality</label> -->
<label class="center" data-i18n="mount-name">Name</label>
<label class="center" data-i18n="mount-vigour">Vigour</label>
<label class="center" data-i18n="mount-treasure">Treasure</label>
<input class="text" type="text" name="attr_mount">
<!-- <input class="center number" type="number" name="attr_mountquality" value="0"> -->
<input class="center number" type="number" name="attr_mountvigour" value="0">
<input class="center number" type="number" name="attr_mounttreasure" value="0">
</div>
</div>
<div id="protection">
<!-- <h1>Protection</h1> -->
<div id="protection-nested">
<br />
<span class="diamond-red">
<span><input class="strong" name="attr_protection" value="0" type="number"
readonly="readonly"></span>
</span>
<span>
<button type="roll" class="table-rolls" name="roll_protectioncheck"
value="@{protection_roll}"></button>
<input type='hidden' name='attr_protection_action' value=''>
<button type='action' name='act_protection_action' style="display: none;"></button>
<button type='roll' name='roll_protection' class="parsed-rolls"
value='@{protection_action}'></button>
&nbsp;<input type="checkbox" name="attr_protection_favoured" />
<label class="center" data-i18n="protection">Protection</label>
</span>
<span class="diamond-small">
<span><input name="attr_stanceprot" value="0" type="number"></span></span>
<label class="center"><input type="checkbox" name="attr_stanceprot_active" value=1
checked="checked" /><span data-i18n="stance">Stance</span></label>
</div>
</div>
<input type="hidden" class="sheet-notestoggle" name="attr_notesactive" />
<div id="notes">
<div id="notes-nested">
<input type="hidden" class="sheet-notestabtoggle" name="attr_notestabactive" />
<div>
<button class="btn-labeled" type="action" name="act_notes1">Show</button>
<input name="attr_notesname1" type="text" />
</div>
<div>
<button class="btn-labeled" type="action" name="act_notes2">Show</button>
<input name="attr_notesname2" type="text" />
</div>
<div>
<button class="btn-labeled" type="action" name="act_notes3">Show</button>
<input name="attr_notesname3" type="text" />
</div>
<div>
<button class="btn-labeled" type="action" name="act_notes4">Show</button>
<input name="attr_notesname4" type="text" />
</div>
<div class="notes-text" id="notes-text1">
<textarea name="attr_notes" />
</div>
<div class="notes-text" id="notes-text2">
<textarea name="attr_notes2" />
</div>
<div class="notes-text" id="notes-text3">
<textarea name="attr_notes3" />
</div>
<div class="notes-text" id="notes-text4">
<textarea name="attr_notes4" />
</div>
</div>
</div>
</div>
</div>
<div class="sheet-adversary">
<div class="adversary-header">
<h1 class="left" data-i18n="character-name"></h1>
<h1 data-i18n="attribute-level"></h1>
<div class="adversary-level">
<span class="diamond-red">
<span><input class="strong center" type="number" name="attr_attribute-level" value="0" /></span>
</span>
</div>
<input type="text" name="attr_name" value="" />
<label data-i18n="distinctive-features"></label><span />
<input type="text" name="attr_distinctive-features" />
<div class="left">
<label data-i18n="parsed-rolls"></label>
<div class="sheet-hover-info" data-i18n="parsedroll-description"></div>
<span class="toggle">
<input type="checkbox" name="attr_parsedrolls" value="1" checked="checked" id="config_parsedrolls" />
&nbsp;
<input type="checkbox" name="attr_parsedrolls" value="0" id="config_tablerolls" />
</span>
<label data-i18n="table-rolls"></label>
<div class="sheet-hover-info" data-i18n="tableroll-description"></div>
<span>
<label> | </label>
<label data-i18n="whisper" />
<input class="center" type="text" data-i18n-placeholder="whisper-placeholder" name="attr_whisper">
</span>
<span id="darkmode-toggle">&nbsp;&nbsp;
<label data-i18n="darkmode">Darkmode</label>
<input name="attr_darktoggle" type="checkbox" value=1 checked="checked">
</span>
</div>
<div class="center">
<span class="toggle">
<label>
<input name="attr_favorill" type="checkbox" value="{1t[feat]}" checked="checked">
<span data-i18n="normal"></span>
</label>
<label>
<input name="attr_favorill" type="checkbox" value="{2t[feat]}kh1">
<span data-i18n="favoured"></span>
</label>
<label>
<input name="attr_favorill" type="checkbox" value="{2t[feat]}kl1">
<span data-i18n="illfavoured"></span>
</label>
</span>
<br />
<label><input name="attr_weary" type="checkbox" value=1><span data-i18n="weary-weary">Weary</span></label>
</div>
</div>
<div class="adversary-attributes">
<span />
<h1 data-i18n="endurance"></h1>
<h1 data-i18n="might"></h1>
<!--<h1 data-i18n="hate">Hate/Resolve</h1>-->
<select name="attr_hateresolve">
<option value="1" data-i18n="hate"></option>
<option value="2" data-i18n="resolve"></option>
</select>
<h1 data-i18n="parry"></h1>
<h1 data-i18n="armour"></h1>
<span />
<span />
<span class="diamond-red">
<span><input class="strong" type="number" name="attr_endurance" /></span>
</span>
<span class="diamond-red">
<span><input class="strong" type="number" name="attr_might" /></span>
</span>
<span class="diamond-red">
<span><input class="strong" type="number" name="attr_hate" /></span>
</span>
<span class="diamond-red">
<span><input class="strong" type="number" name="attr_parry" /></span>
</span>
<span class="diamond-red">
<span><input class="strong" type="number" name="attr_armourprot" /></span>
</span>
<span />
<span />
<span />
<span />
<span />
<span />
<button type="roll" class="table-rolls"
value="/me rolls protection against ?{Injury|16}.\n/roll 1t[lm-feat] + @{armourprot}t[@{wearytype}]"
name="armourcheck"></button>
<input type='hidden' name='attr_protection_action' value=''>
<button type='action' name='act_protection_action' style="display: none;"></button>
<button type='roll' name='roll_protection' class="parsed-rolls" value='@{protection_action}'></button>
<span />
</div>
<div class="adversary-combat-proficiencies">
<h1 class="left" data-i18n="combat-proficiency"></h1>
<label class="center" data-i18n="weapon-rating"></label>
<label class="center" data-i18n="weapon-damage"></label>
<label class="center" data-i18n="weapon-injury"></label>
<label class="left" data-i18n="special-damage"></label>
<span>
<input type="hidden" name="attr_adv_weapon1_roll1" value="" />
<button type="roll" class="table-rolls" value="@{adv_weapon1_roll1}" name="roll_weapon1"></button>
<input type="hidden" name="attr_adv_weapon1_roll2" value="" />
<button type="roll" class="table-rolls crosshair" value="@{adv_weapon1_roll2}"
name="roll_weapon1_target"></button>
<span class="parsed-rolls">
<input type='hidden' name='attr_adv_weapon1_action' value=''>
<button type='action' name='act_adv_weapon1_action' style="display: none;"></button>
<button type='roll' name='roll_adv_weapon1' class="parsed-rolls" value='@{adv_weapon1_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_adv_weapon1_target_action' value=''>
<button type='action' name='act_adv_weapon1_target_action' style="display: none;"></button>
<button type='roll' name='roll_adv_weapon1_target' class="parsed-rolls crosshair"
value='@{adv_weapon1_target_action}'
title="Use this button when you have an player token to target."></button>
</span>
<input name="attr_weapon_skill_name_1" type="text">
</span>
<input name="attr_weapon_rating_1" value="0" class="number" type="number">
<input name="attr_weapon_damage_1" value="0" class="number" type="number">
<input name="attr_weapon_injury_1" value="0" class="number" type="number">
<input name="attr_weapon_special_damage_1" type="text">
<span>
<input type="hidden" name="attr_adv_weapon2_roll1" value="" />
<button type="roll" class="table-rolls" value="@{adv_weapon2_roll1}" name="roll_weapon2"></button>
<input type="hidden" name="attr_adv_weapon2_roll2" value="" />
<button type="roll" class="table-rolls crosshair" value="@{adv_weapon2_roll2}"
name="roll_weapon2_target"></button>
<span class="parsed-rolls">
<input type='hidden' name='attr_adv_weapon2_action' value=''>
<button type='action' name='act_adv_weapon2_action' style="display: none;"></button>
<button type='roll' name='roll_adv_weapon2' class="parsed-rolls" value='@{adv_weapon2_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_adv_weapon2_target_action' value=''>
<button type='action' name='act_adv_weapon2_target_action' style="display: none;"></button>
<button type='roll' name='roll_adv_weapon2_target' class="parsed-rolls crosshair"
value='@{adv_weapon2_target_action}'
title="Use this button when you have an player token to target."></button>
</span>
<input name="attr_weapon_skill_name_2" type="text">
</span>
<input name="attr_weapon_rating_2" value="0" class="number" type="number">
<input name="attr_weapon_damage_2" value="0" class="number" type="number">
<input name="attr_weapon_injury_2" value="0" class="number" type="number">
<input name="attr_weapon_special_damage_2" type="text">
<span>
<input type="hidden" name="attr_adv_weapon3_roll1" value="" />
<button type="roll" class="table-rolls" value="@{adv_weapon3_roll1}" name="roll_weapon3"></button>
<input type="hidden" name="attr_adv_weapon3_roll2" value="" />
<button type="roll" class="table-rolls crosshair" value="@{adv_weapon3_roll2}"
name="roll_weapon3_target"></button>
<span class="parsed-rolls">
<input type='hidden' name='attr_adv_weapon3_action' value=''>
<button type='action' name='act_adv_weapon3_action' style="display: none;"></button>
<button type='roll' name='roll_adv_weapon3' class="parsed-rolls" value='@{adv_weapon3_action}'
title="Use this button when you have a Parry Rating that you can enter manually."></button>
<input type='hidden' name='attr_adv_weapon3_target_action' value=''>
<button type='action' name='act_adv_weapon3_target_action' style="display: none;"></button>
<button type='roll' name='roll_adv_weapon3_target' class="parsed-rolls crosshair"
value='@{adv_weapon3_target_action}'
title="Use this button when you have an player token to target."></button>
</span>
<input name="attr_weapon_skill_name_3" type="text">
</span>
<input name="attr_weapon_rating_3" value="0" class="number" type="number">
<input name="attr_weapon_damage_3" value="0" class="number" type="number">
<input name="attr_weapon_injury_3" value="0" class="number" type="number">
<input name="attr_weapon_special_damage_3" type="text">
</div>
<div class="adversary-fell-abilities">
<h1 data-i18n="fell-ability">Fell Ability</h1>
<span />
<label class="empf-black left" data-i18n="description">Description</label>
</div>
<fieldset class="repeating_fell-abilities">
<div class="adversary-fell-abilities">
<button type='action' name='act_adv-fell' class="parsed-rolls chat"></button>
<input name="attr_fell_ability" type="text" />
<textarea name="attr_fell_ability_desc" type="text" />
</div>
</fieldset>
<div class="adversary-notes">
<h2 data-i18n="notes">Notes</h2>
<div class="autoExpand">
<textarea name="attr_notes">
</div>
</div>
</div>
<div class="center">
<br />
<button class="btn-tab" type="action" name="act_isPC" data-i18n="sheet-type-Player-Character"></button>
<button class="btn-tab" type="action" name="act_isAdversary" data-i18n="sheet-type-Adversary"></button>
<button class="btn-tab" type="action" name="act_releaselog" data-i18n="sheet-type-Releaselog"></button>
<br />
<div id="version">Version <span name="attr_version"></span></div>
</div>
<input type="hidden" class="sheet-releaselogtoggle" name="attr_releaselogactive"/>
<div id="releaselog">
<textarea name="attr_releaselog" readonly="readonly"/>
</div>
<div style="display: none;">
<input name="attr_wearytype">
<input name="attr_awe_roll">
<input name="attr_athletics_roll">
<input name="attr_awareness_roll">
<input name="attr_hunting_roll">
<input name="attr_song_roll">
<input name="attr_craft_roll">
<input name="attr_enhearten_roll">
<input name="attr_travel_roll">
<input name="attr_insight_roll">
<input name="attr_healing_roll">
<input name="attr_courtesy_roll">
<input name="attr_battle_roll">
<input name="attr_persuade_roll">
<input name="attr_stealth_roll">
<input name="attr_scan_roll">
<input name="attr_explore_roll">
<input name="attr_riddle_roll">
<input name="attr_lore_roll">
<input name="attr_valour_roll">
<input name="attr_wisdom_roll">
<input name="attr_protection_roll">
<input name="attr_favourill_id">
<input name="attr_stance_max" value="4" />
</div>
<!-- Sheet Workers -->
<script type="text/worker">
/* number and log handling */
const int = (score, on_error = 0) => parseInt(score) || on_error;
const float = (score, on_error = 0) => parseFloat(score) || on_error;
const clog = (text, title = "", color = "green", style = "font-size:12px; font-weight:normal;", headerstyle = "font-size:13px; font-weight:bold;") => {
let titleStyle = `color:${color}; ${headerstyle} text-decoration:underline;`;
let textStyle = `color:${color}; ${style}`;
let output = `%c${title} %c${text}`;
if (title) {
console.log(output, titleStyle, textStyle);
} else {
output = `%c${text}`;
console.log(output, textStyle);
}
};
const hlog = (text, msg = {msg: ""}) => {
msg.msg = msg.msg + text + "\n";
return msg;
};
const capitalize = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
const stripaction = (str) => {
return str.replace(/_action/g,'');
};
const range = (start, stop, step=1) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
// ASYNC ATTRIBUTE METHODS (see https://app.roll20.net/forum/post/10346883/adventures-with-startroll)
const asw = (() => {
const setActiveCharacterId = function(charId){
let oldAcid=getActiveCharacterId();
let ev = new CustomEvent("message");
ev.data={"id":"0", "type":"setActiveCharacter", "data":charId};
self.dispatchEvent(ev);
return oldAcid;
};
const promisifyWorker = (worker, parameters) => {
let acid=getActiveCharacterId();
let prevAcid=null;
return new Promise((res,rej)=>{
prevAcid=setActiveCharacterId(acid);
try {if (worker===0) getAttrs(parameters[0]||[],(v)=>res(v));
else if (worker===1) setAttrs(parameters[0]||{}, parameters[1]||{},(v)=>res(v));
else if (worker===2) getSectionIDs(parameters[0]||'',(v)=>res(v));
} catch(err) {rej(console.error(err))}
}).finally(()=>setActiveCharacterId(prevAcid));
}
return {
getAttrs(attrArray) {return promisifyWorker(0, [attrArray])},
setAttrs(attrObj, options) {return promisifyWorker(1, [attrObj, options])},
getSectionIDs(section) {return promisifyWorker(2, [section])},
setActiveCharacterId,
}
})();
// Helper function to grab player input
const getQuery = async (queryText) => {
const rxGrab = /^0\[(.*)\]\s*$/;
let rollBase = `! {{query1=[[ 0[${queryText}] ]]}}`, // just a [[0]] roll with an inline tag
queryRoll = await startRoll(rollBase),
queryResponse = (queryRoll.results.query1.expression.match(rxGrab) || [])[1];
finishRoll(queryRoll.rollId); // you can just let this time out if you want - we're done with it
return queryResponse;
};
// STRING PARSING METHODS FOR ROLLS
const rollEscape = {
chars: { '"': '%quot;', ',': '%comma;', ':': '%colon;', '}': '%rcub;', '{': '%lcub;', },
escape(str) {
str = (typeof(str) === 'object') ? JSON.stringify(str) : (typeof(str) === 'string') ? str : null;
return (str) ? `${str}`.replace(new RegExp(`[${Object.keys(this.chars)}]`, 'g'), (r) => this.chars[r]) : null;
},
unescape(str) {
str = `${str}`.replace(new RegExp(`(${Object.values(this.chars).join('|')})`, 'g'), (r) => Object.entries(this.chars).find(e=>e[1]===r)[0]);
return JSON.parse(str);
}
}
const rollMessage = async ({header, header_alt, sub1, sub1_alt, sub2, sub2_alt, msg, msg_alt} = {}) => {
const attrs = await asw.getAttrs(["whisper"]);
let whisper = attrs.whisper;
// Handling whispered messages
let whisper_mode = "";
if (whisper === "me") {
whisper_mode = "/me ";
} else if (whisper != "") {
whisper_mode = `/w ${whisper} `;
}
header = header === undefined ? "" : `{{header=${header}}}`;
header_alt = header_alt === undefined ? "" : `{{header-alt=${header_alt}}}`;
sub1 = sub1 === undefined ? "" : `{{sub1=${sub1}}}`;
sub1_alt = sub1_alt === undefined ? "" : `{{sub1-alt=${sub1_alt}}}`;
sub2 = sub2 === undefined ? "" : `{{sub2=${sub2}}}`;
sub2_alt = sub2_alt === undefined ? "" : `{{sub2-alt=${sub2_alt}}}`;
msg = msg === undefined ? "" : `{{msg=${msg}}}`;
msg_alt = msg_alt === undefined ? "" : `{{msg-alt=${msg_alt}}}`;
let rollBase = `${whisper_mode}&{template:msg} ${header}${header_alt}${sub1}${sub1_alt}${sub2_alt}${msg}${msg_alt}`;
let targetRoll = await startRoll(rollBase);
clog (`targetRoll: ${JSON.stringify(targetRoll)})`);
finishRoll(targetRoll.rollId);
clog (`targetRoll: ${JSON.stringify(targetRoll)})`);
return;
};
// isolated target call
const getTarget = async () => {
const rxGrab = /^0\[(.*)\]\s*$/;
// target charactername roll is tricky, as we can only make rolls on numeric attributes. Thus we use roll labels to get alphanumeric attributes from the target
let rollBase = `! {{charname=[[0[@{target|character_name}]]]}} {{stanceattackbonus=[[@{target|stanceattackbonus}]]}} {{parrytotal=[[@{target|totalparry}]]}} {{parry=[[@{target|parry}]]}}`;
clog (`target rollbase: ${rollBase})`);
let targetRoll = await startRoll(rollBase);
clog (`targetRoll: ${JSON.stringify(targetRoll)})`);
finishRoll(targetRoll.rollId);
let target = {
name: targetRoll.results.charname.expression.match(rxGrab)[1],
stanceattackbonus: targetRoll.results.stanceattackbonus.result,
parrytotal: targetRoll.results.parrytotal.result,
parry: targetRoll.results.parry.result,
};
clog (`target charname: ${target.name}, target stanceattackbonus: ${target.stanceattackbonus}, target parrytotal: ${target.parrytotal}, target parry: ${target.parry}`)
return target;
};
const parseFeat = (rollresult, crit, fumble, favId) => {
// favId: 0: illfavoured; 1: normal; 2: favoured
// example roll: "feat":{"result":11,"dice":[11,8],"expression":"2d12kh1","rolls":[{"sides":12,"dice":2,"results":[11,8]}]}
let feat = int(rollresult.result),
r1 = int(rollresult.dice[0]),
r2 = int(rollresult.dice[1]),
favouredStr = "normal";
clog (`feat=${feat}; r1=${r1}; r2=${r2}`);
if (favId === 0){
favouredStr = "illfavoured";
if (r1 === fumble || r2 === fumble){
feat = fumble;
} else {
feat = Math.min(r1,r2);
}
} else if (favId === 2) {
favouredStr = "favoured";
if (r1 === fumble || r2 === fumble){
if (r1 === r2) {
feat = fumble;
} else {
feat = (r1 === fumble) ? r2 : r1;
}
} else {
feat = Math.max(r1,r2);
}
}
clog (`Roll is ${favouredStr}. Result: ${feat}`);
return feat;
};
// ROLL FROM ACTION BUTTONS, FUNCTIONS BELOW
const rollFirst = async (char, act, dice, tn, act_fav, rolltype, additional="", lm=false) => {
let outcome = 0,
favId = 1,
featRoll = "1d12",
favouredStr = "",
modifiers = 0,
successdice = 0,
successStr = "",
rollBase = "",
successDegree = 0,
weaponinfo = "",
additionalinfo = "",
additionalStr = "",
parrymod = 0,
parrymodStr = "",
stanceattackmodStr = "",
targetnameStr = "",
target,
closefit="",
closefitStr="",
keen=10,
match=[];
act = capitalize(act);
act = (act === "Wisdom" || act === "Valour") ? "Shadow test: "+act : act;
clog(`Character name: ${name}, Roll name: ${act}, Roll type: ${rolltype}, Target number: ${tn}, Action favoured: ${act_fav}`);
// ATTRIBUTES
const attrs = await asw.getAttrs([
"favorill", "weary", "miserable", "hope", "shadow", "shadowscar", "taint", "favourill_id",
"stanceattack_active", "stanceattackbonus", "stancedamagebonus", "whisper"
]);
let wearyStr = (attrs.weary == "on" || attrs.weary == 1) ? "{{weary=Weary}}" : "",
weary = (attrs.weary == "on" || attrs.weary == 1) ? 1 : 0;
miserableStr = (attrs.miserable == "on" || attrs.miserable == 1) ? "{{miserable=Miserable}}" : "",
miserable = (attrs.miserable == "on" || attrs.miserable == 1) ? 1 : 0,
hope = int(attrs.hope),
shadow = int(attrs.shadow) + int(attrs.shadowscars) + int(attrs.taint),
favourill_id = int(attrs.favourill_id),
stanceAttackActive = int(attrs.stanceattack_active),
stanceAttackBonus = int(attrs.stanceattackbonus),
stanceDamageBonus = int(attrs.stancedamagebonus);
whisper = attrs.whisper;
clog(`Weary: ${attrs.weary}, Weary Str: ${wearyStr}, Miserable: ${attrs.miserable}, Miserable Str: ${miserableStr}, Favourill_id: ${favourill_id}, StanceAttackActive: ${stanceAttackActive}, StanceAttackBonus: ${stanceAttackBonus}, StanceDamageBonus: ${stanceDamageBonus}, Whisper: ${whisper}`);
if (rolltype.includes("target")){
target = await getTarget();
targetnameStr = `{{targetname=${target.name}}}`;
}
// GET MODIFIER AND FAVOURED HERE
if (rolltype.startsWith("protection") ) {
if ( rolltype.includes("target") ) {
tn = await getQuery(`?{Injury rating|@{target|weapon_injury_1}|@{target|weapon_injury_2}}`);
} else {
tn = await getQuery(`?{Injury rating|14}`);
}
} else if ( rolltype.startsWith("combat") ) {
if ( rolltype.includes("target") ) {
if (lm){
// totalparry includes shield, stance and other bonus
parrymodStr = `{{parrymod=[[${target.parrytotal}]]}}`
// we include targets stance modifier
stanceAttackBonus = target.stanceattackbonus;
} else {
parrymodStr = `{{parrymod=[[${target.parry}]]}}`
}
} else {
parrymodStr = `{{parrymod=[[?{Target's Parry|0}]]}}`;
}
clog(`Parry modifier string: ${parrymodStr}`);
}
// bonus dice
modifiers = rolltype !== "custom" ? await getQuery(`?{Bonus dice|${rolltype.startsWith("combat") ? stanceAttackBonus : 0}}`) : 0;
// add stance attack modifier
modifiers = int(modifiers);
let modStr = modifiers == 0 ? "" : (modifiers > 0 ? `{{modification=+${modifiers}}}` : `{{modification=${modifiers}}}`);
// FEAT DIE ROLL DATA
if (rolltype === "custom" ) {
favId = act_fav;
/* since we now have favoured state for combat actions, we don't need to check for combat actions
} else if (rolltype.startsWith("combat")) {
// combat actions don't have local favoured state
favId = favourill_id;
*/
} else {
if (act_fav == "1" || act_fav === "on") {
// global illfavoured + local favoured
if (favourill_id == 0) {
//normal
favId = 1;
} else {
// favoured
favId = 2
}
} else {
favId = favourill_id;
}
}
// favourill handler
featRoll = favId == 2 ? "{{feat=[[2d12kh1]]}}" : ( favId == 0 ? "{{feat=[[2d12kl1]]}}" : "{{feat=[[1d12]]}}" );
featRoll = favId == -1 ? "{{feat=[[0d12]]}}" : featRoll; // For custom rolls without Feat die, the feat die is 0
favouredStr = favId == 2 ? "{{favoured=Favoured}}" : ( favId == 0 ? "{{favoured=Ill-favoured}}" : "" );
// REWARDS, KEEN WEAPONS AND CLOSE FITTING ARMOUR
match = additional.match(/keen='(.*)';/);
keen = match ? match[1] : 10;
if( keen < 10 ) { clog(`Weapon is keen: ${keen}`); }
match = additional.match(/closefit='(.*)';/);
closefit = match ? match[1] : 0;
closefitStr = "";
if( closefit > 0 ) {
clog(`Armour is close fitting: ${closefit}`);
closefitStr = `+${closefit}[Close fit]`;
}
// SUCCESS DICE ROLL DATA
successdice = int(dice) + int(modifiers);
successdice = successdice < 0 ? 0 : successdice;
successStr = `[[${successdice}]]d6${closefitStr}`;
// WEAPON INFO & ADDITIONAL INFO
// Weapon info
weaponinfo = additional.match(/weapon='(.*?)';/);
clog(`Weapon info: ${JSON.stringify(weaponinfo)}`);
weaponStr = ( weaponinfo ) ? ` {{weaponinfo=${weaponinfo[1]}}}` : "";
clog(`Weapon info: ${weaponStr}`);
// Additional info
additionalinfo = additional.match(/additional='(.*?)';/);
clog(`Additional info: ${JSON.stringify(additionalinfo)}`);
additionalStr = additionalStr + (( additionalinfo ) ? ` {{additional=${additionalinfo[1]}}}` : "");
clog(`Additional info: ${additionalStr}`);
//LOG
clog(`Character: ${char}, Base dice: ${successdice}, base string ${successStr}, modifiers: ${modifiers}, target: ${tn}, favoured ${featRoll}, skill favoured: ${act_fav}, parry mod: ${parrymodStr}`);
// Outcome: switch success criteria depending on loremaster or pc roll
if (lm){
clog("Loremaster roll!")
fumble = 12; // gandalf
crit = 11;
} else {
clog("Player roll!")
fumble = 11 // Eye of Sauron
crit = 12;
}
clog(`Crit: ${crit} - Fumble: ${fumble}`);
// Handling whispered messages
let whisper_mode = "";
if (whisper === "me") {
whisper_mode = "/me ";
} else if (whisper != "") {
whisper_mode = `/w ${whisper} `;
}
// START ROLL
rollBase = `${whisper_mode}&{template:tor} {{character-name=${char}}} {{roll-name=${act}}} {{total=[[0]]}} {{diff=[[0]]}} {{greatness=[[0]]}} {{passthroughdata=[[0]]}} {{outcome=[[0]]}} {{successes=[[0]]}} {{featcalc=[[0]]}} {{target=[[${tn}]]}} ${featRoll} {{r1=[[${successStr}]]}} ${parrymodStr} ${favouredStr} ${wearyStr} ${miserableStr} ${modStr} {{skill-fav=${act_fav}}} ${weaponStr} ${additionalStr} ${targetnameStr}`;
let rollresult = await startRoll(rollBase),
rollSuccess = int(rollresult.results.r1.result,0),
rollFeat = parseFeat(rollresult.results.feat, crit, fumble, favId);
clog(`Roll: ${JSON.stringify(rollresult)}`);
if (rolltype.startsWith("combat") ) {
clog(`TN before parry modification: ${tn}`);
tn = int(tn) + int(rollresult.results.parrymod.result);
clog(`TN after parry modification: ${tn}`);
}
// FEAT DIE AND MISERABLE
// Outcomes: Failure = 0, Success = 1, Feat success = 2, Piercing blow = 3, Weary failure = -1, Miserable failure = -2
clog(`Roll result results: ${JSON.stringify(rollresult.results)}`);
// weary success dice logic
if (weary === 1) {
// remove the 1, 2, 3, results, still add any closefitting bonus for protection rolls (already done)
// Weary condition affects protections rolls, see discussion here: https://boardgamegeek.com/thread/2031462/protection-tests-when-weary
// Headsup: rollresult.results.r1.dice only includes the dice (excluding a bonus e.g. for closefit)
let wearydice = (_.reduce(rollresult.results.r1.dice, (memo, num) => { if(num <= 3) {return memo} else {return memo+num} }, 0));
let nonwearydice = (_.reduce(rollresult.results.r1.dice, (memo, num) => {return memo+num}, 0));
rollSuccess = rollSuccess - (nonwearydice - wearydice);
clog(`Weary successes: ${rollSuccess}`);
} else {
clog(`Normal successes: ${rollSuccess}`);
}
// totals (eye of sauron for pc rolls counts as 0)
let rollTotal = rollSuccess + ((rollFeat === fumble && !lm) ? 0 : rollFeat),
rollDiff = rollTotal - int(tn);
clog(`rollFeat: ${rollFeat}, rollTotal: ${rollTotal}, Target Number: ${tn}, Diff: ${rollDiff}`);
// Determine outcome
if ( rollFeat === crit ) {
outcome = 2; // Feat Success (Gandalf or Eye of Sauron)
rollTotal = 0;
clog(`Outcome after critical success: ${outcome}`);
} else if (rollFeat === fumble && lm){
outcome = 0; // normal failure
rollTotal = 0;
clog(`Adversaries fail on gandalf rune! Outcome: ${outcome}`);
} else if (rollFeat === fumble && !lm && miserable){
outcome = -2; // miserable failure
rollTotal = 0;
clog(`PC fail on Eye of Sauron and Miserable. Outcome: ${outcome}`);
} else if (rollTotal >= tn) {
outcome = 1; // normal success
clog(`Outcome after normal success: ${outcome}`);
} else if (weary) {
outcome = -1; // weary failure
clog(`Outcome after weary failure: ${outcome}`);
} else {
outcome = 0; // normal failure
clog(`Outcome: ${outcome}`);
}
// GREATNESS & FEAT DIE
// Test for piercing blow on crit success
outcome = rolltype.startsWith("combat") && (outcome === 2) ? 3 : outcome;
clog(`Outcome after Crit: ${outcome}`);
// Piercing blow also at 10 or 8/9 if the used weapon is keen
outcome = rolltype.startsWith("combat") && (outcome === 1) && (rollFeat >= keen && rollFeat <= 10) ? 3 : outcome;
clog(`Outcome after Piercing or Keen: ${outcome}`);
// count number of 6s in success, great or extraordinary success
// Count the number of sixes rolled, to report degree of success
clog(`Roll r1 : ${JSON.stringify(rollresult.results.r1.dice)}`);
successDegree = (outcome === 1 || outcome === 2 || outcome === 3) ? _.reduce(rollresult.results.r1.dice, (memo, num) => { if(num == 6) {return ++memo} else {return memo} }, 0) : 0;
clog(`Calculated degree of success: ${successDegree}`);
// PASSTHROUGH DATA
// Storing all the passthrough data required for the next roll in an Object helps for larger rolls
//rollresult.results.difference.result = rollDiff;
//rollresult.results.passthroughdata = "This is a test";
//clog(`Roll result results II: ${JSON.stringify(rollresult.results)}`);
//clog(`First roll data: ${JSON.stringify(rollresult)}`);
//clog(`First roll diff: ${JSON.stringify(rollDiff)}`);
//clog(`Roll data: ${rollEscape.escape(rollData)}`);
// Storing all the passthrough data required for the next roll in an Object helps for larger rolls
// CALCULATED ROLL DATA
//let rollData = rollresult.results; // Holding the computed data in an object is a bit cleaner if your rolls get more complex
let rollData = Object.assign(rollresult); // Holding the computed data in an object is a bit cleaner if your rolls get more complex
rollData.total = rollTotal;
rollData.target = tn;
rollData.successes = rollSuccess;
rollData.outcome = outcome;
rollData.greatness = successDegree;
rollData.feat = rollFeat;
console.log('Roll data: ' + JSON.stringify(rollData));
//rollData.passthroughdata = "This is a test";
// FINISH ROLL
finishRoll(rollresult.rollId, rollData);
};
// handle sheet types
const buttonlist = ["isPC","isAdversary"];
buttonlist.forEach(button => {
console.log(button);
on(`clicked:${button}`, function() {
console.log("Toggle charsheet: " + button);
setAttrs({
sheetTab: button,
});
});
});
// toggle notes area visibility
on( "clicked:notestoggle", function(){
getAttrs(["notesactive"], function(values){
let state = int(values.notesactive);
let newstate = 1-state; // xor
setAttrs({notesactive:newstate});
console.log("Toggle notes state: " + newstate);
});
});
// toggle notes area visibility
const notesbuttonlist = ["notes1", "notes2", "notes3", "notes4"];
notesbuttonlist.forEach(button => {
console.log(button);
on(`clicked:${button}`, function() {
console.log("Toggle Notestab: " + button);
setAttrs({
notestabactive: button,
});
});
});
// toggle release notes visibility
on( "clicked:releaselog", function(){
getAttrs(["releaselogactive"], function(values){
let state = int(values.releaselogactive);
let newstate = 1-state; // xor
setAttrs({releaselogactive:newstate});
console.log("Releaselog state: " + newstate);
});
});
// toggle gear/items visibility
on( "sheet:opened change:gearoritems", function(){
getAttrs(["gearoritems"], function(values){
let gearoritems = int(values.gearoritems,1);
setAttrs({gearoritems_toggle:gearoritems});
console.log("Gear or Items state: " + gearoritems);
});
});
/*==========================
defaults
============================*/
on('sheet:opened', function() {
getAttrs(["favourill_id", "hope", "hope_max", "endurance", "endurance_max", "stance", "stance_max"], function(values){
let favourill_id = int(values.favourill_id,1),
hope = int(values.hope,1),
hope_max = int(values.hope_max,1),
endurance = int(values.endurance,1),
endurance_max = int(values.endurance_max,1),
stance = int(values.stance,2),
stance_max = int(values.stance_max,4);
setAttrs({
favourill_id: favourill_id,
hope: hope,
hope_max: hope_max,
endurance: endurance,
endurance_max: endurance_max,
stance: stance,
stance_max: stance_max,
});
});
});
/*==========================
Action Roll Button Updates
============================*/
// For a generic solution for repeating actions see https://app.roll20.net/forum/post/10534166/action-buttons-in-the-macro-bar
on('sheet:opened change:character_name', function() {
getAttrs(["character_name"], function(values){
const actions = ['protection_action',
'weapon_1_action', 'weapon_2_action', 'weapon_3_action', 'weapon_4_action', 'weapon_5_action', 'weapon_6_action',
'weapon_1_target_action', 'weapon_2_target_action', 'weapon_3_target_action', 'weapon_4_target_action', 'weapon_5_target_action', 'weapon_6_target_action',
'axes_action', 'bows_action', 'spears_action', 'swords_action', 'brawl_action',
'axes_target_action', 'bows_target_action', 'spears_target_action', 'swords_target_action', 'brawl_target_action',
'adv_weapon1_action', 'adv_weapon2_action', 'adv_weapon3_action',
'adv_weapon1_target_action', 'adv_weapon2_target_action', 'adv_weapon3_target_action'
];
const setObj = actions.reduce((accumulator,actionName)=>{
accumulator[actionName] = `%{${values.character_name}|${actionName}}`;//Update the action call
return accumulator; //The memo (accumulator in this case) must always be returned when using a reduce function
},{});
setAttrs(setObj,{silent:true});//Apply the changes
});
});
/*==========================
Conditions / Stance / Load
============================*/
// weary roll table change
on("change:weary sheet:opened", function() {
getAttrs(["weary", "wearytype", "sheetTab"], function(values) {
let weary = values.weary||0;
if (weary === "on" || weary == 1) {
wearytype = "weary";
}
else {
wearytype = "normal";
}
setAttrs({
wearytype: wearytype,
});
});
});
// Calculate Weary condition and check that current endurance is not higher than max endurance
on("change:endurance_max change:endurance change:load change:fatigue sheet:opened", () => {
getAttrs(["endurance_max", "endurance", "weary", "fatigue", "load", "sheetTab"], (values) => {
if (values.sheetTab === "isPC"){
const fatigue = int(values.fatigue),
load = int(values.load),
endurance_max = int(values.endurance_max);
let weary = values.weary,
endurance = int(values.endurance);
clog(`Endurance: ${JSON.stringify(values)}`);
if ( load >= (endurance-fatigue) ) { weary = 1; } else { weary = 0}
if ( endurance > endurance_max ) { endurance = endurance_max; }
setAttrs({
weary: weary,
endurance: endurance,
});
};
});
});
// calc miserable and favourill_id
on("change:hope change:shadow change:shadowscars change:taint change:favorill sheet:opened", () => {
getAttrs(["hope", "hope_max", "shadow", "shadowscar", "taint", "favourill_id", "favorill", "sheetTab" ], (values) => {
if (values.sheetTab ==="isPC"){
const hope = int(values.hope),
hope_max = int(values.hope_max),
shadow = int(values.shadow),
scars = int(values.shadowscar),
taint = int(values.taint),
favorill = values.favorill,
favourill_id = int(values.favourill_id),
maxshadow = hope_max - scars;
// miserable
if ( (shadow + scars + taint) >= hope ) {
setAttrs({
miserable: 1,
});
clog(`Set miserable based on shadow score: shadow ${shadow} + scars ${scars} + taint ${taint} higher than current hope ${hope}.`);
} else {
setAttrs({
miserable: 0,
});
};
// favourill
if ( (shadow + scars + taint) >= hope_max || favorill === "{2t[feat]}kl1") {
setAttrs({
favourill_id: 0,
favorill : "{2t[feat]}kl1" // to make table rolls consistent
});
clog(`Set illfavoured rolls global state or shadow score: shadow ${shadow} + scars ${scars} + taint ${taint} higher than maximum hope ${hope_max}.`);
} else if (favorill === "{1t[feat]}"){
setAttrs({
favourill_id: 1,
});
clog(`Reset normal rolls based on global state.`);
} else if (favorill === "{2t[feat]}kh1"){
setAttrs({
favourill_id: 2,
});
clog(`Reset favoured rolls based on global state.`);
};
} else if (values.sheetTab ==="isAdversary") {
const favorill = values.favorill,
favourill_id = int(values.favourill_id);
if (favorill === "{2t[feat]}kl1"){
setAttrs({
favourill_id: 0,
});
clog(`Set favourill_id to illfavoured.`);
} else if (favorill === "{2t[feat]}kh1"){
setAttrs({
favourill_id: 2,
});
clog(`Set favourill_id to favoured.`);
} else {
setAttrs({
favourill_id: 1,
});
clog(`Reset favourill_id to normal`);
};
};
});
});
// automatic stance toggle of attack damage/bonus, parry (open stance) and protection (defensive)
on( "change:stance sheet:opened", function() {
getAttrs(["stance"], function(values) {
let attr = new Map([
["stanceparry_active", 0],
["stanceprot_active", 0],
["stanceattack_active", 0],
["stanceattackbonus", 0]
]);
clog(`Stance: ${values.stance}`)
if (values.stance == 1){
clog("Handle forward stance toggle");
attr.set("stanceattack_active", 1);
attr.set("stanceattackbonus", 1);
} else if (values.stance == 2){
clog("Handle open stance toggle");
attr.set("stanceparry_active", 1);
} else if (values.stance == 3){
clog("Handle defensive stance toggle");
attr.set("stanceprot_active", 1);
attr.set("stanceattackbonus", -1);
} else if (values.stance == 4){
clog("Handle rearward stance toggle");
}
clog(`Attackbonus: ${attr.get("stanceattackbonus")}`);
setAttrs({
stanceparry_active: attr.get("stanceparry_active"),
stanceprot_active: attr.get("stanceprot_active"),
stanceattack_active: attr.get("stanceattack_active"),
stanceattackbonus: attr.get("stanceattackbonus")
})
});
});
// calc total load on change events for weapons, armour and treasure
on( "change:weapon_load_1 change:weapon_load_2 change:weapon_load_3 change:weapon_load_4 change:weapon_load_5 change:weapon_load_6 " +
"change:armourload change:helmload change:shieldload change:otherload change:treasureload " +
"change:armourcm_val change:helmetcm_val change:othercm_val change:shieldcm_val " +
"change:armourprot_active change:shieldparry_active change:helmprot_active change:otherprot_active " +
"change:weapon_active_1 change:weapon_active_2 change:weapon_active_3 change:weapon_active_4 change:weapon_active_5 change:weapon_active_6 " +
"change:fatigue change:load sheet:opened", function() {
getAttrs(["weapon_load_1","weapon_load_2","weapon_load_3","weapon_load_4","weapon_load_5","weapon_load_6",
"armourload","shieldload","helmload","otherload","fatigue","treasureload",
"armourcm_val","shieldcm_val","helmetcm_val","othercm_val",
"armourprot_active", "helmprot_active", "shieldparry_active", "otherprot_active",
"weapon_active_1", "weapon_active_2", "weapon_active_3", "weapon_active_4", "weapon_active_5", "weapon_active_6"], function(values) {
const weaponload1 = (int(values.weapon_active_1) == 1) ? int(values.weapon_load_1) : 0,
weaponload2 = (int(values.weapon_active_2) == 1) ? int(values.weapon_load_2) : 0,
weaponload3 = (int(values.weapon_active_3) == 1) ? int(values.weapon_load_3) : 0,
weaponload4 = (int(values.weapon_active_4) == 1) ? int(values.weapon_load_4) : 0,
weaponload5 = (int(values.weapon_active_5) == 1) ? int(values.weapon_load_5) : 0,
weaponload6 = (int(values.weapon_active_6) == 1) ? int(values.weapon_load_6) : 0,
armourload = (int(values.armourprot_active) == 1) ? int(values.armourload) + int(values.armourcm_val) : 0,
shieldload = (int(values.shieldparry_active) == 1) ? int(values.shieldload) + int(values.shieldcm_val) : 0,
helmload = (int(values.helmprot_active) == 1) ? int(values.helmload) + int(values.helmetcm_val) : 0,
otherload = (int(values.otherprot_active) == 1) ? int(values.otherload) + int(values.othercm_val) : 0,
treasureload = int(values.treasureload),
load = armourload + shieldload + helmload + otherload + weaponload1 + weaponload2 + weaponload3 + weaponload4 + weaponload5 + weaponload6 + treasureload; // Removed Fatigue, used to calculate vs Current Endurance and Weary condition below.
clog(`Shieldparry_active: ${values.shieldparry_active}`);
setAttrs({
load: load,
});
});
});
on("change:daunted sheet:opened", function() {
getAttrs(["daunted", "sheetTab"], function(values) {
let daunted = values.daunted||0;
clog(`Hope toggle: ${daunted}`);
setAttrs({
hopetoggle: daunted,
});
});
});
/*==================
Valour & Wisdom
====================*/
// parsed valour roll
on('clicked:valour', async (ev) => {
clog(`Starting first roll`);
let action = 'valour',
data = await asw.getAttrs(['character_name', 'hearttn', 'valour', 'valour_favoured']),
actdice = data.valour,
actfav = data.valour_favoured;
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, protection value: ${actdice}`);
await rollFirst(data.character_name, action, actdice, data.hearttn, actfav, "valour");
clog(`Completed first roll`);
});
// parsed wisdom roll
on('clicked:wisdom', async (ev) => {
clog(`Starting first roll`);
let action = 'wisdom',
data = await asw.getAttrs(['character_name', 'witstn', 'wisdom', 'wisdom_favoured']),
actdice = data.wisdom,
actfav = data.wisdom_favoured;
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, protection value: ${actdice}`);
await rollFirst(data.character_name, action, actdice, data.witstn, actfav, "wisdom");
clog(`Completed first roll`);
});
/*==================
Protection and Parry
====================*/
// calc total protection on change events for the checkboxes and values
on( "change:armourprot_active change:helmprot_active change:otherprot_active change:stanceprot_active " +
"change:armourprot change:helmprot change:otherprot change:stanceprot " +
"change:protection sheet:opened", function() {
getAttrs(["armourprot", "helmprot", "stanceprot", "otherprot",
"armourprot_active", "helmprot_active", "stanceprot_active", "otherprot_active"], function(values) {
let armourprot = (values.armourprot_active == 1) ? int(values.armourprot) : 0;
let helmprot = (values.helmprot_active == 1) ? int(values.helmprot) : 0;
let otherprot = (values.otherprot_active == 1) ? int(values.otherprot) : 0;
let stanceprot = (values.stanceprot_active == 1) ? int(values.stanceprot) : 0;
let protectiontotal = armourprot + helmprot + otherprot + stanceprot;
setAttrs({
protection: protectiontotal,
});
console.log("Updated protection to " + protectiontotal);
});
});
// calc total parry on change events for the check boxes and values
on( "change:shieldparry_active change:otherparry_active change:stanceparry_active " +
"change:parry change:shieldparry change:otherparry change:stanceparry change:shieldreinf_val " +
"change:totalparry sheet:opened", function() {
getAttrs(["parry", "shieldparry", "stanceparry", "otherparry", "shieldreinf_val",
"shieldparry_active", "stanceparry_active", "otherparry_active"], function(values) {
let parry = int(values.parry);
let shieldparry = (values.shieldparry_active == 1) ? int(values.shieldparry) + int(values.shieldreinf_val) : 0;
let stanceparry = (values.stanceparry_active == 1) ? int(values.stanceparry) : 0;
let otherparry = (values.otherparry_active == 1) ? int(values.otherparry) : 0;
let parrytotal = parry + shieldparry + stanceparry + otherparry;
setAttrs({
totalparry: parrytotal,
shieldparry_total: int(values.shieldparry) + int(values.shieldreinf_val),
});
console.log("Updated total parry to " + parrytotal
+ " - parry: " + parry + " - shieldparry: " + shieldparry
+ " - stanceparry: " + stanceparry + " - otherparry: " + otherparry);
});
});
// parsed protection rolls
on('clicked:protection_action', async (ev) => {
clog(`Starting first roll`);
let action = 'protection',
data = await asw.getAttrs(['character_name', action, 'protection',
'armourcf', 'armourcm', 'helmetcf', 'helmetcm', 'othercf', 'othercm',
'armourcf_val', 'armourcm_val', 'helmetcf_val', 'helmetcm_val', 'othercf_val', 'othercm_val',
'armourprot_active', 'helmprot_active', 'otherprot_active',
'sheetTab', 'protection_favoured']),
actdice = int(data.protection),
actfav = data.protection_favoured,
lm = data.sheetTab ==="isAdversary" ? true : false;
let additionalStr = "";
additionalStr = additionalStr + ((data.armourcf_val != "0" && data.armourprot_active === "1") ? "Close fit armour, " : "");
additionalStr = additionalStr + ((data.helmetcf_val != "0" && data.helmprot_active === "1") ? "Close fit helm, " : "");
additionalStr = additionalStr + ((data.othercf_val != "0" && data.otherprot_active === "1") ? "Close fit other, " : "");
additionalStr = additionalStr + ((data.armourcm_val != "0" && data.armourprot_active === "1") ? "Cunning armour, " : "");
additionalStr = additionalStr + ((data.helmetcm_val != "0" && data.helmprot_active === "1") ? "Cunning helm, " : "");
additionalStr = additionalStr + ((data.othercm_val != "0" && data.otherprot_active === "1") ? "Cunning other, " : "");
additionalStr = additionalStr.slice(0,-2);
let closefit =
int(data.armourprot_active) * int(data.armourcf_val)
+ int(data.helmprot_active) * int(data.helmetcf_val)
+ int(data.otherprot_active) * int(data.othercf_val);
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, Protection value: ${actdice}, Closefit: ${closefit}, Additional: ${additionalStr}, Favoured: ${actfav}`);
await rollFirst(data.character_name, action, actdice, "0", actfav, "protection", `additional='${additionalStr}';closefit='${closefit}';`, lm);
clog(`Completed first roll`);
});
// adapt protection table roll
on("change:protection_favoured change:favourill_id sheet:opened", function() {
getAttrs(["protection_favoured","favourill_id"], function(values) {
// get attribute favoured state, 0 if unset
let faved = values["protection_favoured"]||0;
// convert checked state to 1
let favattr = (faved == 0) ? 0 : 1;
// get global favoured/illfavoured state, "normal" if unset
let favourill = int(values.favourill_id)-1; // shift value to -1/0/+1 and use this later to calc
// favoured / illfavoured states can negate each other
// 2*favoured stays a simple favoured roll
let favourill_result = favattr + favourill;
// derive resulting roll expression. we calculate the complete expression at this central location
// to make easy maintenance later when this needs to be changed
let favourill_roll = "{1t[feat]}";
if (favourill_result >= 1){
favourill_roll = "{2t[feat]}kh1";
} else if (favourill_result <= -1) {
favourill_roll = "{2t[feat]}kl1";
}
clog(`Protection favourill: ${favourill_result}`);
let roll =
`/me rolls for Protection against Injury TN.\n/roll ${favourill_roll} + (@{protection}+?{Bonus Dice|0})t[@{wearytype}]`;
setAttrs({
["protection_roll"]: roll,
});
});
});
/*==================
Skills
====================*/
// table rolls skills
// This sheet worker will derive the correct normal / favoured / illfavoured rolls based on the
// global favoured status and the attribute specific favoured status
let attrmap = new Map([
["strength", ["awe","athletics", "awareness", "hunting", "song", "craft"]],
["heart", ["enhearten", "travel", "insight", "healing", "courtesy", "battle","valour"]],
["wits", ["persuade", "stealth", "scan", "explore", "riddle", "lore","wisdom"]]
]);
attrmap.forEach((skillList, attr, attrmap) => {
let attrcapitalized = attr.replace(/^\w/, (c) => c.toUpperCase()); // first letter
skillList.forEach(skill => {
let skillfav = `${skill}_favoured`;
let skillcapitalized = skill.replace(/^\w/, (c) => c.toUpperCase()); // first letter
on(`change:${skillfav} change:favorill sheet:opened`, function() {
getAttrs([`${skillfav}`,"favorill"], function(values) {
// get attribute favoured state, 0 if unset
let faved = values[`${skillfav}`]||0;
// convert checked state to 1
let favattr = (faved == 0) ? 0 : 1;
// get global favoured/illfavoured state, "normal" if unset
let favorill = values.favorill ||"{1t[feat]}";
// favoured / illfavoured states can negate each other
// 2*favoured stays a simple favoured roll
let favorill_result = favattr;
if (favorill === "{2t[feat]}kh1"){
favorill_result = favorill_result + 1;
} else if (favorill === "{2t[feat]}kl1"){
favorill_result = favorill_result - 1;
}
// derive resulting roll expression. we calculate the complete expression at this central location
// to make easy maintenance later when this needs to be changed
let favorill_roll = "{1t[feat]}";
if (favorill_result >= 1){
favorill_roll = "{2t[feat]}kh1";
} else if (favorill_result <= -1) {
favorill_roll = "{2t[feat]}kl1";
}
let roll =
`/me rolls for ${skillcapitalized} against ${attrcapitalized} TN (@{${attr}tn}).\n`
+ `/roll ${favorill_roll} + (@{${skill}}+?{Bonus Dice|0})t[@{wearytype}] `;
setAttrs({
[`${skill}_roll`]: roll,
});
});
});
});
});
// parsed strength based skill rolls
on('clicked:awe clicked:athletics clicked:awareness clicked:hunting clicked:song clicked:craft', async (ev) => {
clog(`Starting first roll`);
let action = (ev.htmlAttributes.name).slice(4),
data = await asw.getAttrs(['character_name', 'strengthtn', action, `${action}_favoured`]),
actdice = data[action],
act_fav = data[`${action}_favoured`];
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, Action value: ${actdice}, Action favoured value: ${act_fav}`);
await rollFirst(data.character_name, action, actdice, data.strengthtn, act_fav, "skill");
clog(`Completed first roll`);
});
// parsed heart based skill rolls
on('clicked:enhearten clicked:travel clicked:insight clicked:healing clicked:courtesy clicked:battle', async (ev) => {
clog(`Starting first roll`);
let action = (ev.htmlAttributes.name).slice(4),
data = await asw.getAttrs(['character_name', 'hearttn', action, `${action}_favoured`]),
actdice = data[action],
act_fav = data[`${action}_favoured`];
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, Action value: ${actdice}, Action favoured value: ${act_fav}`);
await rollFirst(data.character_name, action, actdice, data.hearttn, act_fav, "skill");
clog(`Completed first roll`);
});
// parsed wits based skill rolls
on('clicked:persuade clicked:stealth clicked:scan clicked:explore clicked:riddle clicked:lore', async (ev) => {
clog(`Starting first roll`);
let action = (ev.htmlAttributes.name).slice(4),
data = await asw.getAttrs(['character_name', 'witstn', action, `${action}_favoured`]),
actdice = data[action],
act_fav = data[`${action}_favoured`];
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, Action value: ${actdice}, Action favoured value: ${act_fav}`);
await rollFirst(data.character_name, action, actdice, data.witstn, act_fav, "skill");
clog(`Completed first roll`);
});
/*==================
COMBAT PROFICIENCES
====================*/
// table combat proficiency rolls (to reflect the active stance attack bonus)
const battleattrs = ["axes", "bows", "spears", "swords"];
on(`change:stance sheet:opened`, function() {
getAttrs(["stanceattackbonus"], function(values) {
battleattrs.forEach(battleattr => {
let battleattrcapitalized = battleattr.replace(/^\w/, (c) => c.toUpperCase()); // first letter
let stanceattackbonus = "@{stanceattackbonus} ";
let roll1 =
`/me rolls for ${battleattrcapitalized} against TN [[@{strengthtn}+?{Target's Parry|0}]] (Strength TN + target's parry).\n`
+ `/roll @{favorill} + ([[@{${battleattr}} + ?{Bonus Dice|${stanceattackbonus}}]])t[@{wearytype}]`;
let roll2 =
`/me rolls for ${battleattrcapitalized} against TN [[@{strengthtn}+@{target|totalparry}]] (Strength TN + target's parry).\n`
+ `/roll @{favorill} + ([[@{${battleattr}} + ?{Bonus Dice|${stanceattackbonus}}]])t[@{wearytype}]`;
setAttrs({
[`${battleattr}_roll1`]: roll1,
[`${battleattr}_roll2`]: roll2,
});
});
});
});
// table adversary weapon rolls (to reflect the active stance attack bonus)
const advweaponattrs = ["adv_weapon1", "adv_weapon2", "adv_weapon3"];
on(`change:stance sheet:opened`, function() {
getAttrs([""], function(values) {
advweaponattrs.forEach(advweaponattr => {
index = int(advweaponattr.slice(-1)); // last char
let roll1 =
`/me attacks against parry ?{Parry|0}.\n/roll 1t[lm-feat] + [[(@{weapon_rating_${index}}+?{Bonus Dice|0})]]t[@{wearytype}]`;
let roll2 =
`/me attacks @{target|name} against parry @{target|totalparry}.\n/roll 1t[lm-feat] + [[(@{weapon_rating_${index}}+?{Bonus Dice|@{target|stanceattackbonus}})]]t[@{wearytype}]`;
setAttrs({
[`${advweaponattr}_roll1`]: roll1,
[`${advweaponattr}_roll2`]: roll2,
});
});
});
});
// parsed adversary combat proficiency rolls
// act_adv_weapon1_target
on('clicked:adv_weapon1_action clicked:adv_weapon1_target_action clicked:adv_weapon2_action clicked:adv_weapon2_target_action clicked:adv_weapon3_action clicked:adv_weapon3_target_action', async (ev) => {
clog(`Starting first roll`);
let options = stripaction((ev.triggerName).slice(18)).split("_"),
index = options[0],
target = options[1] || "",
data = await asw.getAttrs([
'character_name', `weapon_skill_name_${index}`,
`weapon_rating_${index}`, `weapon_damage_${index}`,
`weapon_injury_${index}`, 'favorill', 'favourill_id']
),
action = data[`weapon_skill_name_${index}`],
actdice = data[`weapon_rating_${index}`],
damage = data[`weapon_damage_${index}`],
injury = data[`weapon_injury_${index}`],
favorill = data['favorill'] || "{1t[feat]}",
favourill_id = data['favourill_id'];
clog(`Index: ${index}, Target: ${target}, Action: ${action}`);
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, Action value: ${actdice}`);
await rollFirst(data.character_name, action, actdice, 0, 0, "combat"+target, `weapon='Damage: ${damage}, Injury: ${injury}';`, true);
clog(`Completed first roll`);
});
// parsed combat proficiency rolls
on('clicked:axes_action clicked:bows_action clicked:spears_action clicked:swords_action clicked:brawl_action clicked:axes_target_action clicked:bows_target_action clicked:spears_target_action clicked:swords_target_action clicked:brawl_target_action', async (ev) => {
clog(`Starting first roll`);
let options = stripaction((ev.triggerName).slice(8)).split("_"),
action = options[0],
target = options[1] || "",
data = await asw.getAttrs(['character_name', 'strengthtn', action, `${action}_favoured`, 'favorill', 'favourill_id']),
actdice = data[action],
favorill = data['favorill'] || "{1t[feat]}",
favourill_id = data['favourill_id'],
act_fav = data[`${action}_favoured`] || 0;
clog(`Action: ${action}`);
action = action.split("_")[0] || action;
clog(`Target: ${target}`);
if (favorill === "{2t[feat]}kh1"){
act_fav = 1;
} else if (favorill === "{2t[feat]}kl1"){
act_fav = 0;
} else {
act_fav = 0;
}
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}, Action value: ${actdice}, Action favoured value: ${act_fav}`);
await rollFirst(data.character_name, action, actdice, data.strengthtn, act_fav, "combat"+target);
clog(`Completed first roll`);
});
// parsed combat rolls per weapon
on("clicked:weapon_1_action clicked:weapon_2_action clicked:weapon_3_action clicked:weapon_4_action clicked:weapon_5_action clicked:weapon_6_action clicked:weapon_1_target_action clicked:weapon_2_target_action clicked:weapon_3_target_action clicked:weapon_4_target_action clicked:weapon_5_target_action clicked:weapon_6_target_action ", async (ev) => {
let options = stripaction((ev.triggerName).slice(15)),
index = options.split('_')[0],
target = options.split('_')[1] || "";
target = target === "" ? "" : "-"+target;
clog(`Starting first roll: weapon_${index}, target: ${target}`);
let data = await asw.getAttrs([
'character_name', 'strengthtn', `weapon_skill_name_${index}`, `weapon_combat_prof_${index}`, `weapon_damage_${index}`,
`weapon_injury_${index}`, `weapon_note_${index}`,
`weapon_fell_${index}`, `weapon_grievous_${index}`, `weapon_keen_${index}`,
`weapon_fell_val_${index}`, `weapon_grievous_val_${index}`, `weapon_keen_val_${index}`,
'stanceattack_active', 'stanceattackbonus', 'stancedamagebonus',
'axes', 'bows', 'spears', 'swords', 'brawl',
'axes_favoured', 'bows_favoured', 'spears_favoured', 'swords_favoured', 'brawl_favoured']),
action = data[`weapon_skill_name_${index}`],
combatprof = data[`weapon_combat_prof_${index}`],
damage = data[`weapon_damage_${index}`],
injury = data[`weapon_injury_${index}`],
note = data[`weapon_note_${index}`],
fell_val = int(data[`weapon_fell_val_${index}`],0),
grievous_val = int(data[`weapon_grievous_val_${index}`],0),
keen_val = int(data[`weapon_keen_val_${index}`],0),
fell = fell_val === 0 ? "" : "Fell, ",
grievous = grievous_val === 0 ? "" : "Grievous, ",
keen = keen_val === 10 ? "" : "Keen, ",
actdice = int(data[`${combatprof}`]),
stanceattack_active = int(data['stanceattack_active']),
stanceattackbonus = int(data['stanceattackbonus']),
stancedamagebonus = int(data['stancedamagebonus']);
damage_bonus = stanceattack_active == 1 ? stancedamagebonus + grievous_val : grievous_val;
damage = (damage_bonus > 0) ? `${damage}+${damage_bonus}` : damage;
injury = (fell_val > 0) ? `${injury}+${fell_val}` : injury;
act_fav = int(data[`${combatprof}_favoured`], 0);
clog(`First roll: ${JSON.stringify(data)}, Action: ${action}, Dice: ${actdice}, tn: ${data.strengthtn}, act_fav: ${act_fav}`);
await rollFirst(data.character_name, action, actdice, data.strengthtn, act_fav, "combat"+target, `weapon='${keen}${fell}${grievous}Damage:${damage}, Injury:${injury}'; additional='Notes: ${note}';keen='${keen_val}';`, false);
clog(`Completed first roll: weapon_${index}`);
});
/*==================
Custom Roll
====================*/
on('clicked:customroll', async (ev) => {
clog(`Starting first roll`);
let data = await asw.getAttrs(['character_name', 'customfeatdie', 'customtn', 'customsuccessdice', 'customrollname', 'favourill_id']),
action = `Custom: ${data.customrollname}`,
actfeat = int(data.customfeatdie),
actdice = int(data.customsuccessdice),
acttn = int(data.customtn);
clog(`First roll: ${JSON.stringify(data)}, Action : ${action}`);
await rollFirst(data.character_name, action, actdice, acttn, actfeat, "custom");
clog(`Completed first roll`);
});
/*==================
Adversary Fell Abilities
====================*/
on('clicked:repeating_fell-abilities:adv-fell', async (ev) => {
const source = (ev.sourceAttribute).slice(0, -8);
clog(`${source}fell_ability_desc`);
let data = await asw.getAttrs([`${source}fell_ability`, `${source}fell_ability_desc`]),
fell_ability = data[`${source}fell_ability`],
fell_ability_desc = data[`${source}fell_ability_desc`];
// remove last dot from fell_ability if it exists
fell_ability = fell_ability.replace(/\.$/, '');
clog(`${fell_ability}: ${fell_ability_desc}`);
await rollMessage({header:fell_ability, msg:fell_ability_desc});
});
/*==================
Adversary Import
====================*/
on(`change:notes sheet:opened`, function() {
getAttrs(["notes", "sheetTab"], function(values) {
if (values.sheetTab ==="isAdversary"){
let importerror = false;
let json = values.notes;
json = json.substring(json.indexOf('{'));
json = json.substring(0,json.lastIndexOf("}") + 1);
clog(json);
try{
var characterData = JSON.parse(json);
} catch(err){
importerror = true;
}
if (!importerror && values.notes != "") {
clearSheet();
writeToSheet(characterData);
} else {
if (importerror && values.notes != "Adversary json import successful.") {
clog('Adversary import skipped. Notes field is no valid JSON.')
}
}
}
});
});
function writeToSheet (characterData) {
let character = {};
character["name"] = characterData["name"] || "";
character["attribute-level"] = int(characterData["attributeLevel"]);
character["distinctive-features"] = characterData["distinctiveFeatures"] || "";
character["endurance"] = int(characterData["endurance"]);
character["might"] = int(characterData["might"]);
let resolve = int(characterData["resolve"]);
let hate = int(characterData["hate"]);
clog("Hate: " + hate + " Resolve: " + resolve);
character["hate"] = Math.max(resolve, hate);
character["hateresolve"] = hate > resolve ? 1 : 2;
character["parry"] = int(characterData["parry"]);
character["armourprot"] = int(characterData["armour"]);
let weapon1 = characterData["weaponProficiencies"][0] || false;
let weapon2 = characterData["weaponProficiencies"][1] || false;
let weapon3 = characterData["weaponProficiencies"][2] || false;
if (weapon1) {
character["weapon_skill_name_1"] = weapon1["weaponname"] || "";
character["weapon_rating_1"] = int(weapon1["rating"]);
character["weapon_damage_1"] = int(weapon1["damage"]);
character["weapon_injury_1"] = int(weapon1["injury"]);
character["weapon_special_damage_1"] = weapon1["special"] || "";
}
if (weapon2){
character["weapon_skill_name_2"] = weapon2["weaponname"] || "";
character["weapon_rating_2"] = int(weapon2["rating"]);
character["weapon_damage_2"] = int(weapon2["damage"]);
character["weapon_injury_2"] = int(weapon2["injury"]);
character["weapon_special_damage_2"] = weapon2["special"] || "";
}
if (weapon3){
character["weapon_skill_name_3"] = weapon2["weaponname"] || "";
character["weapon_rating_3"] = int(weapon2["rating"]);
character["weapon_damage_3"] = int(weapon2["damage"]);
character["weapon_injury_3"] = int(weapon2["injury"]);
character["weapon_special_damage_3"] = weapon2["special"] || "";
}
let newrowid = 0;
for (var i = 0; i < characterData["fellAbilities"].length; i++) {
newrowid = generateRowID();
character["repeating_fell-abilities_" + newrowid + "_fell_ability"] = characterData["fellAbilities"][i]["abilityname"];
character["repeating_fell-abilities_" + newrowid + "_fell_ability_desc"] = characterData["fellAbilities"][i]["description"];
}
setAttrs(character);
setAttrs({['notes']: "Adversary json import successful."});
};
function clearSheet() {
setAttrs({
["name"]: "",
["distinctive-features"]: "",
["weapon_skill_name_1"]: "",
["weapon_rating_1"] : 0,
["weapon_damage_1"] : 0,
["weapon_injury_1"] : 0,
["weapon_special_damage_1"] : "",
["weapon_skill_name_2"] : "",
["weapon_rating_2"] : 0,
["weapon_damage_2"] : 0,
["weapon_injury_2"] : 0,
["weapon_special_damage_2"] : "",
["weapon_skill_name_3"] : "",
["weapon_rating_3"] : 0,
["weapon_damage_3"] : 0,
["weapon_injury_3"] : 0,
["weapon_special_damage_3"] : ""
});
getSectionIDs("repeating_fell-abilities", function(idarray) {
for(var i=0; i < idarray.length; i++) {
removeRepeatingRow("repeating_fell-abilities_" + idarray[i]);
}
});
};
/*==================
Migration scripts.
====================*/
on("sheet:opened", function() {
getAttrs(["build", "version", "sheettab", "character_name"], function(v) {
const build = int(v.build);
const character_name = v.character_name
var attrs = {};
console.log(`Character: ${character_name} - Current version: ${v.version}`);
// get attribute updates for each version until the sheet has completed all steps
// NOTE: to maintain backwards compatibility with sheets predating the version attribute, all steps will be performed for new sheets
if (build < 1) {
// Version 01.00.00
console.log(`Character: ${character_name} - Migration 01.00.00`)
attrs["build"] = 1;
if (v.sheettab === "isPC"){
getAttrs(["treaure"], function(values){
let treaure = int(values.treaure);
attrs["treasure"] = treaure;
clog(`${JSON.stringify(attrs)}`);
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 9) {
console.log(`Character: ${character_name} - Migration 02.06.00`)
attrs["build"] = 9;
if (v.sheettab === "isPC"){
getAttrs(["currenthope", "hope", "hope_max", "currentendurance", "endurance", "endurance_max"], function(values){
let currenthope = int(values.currenthope),
hope = int(values.hope),
hope_max = int(values.hope_max),
currentendurance = int(values.currentendurance),
endurance = int(values.endurance),
endurance_max = int(values.endurance_max);
clog(`Character: ${character_name} - Migration of currenthope: ${currenthope} into hope: ${hope}`);
attrs["hope"] = currenthope;
clog(`Character: ${character_name} - Migration of hope: ${hope} into hope_max: ${hope_max}`);
attrs["hope_max"] = hope;
clog(`Character: ${character_name} - Migration of currentendurance: ${currentendurance} into endurance: ${endurance}`);
attrs["endurance"] = currentendurance;
clog(`Character: ${character_name} - Migration of endurance: ${endurance} into endurance_max: ${endurance_max}`);
attrs["endurance_max"] = endurance;
clog(`${JSON.stringify(attrs)}`);
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 15) {
attrs["build"] = 15;
let releaselog = {msg:""};
hlog(`Migration 02.12.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs([
'weapon_skill_name_1', 'weapon_skill_name_2', 'weapon_skill_name_3', 'weapon_skill_name_4', 'weapon_skill_name_5', 'weapon_skill_name_6',
'weapon_damage_1', 'weapon_damage_2', 'weapon_damage_3', 'weapon_damage_4', 'weapon_damage_5', 'weapon_damage_6',
'weapon_injury_1', 'weapon_injury_2', 'weapon_injury_3', 'weapon_injury_4', 'weapon_injury_5', 'weapon_injury_6',
'weapon_fell_1', 'weapon_fell_2', 'weapon_fell_3', 'weapon_fell_4', 'weapon_fell_5', 'weapon_fell_6',
'weapon_grievous_1', 'weapon_grievous_2','weapon_grievous_3','weapon_grievous_4','weapon_grievous_5','weapon_grievous_6',
'weapon_keen_1', 'weapon_keen_2','weapon_keen_3','weapon_keen_4','weapon_keen_5','weapon_keen_6',
'weapon_fell_val_1', 'weapon_fell_val_2','weapon_fell_val_3','weapon_fell_val_4','weapon_fell_val_5','weapon_fell_val_6',
'weapon_grievous_val_1', 'weapon_grievous_val_2', 'weapon_grievous_val_3', 'weapon_grievous_val_4', 'weapon_grievous_val_5', 'weapon_grievous_val_6',
'weapon_keen_val_1', 'weapon_keen_val_2','weapon_keen_val_3','weapon_keen_val_4','weapon_keen_val_5','weapon_keen_val_6',
'armourcf', 'armourcm', 'helmetcf', 'helmetcm', 'othercf', 'othercm', 'shieldreinf', 'shieldcm',
'armourload', 'helmload', 'otherload', 'shieldload', 'shieldparry',
'releaselog',
], function(values){
for (let index of range(1,6)){
if (values[`weapon_skill_name_${index}`] != ""){
hlog(`Migration of Weapon ${index}:`, releaselog);
// fell migration if checked on the old sheet we set grievous +2 and injury -2
let fell_check = values[`weapon_fell_${index}`];
let fell_val = ["on", "1"].includes(fell_check) ? 2 : 0;
if (fell_val == 2){
attrs[`weapon_fell_val_${index}`] = fell_val;
hlog(`'Fell' property: changing old checkbox value: ${fell_check} into new combox value: ${fell_val}`, releaselog);
let injury_old = int(values[`weapon_injury_${index}`]);
let injury_new = (injury_old -2);
attrs[`weapon_injury_${index}`] = injury_new;
hlog(`'Injury' property: changing old value: ${injury_old} into new value: ${injury_new} - the bonus is now expressed by 'Fell' property!`, releaselog);
}
// grievous migration if checked on the old sheet we set grievous +1 and damage -1
let grievous_check = values[`weapon_grievous_${index}`];
let grievous_val = ["on", "1"].includes(grievous_check) ? 1 : 0;
if (grievous_val == 1) {
attrs[`weapon_grievous_val_${index}`] = grievous_val;
hlog(`'Grievous' property: changing old checkbox value: ${grievous_check} into new combox value: ${grievous_val}`, releaselog);
let damage_old = int(values[`weapon_damage_${index}`]);
let damage_new = (damage_old -1);
attrs[`weapon_damage_${index}`] = damage_new;
hlog(`'Damage' property: changing old value: ${damage_old} into new value: ${damage_new} - the bonus is now expressed by 'Grievous' property!`, releaselog);
}
// keen migration: if checked on the old sheet we set it to 9+
let keen_check = values[`weapon_keen_${index}`];
let keen_val = ["on", "1"].includes(keen_check) ? 9 : 10;
if (keen_val == 9) {
hlog(`'Keen' property: changing old checkbox value: ${keen_check} into new combox value: ${keen_val}. The roll template will automatically note this to calculate a Piercing Blow.`, releaselog);
attrs[`weapon_keen_val_${index}`] = keen_val;
}
}
}
hlog(`Migration of Armour:`, releaselog);
// close fitting armour -> protection bonus +2
let cfs = ['armourcf', 'helmetcf', 'othercf'];
cfs.forEach(cf => {
let cf_check = values[`${cf}`];
let cf_val = ["on", "1"].includes(cf_check) ? 2 : 0;
if (cf_val == 2) {
hlog(`'${cf}' property: changing old checkbox value: ${cf_check} into new combox value: ${cf_val}. You can see the bonus as part of the d6 dice of the Protection roll!`, releaselog);
attrs[`${cf}_val`] = cf_val;
}
});
// cunning make armour -> load reduction -2
let cms = ['armourcm', 'helmetcm', 'othercm', 'shieldcm'];
cms.forEach(cm => {
let cm_prefix = cm.slice(0,-2);
cm_prefix = cm_prefix == "helmet" ? "helm" : cm_prefix; // handle naming inconsistency helm/helmet
let cm_check = values[`${cm}`];
let cm_val = ["on", "1"].includes(cm_check) ? -2 : 0;
if (cm_val == -2) {
hlog(`'${cm}' property: changing old checkbox value: ${cm_check} into new combox value: ${cm_val}. You can see the Load reduction as part of the 'Total Load' if equipped!`, releaselog);
attrs[`${cm}_val`] = cm_val;
let load_old = int(values[`${cm_prefix}load`]);
let load_new = (load_old +2);
attrs[`${cm_prefix}load`] = load_new;
hlog(`'${cm_prefix} Load' property: changing old value: ${load_old} into new value: ${load_new} - the Load bonus is now expressed by 'Cunning Make' property!`, releaselog);
}
});
// reinforced shield -> parry bonus +1
let ri_check = values["shieldreinf"];
let ri_val = ["on", "1"].includes(ri_check) ? 1 : 0;
if (ri_val == 1) {
hlog(`'Reinforced Shield' property: changing old checkbox value: ${ri_check} into new combox value: ${ri_val}. You can see the bonus as part of the 'Total Parry' if equipped!`, releaselog);
attrs[`shieldreinf_val`] = ri_val;
let parry_old = int(values['shieldparry']);
let parry_new = (parry_old -1);
attrs['shieldparry'] = parry_new;
hlog(`'Shield Parry' property: changing old value: ${parry_old} into new value: ${parry_new} - the Shield Parry bonus is now expressed by 'Reinforced' shield property!`, releaselog);
}
hlog("Migration end!", releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 16) {
attrs["build"] = 16;
let releaselog = {msg:""};
hlog(`Release 02.12.01 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Bugfixes
- Fixed stance damagebonus should be dependent on the stance damage active checkbox (error was introduced with the grievous selectbox)
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 18) {
attrs["build"] = 18;
let releaselog = {msg:""};
hlog(`Release 02.13.01 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### CSS
- fixed protection roll-button may be not available with minimal width
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 19) {
attrs["build"] = 19;
let releaselog = {msg:""};
hlog(`Release 02.14.0 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Features
- added "fellowship focus" to pc sheet
### Translation
- fixed some missing support for translations on the pc sheet (thanks to iosu Li for the spanish translation)
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 20) {
attrs["build"] = 20;
let releaselog = {msg:""};
hlog(`Release 03.0.0 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Features
- added adversary json import
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 21) {
attrs["build"] = 21;
let releaselog = {msg:""};
hlog(`Release 03.01.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Features
- msg custom rolltemplate: added header-alt, sub1-alt, sub2-alt and fixe horizontal line hides correctly
- added button to post fell abilities of adversaries to chat
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 22) {
attrs["build"] = 22;
let releaselog = {msg:""};
hlog(`Release 03.02.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Fixed
- Target attacks calculated "piercing blow" correctly
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 23) {
attrs["build"] = 23;
let releaselog = {msg:""};
hlog(`Release 03.03.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Added
- Usefull item support
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 24) {
attrs["build"] = 24;
let releaselog = {msg:""};
hlog(`Release 03.04.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Added
- bonus modifier to useful items
- whisper mode of pc and npc
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 25) {
attrs["build"] = 25;
let releaselog = {msg:""};
hlog(`Release 03.05.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Added
- added "Daunted" modifier
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 26) {
attrs["build"] = 26;
let releaselog = {msg:""};
hlog(`Release 03.05.01 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Fixed
- translation bugs
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 27) {
attrs["build"] = 27;
let releaselog = {msg:""};
hlog(`Release 03.06.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Fixed
- missing checkboxes stance parry, shield parry, other parry
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 28) {
attrs["build"] = 28;
let releaselog = {msg:""};
hlog(`Release 03.07.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Added
- third adversary attack
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 29) {
attrs["build"] = 29;
let releaselog = {msg:""};
hlog(`Release 03.08.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Added
- dark theme for all sheets and roll templates
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 30) {
attrs["build"] = 30;
let releaselog = {msg:""};
hlog(`Release 03.09.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Added
- dark theme configurable for pc + adv sheets
### Fixed
- Firefox rolltemplate layout bug
- several CSS bugfixes and improvements
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 31) {
attrs["build"] = 31;
let releaselog = {msg:""};
hlog(`Release 03.10.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Fixed
- fixed minor CSS bug
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 32) {
attrs["build"] = 32;
let releaselog = {msg:""};
hlog(`Release 03.10.01 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Fixed
- fixed minor CSS bug
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 33) {
attrs["build"] = 33;
let releaselog = {msg:""};
hlog(`Release 03.11.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### Fixed
- fixed stance toggle
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 34) {
attrs["build"] = 34;
let releaselog = {msg:""};
hlog(`Release 03.12.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### New
- added "Favoured" modifier for pc combat proficiencies to allow handling of specific cultural virtues (e.g. Hobbit Cultural Virtue Sure At The Mark)
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 35) {
attrs["build"] = 35;
let releaselog = {msg:""};
hlog(`Release 03.13.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### New
- added "Taint" of items that will add to shadow / scars and leads to miserable / ill-favoured state when >= hope / hope_max
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
if (build < 36) {
attrs["build"] = 36;
let releaselog = {msg:""};
hlog(`Release 03.14.00 - ${new Date().toLocaleString()}`, releaselog);
if (v.sheettab === "isPC"){
getAttrs(['releaselog'], function(values){
hlog(`
### New
- added brawl combat proficiency
`, releaselog);
hlog("==============", releaselog);
attrs['releaselog'] = releaselog.msg + values['releaselog'];
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
}
}
/*
if (build === 9) {
attrs["build"] = 8;
}
*/
clog(`${JSON.stringify(attrs)}`);
if (Object.keys(attrs).length) {
setAttrs(attrs);
}
});
});
</script>
<rolltemplate class="sheet-rolltemplate-standard">
<div class="sheet-pc">
<div class="sheet-main">{{skill}}</div>
{{#rollTotal() favorill 1}}
<div class="sheet-main">stand {{standard}}</div>
{{/rollTotal() favorill 1}}
{{#rollTotal() favorill 2}}
<div class="sheet-main">fav {{fav}}</div>
{{/rollTotal() favorill 2}}
{{#rollTotal() favorill 3}}
<div class="sheet-main">ill {{ill}}</div>
{{/rollTotal() favorill 3}}
</div>
</rolltemplate>
<rolltemplate class="sheet-rolltemplate-msg">
<div class="sheet-container">
<div class="sheet-header">
{{#header}}<div class="sheet-title sheet-text-center">{{header}}</div>{{/header}}
{{#header-alt}}<div class="sheet-title-alt sheet-text-center">{{header-alt}}</div>{{/header-alt}}
{{#sub1}}<div class="sheet-subtitle sheet-text-center">{{sub1}}</div>{{/sub1}}
{{#sub1-alt}}<div class="sheet-subtitle-alt sheet-text-center">{{sub1-alt}}</div>{{/sub1-alt}}
{{#sub2}}<div class="sheet-subtitle sheet-text-center">{{sub2}}</div>{{/sub2}}
{{#sub2-alt}}<div class="sheet-subtitle-alt sheet-text-center">{{sub2-alt}}</div>{{/sub2-alt}}
</div>
{{#header}}{{^sub1}}{{^sub2}}{{#msg}}<div class="sheet-header-sep"/>{{/msg}}{{/sub2}}{{/sub1}}{{/header}}
{{#sub1}}{{^sub2}}{{#msg}}<div class="sheet-header-sep"/>{{/msg}}{{/sub2}}{{/sub1}}
{{#sub2}}{{#msg}}<div class="sheet-header-sep"/>{{/msg}}{{/sub2}}
{{#header-alt}}{{^sub1-alt}}{{^sub2-alt}}{{#msg-alt}}<div class="sheet-header-sep"/>{{/msg-alt}}{{/sub2-alt}}{{/sub1-alt}}{{/header-alt}}
{{#sub1-alt}}{{^sub2-alt}}{{#msg-alt}}<div class="sheet-header-sep"/>{{/msg-alt}}{{/sub2-alt}}{{/sub1-alt}}
{{#sub2-alt}}{{#msg-alt}}<div class="sheet-header-sep"/>{{/msg-alt}}{{/sub2-alt}}
{{#msg}}
<div class="sheet-contentmin">
<div class="sheet-main">{{msg}}</div>
</div>
{{/msg}}
{{#msg-alt}}
<div class="sheet-contentmin">
<div class="sheet-main-alt">{{msg-alt}}</div>
</div>
{{/msg-alt}}
</div>
</rolltemplate>
<rolltemplate class="sheet-rolltemplate-tor">
<div class="sheet-container">
<div class="sheet-header">
{{#character-name}}<div class="sheet-title sheet-text-center">{{character-name}}</div>{{/character-name}}
{{#roll-name}}<div class="sheet-subtitle sheet-text-center">{{roll-name}}</div>{{/roll-name}}
{{#targetname}}<div class="sheet-subtitle sheet-text-center">Target: {{targetname}}</div>{{/targetname}}
</div>
<div class="sheet-content">
<div class="sheet-full-col sheet-center sheet-die-title sheet-target-number">Target Number</div>
<div class="sheet-full-col sheet-center sheet-die-result sheet-target-number">
<span class="sheet-rotated-box"><span class="sheet-die-result">{{computed::target}}</span></span>
</div>
<div class="sheet-half-col sheet-die-title sheet-feat-label">Feat<br/>Die</div>
<div class="sheet-half-col sheet-die-title sheet-success-label">Success<br /> Dice</div>
{{#rollTotal() computed::feat 0}}
<div class="sheet-half-col sheet-die-result sheet-feat-die">
<span class="sheet-rotated-box"><span>-</span></span>
</div>
{{/rollTotal() computed::feat 0}}
{{#rollBetween() computed::feat 1 10}}
<div class="sheet-half-col sheet-die-result sheet-feat-die">
<span class="sheet-rotated-box">{{computed::feat}}</span>
</div>
{{/rollBetween() computed::feat 1 10}}
{{#rollTotal() computed::feat 11}}
<div class="sheet-half-col sheet-die-result sheet-feat-die">
<span class="sheet-rotated-box"><span class="sheet-fullfail">{{computed::feat}}</span><span
class="sheet-eye"></span></span>
</div>
{{/rollTotal() computed::feat 11}}
{{#rollTotal() computed::feat 12}}
<div class="sheet-half-col sheet-die-result sheet-feat-die">
<span class="sheet-rotated-box"><span class="sheet-fullcrit">{{computed::feat}}</span><span class="sheet-gandalf"></span></span>
</div>
{{/rollTotal() computed::feat 12}}
<div class="sheet-half-col sheet-die-result sheet-success-die"><span class="sheet-rotated-box">{{r1}}</span></div>
<div class="sheet-half-col sheet-die-comment sheet-favoured">
{{#favoured}}{{favoured}}{{/favoured}}
</div>
<div class="sheet-half-col sheet-die-comment sheet-modification">
{{#modification}}Bonus {{modification}}{{/modification}}
</div>
<div class="sheet-half-col sheet-die-comment sheet-favoured sheet-red">
{{#miserable}}{{miserable}}{{/miserable}}
</div>
<div class="sheet-half-col sheet-die-comment sheet-weary sheet-red">
{{#weary}}{{weary}}{{/weary}}
</div>
<div class="sheet-full-col sheet-center sheet-die-result sheet-roll-total">
<span class="sheet-rotated-box">{{computed::total}}</span>
</div>
<div class="sheet-full-col sheet-center sheet-die-title sheet-roll-total">Total</div>
<div class="sheet-full-col sheet-center sheet-roll-outcome">
<div class="sheet-center sheet-die-title">
{{#rollLess() computed::outcome 1}}
{{#rollTotal() computed::outcome -2}}Miserable&nbsp;&nbsp;{{/rollTotal() computed::outcome -2}}
{{#rollTotal() computed::outcome -1}}Weary&nbsp;&nbsp;{{/rollTotal() computed::outcome -1}}
Failure!
{{/rollLess() computed::outcome 1}}
{{#rollBetween() computed::outcome 1 3}}
{{#rollTotal() computed::greatness 1}}Great&nbsp;&nbsp;({{computed::greatness}})&nbsp;
{{/rollTotal() computed::greatness 1}}
{{#rollGreater() computed::greatness 1}}Extraordinary&nbsp;&nbsp;({{computed::greatness}})&nbsp;
{{/rollGreater() computed::greatness 1}}
{{#rollTotal() computed::outcome 2}}Feat&nbsp;&nbsp;{{/rollTotal() computed::outcome 2}}
{{#rollBetween() computed::outcome 1 2}}Success!{{/rollBetween() computed::outcome 1 2}}
{{#rollTotal() computed::outcome 3}}Piercing&nbsp;&nbsp;Blow!{{/rollTotal() computed::outcome 3}}
{{/rollBetween() computed::outcome 1 3}}
</div>
</div>
</div>
<div class="sheet-footer">
{{#rollBetween() computed::outcome 1 3}}
{{#weaponinfo}}
<div class="sheet-full-col sheet-center sheet-additional">
<div class="sheet-center">
{{weaponinfo}}
</div>
</div>
{{/weaponinfo}}
{{#additional}}
<div class="sheet-full-col sheet-center sheet-additional">
<div class="sheet-center">
{{additional}}
</div>
</div>
{{/additional}}
{{/rollBetween() computed::outcome 1 3}}
</div>
</div>
</rolltemplate>