mirror of
https://github.com/Nighthawk42/roll20-character-sheets.git
synced 2026-08-30 03:40:32 +00:00
6529 lines
284 KiB
HTML
6529 lines
284 KiB
HTML
<!-- <editor-fold desc="ButtonBar"> -->
|
|
<input type="hidden" class="sheet-tabstoggle" name="attr_sheetTab" value="main"/>
|
|
<input type="hidden" name="attr_sheet_version" value="1"/>
|
|
<input type="hidden" name="attr_constitution_score_backup"/>
|
|
<input type="hidden" name="attr_intelligence_score_backup"/>
|
|
<div style="text-align: center; width: 800px;" class="SAbutton">
|
|
<button class="sheet-tab-button-main" type="action" name="act_main">Main</button>
|
|
<button class="sheet-tab-button-definitions" type="action" name="act_definitions">Definitions</button>
|
|
<button class="sheet-tab-button-abilities" type="action" name="act_abilities">Abilities/Feats</button>
|
|
<button class="sheet-tab-button-spells" type="action" name="act_spells">Spells</button>
|
|
<button class="sheet-tab-button-skills" type="action" name="act_skills">Skills</button>
|
|
<button class="sheet-tab-button-gear" type="action" name="act_gear">Weapons/Armor</button>
|
|
<button class="sheet-tab-button-accessories" type="action" name="act_accessories">Accessories</button>
|
|
<button class="sheet-tab-button-inventory" type="action" name="act_inventory">Inventory</button>
|
|
<button class="sheet-tab-button-profitloss" type="action" name="act_profitloss">Profit/Loss</button>
|
|
<button class="sheet-tab-button-settings" type="action" name="act_settings">⚙</button>
|
|
</div>
|
|
|
|
<!-- </editor-fold> -->
|
|
|
|
<!-- <editor-fold desc="Main Tab"> -->
|
|
<div class="sheet-main">
|
|
<div class="character-info-block main-full">
|
|
<div class="column-header grcsa">Character Information</div>
|
|
<div id="player-name">
|
|
<div>Character Name</div>
|
|
<div><input title="@{character_name}" class="flex-input" type="text" readonly name="attr_character_name"/></div>
|
|
<div>Player Name</div>
|
|
<div><input title="@{PlayerName}" class="flex-input" type="text" name="attr_PlayerName"/></div>
|
|
</div>
|
|
<div id="age-and-height">
|
|
<div>Age</div>
|
|
<div><input title="@{characterage}" class="flex-input" type="number" name="attr_characterage"/></div>
|
|
<div>Height</div>
|
|
<div><input title="@{characterheight}" class="flex-input" type="text" name="attr_characterheight"/></div>
|
|
</div>
|
|
<div id="weight-and-gender">
|
|
<div>Weight</div>
|
|
<div><input title="@{characterweight}" class="flex-input" type="text" name="attr_characterweight" /></div>
|
|
<div>Gender</div>
|
|
<div><input title="@{charactergender}" class="flex-input" type="text" name="attr_charactergender"/></div>
|
|
</div>
|
|
<div id="species-name">
|
|
<div>Species</div>
|
|
<div><input title="@{species}" class="flex-input" type="text" name="attr_species"/></div>
|
|
<div>Speed (Land)</div>
|
|
<div><input title="@{basespeed}" class="flex-input" type="text" name="attr_basespeed"/></div>
|
|
</div>
|
|
<div id="more-speed">
|
|
<div>Sanctity</div>
|
|
<div><input title="@{Sanctity}" class="flex-input" type="text" name="attr_Sanctity"/></div>
|
|
<div>Speed (Swim)</div>
|
|
<div><input title="@{swimspeed}" class="flex-input" type="text" name="attr_swimspeed"/></div>
|
|
</div>
|
|
<div id="religion-name">
|
|
<div>Religion</div>
|
|
<div><input title="@{Religion}" class="flex-input" type="text" name="attr_Religion"/></div>
|
|
<div>Speed (Fly)</div>
|
|
<div><input title="@{flyspeed}" class="flex-input" type="text" name="attr_flyspeed" placeholder="#(Manuverability)"/></div>
|
|
</div>
|
|
<div id="hd-and-size">
|
|
<div>HD</div>
|
|
<div><input title="@{HD}" class="flex-input" type="number" name="attr_HD" /></div>
|
|
<div>Size Category</div>
|
|
<div class="DataBox">
|
|
<select title="@{size}" type="text" name="attr_size" id="SizeCategory">
|
|
<option value="Sub Tiny">Sub Tiny</option>
|
|
<option value="Tiny">Tiny</option>
|
|
<option value="Very Small">Very Small</option>
|
|
<option value="Small">Small</option>
|
|
<option selected="selected" value="Medium">Medium</option>
|
|
<option value="Large">Large</option>
|
|
<option value="Very Large">Very Large</option>
|
|
<option value="Gargantuan">Gargantuan</option>
|
|
<option value="Super Gargantuan">Super Gargantuan</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="main-left">
|
|
<div class="attribute-block">
|
|
<div class="column-header grcsa">Attributes</div>
|
|
<div id="name">
|
|
<div class="titleblock_stat"> </div>
|
|
<div class="titleblock_stat">Strength</div>
|
|
<div class="titleblock_stat">Dexterity</div>
|
|
<div class="titleblock_stat">Constitution</div>
|
|
<div class="titleblock_stat">Intelligence</div>
|
|
<div class="titleblock_stat">Wisdom</div>
|
|
<div class="titleblock_stat">Charisma</div>
|
|
</div>
|
|
<div id="base">
|
|
<div class="titleblock_stat">Base</div>
|
|
<div><input title="@{strength}" type="number" name="attr_strength"/></div>
|
|
<div><input title="@{dexterity}" type="number" name="attr_dexterity"/></div>
|
|
<div><input title="@{constitution}" type="text" name="attr_constitution"/></div>
|
|
<div><input title="@{intelligence}" type="text" name="attr_intelligence"/></div>
|
|
<div><input title="@{wisdom}" type="number" name="attr_wisdom"/></div>
|
|
<div><input title="@{charisma}" type="number" name="attr_charisma"/></div>
|
|
</div>
|
|
<div id="enhancement">
|
|
<div class="titleblock_stat">Magic</div>
|
|
<div><input title="@{StrEnch}" type="number" name="attr_StrEnch"/></div>
|
|
<div><input title="@{DexEnch}" type="number" name="attr_DexEnch"/></div>
|
|
<div><input title="@{ConEnch}" type="number" name="attr_ConEnch"/></div>
|
|
<div><input title="@{IntEnch}" type="number" name="attr_IntEnch"/></div>
|
|
<div><input title="@{WisEnch}" type="number" name="attr_WisEnch"/></div>
|
|
<div><input title="@{ChaEnch}" type="number" name="attr_ChaEnch"/></div>
|
|
</div>
|
|
<div id="bonus">
|
|
<div class="titleblock_stat">Bonus</div>
|
|
<div><input title="@{StrBonus}" type="number" name="attr_StrBonus"/></div>
|
|
<div><input title="@{DexBonus}" type="number" name="attr_DexBonus"/></div>
|
|
<div><input title="@{ConBonus}" type="number" name="attr_ConBonus"/></div>
|
|
<div><input title="@{IntBonus}" type="number" name="attr_IntBonus"/></div>
|
|
<div><input title="@{WisBonus}" type="number" name="attr_WisBonus"/></div>
|
|
<div><input title="@{ChaBonus}" type="number" name="attr_ChaBonus"/></div>
|
|
</div>
|
|
<div id="penalty">
|
|
<div class="titleblock_stat">Penalty</div>
|
|
<div><input title="@{StrPen}" type="number" name="attr_StrPen"/></div>
|
|
<div><input title="@{DexPen}" type="number" name="attr_DexPen"/></div>
|
|
<div><input title="@{ConPen}" type="number" name="attr_ConPen"/></div>
|
|
<div><input title="@{IntPen}" type="number" name="attr_IntPen"/></div>
|
|
<div><input title="@{WisPen}" type="number" name="attr_WisPen"/></div>
|
|
<div><input title="@{ChaPen}" type="number" name="attr_ChaPen"/></div>
|
|
</div>
|
|
<div id="total">
|
|
<div class="titleblock_stat">Total</div>
|
|
<div><input title="@{StrTotal}" type="number" name="attr_StrTotal" readonly/></div>
|
|
<div><input title="@{DexTotal}" type="number" name="attr_DexTotal" readonly/></div>
|
|
<div><input title="@{ConTotal}" type="text" name="attr_ConTotal" readonly/></div>
|
|
<div><input title="@{IntTotal}" type="text" name="attr_IntTotal" readonly/></div>
|
|
<div><input title="@{WisTotal}" type="number" name="attr_WisTotal" readonly/></div>
|
|
<div><input title="@{ChaTotal}" type="number" name="attr_ChaTotal" readonly/></div>
|
|
</div>
|
|
<div id="modifier">
|
|
<div class="titleblock_stat">Modifier</div>
|
|
<div><input title="@{strmod}" type="number" name="attr_strmod" readonly/></div>
|
|
<div><input title="@{dexmod}" type="number" name="attr_dexmod" readonly/></div>
|
|
<div><input title="@{conmod}" type="number" name="attr_conmod" readonly/></div>
|
|
<div><input title="@{intmod}" type="number" name="attr_intmod" readonly/></div>
|
|
<div><input title="@{wisdom}" type="number" name="attr_wismod" readonly/></div>
|
|
<div><input title="@{chamod}" type="number" name="attr_chamod" readonly/></div>
|
|
</div>
|
|
<div id="check">
|
|
<div class="titleblock_stat">Roll</div>
|
|
<div>
|
|
<button title="Strength Check"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Strength Check}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{strmod}]]}}"
|
|
name="roll_Strength-Check"></button>
|
|
</div>
|
|
<div>
|
|
<button title="Dexterity Check"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Dexterity Check}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{dexmod}]]}}"
|
|
name="roll_Dexterity-check"></button>
|
|
</div>
|
|
<div>
|
|
<button title="Constitution Check"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Constitution Check}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{conmod}]]}}"
|
|
name="roll_Constitution-check"></button>
|
|
</div>
|
|
<div>
|
|
<button title="Intelligence Check"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Intelligence Check}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{intmod}]]}}"
|
|
name="roll_Intelligence-check"></button>
|
|
</div>
|
|
<div>
|
|
<button title="Wisdom Check"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Wisdom Check}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{wismod}]]}}"
|
|
name="roll_Wisdom-check"></button>
|
|
</div>
|
|
<div>
|
|
<button title="Charisma Check"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Charisma Check}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{chamod}]]}}"
|
|
name="roll_Charisma-check"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="saving-throw-block">
|
|
<div class="column-header grcsa">Saving Throws</div>
|
|
<div id="save-name">
|
|
<div class="titleblock_stat">Ego</div>
|
|
<div class="titleblock_stat">
|
|
<select title="@{EgoBaseStr}" type="text" name="attr_EgoBaseStr" id="EgoBase">
|
|
<option value="Low">Low</option>
|
|
<option value="High">High</option>
|
|
</select>
|
|
</div>
|
|
<div class="titleblock_stat">Fortitude</div>
|
|
<div class="titleblock_stat">
|
|
<select title="@{FortBase}" type="text" name="attr_FortBaseStr" id="FortBase">
|
|
<option value="Low">Low</option>
|
|
<option value="High">High</option>
|
|
</select>
|
|
</div>
|
|
<div class="titleblock_stat">Reflex</div>
|
|
<div class="titleblock_stat">
|
|
<select title="@{ReflexBase}" type="text" name="attr_RefBaseStr" id="ReflexBase">
|
|
<option value="Low">Low</option>
|
|
<option value="High">High</option>
|
|
</select>
|
|
</div>
|
|
<div class="titleblock_stat">Will</div>
|
|
<div class="titleblock_stat">
|
|
<select title="@{WillBase}" type="text" name="attr_WilBaseStr" id="WillBase">
|
|
<option value="Low">Low</option>
|
|
<option value="High">High</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div id="save-total">
|
|
<div><b>Total</b></div>
|
|
<div><input title="@{EgoTotal}" type="number" readonly name="attr_EgoTotal"/></div>
|
|
<div><b>Total</b></div>
|
|
<div><input title="@{FortTotal}" type="number" readonly name="attr_FortTotal"/></div>
|
|
<div><b>Total</b></div>
|
|
<div><input title="@{RefTotal}" type="number" readonly name="attr_RefTotal"/></div>
|
|
<div><b>Total</b></div>
|
|
<div><input title="@{WilTotal}" type="number" readonly name="attr_WilTotal"/></div>
|
|
</div>
|
|
<div id="save-base">
|
|
<div>Base</div>
|
|
<div><input title="@{EgoBaseNum}" type="number" name="attr_EgoBaseNum" readonly/></div>
|
|
<div>Base</div>
|
|
<div><input title="@{FortBaseNum}" type="number" name="attr_FortBaseNum" readonly/></div>
|
|
<div>Base</div>
|
|
<div><input title="@{RefBaseNum}" type="number" name="attr_RefBaseNum" readonly/></div>
|
|
<div>Base</div>
|
|
<div><input title="@{WilBaseNum}" type="number" name="attr_WilBaseNum" readonly/></div>
|
|
</div>
|
|
<div id="save-key">
|
|
<div>Cha</div>
|
|
<div><input title="@{chamod}" type="number" name="attr_chamod" readonly/></div>
|
|
<div>Con</div>
|
|
<div><input title="@{@conmod}" type="number" name="attr_conmod" readonly/></div>
|
|
<div>Dex</div>
|
|
<div><input title="@{dexmod}" type="number" name="attr_dexmod" readonly/></div>
|
|
<div>Wis</div>
|
|
<div><input title="@{wismod}" type="number" name="attr_wismod" readonly/></div>
|
|
</div>
|
|
<div id="save-magic">
|
|
<div>Magic</div>
|
|
<div><input title="@{EgoMagic}" type="number" name="attr_EgoMagic"/></div>
|
|
<div>Magic</div>
|
|
<div><input title="@{FortMagic}" type="number" name="attr_FortMagic"/></div>
|
|
<div>Magic</div>
|
|
<div><input title="@{RefMagic}" type="number" name="attr_RefMagic"/></div>
|
|
<div>Magic</div>
|
|
<div><input title="@{WilMagic}" type="number" name="attr_WilMagic"/></div>
|
|
</div>
|
|
<div id="save-misc">
|
|
<div>Misc.</div>
|
|
<div><input title="@{EgoMiscNum}" type="number" name="attr_EgoMiscNum"/></div>
|
|
<div>Misc.</div>
|
|
<div><input title="@{FortMiscNum}" type="number" name="attr_FortMiscNum"/></div>
|
|
<div>Misc.</div>
|
|
<div><input title="@{RefMiscNum}" type="number" name="attr_RefMiscNum"/></div>
|
|
<div>Misc.</div>
|
|
<div><input title="@{WilMiscNum}" type="number" name="attr_WilMiscNum"/></div>
|
|
</div>
|
|
<div id="save-temp">
|
|
<div>Temp</div>
|
|
<div><input title="@{EgoTempNum}" type="number" name="attr_EgoTempNum"/></div>
|
|
<div>Temp</div>
|
|
<div><input title="@{FortTempNum}" type="number" name="attr_FortTempNum"/></div>
|
|
<div>Temp</div>
|
|
<div><input title="@{RefTempNum}" type="number" name="attr_RefTempNum"/></div>
|
|
<div>Temp</div>
|
|
<div><input title="@{WilTempNum}" type="number" name="attr_WilTempNum"/></div>
|
|
</div>
|
|
<div id="save-check">
|
|
<div class="titleblock_stat">Save</div>
|
|
<div class="titleblock_stat">
|
|
<button title="Ego Save"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Ego Save}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{EgoTotal}]]}}"
|
|
name="roll_Ego-save"></button>
|
|
</div>
|
|
<div class="titleblock_stat">Save</div>
|
|
<div class="titleblock_stat">
|
|
<button title="Fortitude Save"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Fortitude Save}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{FortTotal}]]}}"
|
|
name="roll_Fortitude-save"></button>
|
|
</div>
|
|
<div class="titleblock_stat">Save</div>
|
|
<div class="titleblock_stat">
|
|
<button title="Reflex Save"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Reflex Save}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{RefTotal}]]}}"
|
|
name="roll_Reflex-save"></button>
|
|
</div>
|
|
<div class="titleblock_stat">Save</div>
|
|
<div class="titleblock_stat">
|
|
<button title="Will Save"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Will Save}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{WilTotal}]]}}"
|
|
name="roll_Will-save"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column-header">Advanced Combat</div>
|
|
<div class="ggrid titleblock_stat">
|
|
<div class="grc1">
|
|
<div> </div>
|
|
<div>Magic Touch Attack:</div>
|
|
<div>Martial Touch Attack:</div>
|
|
<div>Opposed (Trip):</div>
|
|
<div>Opposed (Shove):</div>
|
|
<div>Opposed (Trample):</div>
|
|
<div>Grapple</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div>Total</div>
|
|
<div><input title="@{MagicTouchAttack}" type="number" readonly name="attr_MagicTouchAttack"/></div>
|
|
<div><input title="@{MartialTouchAttack}" type="number" readonly name="attr_MartialTouchAttack"/></div>
|
|
<div><input title="@{TripOpposed}" type="number" readonly name="attr_TripOpposed"/></div>
|
|
<div><input title="@{ShoveOpposed}" type="number" readonly name="attr_ShoveOpposed"/></div>
|
|
<div><input title="@{TrampleOpposed}" type="number" readonly name="attr_TrampleOpposed"/></div>
|
|
<div><input title="@{Grapple}" type="number" readonly name="attr_Grapple"/></div>
|
|
</div>
|
|
<div class="grc3">
|
|
<div>Feat</div>
|
|
<div><input title="@{MagicTouchAttackFeat}" type="number" name="attr_MagicTouchAttackFeat" /></div>
|
|
<div><input title="@{MartialTouchAttackFeat}" type="number" name="attr_MartialTouchAttackFeat" /></div>
|
|
<div><input title="@{TripOpposedFeat}" type="number" name="attr_TripOpposedFeat" /></div>
|
|
<div><input title="@{ShoveOpposedFeat}" type="number" name="attr_ShoveOpposedFeat" /></div>
|
|
<div><input title="@{TrampleOpposedFeat}" type="number" name="attr_TrampleOpposedFeat" /></div>
|
|
<div><input title="@{GrappleFeat}" type="number" name="attr_GrappleFeat"/></div>
|
|
</div>
|
|
<div class="grc4">
|
|
<div>Misc.</div>
|
|
<div><input title="@{MagicTouchAttackMisc}" type="number" name="attr_MagicTouchAttackMisc" /></div>
|
|
<div><input title="@{MartialTouchAttackMisc}" type="number" name="attr_MartialTouchAttackMisc" /></div>
|
|
<div><input title="@{TripOpposedMisc}" type="number" name="attr_TripOpposedMisc" /></div>
|
|
<div><input title="@{ShoveOpposedMisc}" type="number" name="attr_ShoveOpposedMisc" /></div>
|
|
<div><input title="@{TrampleOpposedMisc}" type="number" name="attr_TrampleOpposedMisc" /></div>
|
|
<div><input title="@{GrappleMisc}" type="number" name="attr_GrappleMisc"/></div>
|
|
</div>
|
|
<div class="grc5">
|
|
<div>Temp</div>
|
|
<div><input title="@{MagicTouchAttackTemp}" type="number" name="attr_MagicTouchAttackTemp" /></div>
|
|
<div><input title="@{MartialTouchAttackTemp}" type="number" name="attr_MartialTouchAttackTemp" /></div>
|
|
<div><input title="@{TripOpposedTemp}" type="number" name="attr_TripOpposedTemp" /></div>
|
|
<div><input title="@{ShoveOpposedTemp}" type="number" name="attr_ShoveOpposedTemp" /></div>
|
|
<div><input title="@{TrampleOpposedTemp}" type="number" name="attr_TrampleOpposedTemp" /></div>
|
|
<div><input title="@{GrappleTemp}" type="number" name="attr_GrappleTemp"/></div>
|
|
</div>
|
|
<div class="grc6">
|
|
<div>Roll</div>
|
|
<div>
|
|
<button class="button"
|
|
title="MagicTouchAttack"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Magic Touch Attack}}{{subtitle= @{character_name}'s touch spell}}{{Result:=[[1d20+@{MagicTouchAttack}]]}}"
|
|
name="roll_MagicTouchAttackR"></button>
|
|
</div>
|
|
<div>
|
|
<button class="button"
|
|
title="MartialTouchAttack"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Martial Touch Attack}}{{subtitle= @{character_name}'s touch attack}}{{Result:=[[1d20+@{MartialTouchAttack}]]}}"
|
|
name="roll_MartialTouchAttackR"></button>
|
|
</div>
|
|
<div>
|
|
<button class="button"
|
|
title="Opposed Trip"
|
|
type="roll"
|
|
value="&{template:custom}{{title=oppose strength (Trip)}}{{subtitle= @{character_name}'s opposing strength}}{{Result:=[[1d20+@{TripOpposed}]]}}"
|
|
name="roll_TripOpposedR"></button>
|
|
</div>
|
|
<div>
|
|
<button class="button"
|
|
title="Opposed Shove"
|
|
type="roll"
|
|
value="&{template:custom}{{title=oppose strength (Shove)}}{{subtitle= @{character_name}'s opposing strength}}{{Result:=[[1d20+@{ShoveOpposed}]]}}"
|
|
name="roll_ShoveOpposedR"></button>
|
|
</div>
|
|
<div>
|
|
<button class="button"
|
|
title="Opposed Trample"
|
|
type="roll"
|
|
value="&{template:custom}{{title=oppose strength (Trample)}}{{subtitle= @{character_name}'s opposing strength}}{{Result:=[[1d20+@{TrampleOpposed}]]}}"
|
|
name="roll_opposed-trampleR"></button>
|
|
</div>
|
|
<div>
|
|
<button class="button"
|
|
title="Opposed Grapple"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Opposed Grapple}}{{subtitle= @{character_name} }}{{Result=[[1d20+@{Grapple}]]}}"
|
|
name="roll_opposed-grappleR"></button>
|
|
</div>
|
|
</div>
|
|
</div> <!--Advanced Combat Grid-->
|
|
<div class="conditions-effects-block">
|
|
<div class="column-header">Conditions and Temporary Effects</div>
|
|
<div class="conditions-effects-content">
|
|
<div class="conditions-repeat-section">
|
|
<div class="conditions-subheader">Active Conditions</div>
|
|
<fieldset class="repeating_conditions">
|
|
<div class="condition-repeat-row">
|
|
<div class="condition-repeat-topline">
|
|
<select title="@{condition_type}" class="condition-select" name="attr_condition_type">
|
|
<option value="">Condition</option>
|
|
<option value="Bad Luck">Bad Luck</option>
|
|
<option value="Dizzy">Dizzy</option>
|
|
<option value="Exhausted">Exhausted</option>
|
|
<option value="Fatigued">Fatigued</option>
|
|
<option value="Nauseated">Nauseated</option>
|
|
<option value="Scared">Scared</option>
|
|
<option value="Sickened">Sickened</option>
|
|
<option value="Sleep">Sleep</option>
|
|
<option value="Soaked">Soaked</option>
|
|
<option value="Stifle">Stifle</option>
|
|
<option value="Stunned">Stunned</option>
|
|
</select>
|
|
<input title="@{condition_duration}"
|
|
class="condition-duration-input"
|
|
type="text" name="attr_condition_duration"
|
|
placeholder="Duration / source"/>
|
|
</div>
|
|
<div title="@{condition_effect}"
|
|
class="condition-effect-display">
|
|
<span name="attr_condition_effect"></span></div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="temporary-effects-strip">
|
|
<label><input title="@{haste}" type="checkbox" name="attr_haste" value="1"/> Hasted</label>
|
|
<label><input title="@{slow}" type="checkbox" name="attr_slow" value="1"/> Slowed</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="main-right">
|
|
<div class="hp-armor-block">
|
|
<div class="grc1">
|
|
<div class="column-header">Hit Points</div>
|
|
<div class="hp-column">
|
|
<div id="hp-names">
|
|
<div>Current HP:</div>
|
|
<div>Max HP:</div>
|
|
<div>Constitution:</div>
|
|
<div>Progression:</div>
|
|
<div>Misc. HP:</div>
|
|
<div>Rolled HP:</div>
|
|
</div>
|
|
<div id="hp-inputs">
|
|
<div><input title="@{hp}" type="number" name="attr_hp"/></td></div>
|
|
<div><input title="@{hp_max}" type="number" readonly name="attr_hp_max"/></div>
|
|
<div><input title="@{ConHP}" type="number" readonly name="attr_ConHP"/></div>
|
|
<div><input title="@{ProgHP}" type="number" readonly name="attr_ProgHP"/></div>
|
|
<div><input title="@{MiscHP}" type="number" name="attr_MiscHP"/></div>
|
|
<div><input title="@{RollHP}" type="number" name="attr_RollHP"/></div>
|
|
</div>
|
|
</div>
|
|
<div class="column-header">Initiative
|
|
<button class="button tokenaction"
|
|
title="Initiative"
|
|
type="roll"
|
|
value="/gr [[1d20+@{InitTotal}+(@{InitTotal}/100)+([[d10-1]]/1000)&{tracker}]]"
|
|
name="roll_00-Inintiative"></button>
|
|
</div>
|
|
<div class="ggrid">
|
|
<div class="grc1">
|
|
<div style="color: #FFFFFF">Total</div>
|
|
<div><input title="@{InitTotal}" type="number" readonly="true" name="attr_InitTotal"/></div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div> </div>
|
|
<div class="titleblock_stat">=</div>
|
|
</div>
|
|
<div class="grc3">
|
|
<div style="color: #FFFFFF">Dex</div>
|
|
<div class="titleblock_stat"><input title="@{dexmod}" type="number" name="attr_dexmod" readonly="true"/></div>
|
|
</div>
|
|
<div class="grc4">
|
|
<div> </div>
|
|
<div class="titleblock_stat">+</div>
|
|
</div>
|
|
<div class="grc5">
|
|
<div style="color: #FFFFFF">Misc</div>
|
|
<div><input title="@{InitBonus}" type="number" name="attr_InitBonus"/></div>
|
|
</div>
|
|
</div> <!-- Initiative Boxes -->
|
|
<div class="column-header">Wound and Base Attack</div>
|
|
<div class="ggrid"> <!--Wound and Base Attack Grid-->
|
|
<div class="grc1">
|
|
<div class="titleblock_stat">Wound DC</div>
|
|
<div><input title="@{WoundDC}" type="number" name="attr_WoundDC" readonly/></div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div class="titleblock_stat">Base Attack</div>
|
|
<div><input title="@{BAB}" type="number" name="attr_BAB" readonly/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div class="column-header">Armor Class</div>
|
|
<div class="ac-column">
|
|
<div id="ac-names">
|
|
<div>Total AC:</div>
|
|
<div>Touch AC:</div>
|
|
<div>Flat-Footed AC:</div>
|
|
<div>Armor:</div>
|
|
<div>Shield:</div>
|
|
<div>Natural:</div>
|
|
<div>Deflection:</div>
|
|
<div>Parry:</div>
|
|
<div>Dodge:</div>
|
|
<div>Insight:</div>
|
|
<div>Misc:</div>
|
|
</div>
|
|
<div id="ac-inputs">
|
|
<div><input title="@{TotalAC}" type="number" readonly="true" name="attr_TotalAC"/></div>
|
|
<div><input title="@{TouchAC}" type="number" readonly="true" name="attr_TouchAC"/></div>
|
|
<div><input title="@{FlatFAC}" type="number" readonly="true" name="attr_FlatFAC"/></div>
|
|
<div><input title="@{ArmorBonus}" type="number" readonly="true" name="attr_ArmorBonus"/></div>
|
|
<div><input title="@{Shield}" type="number" readonly="true" name="attr_Shield"/></div>
|
|
<div><input title="@{NaturalAC}" type="number" name="attr_NaturalAC"></div>
|
|
<div><input title="@{Deflection}" type="number" name="attr_Deflection"/></div>
|
|
<div><input title="@{ParryAC}" type="number" name="attr_ParryAC"/></div>
|
|
<div><input title="@{DodgeAC}" type="number" name="attr_DodgeAC"/></div>
|
|
<div><input title="@{InsightAC}" type="number" name="attr_InsightAC"/></div>
|
|
<div><input title="@{MiscAC}" type="number" name="attr_MiscAC"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="vitals-resistances-block">
|
|
<div class="column-header">Vitals and Resistances</div>
|
|
<div class="vitals-resistances-content">
|
|
<div class="vitals-rest-row">
|
|
<span>Rest:</span>
|
|
<button type="action" class="Small-Button vitals-rest-button" name="act_rest">Rest</button>
|
|
</div>
|
|
<div class="vitals-death-save-row">
|
|
<span>Death Saves: </span>
|
|
<!--<button type="action" class="Small-Button vitals-death-save-button" name="act_deathsave">Roll</button>-->
|
|
<label><input class="death-save-checkbox"
|
|
title="@{death_save_1}"
|
|
type="checkbox"
|
|
name="attr_death_save_1"
|
|
value="1"/> First Fail</label>
|
|
<label><input class="death-save-checkbox"
|
|
title="@{death_save_2}"
|
|
type="checkbox"
|
|
name="attr_death_save_2"
|
|
value="1"/> Second Fail</label>
|
|
<label><input class="death-save-checkbox"
|
|
title="@{death_save_3}"
|
|
type="checkbox"
|
|
name="attr_death_save_3"
|
|
value="1"/> Death</label>
|
|
</div>
|
|
<div class="vitals-repeat-columns">
|
|
<div class="vitals-repeat-section">
|
|
<div class="vitals-subheader">Damage Reduction</div>
|
|
<fieldset class="repeating_damagereduction">
|
|
<div class="damage-reduction-row">
|
|
<input title="@{damage_reduction_value}" class="vitals-small-number" type="number" name="attr_damage_reduction_value"/>
|
|
<span>/</span>
|
|
<input title="@{damage_reduction_bypass}" class="vitals-bypass-input" type="text" name="attr_damage_reduction_bypass" placeholder="Bypass"/>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="vitals-repeat-section">
|
|
<div class="vitals-subheader">Resistance</div>
|
|
<fieldset class="repeating_resistance">
|
|
<div class="resistance-row">
|
|
<select title="@{resistance_type}" class="vitals-element-select" name="attr_resistance_type">
|
|
<option value="Cold">Cold</option>
|
|
<option value="Corrosive">Corrosive</option>
|
|
<option value="Desiccation">Desiccation</option>
|
|
<option value="Electric">Electric</option>
|
|
<option value="Entropic">Entropic</option>
|
|
<option value="Force">Force</option>
|
|
<option value="Heat">Heat</option>
|
|
<option value="Holy">Holy</option>
|
|
<option value="Negative">Negative</option>
|
|
<option value="Positive">Positive</option>
|
|
<option value="Unholy">Unholy</option>
|
|
</select>
|
|
<input title="@{resistance_value}" class="vitals-small-number" type="number" name="attr_resistance_value"/>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column-header grcsa main-notes-header">Notes</div>
|
|
<div class="main-notes-body">
|
|
<textarea class="main-notes-textarea" name="attr_Main-Notes" placeholder="Pertinent information, notes, and bonuses..."></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Definitions and Traits">-->
|
|
<div class="sheet-definitions">
|
|
<div class="ggrid">
|
|
<div class="grr1 row-header">Definitions, Traits, & Afflictions</div>
|
|
<div class="grr2 ggrid titleblock_stat">
|
|
<div class="grc1">
|
|
<div>Attack Curve</div>
|
|
<div><select title="@{AttackCurve}" class="standard-input" type="text" name="attr_AttackCurve">
|
|
<option value="High">High</option>
|
|
<option value="Medium">Medium</option>
|
|
<option value="Low">Low</option>
|
|
</select></div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div>Magic Type</div>
|
|
<div><select title="@{MagicCurve}" class="standard-input" type="text" name="attr_MagicCurve">
|
|
<option value="None">Null</option>
|
|
<option value="Basic">Basic</option>
|
|
<option value="Standard">Standard</option>
|
|
<option value="Advanced">Advanced</option>
|
|
</select></div>
|
|
</div>
|
|
<div class="grc3">
|
|
<div>Specialty</div>
|
|
<div><select title="@{Specialty}" class="standard-input" type="text" name="attr_Specialty">
|
|
<option value="Combatant">Combatant</option>
|
|
<option value="Generalist">Generalist</option>
|
|
<option value="Specialist">Specialist</option>
|
|
</select></div>
|
|
</div>
|
|
<div class="grc4">
|
|
<div>Natural Int Mod</div>
|
|
<div><input title="@{NatIntMod}" type="number" name="attr_NatIntMod" readonly/></div>
|
|
</div>
|
|
<div class="grc5">
|
|
<div>Base Skill Growth</div>
|
|
<div><input title="@{BaseSkillGrowth}" type="number" name="attr_BaseSkillGrowth" readonly/></div>
|
|
</div>
|
|
<div class="grc6">
|
|
<div>Skills Known</div>
|
|
<div><input title="@{SkillsKnown}" type="number" name="attr_SkillsKnown" readonly/></div>
|
|
</div>
|
|
<div class="grc7">
|
|
<div>Total Skill Points</div>
|
|
<div><input title="@{TotalPossibleSkillPoints}" type="number" name="attr_TotalPossibleSkillPoints" readonly/></div>
|
|
</div>
|
|
<div class="grc8">
|
|
<div>Unspent Skill Point</div>
|
|
<div><input title="@{RemainingSkillPoints}" type="number" name="attr_RemainingSkillPoints" readonly/></div>
|
|
</div>
|
|
</div>
|
|
<div class="grr3 ggrid">
|
|
<div class="grc1 bottom-border-div">
|
|
<div class="column-header">Species Info/Traits</div>
|
|
<div>Versatile?<input type="checkbox" name="attr_Versatile"/></div>
|
|
<div>Mystic?<input type="checkbox" name="attr_mystic" value="1"/></div>
|
|
<div>
|
|
<fieldset class="repeating_DTA1">
|
|
<div class="column-header-dark">
|
|
<button type="action" class="Small-Button" name="act_dta1minimize">-</button><input title="@{speciestraitname}" class="DTA-name-dark" type="text" name="attr_speciestraitname" placeholder="<Trait name here>"/>
|
|
</div>
|
|
<input type="hidden" class="dta-toggle" name="attr_dta1minimizetoggle" value="0"/>
|
|
<div class="dta-shrink">
|
|
<textarea title="@{speciestraitdescription}" name="attr_speciestraitdescription" placeholder="<Description here>"></textarea>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
<div class="grc2 wrapped-div">
|
|
<div class="column-header">Definitions</div>
|
|
<div class="definition-flag">Diffuse Background?<input title="@{diffuse_background}" type="checkbox" name="attr_diffuse_background" value="1"/></div>
|
|
<div class="titleblock_stat" style="font-size: medium">Primary</div>
|
|
<div class="column-header"><input title="@{primarydefinitionname}" class="DTA-name" type="text" name="attr_primarydefinitionname" placeholder="<Primary Definition here>"></div>
|
|
<div><textarea title="@{primarydescription}" name="attr_primarydescription" placeholder="<Description here>"></textarea></div>
|
|
<div class="column-header-dark">Secondary</div>
|
|
<div>
|
|
<fieldset class="repeating_DTA2">
|
|
<div class="column-header"><button type="action" class="Small-Button" name="act_dta2minimize">-</button><input class="DTA-name" type="text" name="attr_secdefname" placeholder="<Secondary Definition here>"/>
|
|
</div>
|
|
<input type="hidden" class="dta-toggle" name="attr_dta2minimizetoggle" value="0"/>
|
|
<div class="dta-shrink">
|
|
<textarea name="attr_secdefdescription" placeholder="<Description here>"></textarea>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
<div class="grc3 bottom-border-div">
|
|
<div class="column-header">Afflictions</div>
|
|
<div>
|
|
<fieldset class="repeating_DTA3">
|
|
<input type="hidden" class="afflictions-toggle" name="attr_minafflictionsval" value="0"/>
|
|
<div class="column-header-dark"><button type="action" class="Small-Button" name="act_dta3minimize">-</button><input class="DTA-name-dark" type="text" name="attr_afflictionsname" placeholder="<Affliction name here>"/>
|
|
</div>
|
|
<input type="hidden" class="dta-toggle" name="attr_dta3minimizetoggle" value="0"/>
|
|
<div class="dta-shrink">
|
|
<textarea name="attr_afflictionsdescription" placeholder="<Description here>"></textarea>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- This is the feats list
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_feats">
|
|
<input type="hidden" class="feats-toggle" name="attr_minfeatval" value="0"/>
|
|
<div class="feats_title"><button style="color:black" type="action" class="Small-Button" name="act_minfeats">-</button><input type="text" name="attr_featsname" placeholder="<Feat name here>">
|
|
</div>
|
|
<div class="feats_description">
|
|
<textarea name="attr_featsdescription" placeholder="<Description here>"></textarea>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
-->
|
|
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Abilities">-->
|
|
<div class="sheet-abilities">
|
|
<div class="ggrid">
|
|
<div class="grr1 row-header">
|
|
Abilities and Feats
|
|
</div>
|
|
<div class="titleblock_stat grr2 ggrid">
|
|
<div class="grc1">
|
|
<div>Close Range</div>
|
|
<div><input title="@{CloseRange}" type="number" name="attr_CloseRange" readonly/></div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div>Medium Range</div>
|
|
<div><input title="@{MediumRange}" type="number" name="attr_MediumRange" readonly/></div>
|
|
</div>
|
|
<div class="grc3">
|
|
<div>Long Range</div>
|
|
<div><input title="@{LongRange}" type="number" name="attr_LongRange" readonly/></div>
|
|
</div>
|
|
<div class="grc4">
|
|
<div>Spell Proficiency</div>
|
|
<div><input title="@{SpellProf}" type="number" name="attr_SpellProf" readonly/></div>
|
|
</div>
|
|
</div>
|
|
<div class="grr3 ggrid">
|
|
<div class="grr1 row-header">Resources</div>
|
|
<fieldset class="repeating_resources">
|
|
<div class="grr2">
|
|
<div class="ggrid">
|
|
<div class="grr1 column-header-dark">
|
|
<input class="resourceName" title="Resource Name" type="text" name="attr_resourceName" placeholder="Grace, Focus, Etc..."/>
|
|
</div>
|
|
<div class="grr2">
|
|
Remaining:
|
|
<input class="standard-input" title="Resource Current" type="number" name="attr_resourceNumber" />
|
|
</div>
|
|
<div class="grr3">
|
|
Maximum:
|
|
<input class="standard-input" title="Resource Max" type="number" name="attr_resourceNumber_max" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="grr4 ggridc">
|
|
<div class="grc1">
|
|
<div class="column-header">Abilities</div>
|
|
<fieldset class="repeating_abilities">
|
|
<input type="hidden" name="attr_grant_key"/>
|
|
<input type="hidden" class="grant-hidden" name="attr_grant_hidden" value="0"/>
|
|
<div class="midline-right-div ggrid grant-row">
|
|
<div class="row-header-dark grr1">
|
|
<div class="ability-title-row">
|
|
<button type="action" class="Small-Button" name="act_minabilitytog">-</button>
|
|
<input type="hidden" class="grant-available" name="attr_source_available" value="1"/>
|
|
<input type="text" class="Ability-name" name="attr_abilityname" placeholder="<Ability Name Here>"/>
|
|
<span class="grant-meta">
|
|
HD <input class="grant-level-input"
|
|
title="@{granted_level}"
|
|
type="number" name="attr_granted_level"
|
|
placeholder="#" readonly/>
|
|
Source <input class="grant-source-input"
|
|
title="@{granted_source}"
|
|
type="text" name="attr_granted_source"
|
|
placeholder="Manual" readonly/>
|
|
</span>
|
|
<button type="roll" name="roll_ability_card" value="@{abilityroll}"></button>
|
|
</div>
|
|
<div class="grr2 titleblock" style="font-size: small; font-weight: normal; margin-bottom: 2px">
|
|
Use(s): <input class="standard-input" type="text" name="attr_userdescription" placeholder="per day"/>
|
|
Max Uses: <input class="standard-input" type="text" name="attr_uses"/>
|
|
Resource: <input title="Resource Name" class="standard-input" type="text" name="attr_resourceNameCard"/>
|
|
<input type="hidden" name="attr_abilityroll"/>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" class="ability-toggle" name="attr_minimizeability" value="0"/>
|
|
<div class="ability_description ggrid">
|
|
<div class="grr1 ggridc" style="margin-top: 2px">
|
|
<div class="grc1">
|
|
<div>Target/Effect:</div>
|
|
<div>Duration:</div>
|
|
<div>DC:</div>
|
|
<div>Ability Type?</div>
|
|
<div>Dice Rolled?</div>
|
|
<div>Spell Resistance?</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input class="standard-input" type="text" name="attr_abilitytarget"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_abilityduration" placeholder="Rounds"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_abilitydc"/></div>
|
|
<div>
|
|
<select class="fixed-select" name="attr_abilitytype">
|
|
<option value="0">Utility</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<input class="standard-input" type="text" name="attr_abilitydicenum" placeholder="#"/>
|
|
<select class="die-select" name="attr_abilitydicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select>
|
|
</div>
|
|
<div><input type="checkbox" name="attr_abilitysrconfirm" value="1"/></div>
|
|
</div>
|
|
<div class="grc3">
|
|
<div>Range:</div>
|
|
<div>Action:</div>
|
|
<div>Saving Throw:</div>
|
|
<div>Spell Proficiency?</div>
|
|
</div>
|
|
<div class="grc4">
|
|
<div><input class="standard-input" type="text" name="attr_abilityrange"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_abilityaction"/></div>
|
|
<div>
|
|
<select class="fixed-select" name="attr_absavethrow" value="N/A" class="abilitysaving">
|
|
<option value="N/A">N/A</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div><input type="checkbox" name="attr_asprof" value="1"/></div>
|
|
</div>
|
|
</div>
|
|
<div class="grr2">
|
|
Ability Description:<br><textarea name="attr_abilitydescriptiontext"></textarea><br>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="grc2">
|
|
<div class="column-header">Feats</div>
|
|
<fieldset class="repeating_feats">
|
|
<input type="hidden" name="attr_grant_key"/>
|
|
<input type="hidden" class="grant-hidden" name="attr_grant_hidden" value="0"/>
|
|
<div class="column-header-dark feat-title-row grant-row">
|
|
<button style="color:black" type="action" class="Small-Button" name="act_minfeats">-</button>
|
|
<input type="hidden" class="grant-available" name="attr_source_available" value="1"/>
|
|
<input class="Ability-name" type="text" name="attr_featsname" placeholder="<Feat name here>">
|
|
<span class="grant-meta">
|
|
HD <input class="grant-level-input"
|
|
title="@{granted_level}"
|
|
type="number"
|
|
name="attr_granted_level"
|
|
placeholder="#" readonly/>
|
|
Source <input class="grant-source-input"
|
|
title="@{granted_source}"
|
|
type="text" name="attr_granted_source"
|
|
placeholder="Manual" readonly/></span>
|
|
</div>
|
|
<input type="hidden" class="feats-toggle" name="attr_minfeatval" value="0"/>
|
|
<div class="feats_description grant-row">
|
|
<textarea name="attr_featsdescription" placeholder="<Description here>"></textarea>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--</editor-fold>-->
|
|
|
|
<!-- <editor-fold desc="Spells"-->
|
|
<div class="sheet-spells">
|
|
<div class="gridarea">
|
|
<div class="titleblock">
|
|
<h3 style="color:white">Spell Casting</h3>
|
|
<div class="titleblock_stat">
|
|
Primary Mental Attribute(PMA): <select title="@{PMA}" name="attr_PMA" value="" class="fixed-select">
|
|
<option value="@{strmod}">Str</option>
|
|
<option value="@{dexmod}">Dex</option>
|
|
<option value="@{wismod}">Wis</option>
|
|
<option value="@{intmod}">Int</option>
|
|
<option value="@{chamod}">Cha</option>
|
|
</select><br>
|
|
Caster Level: <input title="@{cl}" type="number" name="attr_cl" readonly/>
|
|
Spell Penetration Bonus:<input title="@{spellpenetrationbonus}" type="number" name="attr_spellpenetrationbonus" value="0">
|
|
Spell Proficiency: <input title="@{SpellProf}" type="number" name="attr_SpellProf" readonly/><br>
|
|
Close Range: <input title="@{CloseRange}" type="number" name="attr_CloseRange" readonly/>
|
|
Medium Range: <input title="@{MediumRange}" type="number" name="attr_MediumRange" readonly/>
|
|
Long: <input title="@{LongRange}" type="number" name="attr_LongRange" readonly/>
|
|
</div>
|
|
</div>
|
|
<div class="Column1"> <!--Left Column-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell0minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell0minimize">-</button>
|
|
<span>Simplex Spells</span><br>
|
|
Per Day: <input type="text" readonly name="attr_0perday" value="∞"/>
|
|
Remaining: <input type="text" readonly name="attr_0remaining" value="∞"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-0">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell0minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell0minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Simplex
|
|
</span>
|
|
<input style="float:right; width: 40px;" type="text" readonly="true" name="attr_prepared" value="∞">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:
|
|
<span style="float: right; background: #D0D0D0">
|
|
<input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select>
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<div style="float:left"><div style="float:left">On Success:</div></div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell0minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell0minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Simplex Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell2minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell2minimize">-</button>
|
|
<span>Level 2 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_2perday"/>
|
|
Remaining: <input type="number" name="attr_2remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-2">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell2minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell2minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell2minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell2minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float:none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 2 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell4minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell4minimize">-</button>
|
|
<span>Level 4 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_4perday"/>
|
|
Remaining: <input type="number" name="attr_4remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-4">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell4minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell4minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell4minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell4minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float:none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 4 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell6minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell6minimize">-</button>
|
|
<span>Level 6 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_6perday"/>
|
|
Remaining: <input type="number" name="attr_6remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-6">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell6minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell6minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell6minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell6minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float:none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 6 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell8minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell8minimize">-</button>
|
|
<span>Level 8 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_8perday"/>
|
|
Remaining: <input type="number" name="attr_8remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-8">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell8minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell8minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell8minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell8minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 8 Spells-->
|
|
</div>
|
|
<div class="Column2"> <!--Right Column-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell1minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell1minimize">-</button>
|
|
<span>Level 1 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_1perday"/>
|
|
Remaining: <input type="number" name="attr_1remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-1">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell1minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell1minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell1minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell1minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 1 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell3minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell3minimize">-</button>
|
|
<span>Level 3 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_3perday"/>
|
|
Remaining: <input type="number" name="attr_3remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-3">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell3minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell3minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell3minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell3minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 3 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell5minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell5minimize">-</button>
|
|
<span>Level 5 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_5perday"/>
|
|
Remaining: <input type="number" name="attr_5remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-5">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell5minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell5minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell5minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell5minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 5 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell7minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell7minimize">-</button>
|
|
<span>Level 7 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_7perday"/>
|
|
Remaining: <input type="number" name="attr_7remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-7">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell7minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell7minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description">
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell7minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell7minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 7 Spells-->
|
|
<div class="Spell-Level">
|
|
<input class="sptoggle" type="hidden" name="attr_spell9minimizetoggle" value="1"/>
|
|
<div class="Spell-Level-Name"><button type="action" class="Small-Button" name="act_spell9minimize">-</button>
|
|
<span>Level 9 Spells</span><br>
|
|
Per Day: <input readonly type="number" name="attr_9perday"/>
|
|
Remaining: <input type="number" name="attr_9remaining"/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_spells-9">
|
|
<div class="minimizable-repeat-spells">
|
|
<input type="hidden" class="spells-toggle" name="attr_spell9minimizetoggle" value="1"/>
|
|
<div class="spelltitle">
|
|
<button type="action" class="Small-Button" name="act_spell9minimize">-</button>
|
|
<button style="float:right" type="roll" name="act_rollspellcard" value="@{spellcard}"></button>
|
|
<input type="text" name="attr_spellname" placeholder="<Spell Name Here>"/>
|
|
<input type="hidden" name="attr_spellcard"/><br>
|
|
<span style="float:left; color: #FFFFFF">
|
|
Known
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_known">
|
|
<span style="float:left; color: #FFFFFF">
|
|
Memorized
|
|
</span>
|
|
<input style="margin-top: 3px; float:left;" type="checkbox" name="attr_memorized">
|
|
<input style="float:right; width: 40px;" type="text" name="attr_prepared" placeholder="#">
|
|
<span style="float:right; color: #FFFFFF">
|
|
Number Prepared:
|
|
</span>
|
|
</div>
|
|
<div class="spells_description">
|
|
<div class="Details-1">
|
|
<div>School: <input type="text" name="attr_school"/></div>
|
|
<div>Casting Time: <input type="text" name="attr_castingtime"/></div>
|
|
<div>Effect: <input type="text" name="attr_effect"/></div>
|
|
<div>Saving Throw:
|
|
<select name="attr_spellsaving" value="N/A" class="spellselect">
|
|
<option value="No">None</option>
|
|
<option value="Ego">Ego</option>
|
|
<option value="Fortitude">Fortitude</option>
|
|
<option value="Reflex">Reflex</option>
|
|
<option value="Will">Will</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
Type of Spell:
|
|
<select style="font-size: 12px" name="attr_category" value="" class="spellselect">
|
|
<option value="0">Utility</option>
|
|
<option value="Healing">Healing</option>
|
|
<option value="Damage">Damage</option>
|
|
<option value="Warding">Warding</option>
|
|
</select>
|
|
</div>
|
|
<div>Harmless?<input type="checkbox" name="attr_harmless" value="; harmless"/></div>
|
|
</div>
|
|
<div class="Details-2">
|
|
<div>Components: <input type="text" name="attr_components"/></div>
|
|
<div>Range: <input type="text" name="attr_range"/></div>
|
|
<div>Duration: <input type="text" name="attr_duration"/></div>
|
|
<div>Dice Rolled:<span style="float: right; background: #D0D0D0"><input style="float:none" type="text" name="attr_dicenum" placeholder="#">
|
|
<select class="die-select" name="attr_dicetype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select></span></div>
|
|
<div>
|
|
<div style="float:left">On Success:</div>
|
|
<select name="attr_savesucces" class="spellselect">
|
|
<option value="">None</option>
|
|
<option value="; disbelief">Disbelief</option>
|
|
<option value="; half">Half</option>
|
|
<option value="; partial">Partial</option>
|
|
<option value="; negates">Negates</option>
|
|
</select>
|
|
</div>
|
|
<div>Spell Resistance?<input type="checkbox" name="attr_sr" value="1"/></div>
|
|
</div>
|
|
<div class="Description" >
|
|
<div>Description:<br><textarea name="attr_spelldescription"></textarea></div>
|
|
</div>
|
|
<div class="Advanced ggrid">
|
|
<div class="grr1 row-header"><button type="action" class="Small-Button" name="act_spell9minimizeadvanced">-</button>Advanced</div>
|
|
<input type="hidden" class="spells-advanced-toggle" name="attr_spell9minimizeadvancedtoggle" value="1"/>
|
|
<div class="grr2 ggridc">
|
|
<div class="grc1">
|
|
<div>DC Modifier:</div>
|
|
</div>
|
|
<div class="grc2">
|
|
<div><input style="float: none" type="number" class="standard-input" name="attr_spelldcmod"/></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div> <!--Level 9 Spells-->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Skill-Sheet">-->
|
|
<div class="sheet-skills">
|
|
<div class="SkillsPage">
|
|
<table>
|
|
<tr>
|
|
<th colspan="9">Skills</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="titleblock_stat" colspan="4">Unspent Skill Points</td>
|
|
<td class="titleblock_stat" colspan="5">Total Skill Points</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="titleblock_stat" colspan="4">
|
|
<input title="@{RemainingSkillPoints}" type="number" name="attr_RemainingSkillPoints" readonly/>
|
|
</td>
|
|
<td class="titleblock_stat" colspan="5">
|
|
<input title="@{TotalPossibleSkillPoints}" type="number" name="attr_TotalPossibleSkillPoints" readonly/>
|
|
</td>
|
|
</tr>
|
|
<tr class="skill-desc">
|
|
<td>Trained?</td>
|
|
<td>Skill Name</td>
|
|
<td>Use Untrained?</td>
|
|
<td>Key</td>
|
|
<td>Roll</td>
|
|
<td>Total</td>
|
|
<td>Attribute</td>
|
|
<td>Skill Points</td>
|
|
<td>Misc.</td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Acrobatics Trained}" type="checkbox" name="attr_AcrobaticsTrained"/></td>
|
|
<td>Acrobatics*</td>
|
|
<td>Yes</td>
|
|
<td>Str<input type="hidden" name="attr_KeyStr"/></td>
|
|
<td><button class="button"
|
|
title="Acrobatics"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Acrobatics}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{AcrobaticsTotal}]]}}"
|
|
name="roll_Acrobatics-check"></button></td>
|
|
<td><input title="@{AcrobaticsTotal}" type="number" readonly name="attr_AcrobaticsTotal"/></td>
|
|
<td><input title="@{strmod}" type="number" readonly name="attr_strmod"/></td>
|
|
<td><input title="@{AcrobaticsSP}" type="number" name="attr_AcrobaticsSP"/></td>
|
|
<td><input title="@{AcrobaticsMisc}" type="number" name="attr_AcrobaticsMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{BalanceTrained}" type="checkbox" name="attr_BalanceTrained"/></td>
|
|
<td>Balance</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="Balance"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Balance}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{BalanceTotal}]]}}"
|
|
name="roll_Balance-check"></button></td>
|
|
<td><input title="@{BalanceTotal}" type="number" readonly name="attr_BalanceTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{BalanceSP}" type="number" name="attr_BalanceSP"/></td>
|
|
<td><input title="@{BalanceMisc}" type="number" name="attr_BalanceMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{BeguileTrained}" type="checkbox" name="attr_BeguileTrained"/></td>
|
|
<td>Beguile</td>
|
|
<td>Yes</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Beguile"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Beguile}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{BeguileTotal}]]}}"
|
|
name="roll_Beguile-check"></button></td>
|
|
<td><input title="@{BeguileTotal}" type="number" readonly name="attr_BeguileTotal"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{BeguileSP}" type="number" name="attr_BeguileSP"/></td>
|
|
<td><input title="@{BeguileMisc}" type="number" name="attr_BeguileMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{BushcraftTrained}" type="checkbox" name="attr_BushcraftTrained"/></td>
|
|
<td>Bushcraft</td>
|
|
<td>No</td>
|
|
<td>Wis<input type="hidden" name="attr_KeyWis"/></td>
|
|
<td><button class="button"
|
|
title="Bushcraft"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Bushcraft}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{BushcraftTotal}]]}}"
|
|
name="roll_Bushcraft-check"></button></td>
|
|
<td><input title="@{BushcraftTotal}" type="number" readonly name="attr_BushcraftTotal"/></td>
|
|
<td><input title="@{wismod}" type="number" readonly name="attr_wismod"/></td>
|
|
<td><input title="@{BushcraftSP}" type="number" name="attr_BushcraftSP"/></td>
|
|
<td><input title="@{BushcraftMisc}" type="number" name="attr_BushcraftMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{ConcealTrained}" type="checkbox" name="attr_ConcealTrained"/></td>
|
|
<td>Conceal</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="Conceal"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Conceal}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{ConcealTotal}]]}}"
|
|
name="roll_Conceal-check"></button></td>
|
|
<td><input title="@{ConcealTotal}" type="number" readonly name="attr_ConcealTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{ConcealSP}" type="number" name="attr_ConcealSP"/></td>
|
|
<td><input title="@{ConcealMisc}" type="number" name="attr_ConcealMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{ConcentrationTrained}" type="checkbox" name="attr_ConcentrationTrained"/></td>
|
|
<td>Concentration</td>
|
|
<td>Yes</td>
|
|
<td>Con<input type="hidden" name="attr_KeyCon"/></td>
|
|
<td><button class="button"
|
|
title="Concentration"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Concentration}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{ConcentrationTotal}]]}}"
|
|
name="roll_Concentration-check"></button></td>
|
|
<td><input title="@{ConcentrationTotal}" type="number" readonly name="attr_ConcentrationTotal"/></td>
|
|
<td><input title="@{conmod}" type="number" readonly name="attr_conmod"/></td>
|
|
<td><input title="@{ConcentrationSP}" type="number" name="attr_ConcentrationSP"/></td>
|
|
<td><input title="@{ConcentrationMisc}" type="number" name="attr_ConcentrationMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{CounterfeitTrained}" type="checkbox" name="attr_CounterfeitTrained"/></td>
|
|
<td>Counterfeit</td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Counterfeit"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Counterfeit}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{CounterfeitTotal}]]}}"
|
|
name="roll_Counterfeit-check"></button></td>
|
|
<td><input title="@{CounterfeitTotal}" type="number" readonly name="attr_CounterfeitTotal"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{CounterfeitSP}" type="number" name="attr_CounterfeitSP"/></td>
|
|
<td><input title="@{CounterfeitMisc}" type="number" name="attr_CounterfeitMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Craft1Trained}" type="checkbox" name="attr_Craft1Trained"/></td>
|
|
<td>Craft: <input title="@{Craft1Name}" type="text" name="attr_Craft1Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Craft1"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Craft: @{Craft1Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Craft1Total}]]}}"
|
|
name="roll_Craft1-check"></button></td>
|
|
<td><input title="@{Craft1Total}" type="number" readonly name="attr_Craft1Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Craft1SP}" type="number" name="attr_Craft1SP"/></td>
|
|
<td><input title="@{Craft1Misc}" type="number" name="attr_Craft1Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Craft2Trained}" type="checkbox" name="attr_Craft2Trained"/></td>
|
|
<td>Craft: <input title="@{Craft2Name}" type="text" name="attr_Craft2Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Craft2"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Craft: @{Craft2Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Craft2Total}]]}}"
|
|
name="roll_Craft2-check"></button></td>
|
|
<td><input title="@{Craft2Total}" type="number" readonly name="attr_Craft2Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Craft2SP}" type="number" name="attr_Craft2SP"/></td>
|
|
<td><input title="@{Craft2Misc}" type="number" name="attr_Craft2Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Craft3Trained}" type="checkbox" name="attr_Craft3Trained"/></td>
|
|
<td>Craft: <input title="@{Craft3Name}" type="text" name="attr_Craft3Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Craft3"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Craft: @{Craft3Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Craft3Total}]]}}"
|
|
name="roll_Craft3-check"></button></td>
|
|
<td><input title="@{Craft3Total}" type="number" readonly name="attr_Craft3Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Craft3SP}" type="number" name="attr_Craft3SP"/></td>
|
|
<td><input title="@{Craft3Misc}" type="number" name="attr_Craft3Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{DiscernIntentTrained}" type="checkbox" name="attr_DiscernIntentTrained"/></td>
|
|
<td>Discern Intent</td>
|
|
<td>Yes</td>
|
|
<td>Wis<input type="hidden" name="attr_KeyWis"/></td>
|
|
<td><button class="button"
|
|
title="DiscernIntent"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Discern Intent}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{DiscernIntentTotal}]]}}"
|
|
name="roll_DiscernIntent-check"></button></td>
|
|
<td><input title="@{DiscernIntentTotal}" type="number" readonly name="attr_DiscernIntentTotal"/></td>
|
|
<td><input title="@{wismod}" type="number" readonly name="attr_wismod"/></td>
|
|
<td><input title="@{DiscernIntentSP}" type="number" name="attr_DiscernIntentSP"/></td>
|
|
<td><input title="@{DiscernIntentMisc}" type="number" name="attr_DiscernIntentMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{DiplomacyTrained}" type="checkbox" name="attr_DiplomacyTrained"/></td>
|
|
<td>Diplomacy</td>
|
|
<td>Yes</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Diplomacy"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Diplomacy}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{DiplomacyTotal}]]}}"
|
|
name="roll_Diplomacy-check"></button></td>
|
|
<td><input title="@{DiplomacyTotal}" type="number" readonly name="attr_DiplomacyTotal"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{DiplomacySP}" type="number" name="attr_DiplomacySP"/></td>
|
|
<td><input title="@{DiplomacyMisc}" type="number" name="attr_DiplomacyMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{DisguiseTrained}" type="checkbox" name="attr_DisguiseTrained"/></td>
|
|
<td>Disguise</td>
|
|
<td>Yes</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Disguise"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Disguise}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{DisguiseTotal}]]}}"
|
|
name="roll_Disguise-check"></button></td>
|
|
<td><input title="@{DisguiseTotal}" type="number" readonly name="attr_DisguiseTotal"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{DisguiseSP}" type="number" name="attr_DisguiseSP"/></td>
|
|
<td><input title="@{DisguiseMisc}" type="number" name="attr_DisguiseMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{EscapeArtistTrained}" type="checkbox" name="attr_EscapeArtistTrained"/></td>
|
|
<td>Escape Artist</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="Escape Artist"
|
|
type="roll"
|
|
value="&{template:custom}{{title=EscapeArtist}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{EscapeArtistTotal}]]}}"
|
|
name="roll_EscapeArtist-check"></button></td>
|
|
<td><input title="@{EscapeArtistTotal}" type="number" readonly name="attr_EscapeArtistTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{EscapeArtistSP}" type="number" name="attr_EscapeArtistSP"/></td>
|
|
<td><input title="@{EscapeArtistMisc}" type="number" name="attr_EscapeArtistMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{GatherInformationTrained}" type="checkbox" name="attr_GatherInformationTrained"/></td>
|
|
<td>Gather Information</td>
|
|
<td>Yes</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Gather Information"
|
|
type="roll"
|
|
value="&{template:custom}{{title=GatherInformation}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{GatherInformationTotal}]]}}"
|
|
name="roll_GatherInformation-check"></button></td>
|
|
<td><input title="@{GatherInformationTotal}" type="number" readonly name="attr_GatherInformationTotal"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{GatherInformationSP}" type="number" name="attr_GatherInformationSP"/></td>
|
|
<td><input title="@{GatherInformationMisc}" type="number" name="attr_GatherInformationMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{HaggleTrained}" type="checkbox" name="attr_HaggleTrained"/></td>
|
|
<td>Haggle</td>
|
|
<td>Yes</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Haggle"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Haggle}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{HaggleTotal}]]}}"
|
|
name="roll_Haggle-check"></button></td>
|
|
<td><input title="@{HattleTotal}" type="number" readonly name="attr_HaggleTotal"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{HaggleSP}" type="number" name="attr_HaggleSP"/></td>
|
|
<td><input title="@{HaggleMisc}" type="number" name="attr_HaggleMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{HealTrained}" type="checkbox" name="attr_HealTrained"/></td>
|
|
<td>Heal</td>
|
|
<td>No</td>
|
|
<td>Wis<input type="hidden" name="attr_KeyWis"/></td>
|
|
<td><button class="button"
|
|
title="Heal"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Heal}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{HealTotal}]]}}"
|
|
name="roll_Heal-check"></button></td>
|
|
<td><input title="@{HealTotal}" type="number" readonly name="attr_HealTotal"/></td>
|
|
<td><input title="@{wismod}" type="number" readonly name="attr_wismod"/></td>
|
|
<td><input title="@{HealSP}" type="number" name="attr_HealSP"/></td>
|
|
<td><input title="@{HealMisc}" type="number" name="attr_HealMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input type="checkbox" name="attr_IntimidateTrained"/></td>
|
|
<td>Intimidate</td>
|
|
<td>Yes</td>
|
|
<td>Cha<input title="@{KeyCha}" type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Intimidate"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Intimidate}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{IntimidateTotal}]]}}"
|
|
name="roll_Intimidate-check"></button></td>
|
|
<td><input title="@{IntimidateTotal}" type="number" readonly name="attr_IntimidateTotal"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{IntimidateSP}" type="number" name="attr_IntimidateSP"/></td>
|
|
<td><input title="@{IntimidateMisc}" type="number" name="attr_IntimidateMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{InvestigateTrained}" type="checkbox" name="attr_InvestigateTrained"/></td>
|
|
<td>Investigate</td>
|
|
<td>Yes</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Investigate"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Investigate}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{InvestigateTotal}]]}}"
|
|
name="roll_Investigate-check"></button></td>
|
|
<td><input title="@{InvestigateTotal}" type="number" readonly name="attr_InvestigateTotal"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{InvestigateSP}" type="number" name="attr_InvestigateSP"/></td>
|
|
<td><input title="@{InvestigateMisc}" type="number" name="attr_InvestigateMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Knowledge1Trained}" type="checkbox" name="attr_Knowledge1Trained"/></td>
|
|
<td>Knowledge <input title="@{Knowledge1Name}" type="text" name="attr_Knowledge1Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Knowledge1"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Knowledge: @{Knowledge1Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Knowledge1Total}]]}}"
|
|
name="roll_Knowledge1-check"></button></td>
|
|
<td><input title="@{Knowledge1Total}" type="number" readonly name="attr_Knowledge1Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Knowledge1SP}" type="number" name="attr_Knowledge1SP"/></td>
|
|
<td><input title="@{Knowledge1Misc}" type="number" name="attr_Knowledge1Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Knowledge2Trained}" type="checkbox" name="attr_Knowledge2Trained"/></td>
|
|
<td>Knowledge <input title="@{Knowledge2Name}" type="text" name="attr_Knowledge2Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Knowledge2"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Knowledge: @{Knowledge2Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Knowledge2Total}]]}}"
|
|
name="roll_Knowledge2-check"></button></td>
|
|
<td><input title="@{Knowledge2Total}" type="number" readonly name="attr_Knowledge2Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Knowledge2SP}" type="number" name="attr_Knowledge2SP"/></td>
|
|
<td><input title="@{Knowledge2Misc}" type="number" name="attr_Knowledge2Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Knowledge3Trained}" type="checkbox" name="attr_Knowledge3Trained"/></td>
|
|
<td>Knowledge <input title="@{Knowledge3Name}" type="text" name="attr_Knowledge3Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Knowledge3"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Knowledge: @{Knowledge3Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Knowledge3Total}]]}}"
|
|
name="roll_Knowledge3-check"></button></td>
|
|
<td><input title="@{Knowledge3Total}" type="number" readonly name="attr_Knowledge3Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Knowledge3SP}" type="number" name="attr_Knowledge3SP"/></td>
|
|
<td><input title="@{Knowledge3Misc}" type="number" name="attr_Knowledge3Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Knowledge4Trained}" type="checkbox" name="attr_Knowledge4Trained"/></td>
|
|
<td>Knowledge <input title="@{Knowledge4Name}" type="text" name="attr_Knowledge4Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Knowledge4"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Knowledge: @{Knowledge4Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Knowledge4Total}]]}}"
|
|
name="roll_Knowledge4-check"></button></td>
|
|
<td><input title="@{Knowledge4Total}" type="number" readonly name="attr_Knowledge4Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Knowledge4SP}" type="number" name="attr_Knowledge4SP"/></td>
|
|
<td><input title="@{Knowledge4Misc}" type="number" name="attr_Knowledge4Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Knowledge5Trained}" type="checkbox" name="attr_Knowledge5Trained"/></td>
|
|
<td>Knowledge <input title="@{Knowledge5Name}" type="text" name="attr_Knowledge5Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Knowledge5"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Knowledge: @{Knowledge5Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Knowledge5Total}]]}}"
|
|
name="roll_Knowledge5-check"></button></td>
|
|
<td><input title="@{Knowledge5Total}" type="number" readonly name="attr_Knowledge5Total"/></td>
|
|
<td><input title="@{int}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Knowledge5SP}" type="number" name="attr_Knowledge5SP"/></td>
|
|
<td><input title="@{Knowledge5Misc}" type="number" name="attr_Knowledge5Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Knowledge6Trained}" type="checkbox" name="attr_Knowledge6Trained"/></td>
|
|
<td>Knowledge <input title="@{Knowledge6Name}" type="text" name="attr_Knowledge6Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Knowledge6"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Knowledge: @{Knowledge6Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Knowledge6Total}]]}}"
|
|
name="roll_Knowledge6-check"></button></td>
|
|
<td><input title="@{Knowledge6Total}" type="number" readonly name="attr_Knowledge6Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Knowledge6SP}" type="number" name="attr_Knowledge6SP"/></td>
|
|
<td><input title="@{Knowledge6Misc}" type="number" name="attr_Knowledge6Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{ListenTrained}" type="checkbox" name="attr_ListenTrained"/></td>
|
|
<td>Listen</td>
|
|
<td>Yes</td>
|
|
<td>Wis<input type="hidden" name="attr_KeyWis"/></td>
|
|
<td><button class="button"
|
|
title="Listen"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Listen}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{ListenTotal}]]}}"
|
|
name="roll_Listen-check"></button></td>
|
|
<td><input title="@{ListenTotal}" type="number" readonly name="attr_ListenTotal"/></td>
|
|
<td><input title="@{wismod}" type="number" readonly name="attr_wismod"/></td>
|
|
<td><input title="@{ListenSP}" type="number" name="attr_ListenSP"/></td>
|
|
<td><input title="@{ListenMisc}" type="number" name="attr_ListenMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{LockpickingTrained}" type="checkbox" name="attr_LockpickingTrained"/></td>
|
|
<td>Lockpicking</td>
|
|
<td>No</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="Lockpicking"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Lockpicking}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{LockpickingTotal}]]}}"
|
|
name="roll_Lockpicking-check"></button></td>
|
|
<td><input title="@{LockpickingTotal}" type="number" readonly name="attr_LockpickingTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{LockpickingSP}" type="number" name="attr_LockpickingSP"/></td>
|
|
<td><input title="@{LockpickingMisc}" type="number" name="attr_LockpickingMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{MoveSilentlyTrained}" type="checkbox" name="attr_MoveSilentlyTrained"/></td>
|
|
<td>Move Silently*</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="MoveSilently"
|
|
type="roll"
|
|
value="&{template:custom}{{title=MoveSilently}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{MoveSilentlyTotal}]]}}"
|
|
name="roll_MoveSilently-check"></button></td>
|
|
<td><input title="@{MoveSilentlyTotal}" type="number" readonly name="attr_MoveSilentlyTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{MoveSilentlySP}" type="number" name="attr_MoveSilentlySP"/></td>
|
|
<td><input title="@{MoveSilentlyMisc}" type="number" name="attr_MoveSilentlyMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Perform1Trained}" type="checkbox" name="attr_Perform1Trained"/></td>
|
|
<td>Perform <input title="@{Perform1Name}" type="text" name="attr_Perform1Name"/></td>
|
|
<td>No</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Perform1"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Perform: @{Perform1Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Perform1Total}]]}}"
|
|
name="roll_Perform1-check"></button></td>
|
|
<td><input title="@{Perform1Total}" type="number" readonly name="attr_Perform1Total"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{Perform1SP}" type="number" name="attr_Perform1SP"/></td>
|
|
<td><input title="@{Perform1Misc}" type="number" name="attr_Perform1Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Perform2Trained}" type="checkbox" name="attr_Perform2Trained"/></td>
|
|
<td>Perform <input title="@{Perform2Name}" type="text" name="attr_Perform2Name"/></td>
|
|
<td>No</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Perform2"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Perform: @{Perform2Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Perform2Total}]]}}"
|
|
name="roll_Perform2-check"></button></td>
|
|
<td><input title="@{Perform2Total}" type="number" readonly name="attr_Perform2Total"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{Perform2SP}" type="number" name="attr_Perform2SP"/></td>
|
|
<td><input title="@{Perform2Misc}" type="number" name="attr_Perform2Misc"/></td>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Perform3Trained}" type="checkbox" name="attr_Perform3Trained"/></td>
|
|
<td>Perform <input title="@{Perform3Name}" type="text" name="attr_Perform3Name"/></td>
|
|
<td>No</td>
|
|
<td>Cha<input type="hidden" name="attr_KeyCha"/></td>
|
|
<td><button class="button"
|
|
title="Perform3"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Perform: @{Perform3Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Perform3Total}]]}}"
|
|
name="roll_Perform3-check"></button></td>
|
|
<td><input title="@{Perform3Total}" type="number" readonly name="attr_Perform3Total"/></td>
|
|
<td><input title="@{chamod}" type="number" readonly name="attr_chamod"/></td>
|
|
<td><input title="@{Perform3SP}" type="number" name="attr_Perform3SP"/></td>
|
|
<td><input title="@{Perform3Misc}" type="number" name="attr_Perform3Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Profession1Trained}" type="checkbox" name="attr_Profession1Trained"/></td>
|
|
<td>Profession <input title="@{Profession1Name}" type="text" name="attr_Profession1Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Profession1"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Profession: @{Profession1Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Profession1Total}]]}}"
|
|
name="roll_Profession1-check"></button></td>
|
|
<td><input title="@{Profession1Total}" type="number" readonly name="attr_Profession1Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Profession1SP}" type="number" name="attr_Profession1SP"/></td>
|
|
<td><input title="@{Profession1Misc}" type="number" name="attr_Profession1Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{Profession2Trained}" type="checkbox" name="attr_Profession2Trained"/></td>
|
|
<td>Profession <input title="@{Profession2Name}" type="text" name="attr_Profession2Name"/></td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="Profession2"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Profession: @{Profession2Name}}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{Profession2Total}]]}}"
|
|
name="roll_Profession2-check"></button></td>
|
|
<td><input title="@{Profession2Total}" type="number" readonly name="attr_Profession2Total"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{Profession2SP}" type="number" name="attr_Profession2SP"/></td>
|
|
<td><input title="@{Profession2Misc}" type="number" name="attr_Profession2Misc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{RideTrained}" type="checkbox" name="attr_RideTrained"/></td>
|
|
<td>Ride*</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="Ride"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Ride}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{RideTotal}]]}}"
|
|
name="roll_Ride-check"></button></td>
|
|
<td><input title="@{RideTotal}" type="number" readonly name="attr_RideTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{RideSP}" type="number" name="attr_RideSP"/></td>
|
|
<td><input title="@{RideMisc}" type="number" name="attr_RideMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{SleightOfHandTrained}" type="checkbox" name="attr_SleightOfHandTrained"/></td>
|
|
<td>Sleight Of Hand</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="SleightOfHand"
|
|
type="roll"
|
|
value="&{template:custom}{{title=SleightOfHand}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{SleightOfHandTotal}]]}}"
|
|
name="roll_SleightOfHand-check"></button></td>
|
|
<td><input title="@{SleightOfHandTotal}" type="number" readonly name="attr_SleightOfHandTotal"/></td>
|
|
<td><input title="@{dexmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{SleightOfHandSP}" type="number" name="attr_SleightOfHandSP"/></td>
|
|
<td><input title="@{SleightOfHandMisc}" type="number" name="attr_SleightOfHandMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{SpotTrained}" type="checkbox" name="attr_SpotTrained"/></td>
|
|
<td>Spot</td>
|
|
<td>Yes</td>
|
|
<td>Wis<input type="hidden" name="attr_KeyWis"/></td>
|
|
<td><button class="button"
|
|
title="Spot"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Spot}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{SpotTotal}]]}}"
|
|
name="roll_Spot-check"></button></td>
|
|
<td><input title="@{SpotTotal}" type="number" readonly name="attr_SpotTotal"/></td>
|
|
<td><input title="@{wismod}" type="number" readonly name="attr_wismod"/></td>
|
|
<td><input title="@{SpotSP}" type="number" name="attr_SpotSP"/></td>
|
|
<td><input title="@{SpotMisc}" type="number" name="attr_SpotMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{SabotageDeviceTrained}" type="checkbox" name="attr_SabotageDeviceTrained"/></td>
|
|
<td>SabotageDevice</td>
|
|
<td>No</td>
|
|
<td>Int<input type="hidden" name="attr_KeyInt"/></td>
|
|
<td><button class="button"
|
|
title="SabotageDevice"
|
|
type="roll"
|
|
value="&{template:custom}{{title=SabotageDevice}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{SabotageDeviceTotal}]]}}"
|
|
name="roll_SabotageDevice-check"></button></td>
|
|
<td><input title="@{SabotageDeviceTotal}" type="number" readonly name="attr_SabotageDeviceTotal"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_intmod"/></td>
|
|
<td><input title="@{SabotageDeviceSP}" type="number" name="attr_SabotageDeviceSP"/></td>
|
|
<td><input title="@{SabotageDeviceMisc}" type="number" name="attr_SabotageDeviceMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{SwinTrained}" type="checkbox" name="attr_SwimTrained"/></td>
|
|
<td>Swim*</td>
|
|
<td>Yes</td>
|
|
<td>Str<input type="hidden" name="attr_KeyStr"/></td>
|
|
<td><button class="button"
|
|
title="Swim"
|
|
type="roll"
|
|
value="&{template:custom}{{title=Swim}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{SwimTotal}]]}}"
|
|
name="roll_Swim-check"></button></td>
|
|
<td><input title="@{SwimTotal}" type="number" readonly name="attr_SwimTotal"/></td>
|
|
<td><input title="@{strmod}" type="number" readonly name="attr_strmod"/></td>
|
|
<td><input title="@{SwimSP}" type="number" name="attr_SwimSP"/></td>
|
|
<td><input title="@{SwimMisc}" type="number" name="attr_SwimMisc"/></td>
|
|
</tr>
|
|
<tr class="hoverskill">
|
|
<td><input title="@{UseRopeTrained}" type="checkbox" name="attr_UseRopeTrained"/></td>
|
|
<td>Use Rope</td>
|
|
<td>Yes</td>
|
|
<td>Dex<input type="hidden" name="attr_KeyDex"/></td>
|
|
<td><button class="button"
|
|
title="UseRope"
|
|
type="roll"
|
|
value="&{template:custom}{{title=UseRope}}{{subtitle=@{character_name}}}{{Result:= [[1d20+@{UseRopeTotal}]]}}"
|
|
name="roll_UseRope-check"></button></td>
|
|
<td><input title="@{UseRopeTotal}" type="number" readonly name="attr_UseRopeTotal"/></td>
|
|
<td><input title="@{intmod}" type="number" readonly name="attr_dexmod"/></td>
|
|
<td><input title="@{UseRopeSP}" type="number" name="attr_UseRopeSP"/></td>
|
|
<td><input title="@{UseRopeMisc}" type="number" name="attr_UseRopeMisc"/></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!--</editor-fold>-->
|
|
|
|
<!-- <editor-fold desc="Weapons/Armor Tab"-->
|
|
|
|
<div class="sheet-gear">
|
|
<div class="grr1 row-header">Armor/Weapons</div>
|
|
<div class="grr2 row-header-dark">Armor, Shield, and Focus</div>
|
|
<div class="grr3 ggrid">
|
|
<div class="grc1">Armor<br><input class="flex-bordered-input" type="text" name="attr_ArmorName"/></div>
|
|
<div class="grc2">Shatter Resistance<br><input type="number" name="attr_ArmorSR"/></div>
|
|
<div class="grc3">Hit Points<br><input type="number" name="attr_ArmorHP"/></div>
|
|
<div class="grc4">Armor Bonus<br><input type="number" name="attr_ArmorBonus"/></div>
|
|
<div class="grc5">AC Dex Limit<br><input type="number" name="attr_DexACLimit"/></div>
|
|
<div class="grc6">Skill Penalty<br><input type="number" name="attr_CheckPen"/></div>
|
|
</div> <!--Armor-->
|
|
<div class ="grr4 ggrid">
|
|
<div class="grc1">Shield<br><input class="flex-bordered-input" type="text" name="attr_ShieldName"/></div>
|
|
<div class="grc2">Shatter Resistance<br><input type="number" name="attr_ShieldSR"/></div>
|
|
<div class="grc3">Hit Points<br><input type="number" name="attr_ShieldHP"/></div>
|
|
<div class="grc4">Shield Bonus<br><input type="number" name="attr_Shield"/></div>
|
|
<div class="grc5">AC Dex Limit<br><input type="number" name="attr_ShieldDexACLimit"/></div>
|
|
<div class="grc6">Skill Penalty<br><input type="number" name="attr_ShieldCheckPen"/></div>
|
|
</div> <!--Shield-->
|
|
<div class="grr5 ggrid">
|
|
<div class="grc1">Focus<br><input class="flex-bordered-input" type="text" name="attr_FocusName"/></div>
|
|
<div class="grc2">Shatter Resistance<br><input type="number" name="attr_FocusSR"/></div>
|
|
<div class="grc3">Hit Points<br><input type="number" name="attr_FocusHP"/></div>
|
|
<div class="grc4">Enhancement<br><input value="0" type="number" name="attr_FocusEnch"/></div>
|
|
<div class="grc5">Notes<br><textarea name="attr_FocusNotes"/></div>
|
|
</div> <!--Focus-->
|
|
<div class="grr6 ggrid row-header"> <!--Weapon Title-->
|
|
Weapon(s)<br>
|
|
<span style="font-weight: normal; font-size: small">
|
|
Hasted <input title="@{haste}" type="checkbox" name="attr_haste" value="1"/> or
|
|
Slowed?<input title="@{slow}" type="checkbox" name="attr_slow" value="1"/>
|
|
</span>
|
|
</div>
|
|
<div class="grr7 ggrid"> <!--Weapon Container-->
|
|
<div class="grc1"> <!--Left Side Weapons-->
|
|
<fieldset class="repeating_weapons1">
|
|
<div class="weapon-repeat-box">
|
|
<input type="hidden" name="attr_fullattackroll"/>
|
|
<div style="margin: 0" class="column-header-dark weapon-column-span">
|
|
<button type="action" class="Small-Button" name="act_weaponminimize">-</button>
|
|
<input class="weapon-name" type="text" name="attr_weaponname" placeholder="<Weapon Name>"/>
|
|
<div class="column-header">
|
|
<span style="font-weight: normal; font-size:small">
|
|
Single Attack: <button
|
|
class="CRP_Button"
|
|
title="Single Attack"
|
|
type="action"
|
|
name="act_singleattack">t</button>
|
|
Full Attack: <button
|
|
class="CRP_Button"
|
|
title="Full Attack"
|
|
type="action"
|
|
name="act_fullattackroll">t</button>
|
|
</span>
|
|
</div>
|
|
<span style="display:none">
|
|
<button type="action" name="act_fullattackdamage"></button>
|
|
<button type="action" name="act_fullattackcritdamage"></button>
|
|
<button type="action" name="act_fullattackconfirm1"></button>
|
|
<button type="action" name="act_fullattackconfirm2"></button>
|
|
<button type="action" name="act_fullattackconfirm3"></button>
|
|
<button type="action" name="act_fullattackconfirm4"></button>
|
|
<button type="action" name="act_fullattackconfirm5"></button>
|
|
<button type="action" name="act_singleattackdamage"></button>
|
|
<button type="action" name="act_singleattackcritdamage"></button>
|
|
<button type="action" name="act_singleattackconfirm"></button>
|
|
<input type="hidden" name="attr_focus_points_used" value="1"/>
|
|
|
|
<button type="action" name="act_focusattackdamage"></button>
|
|
<button type="action" name="act_focusattackcritdamage"></button>
|
|
<button type="action" name="act_focusattackconfirm"></button>
|
|
</span>
|
|
</div>
|
|
<div class="ggrid">
|
|
<input type="hidden" class="weapon-toggle" name="attr_weaponminimizetoggle" value="0"/>
|
|
<div class="grc1 weapon-shrink">
|
|
<div>Attack Modifier:</div>
|
|
<div>Feat/Misc Attack:</div>
|
|
<div>Enhancement:</div>
|
|
<div>Critical Multiplier:</div>
|
|
<div>Critical Range:</div>
|
|
<div>Extra Critical Dice:</div>
|
|
</div>
|
|
<div class="grc2 weapon-shrink">
|
|
<div>
|
|
<select name="attr_weapontohit" value="" class="standard-select">
|
|
<option value="@{strmod}">Str</option>
|
|
<option value="@{dexmod}">Dex</option>
|
|
<option value="@{wismod}">Wis</option>
|
|
<option value="@{intmod}">Int</option>
|
|
<option value="@{chamod}">Cha</option>
|
|
</select>
|
|
</div>
|
|
<div><input class="standard-input" type="text" name="attr_bonustoattack" value="0"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_enhancetoattack" value="0"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_weaponcritmod" value=""/></div>
|
|
<div>
|
|
<input type="text" name="attr_critlow" class="small-input" value="20"/> -
|
|
<input type="number" class="small-input" value="20" readonly/>
|
|
</div>
|
|
<div><input type="text" name="attr_extraenchdicecrit" class="standard-input" value=""/></div>
|
|
</div>
|
|
<div class="grc3 weapon-shrink">
|
|
<div>Damage Modifier:</div>
|
|
<div>Damage Die:</div>
|
|
<div>Feat Damage:</div>
|
|
<div>Imbuement Dice:</div>
|
|
<div>Damage Type?</div>
|
|
<div>Two Handed?</div>
|
|
</div>
|
|
<div class="grc4 weapon-shrink">
|
|
<div>
|
|
<select name="attr_weapontodamage" value="" class="standard-select">
|
|
<option value="@{strmod}">Str</option>
|
|
<option value="@{dexmod}">Dex</option>
|
|
<option value="@{wismod}">Wis</option>
|
|
<option value="@{intmod}">Int</option>
|
|
<option value="@{chamod}">Cha</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<input type="text" name="attr_dnum" class="small-input" placeholder="#"/>
|
|
<select class="die-select" name="attr_dtype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select>
|
|
<!--<input type="text" name="attr_dtype" class="small-input" placeholder="d#"/>-->
|
|
</div>
|
|
<div><input type="text" name="attr_bonustodamage" class="standard-input" value="0"/></div>
|
|
<div><input type="text" name="attr_enchdamagedice" class="standard-input" value=""/></div>
|
|
<div><input type="text" name="attr_weapondamagtype" class="standard-input" value=""/></div>
|
|
<div><input type="checkbox" name="attr_twohanded"/></div>
|
|
</div>
|
|
</div>
|
|
<div style="margin: 0; display:none" class="column-header-dark weapon-column-span">
|
|
Damage
|
|
</div>
|
|
<div class="ggridc" style="display: none;">
|
|
<div class="grr1 ggrid">
|
|
<input type="hidden" name="attr_weapondamage"/>
|
|
<input type="hidden" name="attr_critweapondamage"/>
|
|
<div style="padding-bottom: 3px;" class="grc1 titleblock">Normal Damage: <button
|
|
type="roll"
|
|
name="roll_weapondamage"
|
|
value="@{weapondamage}"
|
|
></button></div>
|
|
<div style="padding-bottom: 3px;" class="grc2 titleblock">Critical Damage: <button
|
|
type="roll"
|
|
name="roll_critweapondamage"
|
|
value="@{critweapondamage}"
|
|
></button></div>
|
|
</div>
|
|
</div>
|
|
<div style="margin:0; border-radius: 0;display:none" class="column-header weapon-column-span">
|
|
<button type="action" class="Small-Button" name="act_critconfirmminimize">-</button>Critical Confirmation Rolls
|
|
</div>
|
|
<div class="ggridc">
|
|
<div class="grr1 ggrid">
|
|
<input type="hidden" name="attr_grandmastervalue"/>
|
|
<input type="hidden" class="critconfirm-toggle" name="attr_critconfirmminimizetoggle" value="0"/>
|
|
<div class="grc1 crit-shrink">
|
|
First Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack1"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm}}{{subtitle= Attack 1}}{{with a=[[1d20cs>@{critlow}+@{BAB}[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
<div class="grc2 crit-shrink">
|
|
Second Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack2"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm:}}{{subtitle=Attack 2}}{{with a=[[1d20cs>@{critlow}+(@{BAB}-5)[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
<div class="grc3 crit-shrink">
|
|
Third Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack3"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm:}}{{subtitle= Attack 3}}{{with a=[[1d20cs>@{critlow}+(@{BAB}-10)[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
<div class="grc4 crit-shrink">
|
|
Fourth Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack4"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm:}}{{subtitle= Attack 4}}{{with a=[[1d20cs>@{critlow}+(@{BAB}-15)[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" class="weapon-toggle" name="attr_weaponminimizetoggle" value="0"/>
|
|
<div style="margin:0; border-radius: 0" class="column-header-dark weapon-column-span weapon-shrink">
|
|
<button type="action" class="Small-Button" name="act_advancedweaponminimize">-</button>Advanced
|
|
</div> <!--Advanced Block-->
|
|
<div class="ggridc">
|
|
<input type="hidden" class="weapon-toggle" name="attr_weaponminimizetoggle" value="0"/>
|
|
<div class="grr1 ggrid weapon-shrink">
|
|
<input type="hidden" class="advancedweapon-toggle" name="attr_advancedweaponminimizetoggle" value="0"/>
|
|
<div class="advancedweapon-shrink column-header" style="grid-column: 1/5;border-radius: 0;font-size: small">Weapon Grand Master Bonus</div>
|
|
<div class="grc1 advancedweapon-shrink">
|
|
None <input type="radio" name="attr_grandmaster" value="0">
|
|
</div>
|
|
<div class="grc2 advancedweapon-shrink">
|
|
2nd<input type="radio" name="attr_grandmaster" value="2">
|
|
</div>
|
|
<div class="grc3 advancedweapon-shrink">
|
|
3rd<input type="radio" name="attr_grandmaster" value="3">
|
|
</div>
|
|
<div class="grc4 advancedweapon-shrink">
|
|
4th<input type="radio" name="attr_grandmaster" value="4">
|
|
</div>
|
|
</div>
|
|
<div class="grr2 ggrid weapon-shrink advancedAttackButton">
|
|
<input type="hidden" class="advancedweapon-toggle" name="attr_advancedweaponminimizetoggle" value="1"/>
|
|
<div class="advancedweapon-shrink column-header" style="grid-column: 1/5;border-radius: 0;font-size: small">Advanced Attacks</div>
|
|
<input type="hidden" name="attr_twintalon"/>
|
|
<div class="grc1 advancedweapon-shrink">
|
|
<button
|
|
type="roll"
|
|
name="roll_twintalon"
|
|
value="@{twintalon}">
|
|
Twin Talon
|
|
</button>
|
|
</div>
|
|
<div class="grc2 advancedweapon-shrink">
|
|
<input type="hidden" name="attr_crackshot"/>
|
|
<button
|
|
type="roll"
|
|
name="roll_crackshot"
|
|
value="@{crackshot}">
|
|
Crack Shot
|
|
</button>
|
|
</div>
|
|
<div class="grc3 advancedweapon-shrink">
|
|
<input type="hidden" name="attr_deadlyassault"/>
|
|
<button
|
|
type="roll"
|
|
name="roll_deadlyassault"
|
|
value="@{deadlyassault}">
|
|
Deadly Assault
|
|
</button>
|
|
</div>
|
|
<div class="grc4 advancedweapon-shrink">
|
|
<input type="hidden" name="attr_focusattack"/>
|
|
<button
|
|
type="action"
|
|
name="act_focusattack"
|
|
value="@{focusattack}">
|
|
Focus
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div> <!--Advanced Block Grid-->
|
|
</div>
|
|
</fieldset>
|
|
</div> <!--Left Side Weapons-->
|
|
<div class="grc2"> <!--Right Side Weapons-->
|
|
<fieldset class="repeating_weapons2">
|
|
<div class="weapon-repeat-box">
|
|
<input type="hidden" name="attr_fullattackroll"/>
|
|
<div style="margin: 0" class="column-header-dark weapon-column-span">
|
|
<button type="action" class="Small-Button" name="act_weaponminimize">-</button>
|
|
<input class="weapon-name" type="text" name="attr_weaponname" placeholder="<Weapon Name>"/>
|
|
<div class="column-header">
|
|
<span style="font-weight: normal; font-size:small">
|
|
Single Attack: <button
|
|
class="CRP_Button"
|
|
title="Single Attack"
|
|
type="action"
|
|
name="act_singleattack">t</button>
|
|
Full Attack: <button
|
|
class="CRP_Button"
|
|
title="Full Attack"
|
|
type="action"
|
|
name="act_fullattackroll">t</button>
|
|
</span>
|
|
</div>
|
|
<span style="display:none">
|
|
<button type="action" name="act_fullattackdamage"></button>
|
|
<button type="action" name="act_fullattackcritdamage"></button>
|
|
<button type="action" name="act_fullattackconfirm1"></button>
|
|
<button type="action" name="act_fullattackconfirm2"></button>
|
|
<button type="action" name="act_fullattackconfirm3"></button>
|
|
<button type="action" name="act_fullattackconfirm4"></button>
|
|
<button type="action" name="act_fullattackconfirm5"></button>
|
|
<button type="action" name="act_singleattackdamage"></button>
|
|
<button type="action" name="act_singleattackcritdamage"></button>
|
|
<button type="action" name="act_singleattackconfirm"></button>
|
|
<input type="hidden" name="attr_focus_points_used" value="1"/>
|
|
|
|
<button type="action" name="act_focusattackdamage"></button>
|
|
<button type="action" name="act_focusattackcritdamage"></button>
|
|
<button type="action" name="act_focusattackconfirm"></button>
|
|
</span>
|
|
</div>
|
|
<div class="ggrid">
|
|
<input type="hidden" class="weapon-toggle" name="attr_weaponminimizetoggle" value="0"/>
|
|
<div class="grc1 weapon-shrink">
|
|
<div>Attack Modifier:</div>
|
|
<div>Feat/Misc Attack:</div>
|
|
<div>Enhancement:</div>
|
|
<div>Critical Multiplier:</div>
|
|
<div>Critical Range:</div>
|
|
<div>Extra Critical Dice:</div>
|
|
</div>
|
|
<div class="grc2 weapon-shrink">
|
|
<div>
|
|
<select name="attr_weapontohit" value="" class="standard-select">
|
|
<option value="@{strmod}">Str</option>
|
|
<option value="@{dexmod}">Dex</option>
|
|
<option value="@{wismod}">Wis</option>
|
|
<option value="@{intmod}">Int</option>
|
|
<option value="@{chamod}">Cha</option>
|
|
</select>
|
|
</div>
|
|
<div><input class="standard-input" type="text" name="attr_bonustoattack" value="0"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_enhancetoattack" value="0"/></div>
|
|
<div><input class="standard-input" type="text" name="attr_weaponcritmod" value="0"/></div>
|
|
<div>
|
|
<input type="text" name="attr_critlow" class="small-input" value="20"/> -
|
|
<input type="number" class="small-input" value="20" readonly/>
|
|
</div>
|
|
<div><input type="text" name="attr_extraenchdicecrit" class="standard-input" value=""/></div>
|
|
</div>
|
|
<div class="grc3 weapon-shrink">
|
|
<div>Damage Modifier:</div>
|
|
<div>Damage Die:</div>
|
|
<div>Feat Damage:</div>
|
|
<div>Imbuement Dice:</div>
|
|
<div>Damage Type?</div>
|
|
<div>Two Handed?</div>
|
|
</div>
|
|
<div class="grc4 weapon-shrink">
|
|
<div>
|
|
<select name="attr_weapontodamage" value="" class="standard-select">
|
|
<option value="@{strmod}">Str</option>
|
|
<option value="@{dexmod}">Dex</option>
|
|
<option value="@{wismod}">Wis</option>
|
|
<option value="@{intmod}">Int</option>
|
|
<option value="@{chamod}">Cha</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<input type="text" name="attr_dnum" class="small-input" placeholder="#"/>
|
|
<select class="die-select" name="attr_dtype">
|
|
<option value="d3">d3</option>
|
|
<option value="d4">d4</option>
|
|
<option value="d6">d6</option>
|
|
<option value="d8">d8</option>
|
|
<option value="d10">d10</option>
|
|
<option value="d12">d12</option>
|
|
</select>
|
|
</div>
|
|
<div><input type="text" name="attr_bonustodamage" class="standard-input" value="0"/></div>
|
|
<div><input type="text" name="attr_enchdamagedice" class="standard-input" value=""/></div>
|
|
<div><input type="text" name="attr_weapondamagtype" class="standard-input" value=""/></div>
|
|
<div><input type="checkbox" name="attr_twohanded" value=".5"/></div>
|
|
</div>
|
|
</div>
|
|
<div style="margin: 0; display:none" class="column-header-dark weapon-column-span">
|
|
Damage
|
|
</div>
|
|
<div class="ggridc" style="display: none">
|
|
<div class="grr1 ggrid">
|
|
<input type="hidden" name="attr_weapondamage"/>
|
|
<input type="hidden" name="attr_critweapondamage"/>
|
|
<div style="padding-bottom: 3px;" class="grc1 titleblock">Normal Damage: <button
|
|
type="roll"
|
|
name="roll_weapondamage"
|
|
value="@{weapondamage}"
|
|
></button></div>
|
|
<div style="padding-bottom: 3px;" class="grc2 titleblock">Critical Damage: <button
|
|
type="roll"
|
|
name="roll_critweapondamage"
|
|
value="@{critweapondamage}"
|
|
></button></div>
|
|
</div>
|
|
</div>
|
|
<div style="margin:0;border-radius: 0; display:none" class="column-header weapon-column-span">
|
|
<button type="action" class="Small-Button" name="act_critconfirmminimize">-</button>Critical Confirmation Rolls
|
|
</div>
|
|
<div class="ggridc">
|
|
<div class="grr1 ggrid">
|
|
<input type="hidden" class="critconfirm-toggle" name="attr_critconfirmminimizetoggle" value="0"/>
|
|
<div class="grc1 crit-shrink">
|
|
First Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack1"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm}}{{subtitle= Attack 1}}{{with a=[[1d20cs>@{critlow}+@{BAB}[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
<div class="grc2 crit-shrink">
|
|
Second Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack2"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm:}}{{subtitle=Attack 2}}{{with a=[[1d20cs>@{critlow}+(@{BAB}-5)[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
<div class="grc3 crit-shrink">
|
|
Third Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack3"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm:}}{{subtitle= Attack 3}}{{with a=[[1d20cs>@{critlow}+(@{BAB}-10)[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
<div class="grc4 crit-shrink">
|
|
Fourth Attack:
|
|
<button
|
|
type="roll"
|
|
name="roll_attack4"
|
|
value=
|
|
"
|
|
&{template:custom}{{title=Critical Confirm:}}{{subtitle= Attack 4}}{{with a=[[1d20cs>@{critlow}+(@{BAB}-15)[Base Attack]+@{weapontohit}[Key Ability]+@{bonustoattack}[Feats]+@{enhancetoattack}[Enhancement]+(0?{Do you have miscellaneous attack bonus?|0})]] to hit.}}
|
|
"
|
|
></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" class="weapon-toggle" name="attr_weaponminimizetoggle" value="0"/>
|
|
<div style="margin:0; border-radius: 0" class="column-header-dark weapon-column-span weapon-shrink">
|
|
<button type="action" class="Small-Button" name="act_advancedweaponminimize">-</button>Advanced
|
|
</div> <!--Advanced Block-->
|
|
<div class="ggridc">
|
|
<input type="hidden" class="weapon-toggle" name="attr_weaponminimizetoggle" value="0"/>
|
|
<div class="grr1 ggrid weapon-shrink">
|
|
<input type="hidden" class="advancedweapon-toggle" name="attr_advancedweaponminimizetoggle" value="0"/>
|
|
<div class="advancedweapon-shrink column-header" style="grid-column: 1/5;border-radius: 0;font-size: small">Weapon Grand Master Bonus</div>
|
|
<div class="grc1 advancedweapon-shrink">
|
|
None <input type="radio" name="attr_grandmaster" value="0">
|
|
</div>
|
|
<div class="grc2 advancedweapon-shrink">
|
|
2nd<input type="radio" name="attr_grandmaster" value="2">
|
|
</div>
|
|
<div class="grc3 advancedweapon-shrink">
|
|
3rd<input type="radio" name="attr_grandmaster" value="3">
|
|
</div>
|
|
<div class="grc4 advancedweapon-shrink">
|
|
4th<input type="radio" name="attr_grandmaster" value="4">
|
|
</div>
|
|
</div>
|
|
<div class="grr2 ggrid weapon-shrink advancedAttackButton">
|
|
<input type="hidden" class="advancedweapon-toggle" name="attr_advancedweaponminimizetoggle" value="1"/>
|
|
<div class="advancedweapon-shrink column-header" style="grid-column: 1/5;border-radius: 0;font-size: small">Advanced Attacks</div>
|
|
<input type="hidden" name="attr_twintalon"/>
|
|
<div class="grc1 advancedweapon-shrink">
|
|
<button
|
|
type="roll"
|
|
name="roll_twintalon"
|
|
value="@{twintalon}">
|
|
Twin Talon
|
|
</button>
|
|
</div>
|
|
<div class="grc2 advancedweapon-shrink">
|
|
<input type="hidden" name="attr_crackshot"/>
|
|
<button
|
|
type="roll"
|
|
name="roll_crackshot"
|
|
value="@{crackshot}">
|
|
Crack Shot
|
|
</button>
|
|
</div>
|
|
<div class="grc3 advancedweapon-shrink">
|
|
<input type="hidden" name="attr_deadlyassault"/>
|
|
<button
|
|
type="roll"
|
|
name="roll_deadlyassault"
|
|
value="@{deadlyassault}">
|
|
Deadly Assault
|
|
</button>
|
|
</div>
|
|
<div class="grc4 advancedweapon-shrink">
|
|
<input type="hidden" name="attr_focusattack"/>
|
|
<button
|
|
type="action"
|
|
name="act_focusattack"
|
|
value="@{focusattack}">
|
|
Focus
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div> <!--Advanced Block Grid-->
|
|
</div>
|
|
</fieldset>
|
|
</div> <!--Right Side Weapons-->
|
|
</div>
|
|
</div>
|
|
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Accessories">-->
|
|
<div class="sheet-accessories">
|
|
<div class="accessories-grid">
|
|
<div class="HeaderM">
|
|
<div><h3>Accessories</h3></div>
|
|
</div>
|
|
<div class="Column1">
|
|
<div><h4>Crown</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Crown_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Hat_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Hat_Color.png"/>
|
|
<input title="@{Crown}" class="titleinput" type="text" name="attr_Crown" placeholder="(Headband, Helmet, of Phylactery)"/>
|
|
<textarea title="@{CrownDesc}" name="attr_CrownDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Face</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Face_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Face_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Face_Color.png"/>
|
|
<input title="@{Face}" type="text" name="attr_Face" placeholder="(Mask or Goggles)"/>
|
|
<textarea title="@{FaceDesc}" name="attr_FaceDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Neck</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Neck_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Neck_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Neck_Color.png"/>
|
|
<input title="@{Neck}" type="text" name="attr_Neck" placeholder="(Amulet, Brooch, Medallion, Periapt, or Scarab)"/><br>
|
|
<textarea title="@{NeckDesc}" name="attr_NeckDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Shoulders</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Shoulders_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Shoulders_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Shoulders_Color.png"/>
|
|
<input title="@{Shoulders}" type="text" name="attr_Shoulders" placeholder="(Cloak, Cape, or Mantle)"/><br>
|
|
<textarea title="@{ShoulderDesc}" name="attr_ShoulderDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Ring 1</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Ring1_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Ring1_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Ring1_Color.png"/>
|
|
<input title="@{Ring1}" type="text" name="attr_Ring1" placeholder="(Ring)"/><br>
|
|
<textarea title="@{Ring1Desc}" name="attr_Ring1Desc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Ring 2</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Ring2_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Ring2_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Ring2_Color.png"/>
|
|
<input title="@{Ring2}" type="text" name="attr_Ring2" placeholder="(Ring)"/><br>
|
|
<textarea name="attr_Ring2Desc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="Column2">
|
|
<div><h4>Hands</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Hands_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Gloves_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Gloves_Color.png"/>
|
|
<input title="@{Hands}" type="text" name="attr_Hands" placeholder="(Gloves or Gauntlets)"/><br>
|
|
<textarea title="@{HandsDesc}" name="attr_HandsDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Forearms</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Forearms_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Forearm_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Forearm_Color.png"/>
|
|
<input title="@{Forearms}" type="text" name="attr_Forearms" placeholder="(Bracers or Bracelets)"/><br>
|
|
<textarea title="@{FirearmsDesc}" name="attr_ForearmDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Upper Arms</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_UpperArms_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/UpperArm_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/UpperArm_Color.png"/>
|
|
<input title="@{UpperArms}" type="text" name="attr_UpperArms" placeholder="(Bangle or Phylactery)"/><br>
|
|
<textarea title="@{UpperArmDesc}" name="attr_UpperArmDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Torso</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Torso_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Chest_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Chest_Color.png"/>
|
|
<input title="@{Torso}" type="text" name="attr_Torso" placeholder="(Vest, Vestment, or Shirt)"/><br>
|
|
<textarea title="@{TorsoDesc}" name="attr_TorsoDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Waist</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Waist_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Belt_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Belt_Color.png"/>
|
|
<input title="@{Waist}" type="text" name="attr_Waist" placeholder="(Belt or Girdle)"/><br>
|
|
<textarea title="@{BeltDesc}" name="attr_BeltDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
<div><h4>Feet</h4>
|
|
<input class="titleinputhidden" type="hidden" name="attr_Feet_hidden" value="">
|
|
<img class="shadow" src="https://obj.ttdrpg.com/Boots_Shadow.png"/>
|
|
<img class="color" src="https://obj.ttdrpg.com/Boots_Color.png"/>
|
|
<input title="@{Feet}" type="text" name="attr_Feet" placeholder="(Boots, Shoes, or Slippers)"/><br>
|
|
<textarea title="@{FeetDesc}" name="attr_FeetDesc" placeholder="Enter details of the magical item here."></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Inventory"-->
|
|
<div class="sheet-inventory">
|
|
<div class="inventory-grid">
|
|
<div class="Header-I">
|
|
<div class="titleblock">
|
|
<h3>Inventory</h3><input style="width:104px" type="hidden" step="any" name="attr_GP"/>
|
|
</div>
|
|
<div class="titleblock_stat">
|
|
Total Carry Weight: <input title="@{totalweight}" step="any" class="standard-input" name="attr_totalweight" type="text" readonly/>
|
|
</div>
|
|
</div>
|
|
<div class="Column-I">
|
|
<div><h4>Items</h4></div>
|
|
<div class="bag-grid bags Header-I">
|
|
<div style="width: 242px" class="name ">Item Name</div>
|
|
<div style="width: 180px" class="location">Location</div>
|
|
<div style="width: 64px" class="quantity">Quantity</div>
|
|
<div style="width: 64px" class="piece-weight">Unit Weight</div>
|
|
<div style="width: 64px" class="total-weight">Total Weight</div>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_maininventory">
|
|
<div class="bag-grid bags">
|
|
<input class="inventory-location" type="hidden" value="1" name="attr_locationValidation"/>
|
|
<div class="name">
|
|
<div><textarea name="attr_main-inv-name" placeholder="Item name, description, notes etc..."/></div>
|
|
</div>
|
|
<div class="location">
|
|
<input style="width: 180px;" type="text" name="attr_inventoryLocation" placeholder="Name"
|
|
title="Location must match with bag/location name."/>
|
|
</div>
|
|
<div class="quantity">
|
|
<div><input type="number" name="attr_mainquantity"/></div>
|
|
</div>
|
|
<div class="piece-weight">
|
|
<div><input step="any" type="number" name="attr_mainpieceweight"/></div>
|
|
</div>
|
|
<div class="total-weight">
|
|
<div><input step="any" type="text" name="attr_maintotalweight" readonly/></div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div>
|
|
<div class="Header-I">Bags and Other Locations</div>
|
|
<div class="bag-grid bags" style="grid-template-columns: repeat(auto-fit, minmax(0, 1fr));font-weight: bold">
|
|
<div style="width: 1fr" class="name">Include in Carry Weight?</div>
|
|
<div style="width: 1fr" class="location">Bag/Location</div>
|
|
<div style="width: 1fr" class="quantity">Quantity</div>
|
|
<div style="width: 1fr" class="piece-weight">Bag/Location Weight</div>
|
|
</div>
|
|
<fieldset class="repeating_locationtotals">
|
|
<div class="bag-grid bags" style="grid-template-columns: repeat(auto-fit, minmax(0, 1fr));">
|
|
<div class="location">
|
|
<input style="width: 180px;" type="text" name="attr_inventoryLocationName"
|
|
placeholder="Name" title="Location name must be unique."/>
|
|
</div>
|
|
<div class="name">
|
|
<input type="checkbox" value="1" name="attr_locationOnPerson">
|
|
</div>
|
|
<div class="quantity">
|
|
<input type="text" readonly name="attr_locationItemCount"/>
|
|
</div>
|
|
<div class="piece-weight">
|
|
<input step="any" type="text" readonly name="attr_locationTotalWeight">
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Profit/Loss">-->
|
|
<div class="sheet-profitloss">
|
|
<div class="row-header">
|
|
Profit and Loss Sheet
|
|
</div>
|
|
<div class="titleblock_stat">
|
|
Total Gold:<input title="TotalGold" step="any" class="standard-input" name="attr_plTotalGold" type="text" readonly/>
|
|
</div>
|
|
<div class="sheet-repeating-fields">
|
|
<fieldset class="repeating_profitloss">
|
|
<div class="bag-grid bags">
|
|
<div class="name">
|
|
<textarea title="Memo" name="attr_plMemo" placeholder="Memo..."></textarea>
|
|
</div>
|
|
<div class="location">
|
|
Debits: <input title="Debits" step="any" type="number" name="attr_plDebits"/>
|
|
</div>
|
|
<div class="quantity">
|
|
Credits: <input title="Credits" step="any" type="number" name="attr_plCredits"/>
|
|
</div>
|
|
<div class="piece-weight">
|
|
Running Total: <input title="Running Total" type="number" name="attr_plRunningTotal" readonly/>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="row-footer">
|
|
Total Gold:<input title="TotalGold" class="standard-input" name="attr_plTotalGold" type="text" readonly/>
|
|
</div>
|
|
</div>
|
|
|
|
<!--</editor-fold>-->
|
|
|
|
<!--<editor-fold desc="Settings">-->
|
|
<div class="sheet-settings">
|
|
<div class="row-header">Settings</div>
|
|
|
|
<div class="settings-grid">
|
|
<div class="settings-left">
|
|
<div class="settings-row">
|
|
<div class="settings-label">Skill Growth Modifier:</div>
|
|
<div class="settings-value">
|
|
<input title="@{skill_growth_modifier}"
|
|
class="standard-input"
|
|
type="number"
|
|
name="attr_skill_growth_modifier"
|
|
value="0"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="settings-right">
|
|
<div class="settings-row">
|
|
<div class="settings-label">Automatic Feat/Ability Grants:</div>
|
|
<div class="settings-value">
|
|
<input title="@{enable_automatic_grants}"
|
|
type="checkbox"
|
|
name="attr_enable_automatic_grants"
|
|
value="1"/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="settings-row">
|
|
<div class="settings-label">No Constitution Score:</div>
|
|
<div class="settings-value">
|
|
<input title="@{no_constitution_score}"
|
|
type="checkbox"
|
|
name="attr_no_constitution_score"
|
|
value="1"/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="settings-row">
|
|
<div class="settings-label">No Intelligence Score:</div>
|
|
<div class="settings-value">
|
|
<input title="@{no_intelligence_score}"
|
|
type="checkbox"
|
|
name="attr_no_intelligence_score"
|
|
value="1"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--</editor-fold>-->
|
|
|
|
<!-- <editor-fold desc="Roll Template" -->
|
|
<rolltemplate class="sheet-rolltemplate-room">
|
|
<div class="sheet-room-container">
|
|
<div class="sheet-room-header">{{name}}</div>
|
|
|
|
<div class="sheet-room-row">
|
|
<span>Room Type</span>
|
|
<span>{{roomtype}}</span>
|
|
</div>
|
|
|
|
<div class="sheet-room-row">
|
|
<span>Result</span>
|
|
<span>{{computed::roomroll}}</span>
|
|
</div>
|
|
|
|
{{#notes}}
|
|
<div class="sheet-room-notes">{{notes}}</div>
|
|
{{/notes}}
|
|
</div>
|
|
</rolltemplate>
|
|
<rolltemplate class="sheet-rolltemplate-custom">
|
|
<div class="sheet-container sheet-color-{{color}}">
|
|
<div class="sheet-header">
|
|
{{#title}}
|
|
<div class="sheet-title">{{title}}</div>
|
|
{{/title}}
|
|
{{#subtitle}}
|
|
<div class="sheet-subtitle">{{subtitle}}</div>
|
|
{{/subtitle}}
|
|
</div>
|
|
<div class="sheet-content">
|
|
{{#fullattack}}
|
|
{{#attack1}}
|
|
<div class="sheet-key">{{attack1_label}}</div>
|
|
<div class="sheet-value">{{attack1}}</div>
|
|
<div class="sheet-key">Next Step</div>
|
|
<div class="sheet-value">
|
|
{{#rollTotal() computed::attack1_next 0}}[Damage](~{{characterid}}|{{attack1_damage_action}}){{/rollTotal() computed::attack1_next 0}}
|
|
{{#rollTotal() computed::attack1_next 1}}[Confirm Critical](~{{characterid}}|{{attack1_confirm_action}}){{/rollTotal() computed::attack1_next 1}}
|
|
</div>
|
|
{{/attack1}}
|
|
{{#attack2}}
|
|
<div class="sheet-key">{{attack2_label}}</div>
|
|
<div class="sheet-value">{{attack2}}</div>
|
|
<div class="sheet-key">Next Step</div>
|
|
<div class="sheet-value">
|
|
{{#rollTotal() computed::attack2_next 0}}[Damage](~{{characterid}}|{{attack2_damage_action}}){{/rollTotal() computed::attack2_next 0}}
|
|
{{#rollTotal() computed::attack2_next 1}}[Confirm Critical](~{{characterid}}|{{attack2_confirm_action}}){{/rollTotal() computed::attack2_next 1}}
|
|
</div>
|
|
{{/attack2}}
|
|
{{#attack3}}
|
|
<div class="sheet-key">{{attack3_label}}</div>
|
|
<div class="sheet-value">{{attack3}}</div>
|
|
<div class="sheet-key">Next Step</div>
|
|
<div class="sheet-value">
|
|
{{#rollTotal() computed::attack3_next 0}}[Damage](~{{characterid}}|{{attack3_damage_action}}){{/rollTotal() computed::attack3_next 0}}
|
|
{{#rollTotal() computed::attack3_next 1}}[Confirm Critical](~{{characterid}}|{{attack3_confirm_action}}){{/rollTotal() computed::attack3_next 1}}
|
|
</div>
|
|
{{/attack3}}
|
|
{{#attack4}}
|
|
<div class="sheet-key">{{attack4_label}}</div>
|
|
<div class="sheet-value">{{attack4}}</div>
|
|
<div class="sheet-key">Next Step</div>
|
|
<div class="sheet-value">
|
|
{{#rollTotal() computed::attack4_next 0}}[Damage](~{{characterid}}|{{attack4_damage_action}}){{/rollTotal() computed::attack4_next 0}}
|
|
{{#rollTotal() computed::attack4_next 1}}[Confirm Critical](~{{characterid}}|{{attack4_confirm_action}}){{/rollTotal() computed::attack4_next 1}}
|
|
</div>
|
|
{{/attack4}}
|
|
{{#attack5}}
|
|
<div class="sheet-key">{{attack5_label}}</div>
|
|
<div class="sheet-value">{{attack5}}</div>
|
|
<div class="sheet-key">Next Step</div>
|
|
<div class="sheet-value">
|
|
{{#rollTotal() computed::attack5_next 0}}[Damage](~{{characterid}}|{{attack5_damage_action}}){{/rollTotal() computed::attack5_next 0}}
|
|
{{#rollTotal() computed::attack5_next 1}}[Confirm Critical](~{{characterid}}|{{attack5_confirm_action}}){{/rollTotal() computed::attack5_next 1}}
|
|
</div>
|
|
{{/attack5}}
|
|
{{/fullattack}}
|
|
{{#fullattackconfirm}}
|
|
<div class="sheet-key">Confirmation Roll</div>
|
|
<div class="sheet-value">{{confirm}}</div>
|
|
<div class="sheet-key">Damage</div>
|
|
<div class="sheet-value">[Normal Damage](~{{characterid}}|{{confirm_normal_action}}) [Critical Damage](~{{characterid}}|{{confirm_critical_action}})</div>
|
|
{{/fullattackconfirm}}
|
|
{{#rest}}
|
|
<div class="sheet-key">Multiplier</div>
|
|
<div class="sheet-value">{{rest_multiplier}}</div>
|
|
<div class="sheet-key">HP Restored</div>
|
|
<div class="sheet-value">{{computed::rest_healing}}</div>
|
|
<div class="sheet-key">Current HP</div>
|
|
<div class="sheet-value">{{computed::rest_hp}} / {{computed::rest_hp_max}}</div>
|
|
{{/rest}}
|
|
{{#allprops() title subtitle desc color characterid fullattack fullattackconfirm rest deathsave rest_multiplier rest_summary rest_healing rest_hp rest_hp_max rest_death_save_removed attack1 attack2 attack3 attack4 attack5 attack1_label attack2_label attack3_label attack4_label attack5_label attack1_next attack2_next attack3_next attack4_next attack5_next attack1_damage_action attack2_damage_action attack3_damage_action attack4_damage_action attack5_damage_action attack1_confirm_action attack2_confirm_action attack3_confirm_action attack4_confirm_action attack5_confirm_action confirm confirm_normal_action confirm_critical_action}}
|
|
<div class="sheet-key">{{key}}</div>
|
|
<div class="sheet-value">{{value}}</div>
|
|
{{/allprops() title subtitle desc color characterid fullattack fullattackconfirm rest deathsave rest_multiplier rest_summary rest_healing rest_hp rest_hp_max rest_death_save_removed attack1 attack2 attack3 attack4 attack5 attack1_label attack2_label attack3_label attack4_label attack5_label attack1_next attack2_next attack3_next attack4_next attack5_next attack1_damage_action attack2_damage_action attack3_damage_action attack4_damage_action attack5_damage_action attack1_confirm_action attack2_confirm_action attack3_confirm_action attack4_confirm_action attack5_confirm_action confirm confirm_normal_action confirm_critical_action}}
|
|
{{#desc}}
|
|
<div class="sheet-desc">{{desc}}</div>
|
|
{{/desc}}
|
|
</div>
|
|
</div>
|
|
</rolltemplate>
|
|
<!-- </editor-fold -->
|
|
|
|
<!--<editor-fold desc="Java Script">-->
|
|
|
|
<!--type="text/worker"-->
|
|
|
|
<script>
|
|
|
|
<!--<script type="text/worker">-->
|
|
|
|
// <editor-fold desc="General Purpose Things">
|
|
|
|
var getSectionIDsOrdered = function (sectionName, callback) {
|
|
'use strict';
|
|
getAttrs([`_reporder_${sectionName}`], function (v) {
|
|
getSectionIDs(sectionName, function (idArray) {
|
|
let reporderArray = v[`_reporder_${sectionName}`] ? v[`_reporder_${sectionName}`].toLowerCase().split(',') : [],
|
|
ids = [...new Set(reporderArray.filter(x => idArray.includes(x)).concat(idArray))];
|
|
callback(ids);
|
|
});
|
|
});
|
|
};
|
|
|
|
const num = function(values, attr, fallback = 0) {
|
|
const parsed = parseFloat(values[attr]);
|
|
return isNaN(parsed) ? fallback : parsed;
|
|
};
|
|
|
|
const int = function(values, attr, fallback = 0) {
|
|
const parsed = parseInt(values[attr], 10);
|
|
return isNaN(parsed) ? fallback : parsed;
|
|
};
|
|
|
|
const str = function(values, attr, fallback = "") {
|
|
return values[attr] === undefined || values[attr] === null ? fallback : values[attr];
|
|
};
|
|
|
|
const watch = function(attrs, includeSheetOpened = true) {
|
|
const events = attrs.map(attr => `change:${attr.toLowerCase()}`);
|
|
if (includeSheetOpened) events.push("sheet:opened");
|
|
return events.join(" ");
|
|
};
|
|
|
|
const repeatingWatch = function(section, attrs) {
|
|
return attrs.map(attr => `change:${section}:${attr.toLowerCase()}`).join(" ");
|
|
};
|
|
|
|
const toggleAttr = function(attr) {
|
|
getAttrs([attr], function(values) {
|
|
setAttrs({
|
|
[attr]: 1 - int(values, attr, 0)
|
|
});
|
|
});
|
|
};
|
|
|
|
const bindToggle = function(buttonEvent, attr) {
|
|
on(`clicked:${buttonEvent}`, function() {
|
|
toggleAttr(attr);
|
|
});
|
|
};
|
|
|
|
const WeaponCol = [1, 2];
|
|
|
|
// </editor-fold>
|
|
|
|
//<editor-fold desc="Inventory Calculations">
|
|
|
|
// Main Inventory Location Total Weight
|
|
on("change:repeating_maininventory change:repeating_locationtotals remove:repeating_maininventory", function(){
|
|
getSectionIDs(`repeating_locationtotals`,function(locationArray) {
|
|
getSectionIDs(`repeating_maininventory`, function (inventoryArray) {
|
|
let AttrsToGet = [];
|
|
let attrsToSet = {};
|
|
for (let arrayID of inventoryArray) {
|
|
AttrsToGet.push(`repeating_maininventory_${arrayID}_maintotalweight`);
|
|
AttrsToGet.push(`repeating_maininventory_${arrayID}_inventoryLocation`);
|
|
AttrsToGet.push(`repeating_maininventory_${arrayID}_mainquantity`);
|
|
}
|
|
for (let arrayID of locationArray) {
|
|
AttrsToGet.push(`repeating_locationtotals_${arrayID}_inventoryLocationName`);
|
|
// setting these to zero, so we can just add any weights later
|
|
attrsToSet[`repeating_locationtotals_${arrayID}_locationTotalWeight`] = 0;
|
|
attrsToSet[`repeating_locationtotals_${arrayID}_locationItemCount`] = 0;
|
|
}
|
|
getAttrs(AttrsToGet, function (values) {
|
|
let location_names = {};
|
|
for (let arrayID of locationArray){
|
|
// The assumption is that bag names will be unique, if they're not the last one will take precedence
|
|
location_names[values[`repeating_locationtotals_${arrayID}_inventoryLocationName`].toLowerCase()] =
|
|
`repeating_locationtotals_${arrayID}`;
|
|
}
|
|
for (let arrayID of inventoryArray) {
|
|
let item_weight = parseFloat(values[`repeating_maininventory_${arrayID}_maintotalweight`]);
|
|
let item_location = values[`repeating_maininventory_${arrayID}_inventoryLocation`];
|
|
let item_quantity = parseInt(values[`repeating_maininventory_${arrayID}_mainquantity`]);
|
|
if (item_location.toLowerCase() in location_names) {
|
|
attrsToSet[location_names[item_location.toLowerCase()]+"_locationTotalWeight"] += item_weight;
|
|
attrsToSet[location_names[item_location.toLowerCase()]+"_locationItemCount"] += item_quantity;
|
|
attrsToSet[`repeating_maininventory_${arrayID}_locationValidation`] = 1;
|
|
} else {
|
|
attrsToSet[`repeating_maininventory_${arrayID}_locationValidation`] = 0;
|
|
}
|
|
}
|
|
setAttrs(attrsToSet);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
// Always make sure the character has an "On Person" location.
|
|
// This row is recreated if deleted and normalized if renamed with odd casing/spaces.
|
|
const ON_PERSON_LOCATION_SECTION = "repeating_locationtotals";
|
|
const ON_PERSON_LOCATION_NAME = "On Person";
|
|
|
|
const normalizeLocationName = function(value) {
|
|
return String(value || "").trim().toLowerCase();
|
|
};
|
|
|
|
const ensureOnPersonLocation = function() {
|
|
getSectionIDs(ON_PERSON_LOCATION_SECTION, function(rowIds) {
|
|
const attrsToGet = rowIds.map(rowId =>
|
|
`${ON_PERSON_LOCATION_SECTION}_${rowId}_inventoryLocationName`
|
|
);
|
|
|
|
getAttrs(attrsToGet, function(values) {
|
|
const matchingRows = rowIds.filter(rowId =>
|
|
normalizeLocationName(values[`${ON_PERSON_LOCATION_SECTION}_${rowId}_inventoryLocationName`]) ===
|
|
normalizeLocationName(ON_PERSON_LOCATION_NAME)
|
|
);
|
|
|
|
const attrsToSet = {};
|
|
|
|
if (matchingRows.length > 0) {
|
|
const keeperRowId = matchingRows[0];
|
|
|
|
attrsToSet[`${ON_PERSON_LOCATION_SECTION}_${keeperRowId}_inventoryLocationName`] = ON_PERSON_LOCATION_NAME;
|
|
attrsToSet[`${ON_PERSON_LOCATION_SECTION}_${keeperRowId}_locationOnPerson`] = "1";
|
|
|
|
// Optional cleanup: "On Person" should be unique.
|
|
// This prevents the inventory matching logic from having duplicate location names.
|
|
matchingRows.slice(1).forEach(rowId => {
|
|
removeRepeatingRow(`${ON_PERSON_LOCATION_SECTION}_${rowId}`);
|
|
});
|
|
} else {
|
|
const rowId = generateRowID();
|
|
|
|
attrsToSet[`${ON_PERSON_LOCATION_SECTION}_${rowId}_inventoryLocationName`] = ON_PERSON_LOCATION_NAME;
|
|
attrsToSet[`${ON_PERSON_LOCATION_SECTION}_${rowId}_locationOnPerson`] = "1";
|
|
attrsToSet[`${ON_PERSON_LOCATION_SECTION}_${rowId}_locationItemCount`] = "0";
|
|
attrsToSet[`${ON_PERSON_LOCATION_SECTION}_${rowId}_locationTotalWeight`] = "0";
|
|
}
|
|
|
|
if (Object.keys(attrsToSet).length > 0) {
|
|
setAttrs(attrsToSet);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
on(
|
|
"sheet:opened remove:repeating_locationtotals change:repeating_locationtotals:inventorylocationname",
|
|
function() {
|
|
ensureOnPersonLocation();
|
|
}
|
|
);
|
|
|
|
// On Person Total Weight
|
|
on("change:repeating_locationtotals remove:repeating_locationtotals", function(){
|
|
getSectionIDs(`repeating_locationtotals`,function(locationArray) {
|
|
let AttrsToGet = [];
|
|
for (let arrayID of locationArray) {
|
|
AttrsToGet.push(`repeating_locationtotals_${arrayID}_locationTotalWeight`);
|
|
AttrsToGet.push(`repeating_locationtotals_${arrayID}_locationOnPerson`);
|
|
}
|
|
getAttrs(AttrsToGet, function (values) {
|
|
let total = 0;
|
|
for (let arrayID of locationArray){
|
|
total += Math.round((values[`repeating_locationtotals_${arrayID}_locationTotalWeight`] *
|
|
values[`repeating_locationtotals_${arrayID}_locationOnPerson`])*100)/100
|
|
}
|
|
setAttrs({
|
|
totalweight: total
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
on("change:repeating_maininventory:mainquantity " +
|
|
"change:repeating_maininventory:mainpieceweight", function(){
|
|
getAttrs(["repeating_maininventory_mainquantity",
|
|
"repeating_maininventory_mainpieceweight"], function(values){
|
|
let quantity = parseFloat(values.repeating_maininventory_mainquantity)||0;
|
|
let weight = parseFloat(values.repeating_maininventory_mainpieceweight)||0;
|
|
let total = Math.round((quantity * weight)*100)/100;
|
|
setAttrs({
|
|
repeating_maininventory_maintotalweight : total
|
|
});
|
|
});
|
|
})
|
|
|
|
//</editor-fold>
|
|
|
|
// <editor-fold desc="Profit/Loss">
|
|
on("change:_reporder:profitloss change:repeating_profitloss:plcredits " +
|
|
"change:repeating_profitloss:pldebits remove:repeating_profitloss", function(){
|
|
getSectionIDsOrdered(`repeating_profitloss`,function(plArray) {
|
|
let AttrsToGet = [];
|
|
let AttrsToSet = {"plTotalGold": 0};
|
|
for (let arrayID of plArray) {
|
|
AttrsToGet.push(`repeating_profitloss_${arrayID}_plDebits`);
|
|
AttrsToGet.push(`repeating_profitloss_${arrayID}_plCredits`);
|
|
}
|
|
getAttrs(AttrsToGet, function (values) {
|
|
for (let arrayID of plArray){
|
|
AttrsToSet["plTotalGold"] += parseFloat(values[`repeating_profitloss_${arrayID}_plCredits`])||0
|
|
- parseFloat(values[`repeating_profitloss_${arrayID}_plDebits`])||0;
|
|
AttrsToSet[`repeating_profitloss_${arrayID}_plRunningTotal`] = AttrsToSet["plTotalGold"];
|
|
}
|
|
setAttrs(AttrsToSet);
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
// </editor-fold>
|
|
|
|
//<editor-fold desc="Base Attack and Size Calculations">
|
|
|
|
on("change:size sheet:opened",function(){
|
|
getAttrs(["size"], function(values){
|
|
let size = 0;
|
|
if (values.size === "Sub Tiny") {
|
|
size = -8;
|
|
}if (values.size === "Tiny") {
|
|
size = -4;
|
|
}if (values.size === "Very Small") {
|
|
size = -2;
|
|
}if (values.size === "Small") {
|
|
size = -1;
|
|
}if (values.size === "Medium") {
|
|
size = 0;
|
|
}if (values.size === "Large") {
|
|
size = 1;
|
|
}if (values.size === "Very Large") {
|
|
size = 2;
|
|
}if (values.size === "Gargantuan") {
|
|
size = 4;
|
|
}if (values.size === "Super Gargantuan") {
|
|
size = 8;
|
|
}
|
|
setAttrs({
|
|
SizeMod: size
|
|
});
|
|
});
|
|
});
|
|
|
|
on("change:hd change:strmod change:dexmod change:attackcurve sheet:opened", function(){
|
|
getAttrs(["HD","AttackCurve"],function(values){
|
|
let HD = parseFloat(values.HD)||0;
|
|
let BAB = HD;
|
|
if(values.AttackCurve === "Medium"){
|
|
BAB = Math.floor(HD * .75);
|
|
}if(values.AttackCurve === "Low"){
|
|
BAB = Math.floor(HD * .5);
|
|
}
|
|
setAttrs({
|
|
BAB: BAB
|
|
});
|
|
});
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
// <editor-fold desc="Advanced Combat Maneuvers">
|
|
|
|
const ADVANCED_COMBAT_TOTALS = [
|
|
{
|
|
output: "MagicTouchAttack",
|
|
attrs: ["BAB", "dexmod", "MagicTouchAttackMisc", "SpellProf", "FocusEnch", "MagicTouchAttackTemp", "MagicTouchAttackFeat"],
|
|
calc: values => num(values, "BAB") + num(values, "dexmod") + num(values, "MagicTouchAttackMisc") +
|
|
num(values, "SpellProf") + num(values, "FocusEnch") + num(values, "MagicTouchAttackTemp") +
|
|
num(values, "MagicTouchAttackFeat")
|
|
},
|
|
{
|
|
output: "MartialTouchAttack",
|
|
attrs: ["BAB", "dexmod", "strmod", "MartialTouchAttackMisc", "MartialTouchAttackTemp", "MartialTouchAttackFeat"],
|
|
calc: values => num(values, "BAB") + Math.max(num(values, "dexmod"), num(values, "strmod")) +
|
|
num(values, "MartialTouchAttackMisc") + num(values, "MartialTouchAttackTemp") +
|
|
num(values, "MartialTouchAttackFeat")
|
|
},
|
|
{
|
|
output: "TripOpposed",
|
|
attrs: ["strmod", "TripOpposedMisc", "TripOpposedFeat", "TripOpposedTemp", "SizeMod"],
|
|
calc: values => num(values, "strmod") + num(values, "TripOpposedMisc") +
|
|
num(values, "TripOpposedFeat") + num(values, "TripOpposedTemp") + num(values, "SizeMod")
|
|
},
|
|
{
|
|
output: "ShoveOpposed",
|
|
attrs: ["strmod", "dexmod", "ShoveOpposedMisc", "ShoveOpposedFeat", "ShoveOpposedTemp", "SizeMod"],
|
|
calc: values => Math.max(num(values, "strmod"), num(values, "dexmod")) +
|
|
num(values, "ShoveOpposedMisc") + num(values, "ShoveOpposedFeat") +
|
|
num(values, "ShoveOpposedTemp") + num(values, "SizeMod")
|
|
},
|
|
{
|
|
output: "Grapple",
|
|
attrs: ["BAB", "SizeMod", "strmod", "GrappleMisc", "GrappleFeat", "GrappleTemp"],
|
|
calc: values => num(values, "BAB") + num(values, "SizeMod") + num(values, "strmod") +
|
|
num(values, "GrappleMisc") + num(values, "GrappleFeat") + num(values, "GrappleTemp")
|
|
},
|
|
{
|
|
output: "TrampleOpposed",
|
|
attrs: ["strmod", "dexmod", "TrampleOpposedMisc", "TrampleOpposedFeat", "TrampleOpposedTemp", "SizeMod"],
|
|
calc: values => Math.max(num(values, "strmod"), num(values, "dexmod")) +
|
|
num(values, "TrampleOpposedMisc") + num(values, "TrampleOpposedFeat") +
|
|
num(values, "TrampleOpposedTemp") + num(values, "SizeMod")
|
|
}
|
|
];
|
|
|
|
ADVANCED_COMBAT_TOTALS.forEach(def => {
|
|
on(watch(def.attrs), function() {
|
|
getAttrs(def.attrs, function(values) {
|
|
setAttrs({
|
|
[def.output]: def.calc(values)
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Wound DC Calc"">
|
|
on("change:conmod change:hd sheet:opened",function(){
|
|
getAttrs(["HD","conmod"],function(values){
|
|
let HD = parseFloat(values.HD)||0;
|
|
let Con = parseFloat(values.conmod)||0;
|
|
let WoundDC = 12 + HD - Con;
|
|
setAttrs({
|
|
WoundDC: WoundDC
|
|
});
|
|
});
|
|
});
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Skill Mess">
|
|
|
|
// Max Skill Points per HD
|
|
var skill_cap_calc = function(hitdie, trained){
|
|
if(trained === "0"){
|
|
return Math.floor((hitdie + 3)/2);
|
|
}
|
|
return hitdie + 3;
|
|
};
|
|
|
|
const SKILLS = [
|
|
{sp: "AcrobaticsSP", misc: "AcrobaticsMisc", key: "strmod", trained: "AcrobaticsTrained", total: "AcrobaticsTotal", armorPenalty: true},
|
|
{sp: "BalanceSP", misc: "BalanceMisc", key: "dexmod", trained: "BalanceTrained", total: "BalanceTotal"},
|
|
{sp: "BeguileSP", misc: "BeguileMisc", key: "chamod", trained: "BeguileTrained", total: "BeguileTotal"},
|
|
{sp: "BushcraftSP", misc: "BushcraftMisc", key: "wismod", trained: "BushcraftTrained", total: "BushcraftTotal"},
|
|
{sp: "ConcealSP", misc: "ConcealMisc", key: "dexmod", trained: "ConcealTrained", total: "ConcealTotal"},
|
|
{sp: "ConcentrationSP", misc: "ConcentrationMisc", key: "conmod", trained: "ConcentrationTrained", total: "ConcentrationTotal"},
|
|
{sp: "CounterfeitSP", misc: "CounterfeitMisc", key: "intmod", trained: "CounterfeitTrained", total: "CounterfeitTotal"},
|
|
{sp: "Craft1SP", misc: "Craft1Misc", key: "intmod", trained: "Craft1Trained", total: "Craft1Total"},
|
|
{sp: "Craft2SP", misc: "Craft2Misc", key: "intmod", trained: "Craft2Trained", total: "Craft2Total"},
|
|
{sp: "Craft3SP", misc: "Craft3Misc", key: "intmod", trained: "Craft3Trained", total: "Craft3Total"},
|
|
{sp: "DiscernIntentSP", misc: "DiscernIntentMisc", key: "wismod", trained: "DiscernIntentTrained", total: "DiscernIntentTotal"},
|
|
{sp: "DiplomacySP", misc: "DiplomacyMisc", key: "chamod", trained: "DiplomacyTrained", total: "DiplomacyTotal"},
|
|
{sp: "DisguiseSP", misc: "DisguiseMisc", key: "chamod", trained: "DisguiseTrained", total: "DisguiseTotal"},
|
|
{sp: "EscapeArtistSP", misc: "EscapeArtistMisc", key: "dexmod", trained: "EscapeArtistTrained", total: "EscapeArtistTotal"},
|
|
{sp: "GatherInformationSP", misc: "GatherInformationMisc", key: "chamod", trained: "GatherInformationTrained", total: "GatherInformationTotal"},
|
|
{sp: "HaggleSP", misc: "HaggleMisc", key: "chamod", trained: "HaggleTrained", total: "HaggleTotal"},
|
|
{sp: "HealSP", misc: "HealMisc", key: "wismod", trained: "HealTrained", total: "HealTotal"},
|
|
{sp: "IntimidateSP", misc: "IntimidateMisc", key: "chamod", trained: "IntimidateTrained", total: "IntimidateTotal"},
|
|
{sp: "InvestigateSP", misc: "InvestigateMisc", key: "intmod", trained: "InvestigateTrained", total: "InvestigateTotal"},
|
|
{sp: "Knowledge1SP", misc: "Knowledge1Misc", key: "intmod", trained: "Knowledge1Trained", total: "Knowledge1Total"},
|
|
{sp: "Knowledge2SP", misc: "Knowledge2Misc", key: "intmod", trained: "Knowledge2Trained", total: "Knowledge2Total"},
|
|
{sp: "Knowledge3SP", misc: "Knowledge3Misc", key: "intmod", trained: "Knowledge3Trained", total: "Knowledge3Total"},
|
|
{sp: "Knowledge4SP", misc: "Knowledge4Misc", key: "intmod", trained: "Knowledge4Trained", total: "Knowledge4Total"},
|
|
{sp: "Knowledge5SP", misc: "Knowledge5Misc", key: "intmod", trained: "Knowledge5Trained", total: "Knowledge5Total"},
|
|
{sp: "Knowledge6SP", misc: "Knowledge6Misc", key: "intmod", trained: "Knowledge6Trained", total: "Knowledge6Total"},
|
|
{sp: "ListenSP", misc: "ListenMisc", key: "wismod", trained: "ListenTrained", total: "ListenTotal"},
|
|
{sp: "LockpickingSP", misc: "LockpickingMisc", key: "dexmod", trained: "LockpickingTrained", total: "LockpickingTotal"},
|
|
{sp: "MoveSilentlySP", misc: "MoveSilentlyMisc", key: "dexmod", trained: "MoveSilentlyTrained", total: "MoveSilentlyTotal", armorPenalty: true},
|
|
{sp: "Perform1SP", misc: "Perform1Misc", key: "chamod", trained: "Perform1Trained", total: "Perform1Total"},
|
|
{sp: "Perform2SP", misc: "Perform2Misc", key: "chamod", trained: "Perform2Trained", total: "Perform2Total"},
|
|
{sp: "Perform3SP", misc: "Perform3Misc", key: "chamod", trained: "Perform3Trained", total: "Perform3Total"},
|
|
{sp: "Profession1SP", misc: "Profession1Misc", key: "intmod", trained: "Profession1Trained", total: "Profession1Total"},
|
|
{sp: "Profession2SP", misc: "Profession2Misc", key: "intmod", trained: "Profession2Trained", total: "Profession2Total"},
|
|
{sp: "RideSP", misc: "RideMisc", key: "dexmod", trained: "RideTrained", total: "RideTotal", armorPenalty: true},
|
|
{sp: "SleightOfHandSP", misc: "SleightOfHandMisc", key: "dexmod", trained: "SleightOfHandTrained", total: "SleightOfHandTotal"},
|
|
{sp: "SpotSP", misc: "SpotMisc", key: "wismod", trained: "SpotTrained", total: "SpotTotal"},
|
|
{sp: "SabotageDeviceSP", misc: "SabotageDeviceMisc", key: "intmod", trained: "SabotageDeviceTrained", total: "SabotageDeviceTotal"},
|
|
{sp: "SwimSP", misc: "SwimMisc", key: "strmod", trained: "SwimTrained", total: "SwimTotal", armorPenalty: true},
|
|
{sp: "UseRopeSP", misc: "UseRopeMisc", key: "dexmod", trained: "UseRopeTrained", total: "UseRopeTotal"}
|
|
];
|
|
|
|
const SKILL_POINT_ATTRS = SKILLS.map(skill => skill.sp);
|
|
|
|
var checkmaxskillpoints = function() {
|
|
const attrs = SKILL_POINT_ATTRS.concat(["NatIntMod", "BaseSkillGrowth", "HD"]);
|
|
getAttrs(attrs, function(values) {
|
|
const currentSkillPoints = SKILL_POINT_ATTRS.reduce((sum, attr) => sum + num(values, attr), 0);
|
|
const maxSkillPoints = (num(values, "HD") + 3) * (num(values, "NatIntMod") + num(values, "BaseSkillGrowth"));
|
|
setAttrs({
|
|
TotalPossibleSkillPoints: maxSkillPoints,
|
|
RemainingSkillPoints: maxSkillPoints - currentSkillPoints
|
|
});
|
|
});
|
|
};
|
|
|
|
on(watch(["Specialty", "AttackCurve", "Versatile", "skill_growth_modifier"]), function(){
|
|
getAttrs(["Specialty", "AttackCurve", "Versatile", "skill_growth_modifier"], function(values){
|
|
let attack = 2;
|
|
let specialty = 0;
|
|
let versatile = 0;
|
|
let skill_growth_modifier = num(values, "skill_growth_modifier");
|
|
|
|
if(values.AttackCurve === "Medium") attack = 4;
|
|
if(values.Specialty === "Specialist") specialty = 4;
|
|
if(values.Specialty === "Generalist") specialty = 2;
|
|
if(values.Versatile === "on") versatile = 1;
|
|
|
|
setAttrs({
|
|
BaseSkillGrowth: attack + specialty + versatile + skill_growth_modifier
|
|
});
|
|
});
|
|
});
|
|
|
|
on(watch(["intelligence", "IntBonus", "IntPen", "BaseSkillGrowth", "HD", "no_intelligence_score"]), function() {
|
|
getAttrs(["intelligence", "IntBonus", "IntPen", "BaseSkillGrowth", "no_intelligence_score"], function(values) {
|
|
const noIntelligenceScore = values.no_intelligence_score === "1";
|
|
const total = num(values, "intelligence") + num(values, "IntBonus") - num(values, "IntPen");
|
|
const mod = noIntelligenceScore ? 0 : Math.floor((total - 10) / 2);
|
|
setAttrs({
|
|
NatIntMod: mod,
|
|
SkillsKnown: mod + num(values, "BaseSkillGrowth") + 4
|
|
}, checkmaxskillpoints);
|
|
});
|
|
});
|
|
|
|
const bindSkill = function(skill) {
|
|
const attrs = [skill.sp, skill.misc, skill.key, "HD", skill.trained];
|
|
if(skill.armorPenalty) attrs.push("CheckPen", "ShieldCheckPen");
|
|
|
|
on(watch(attrs), function(){
|
|
getAttrs(attrs, function(values){
|
|
const sp = num(values, skill.sp);
|
|
const misc = num(values, skill.misc);
|
|
const key = num(values, skill.key);
|
|
const hd = num(values, "HD");
|
|
const cappedSP = Math.min(skill_cap_calc(hd, str(values, skill.trained, "0")), sp);
|
|
const penalty = skill.armorPenalty ? num(values, "CheckPen") + num(values, "ShieldCheckPen") : 0;
|
|
|
|
setAttrs({
|
|
[skill.total]: cappedSP + key + misc - penalty,
|
|
[skill.sp]: cappedSP
|
|
}, checkmaxskillpoints);
|
|
});
|
|
});
|
|
};
|
|
|
|
SKILLS.forEach(bindSkill);
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Saves">
|
|
|
|
const saveBase = function(curve, hd) {
|
|
if(curve === "Low") return Math.min(6, Math.floor(hd / 3));
|
|
if(curve === "High") return Math.min(12, Math.floor(2 + (hd / 2)));
|
|
return 0;
|
|
};
|
|
|
|
const SAVE_BASE_DEFS = [
|
|
{curve: "EgoBaseStr", output: "EgoBaseNum"},
|
|
{curve: "FortBaseStr", output: "FortBaseNum"},
|
|
{curve: "RefBaseStr", output: "RefBaseNum", bonusAttrs: ["haste", "slow"], bonus: values => num(values, "haste") - num(values, "slow")},
|
|
{curve: "WilBaseStr", output: "WilBaseNum"}
|
|
];
|
|
|
|
SAVE_BASE_DEFS.forEach(def => {
|
|
const attrs = [def.curve, "HD"].concat(def.bonusAttrs || []);
|
|
on(watch(attrs), function(){
|
|
getAttrs(attrs, function(values){
|
|
setAttrs({
|
|
[def.output]: saveBase(str(values, def.curve), num(values, "HD")) + (def.bonus ? def.bonus(values) : 0)
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
const SAVE_TOTAL_DEFS = [
|
|
{total: "EgoTotal", base: "EgoBaseNum", key: "chamod", magic: "EgoMagic", misc: "EgoMiscNum", temp: "EgoTempNum"},
|
|
{total: "FortTotal", base: "FortBaseNum", key: "conmod", magic: "FortMagic", misc: "FortMiscNum", temp: "FortTempNum"},
|
|
{total: "RefTotal", base: "RefBaseNum", key: "dexmod", magic: "RefMagic", misc: "RefMiscNum", temp: "RefTempNum"},
|
|
{total: "WilTotal", base: "WilBaseNum", key: "wismod", magic: "WilMagic", misc: "WilMiscNum", temp: "WilTempNum"}
|
|
];
|
|
|
|
SAVE_TOTAL_DEFS.forEach(def => {
|
|
const attrs = [def.base, def.key, def.magic, def.misc, def.temp];
|
|
on(watch(attrs), function(){
|
|
getAttrs(attrs, function(values){
|
|
setAttrs({
|
|
[def.total]: num(values, def.base) + num(values, def.key) + num(values, def.magic) +
|
|
num(values, def.misc) + num(values, def.temp)
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
// <editor-fold desc="AC">
|
|
on("change:shield change:size change:sizemod change:armorbonus change:dexmod change:naturalac change:parryac change:haste change:slow "+
|
|
"change:miscac change:deflection change:insightac change:dodgeac change:dexaclimit change:shielddexaclimit" +
|
|
" sheet:opened",function(){
|
|
getAttrs(["dexmod","ArmorBonus","NaturalAC","Shield","MiscAC","haste","slow",
|
|
"InsightAC","ParryAC","Deflection","DodgeAC","SizeMod","DexACLimit","ShieldDexACLimit"],function(values){
|
|
let dex = parseFloat(values.dexmod)||0;
|
|
let haste = parseFloat(values.haste)||0;
|
|
let slow = parseFloat(values.slow)
|
|
let armor = parseFloat(values.ArmorBonus)||0;
|
|
let natural = parseFloat(values.NaturalAC)||0;
|
|
let shield = parseFloat(values.Shield)||0;
|
|
let parry = parseFloat(values.ParryAC)||0;
|
|
let dodge = parseFloat(values.DodgeAC)||0;
|
|
let deflection = parseFloat(values.Deflection)||0;
|
|
let insight = parseFloat(values.InsightAC)||0;
|
|
let misc = parseFloat(values.MiscAC)||0;
|
|
let ArmorLimit = parseFloat(values.DexACLimit)||9999;
|
|
let ShieldLimit = parseFloat(values.ShieldDexACLimit)||9999;
|
|
let DexLimit = Math.min(ArmorLimit,ShieldLimit);
|
|
let size = parseFloat(values.SizeMod)||0;
|
|
let total = 10 + Math.min(DexLimit,dex) + armor + natural + shield + haste + parry + dodge + deflection + insight + misc - size - slow;
|
|
let flat = 10 + armor + natural + shield + deflection + misc - size;
|
|
let touch = 10 + Math.min(DexLimit,dex) + dodge + deflection + insight + misc - size + haste - slow;
|
|
setAttrs({
|
|
TotalAC: total,
|
|
FlatFAC: flat,
|
|
TouchAC: touch,
|
|
});
|
|
});
|
|
});
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Initiative Calculations"
|
|
on("change:dexmod change:initbonus sheet:opened", function(){
|
|
getAttrs(["dexmod","InitBonus"],function(values){
|
|
let dex = parseFloat(values.dexmod)||0;
|
|
let InitBonus = parseFloat(values.InitBonus)||0;
|
|
let total = dex + InitBonus
|
|
setAttrs({
|
|
InitTotal: total
|
|
});
|
|
});
|
|
});
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Conditions">
|
|
|
|
const TTD_CONDITIONS = [
|
|
{
|
|
name: "Bad Luck",
|
|
legacyAttr: "condition_bad_luck",
|
|
effect: "Damage rolls are treated as their minimum result."
|
|
},
|
|
{
|
|
name: "Dizzy",
|
|
legacyAttr: "condition_dizzy",
|
|
effect: "Casting requires Concentration DC 10 + HD + spell level. Moving requires Balance DC 15 or fall prone; running raises" +
|
|
"this to DC 25. Melee attacks take a -2 circumstance penalty."
|
|
},
|
|
{
|
|
name: "Exhausted",
|
|
legacyAttr: "condition_exhausted",
|
|
effect: "May either move or take a standard action each round. Ground speed is halved. Takes a -3 dodge penalty to AC and" +
|
|
" Reflex saves."
|
|
},
|
|
{
|
|
name: "Fatigued",
|
|
legacyAttr: "condition_fatigued",
|
|
effect: "Cannot charge or double-move. Excessively tiring activity causes Exhausted. Takes a -1 dodge penalty to AC and" +
|
|
" Reflex saves."
|
|
},
|
|
{
|
|
name: "Nauseated",
|
|
legacyAttr: "condition_nauseated",
|
|
effect: "Each round: 33% chance to lose the action vomiting, 33% chance to need Balance DC 18 or fall prone, and 33% chance to" +
|
|
" act normally."
|
|
},
|
|
{
|
|
name: "Scared",
|
|
legacyAttr: "condition_scared",
|
|
effect: "Against the source of fear, takes -2 on attack rolls and Will saves, prefers staying out of range, and becomes more" +
|
|
" compliant unless a greater fear takes priority."
|
|
},
|
|
{
|
|
name: "Sickened",
|
|
legacyAttr: "condition_sickened",
|
|
effect: "Takes -2 to all rolls. Movement speed is reduced by 10 ft."
|
|
},
|
|
{
|
|
name: "Sleep",
|
|
legacyAttr: "condition_sleep",
|
|
effect: "Temporarily unconscious. Noise of Listen DC 15 or higher gives a chance to wake on a successful Listen check. Takes" +
|
|
" -5 to Listen while asleep."
|
|
},
|
|
{
|
|
name: "Soaked",
|
|
legacyAttr: "condition_soaked",
|
|
effect: "Electric spells gain vulnerability. Electric resistance is lost, immunity becomes resistance, and electric absorption" +
|
|
" heals by the vulnerable damage amount."
|
|
},
|
|
{
|
|
name: "Stifle",
|
|
legacyAttr: "condition_stifle",
|
|
effect: "Cannot act while left alone. May dodge, defend, or protect themselves if attacked. Magical stifle grants another" +
|
|
" immediate Will save after offensive action. Reactive skills take -4 circumstance penalty. Not flat-footed."
|
|
},
|
|
{
|
|
name: "Stunned",
|
|
legacyAttr: "condition_stunned",
|
|
effect: "Drops weapons, cannot take standard actions, and threatens no squares. May move at half speed. Takes -2 dodge penalty" +
|
|
" to AC and Reflex saves, and -4 to Acrobatics, Balance, Investigate, Listen, and Spot."
|
|
}
|
|
];
|
|
|
|
const TTD_CONDITION_EFFECTS = TTD_CONDITIONS.reduce(function(map, condition) {
|
|
map[condition.name] = condition.effect;
|
|
return map;
|
|
}, {});
|
|
|
|
const setConditionEffectForRow = function(rowId, values, attrsToSet) {
|
|
const typeAttr = `repeating_conditions_${rowId}_condition_type`;
|
|
const effectAttr = `repeating_conditions_${rowId}_condition_effect`;
|
|
const conditionType = str(values, typeAttr);
|
|
attrsToSet[effectAttr] = TTD_CONDITION_EFFECTS[conditionType] || "";
|
|
};
|
|
|
|
const updateConditionEffects = function(callback) {
|
|
getSectionIDs("repeating_conditions", function(rowIds) {
|
|
const attrsToGet = rowIds.map(rowId => `repeating_conditions_${rowId}_condition_type`);
|
|
|
|
getAttrs(attrsToGet, function(values) {
|
|
const attrsToSet = {};
|
|
|
|
rowIds.forEach(rowId => {
|
|
setConditionEffectForRow(rowId, values, attrsToSet);
|
|
});
|
|
|
|
if(Object.keys(attrsToSet).length > 0) {
|
|
setAttrs(attrsToSet, typeof callback === "function" ? callback : undefined);
|
|
return;
|
|
}
|
|
|
|
if(typeof callback === "function") callback();
|
|
});
|
|
});
|
|
};
|
|
|
|
const updateConditionEffectFromEvent = function(eventInfo) {
|
|
const source = eventInfo && eventInfo.sourceAttribute ? eventInfo.sourceAttribute : "";
|
|
const match = source.match(/repeating_conditions_([^_]+)_condition_type/);
|
|
|
|
if(!match) {
|
|
updateConditionEffects();
|
|
return;
|
|
}
|
|
|
|
const rowId = match[1];
|
|
const typeAttr = `repeating_conditions_${rowId}_condition_type`;
|
|
|
|
getAttrs([typeAttr], function(values) {
|
|
const attrsToSet = {};
|
|
setConditionEffectForRow(rowId, values, attrsToSet);
|
|
setAttrs(attrsToSet);
|
|
});
|
|
};
|
|
|
|
on("change:repeating_conditions:condition_type", updateConditionEffectFromEvent);
|
|
on("sheet:opened", function() {
|
|
updateConditionEffects();
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Button-Tabs"
|
|
|
|
const inputlist = ["Crown", "Face", "Neck", "Shoulders", "Ring1", "Ring2", "Hands", "Forearms", "UpperArms", "Torso", "Waist", "Feet"];
|
|
inputlist.forEach(input =>{
|
|
on(`change:${input.toLowerCase()}`, function(){
|
|
getAttrs([input], function(values){
|
|
setAttrs({
|
|
[`${input}_hidden`]: values[input]
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
const buttonlist = ["main", "skills", "gear", "definitions", "abilities", "spells", "accessories", "inventory", "profitloss",
|
|
"settings"];
|
|
buttonlist.forEach(button => {
|
|
on(`clicked:${button}`, function() {
|
|
setAttrs({
|
|
sheetTab: button
|
|
});
|
|
});
|
|
});
|
|
|
|
const spellbuttonlist = [0,1,2,3,4,5,6,7,8,9];
|
|
spellbuttonlist.forEach(level => {
|
|
bindToggle(`spell${level}minimize`, `spell${level}minimizetoggle`);
|
|
bindToggle(`repeating_spells-${level}:spell${level}minimize`, `repeating_spells-${level}_spell${level}minimizetoggle`);
|
|
bindToggle(`repeating_spells-${level}:spell${level}minimizeadvanced`, `repeating_spells-${level}_spell${level}minimizeadvancedtoggle`);
|
|
});
|
|
|
|
bindToggle("repeating_abilities:minabilitytog", "repeating_abilities_minimizeability");
|
|
bindToggle("repeating_feats:minfeats", "repeating_feats_minfeatval");
|
|
|
|
WeaponCol.forEach(col => {
|
|
["weaponminimize", "critconfirmminimize", "advancedweaponminimize"].forEach(button => {
|
|
bindToggle(`repeating_weapons${col}:${button}`, `repeating_weapons${col}_${button}toggle`);
|
|
});
|
|
});
|
|
|
|
[1, 2, 3].forEach(col => {
|
|
bindToggle(`repeating_DTA${col}:dta${col}minimize`, `repeating_DTA${col}_dta${col}minimizetoggle`);
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="HP Calculations"
|
|
|
|
on("change:conmod change:hd sheet:opened", function(){
|
|
getAttrs(["HD","conmod"],function(values){
|
|
let HD = parseFloat(values.HD)||0;
|
|
let conmod = parseFloat(values.conmod)||0;
|
|
let conhp = HD * conmod
|
|
setAttrs({
|
|
ConHP: conhp
|
|
});
|
|
});
|
|
});
|
|
|
|
on("change:hd change:magiccurve sheet:opened", function(){
|
|
getAttrs(["HD","MagicCurve"],function(values){
|
|
let progHP = 0;
|
|
let HD = parseFloat(values.HD)||0;
|
|
if(values.MagicCurve === "None"){
|
|
progHP = 6;
|
|
}if(values.MagicCurve === "Basic"){
|
|
progHP = 5;
|
|
}if(values.MagicCurve === "Standard"){
|
|
progHP = 4;
|
|
}if(values.MagicCurve === "Advanced"){
|
|
progHP = 3;
|
|
}
|
|
setAttrs({
|
|
ProgHP: progHP * HD
|
|
});
|
|
});
|
|
});
|
|
|
|
on("change:conhp change:mischp change:proghp change:rollhp sheet:opened", function(){
|
|
getAttrs(["ConHP","ProgHP","MiscHP","RollHP"],function(values){
|
|
let con = parseFloat(values.ConHP)||0;
|
|
let prog = parseFloat(values.ProgHP)||0;
|
|
let misc = parseFloat(values.MiscHP)||0;
|
|
let roll = parseFloat(values.RollHP)||0;
|
|
let total = con + prog + misc + roll;
|
|
if(total === 0){
|
|
total = 1
|
|
}
|
|
setAttrs({
|
|
hp_max: total,
|
|
NLD_max: total,
|
|
});
|
|
});
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Rest Button">
|
|
|
|
const REST_SPELL_LEVELS = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
const REST_MULTIPLIER_QUERY = "?{Rest multiplier|1x,1|1.5x,1.5|2x,2|3x,3}";
|
|
|
|
const restRollResultTotal = function(rollResult, fallback = 0) {
|
|
if(rollResult && rollResult.result !== undefined) {
|
|
const parsed = parseFloat(rollResult.result);
|
|
return isNaN(parsed) ? fallback : parsed;
|
|
}
|
|
|
|
if(rollResult && rollResult.total !== undefined) {
|
|
const parsed = parseFloat(rollResult.total);
|
|
return isNaN(parsed) ? fallback : parsed;
|
|
}
|
|
|
|
return fallback;
|
|
};
|
|
|
|
const resetRepeatingCurrentFromMax = function(section, currentAttr, maxAttr, attrsToSet, callback) {
|
|
getSectionIDs(section, function(rowIds) {
|
|
const attrsToGet = [];
|
|
|
|
rowIds.forEach(rowId => {
|
|
attrsToGet.push(`${section}_${rowId}_${maxAttr}`);
|
|
});
|
|
|
|
getAttrs(attrsToGet, function(values) {
|
|
rowIds.forEach(rowId => {
|
|
const maxValue = values[`${section}_${rowId}_${maxAttr}`];
|
|
|
|
if(maxValue !== undefined && maxValue !== "") {
|
|
attrsToSet[`${section}_${rowId}_${currentAttr}`] = maxValue;
|
|
}
|
|
});
|
|
|
|
callback();
|
|
});
|
|
});
|
|
};
|
|
|
|
const REST_RESOURCE_EXCLUSIONS = [
|
|
"heme"
|
|
];
|
|
|
|
const normalizeRestResourceName = function(value) {
|
|
return String(value || "").replace(/\s+/g, "").toLowerCase();
|
|
};
|
|
|
|
const restShouldSkipResource = function(value) {
|
|
return REST_RESOURCE_EXCLUSIONS.includes(normalizeRestResourceName(value));
|
|
};
|
|
|
|
const resetRestResources = function(attrsToSet, callback) {
|
|
getSectionIDs("repeating_resources", function(rowIds) {
|
|
const attrsToGet = [];
|
|
|
|
rowIds.forEach(rowId => {
|
|
attrsToGet.push(`repeating_resources_${rowId}_resourceName`);
|
|
attrsToGet.push(`repeating_resources_${rowId}_resourceNumber_max`);
|
|
});
|
|
|
|
getAttrs(attrsToGet, function(values) {
|
|
rowIds.forEach(rowId => {
|
|
const resourceName = values[`repeating_resources_${rowId}_resourceName`];
|
|
const maxValue = values[`repeating_resources_${rowId}_resourceNumber_max`];
|
|
|
|
if(restShouldSkipResource(resourceName)) return;
|
|
|
|
if(maxValue !== undefined && maxValue !== "") {
|
|
attrsToSet[`repeating_resources_${rowId}_resourceNumber`] = maxValue;
|
|
}
|
|
});
|
|
|
|
callback();
|
|
});
|
|
});
|
|
};
|
|
|
|
const resetRestRepeatingPools = function(attrsToSet, callback) {
|
|
resetRestResources(attrsToSet, function() {
|
|
resetRepeatingCurrentFromMax("repeating_abilities", "userdescription", "uses", attrsToSet, callback);
|
|
});
|
|
};
|
|
|
|
const deathSaveIsChecked = function(value) {
|
|
return value === "1" || value === 1 || value === true || value === "on" || value === "yes";
|
|
};
|
|
|
|
const applyRestDeathSaveRecovery = function(values, attrsToSet) {
|
|
if(deathSaveIsChecked(values.death_save_3)) return 3;
|
|
|
|
if(deathSaveIsChecked(values.death_save_2)) {
|
|
attrsToSet.death_save_2 = "0";
|
|
return 2;
|
|
}
|
|
|
|
if(deathSaveIsChecked(values.death_save_1)) {
|
|
attrsToSet.death_save_1 = "0";
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
const rollRestingForever = function() {
|
|
startRoll(
|
|
`&{template:custom}{{title=Dead}}{{subtitle=@{character_name}}}` +
|
|
`{{Status=Dead}}{{desc=@{character_name} is dead and is now resting forever.}}`,
|
|
function(roll) {
|
|
finishRoll(roll.rollId);
|
|
}
|
|
);
|
|
};
|
|
|
|
on("clicked:rest", function() {
|
|
getAttrs(["death_save_3"], function(deathValues) {
|
|
if(deathSaveIsChecked(deathValues.death_save_3)) {
|
|
rollRestingForever();
|
|
return;
|
|
}
|
|
|
|
startRoll(
|
|
`&{template:custom}{{title=Rest}}{{subtitle=@{character_name}}}` +
|
|
`{{rest=1}}{{rest_multiplier=[[${REST_MULTIPLIER_QUERY}]]}}` +
|
|
`{{rest_healing=[[0]]}}{{rest_hp=[[0]]}}{{rest_hp_max=[[0]]}}` +
|
|
`{{desc=Spell uses, ability uses, and resources reset to maximum. `+
|
|
`One non-terminal death save failure is cleared. One point of ability damage is reduces from every attribute.}}`,
|
|
function(roll) {
|
|
const multiplier = restRollResultTotal(roll.results.rest_multiplier, 1);
|
|
const attrsToGet = ["hp", "hp_max", "HD", "conmod", "death_save_1", "death_save_2"];
|
|
|
|
REST_SPELL_LEVELS.forEach(level => {
|
|
attrsToGet.push(`${level}perday`);
|
|
});
|
|
|
|
getAttrs(attrsToGet, function(values) {
|
|
const currentHp = num(values, "hp", 0);
|
|
const maxHp = Math.max(0, num(values, "hp_max", 0));
|
|
const hd = Math.max(0, num(values, "HD", 0));
|
|
const constitutionModifier = Math.max(1, num(values, "conmod", 0));
|
|
const restHealing = Math.max(0, Math.floor(hd * constitutionModifier * multiplier));
|
|
const newHp = Math.min(maxHp, currentHp + restHealing);
|
|
const actualHealing = Math.max(0, newHp - currentHp);
|
|
const attrsToSet = {
|
|
hp: newHp
|
|
};
|
|
const deathSaveRemoved = applyRestDeathSaveRecovery(values, attrsToSet);
|
|
|
|
REST_SPELL_LEVELS.forEach(level => {
|
|
const perDay = values[`${level}perday`];
|
|
|
|
if(perDay !== undefined && perDay !== "") {
|
|
attrsToSet[`${level}remaining`] = perDay;
|
|
}
|
|
});
|
|
|
|
resetRestRepeatingPools(attrsToSet, function() {
|
|
setAttrs(attrsToSet, function() {
|
|
finishRoll(roll.rollId, {
|
|
rest_healing: actualHealing,
|
|
rest_hp: newHp,
|
|
rest_hp_max: maxHp,
|
|
rest_death_save_removed: deathSaveRemoved
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
on("clicked:deathsave", function() {
|
|
getAttrs(["death_save_1", "death_save_2", "death_save_3"], function(values) {
|
|
if(deathSaveIsChecked(values.death_save_3)) {
|
|
startRoll(
|
|
`&{template:custom}{{title=Death Save}}{{subtitle=@{character_name}}}` +
|
|
`{{Status=Dead}}{{desc=@{character_name} is dead and is now sleeping forever.}}`,
|
|
function(roll) {
|
|
finishRoll(roll.rollId);
|
|
}
|
|
);
|
|
return;
|
|
}
|
|
|
|
const checkedFailures = ["death_save_1", "death_save_2", "death_save_3"].reduce(function(total, attr) {
|
|
return total + (deathSaveIsChecked(values[attr]) ? 1 : 0);
|
|
}, 0);
|
|
|
|
startRoll(
|
|
`&{template:custom}{{title=Death Save}}{{subtitle=@{character_name}}}` +
|
|
`{{Death Save=[[1d20]]}}{{Current Failures=${checkedFailures} / 3}}`,
|
|
function(roll) {
|
|
finishRoll(roll.rollId);
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="HD Calculations">
|
|
|
|
on("change:hd change:lg sheet:opened", function(){
|
|
getAttrs(["HD", "LG"], function(values){
|
|
let HD = parseFloat(values.HD)||0;
|
|
let LG = parseFloat(values.LG)||0;
|
|
let HDE = HD + LG
|
|
setAttrs({
|
|
HDE: HDE
|
|
});
|
|
});
|
|
});
|
|
|
|
//</editor-fold>
|
|
|
|
//<editor-fold desc="Statblock"
|
|
const STAT_DEFS = [
|
|
{
|
|
base: "strength",
|
|
bonus: "StrBonus",
|
|
enhancement: "StrEnch",
|
|
penalty: "StrPen",
|
|
total: "StrTotal",
|
|
mod: "strmod"
|
|
},
|
|
{
|
|
base: "dexterity",
|
|
bonus: "DexBonus",
|
|
enhancement: "DexEnch",
|
|
penalty: "DexPen",
|
|
total: "DexTotal",
|
|
mod: "dexmod"
|
|
},
|
|
{
|
|
base: "constitution",
|
|
bonus: "ConBonus",
|
|
enhancement: "ConEnch",
|
|
penalty: "ConPen",
|
|
total: "ConTotal",
|
|
mod: "conmod",
|
|
noScore: "no_constitution_score",
|
|
backup: "constitution_score_backup"
|
|
},
|
|
{
|
|
base: "wisdom",
|
|
bonus: "WisBonus",
|
|
enhancement: "WisEnch",
|
|
penalty: "WisPen",
|
|
total: "WisTotal",
|
|
mod: "wismod"
|
|
},
|
|
{
|
|
base: "intelligence",
|
|
bonus: "IntBonus",
|
|
enhancement: "IntEnch",
|
|
penalty: "IntPen",
|
|
total: "IntTotal",
|
|
mod: "intmod",
|
|
noScore: "no_intelligence_score",
|
|
backup: "intelligence_score_backup"
|
|
},
|
|
{
|
|
base: "charisma",
|
|
bonus: "ChaBonus",
|
|
enhancement: "ChaEnch",
|
|
penalty: "ChaPen",
|
|
total: "ChaTotal",
|
|
mod: "chamod"
|
|
}
|
|
];
|
|
|
|
STAT_DEFS.forEach(stat => {
|
|
const attrs = [stat.base, stat.bonus, stat.enhancement, stat.penalty];
|
|
if(stat.noScore) attrs.push(stat.noScore);
|
|
if(stat.backup) attrs.push(stat.backup);
|
|
on(watch(attrs), function() {
|
|
getAttrs(attrs, function(values) {
|
|
const noScore = stat.noScore && values[stat.noScore] === "1";
|
|
const attrsToSet = {};
|
|
if(stat.backup && !noScore && values[stat.base] !== "-") {
|
|
attrsToSet[stat.backup] = values[stat.base];
|
|
}
|
|
if(noScore) {
|
|
attrsToSet[stat.total] = "-";
|
|
attrsToSet[stat.mod] = 0;
|
|
if(values[stat.base] !== "-") {
|
|
if(stat.backup && values[stat.base] !== "") {
|
|
attrsToSet[stat.backup] = values[stat.base];
|
|
}
|
|
attrsToSet[stat.base] = "-";
|
|
}
|
|
setAttrs(attrsToSet);
|
|
return;
|
|
}
|
|
if(stat.backup && values[stat.base] === "-") {
|
|
attrsToSet[stat.base] = values[stat.backup] || 10;
|
|
}
|
|
const baseValue = values[stat.base] === "-"
|
|
? num(values, stat.backup, 10)
|
|
: num(values, stat.base);
|
|
const total = baseValue + num(values, stat.bonus) +
|
|
num(values, stat.enhancement) - num(values, stat.penalty);
|
|
attrsToSet[stat.total] = total;
|
|
attrsToSet[stat.mod] = Math.floor((total - 10) / 2);
|
|
|
|
setAttrs(attrsToSet);
|
|
});
|
|
});
|
|
});
|
|
//</editor-fold>
|
|
|
|
// <editor-fold desc="Spellcasting Calculations">
|
|
|
|
//Block of Constants used by the sheet for spell casting
|
|
const BasicMagicSPD = [ /*Vertical Index is 0 - 19 || Horizontal index is 0 - 3 */
|
|
[null,null,null,null],
|
|
[0,null,null,null],
|
|
[1,null,null,null],
|
|
[1,null,null,null],
|
|
[2,null,null,null],
|
|
[2,0,null,null],
|
|
[2,1,null,null],
|
|
[2,1,null,null],
|
|
[2,1,null,null],
|
|
[3,2,0,null],
|
|
[3,2,1,null],
|
|
[3,2,1,null],
|
|
[3,2,1,null],
|
|
[3,3,1,0],
|
|
[4,3,1,1],
|
|
[4,3,2,1],
|
|
[4,4,2,1],
|
|
[4,4,2,2],
|
|
[4,4,2,2],
|
|
[5,4,2,2]
|
|
];
|
|
const StandardMagicSPD = [ /*Vertical Index is 0 - 19 || Horizontal index is 0 - 5 */
|
|
[0,null,null,null,null,null],
|
|
[1,null,null,null,null,null],
|
|
[2,0,null,null,null,null],
|
|
[3,1,null,null,null,null],
|
|
[3,2,0,null,null,null],
|
|
[3,2,1,null,null,null],
|
|
[3,2,2,0,null,null],
|
|
[4,2,2,1,null,null],
|
|
[4,3,2,2,null,null],
|
|
[4,3,2,2,0,null],
|
|
[4,3,3,2,1,null],
|
|
[5,3,3,2,2,null],
|
|
[5,4,3,3,2,0],
|
|
[5,4,3,3,2,1],
|
|
[5,4,4,3,2,2],
|
|
[5,4,4,3,3,2],
|
|
[5,5,4,4,3,2],
|
|
[5,5,4,4,3,2],
|
|
[5,5,5,4,3,3],
|
|
[5,5,5,4,4,3]
|
|
];
|
|
const AdvancedMagicSPD = [ /*Vertical Index is 0 - 19 || Horizontal index is 0 - 8 */
|
|
[2,null,null,null,null,null,null,null,null],
|
|
[3,null,null,null,null,null,null,null,null],
|
|
[3,1,null,null,null,null,null,null,null],
|
|
[3,2,null,null,null,null,null,null,null],
|
|
[4,2,1,null,null,null,null,null,null],
|
|
[4,3,2,null,null,null,null,null,null],
|
|
[4,3,2,1,null,null,null,null,null],
|
|
[4,3,3,2,null,null,null,null,null],
|
|
[5,4,3,2,1,null,null,null,null],
|
|
[5,4,3,3,2,null,null,null,null],
|
|
[5,4,4,3,3,1,null,null,null],
|
|
[5,4,4,3,3,2,null,null,null],
|
|
[5,5,4,4,3,2,1,null,null],
|
|
[5,5,4,4,4,3,2,null,null],
|
|
[5,5,5,4,4,3,2,1,null],
|
|
[5,5,5,4,4,3,3,2,null],
|
|
[5,5,5,5,4,4,3,2,1],
|
|
[5,5,5,5,5,4,4,3,2],
|
|
[5,5,5,5,5,4,4,4,3],
|
|
[5,5,5,5,5,5,5,5,4]
|
|
];
|
|
const SpellsPerDayLevel = [1,2,3,4,5,6,7,8,9];
|
|
const SpellMacroLevel = [0,1,2,3,4,5,6,7,8,9];
|
|
|
|
SpellsPerDayLevel.forEach(level => { // setting the spells per day
|
|
on(watch(["HD", "MagicCurve", "PMA", "dexmod", "strmod", "intmod", "wismod", "chamod"]), function () {
|
|
getAttrs(["HD", "PMA", "MagicCurve", "strmod", "dexmod", "wismod", "intmod", "chamod"], function (values) {
|
|
const hd = Math.max(1, int(values, "HD", 1));
|
|
const pmaAttr = str(values, "PMA");
|
|
const pmaMap = {
|
|
"@{strmod}": "strmod",
|
|
"@{dexmod}": "dexmod",
|
|
"@{wismod}": "wismod",
|
|
"@{intmod}": "intmod",
|
|
"@{chamod}": "chamod"
|
|
};
|
|
const pma = num(values, pmaMap[pmaAttr], 0);
|
|
const magicTables = {
|
|
Basic: BasicMagicSPD,
|
|
Standard: StandardMagicSPD,
|
|
Advanced: AdvancedMagicSPD
|
|
};
|
|
const table = magicTables[str(values, "MagicCurve")];
|
|
const hdSpellsPerDay = table && table[hd - 1] ? table[hd - 1][level - 1] : null;
|
|
const bonusSpell = Math.max(Math.ceil((pma + 1 - level) / 4), 0);
|
|
const finalSPD = hdSpellsPerDay === null || hdSpellsPerDay === undefined ? 0 : hdSpellsPerDay + bonusSpell;
|
|
|
|
setAttrs({
|
|
[`${level}perday`]: finalSPD
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
on(watch(["HD", "MagicCurve"]), function(){
|
|
getAttrs(["HD","MagicCurve"], function(values){
|
|
let CL = num(values, "HD");
|
|
if (values.MagicCurve === "None"){
|
|
CL = 0;
|
|
}
|
|
else if (values.MagicCurve === "Basic"){
|
|
CL = Math.floor(CL / 2);
|
|
}
|
|
setAttrs({
|
|
cl : CL
|
|
});
|
|
});
|
|
});
|
|
|
|
const buildSpellCard = function(level, values) {
|
|
const prefix = `repeating_spells-${level}_`;
|
|
const save = str(values, `${prefix}spellsaving`, "No");
|
|
const saveSuccess = str(values, `${prefix}savesucces`);
|
|
const dcMod = int(values, `${prefix}spelldcmod`);
|
|
const type = str(values, `${prefix}category`, "0");
|
|
const harmless = str(values, `${prefix}harmless`).replace("0", "");
|
|
const spellResistance = str(values, `${prefix}sr`);
|
|
|
|
let macro = `&{template:custom}{{title=@{spellname}}}{{subtitle=@{school}}}{{Components=@{components}}}`+
|
|
`{{Range=@{range}}}{{Casting Time=@{castingtime}}}{{Effect=@{effect}}}{{Duration=@{duration}}}`;
|
|
|
|
if (save !== "No") {
|
|
macro += `{{${save} save= DC [[10+${dcMod}+@{PMA}+${level}+@{SpellProf}]]${saveSuccess}${harmless}}}`;
|
|
}
|
|
if(type !== "0") {
|
|
macro += `{{${type}=[[@{dicenum}@{dicetype}+(@{dicenum}*@{SpellProf})]]}}`;
|
|
}
|
|
if(spellResistance === "1") {
|
|
macro += `{{Spell Penetration=[[1d20+@{cl}+@{spellpenetrationbonus}+`+
|
|
`(0?{Do you have any Spell penetration Bonuses?|0})]]}}`;
|
|
}
|
|
|
|
return macro + `{{desc= @{spelldescription}}}`;
|
|
};
|
|
|
|
SpellMacroLevel.forEach(level => {
|
|
const section = `repeating_spells-${level}`;
|
|
const watched = repeatingWatch(section, [
|
|
"spellsaving", "category", "savesucces", "harmless", "sr",
|
|
`spell${level}minimizetoggle`, "minimizetoggle", "spellname", "spelldcmod"
|
|
]) + ` change:repeating_spells-${level}`;
|
|
|
|
const attrs = [
|
|
`repeating_spells-${level}_spellsaving`,
|
|
`repeating_spells-${level}_category`,
|
|
`repeating_spells-${level}_savesucces`,
|
|
`repeating_spells-${level}_harmless`,
|
|
`repeating_spells-${level}_sr`,
|
|
`repeating_spells-${level}_spelldcmod`
|
|
];
|
|
|
|
on(watched, function () {
|
|
getAttrs(attrs, function (values) {
|
|
setAttrs({
|
|
[`repeating_spells-${level}_spellcard`]: buildSpellCard(level, values)
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
on(watch(["HD", "MagicCurve"]), function(){
|
|
getAttrs(["HD", "MagicCurve"], function(values){
|
|
let SP = 0;
|
|
const HD = num(values, "HD");
|
|
if(values.MagicCurve === "Basic"){
|
|
SP = Math.floor(HD/10);
|
|
}
|
|
if(values.MagicCurve === "Standard"){
|
|
SP = 1 + Math.floor(HD/8);
|
|
}
|
|
if(values.MagicCurve === "Advanced"){
|
|
SP = 1 + Math.floor(HD/6);
|
|
}
|
|
if(values.MagicCurve === "None"){
|
|
SP = 0;
|
|
}
|
|
setAttrs({
|
|
SpellProf: SP
|
|
});
|
|
});
|
|
});
|
|
//</editor-fold>
|
|
|
|
// <editor-fold desc="Ability Info Calculations">
|
|
|
|
// Automatic grant rows are generated from exact grant keys, not from total row counts.
|
|
// This keeps Universal, ancestry/background, and progression grants from masking one another.
|
|
const UNIVERSAL_SOURCE_NAME = "Universal";
|
|
const VERSATILE_SOURCE_NAME = "Versatile";
|
|
const DIFFUSE_BACKGROUND_SOURCE_NAME = "Diffuse Background";
|
|
const MYSTIC_SOURCE_NAME = "Mystic";
|
|
const NULL_COMBATANT_SOURCE_NAME = "Null Combatant";
|
|
const NULL_GENERALIST_SOURCE_NAME = "Null Generalist";
|
|
const NULL_SPECIALIST_SOURCE_NAME = "Null Specialist";
|
|
const BASIC_COMBATANT_SOURCE_NAME = "Basic Combatant";
|
|
const BASIC_GENERALIST_SOURCE_NAME = "Basic Generalist";
|
|
const BASIC_SPECIALIST_SOURCE_NAME = "Basic Specialist";
|
|
const STANDARD_COMBATANT_SOURCE_NAME = "Standard Combatant";
|
|
const STANDARD_GENERALIST_SOURCE_NAME = "Standard Generalist";
|
|
const STANDARD_SPECIALIST_SOURCE_NAME = "Standard Specialist";
|
|
const ADVANCED_COMBATANT_SOURCE_NAME = "Advanced Combatant";
|
|
const ADVANCED_GENERALIST_SOURCE_NAME = "Advanced Generalist";
|
|
const ADVANCED_SPECIALIST_SOURCE_NAME = "Advanced Specialist";
|
|
|
|
const levelsOneThenStep = function(hd, firstStepLevel, step) {
|
|
const levels = [];
|
|
if(hd >= 1) levels.push(1);
|
|
for(let level = firstStepLevel; level <= hd; level += step) {
|
|
levels.push(level);
|
|
}
|
|
return levels;
|
|
};
|
|
|
|
const levelsStartingAt = function(hd, start, step) {
|
|
const levels = [];
|
|
for(let level = start; level <= hd; level += step) {
|
|
levels.push(level);
|
|
}
|
|
return levels;
|
|
};
|
|
|
|
const universalFeatLevels = function(hd) {
|
|
const levels = [];
|
|
if(hd >= 1) levels.push(1);
|
|
for(let level = 3; level <= hd; level += 3) {
|
|
levels.push(level);
|
|
}
|
|
return levels;
|
|
};
|
|
|
|
const universalAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 10, 10);
|
|
};
|
|
|
|
const nullCombatantFeatLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 2, 2);
|
|
};
|
|
|
|
const nullGeneralistFeatLevels = function(hd) {
|
|
return levelsStartingAt(hd, 2, 4);
|
|
};
|
|
|
|
const nullGeneralistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 4, 4);
|
|
};
|
|
|
|
const nullSpecialistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 2, 2);
|
|
};
|
|
|
|
const basicCombatantFeatLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 4, 3);
|
|
};
|
|
|
|
const basicGeneralistFeatLevels = function(hd) {
|
|
return levelsStartingAt(hd, 4, 6);
|
|
};
|
|
|
|
const basicGeneralistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 7, 6);
|
|
};
|
|
|
|
const basicSpecialistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 4, 3);
|
|
};
|
|
|
|
const standardCombatantFeatLevels = function(hd) {
|
|
const levels = [];
|
|
if(hd >= 1) levels.push(1);
|
|
if(hd >= 4) levels.push(4);
|
|
for(let level = 12; level <= hd; level += 4) {
|
|
levels.push(level);
|
|
}
|
|
return levels;
|
|
};
|
|
|
|
const standardGeneralistFeatLevels = function(hd) {
|
|
const levels = [];
|
|
if(hd >= 4) levels.push(4);
|
|
for(let level = 16; level <= hd; level += 4) {
|
|
levels.push(level);
|
|
}
|
|
return levels;
|
|
};
|
|
|
|
const standardGeneralistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 8, 8);
|
|
};
|
|
|
|
const standardSpecialistAbilityLevels = function(hd) {
|
|
const levels = [];
|
|
if(hd >= 1) levels.push(1);
|
|
if(hd >= 4) levels.push(4);
|
|
for(let level = 12; level <= hd; level += 4) {
|
|
levels.push(level);
|
|
}
|
|
return levels;
|
|
};
|
|
|
|
const advancedCombatantFeatLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 5, 5);
|
|
};
|
|
|
|
const advancedGeneralistFeatLevels = function(hd) {
|
|
return levelsStartingAt(hd, 5, 10);
|
|
};
|
|
|
|
const advancedGeneralistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 10, 10);
|
|
};
|
|
|
|
const advancedSpecialistAbilityLevels = function(hd) {
|
|
return levelsOneThenStep(hd, 5, 5);
|
|
};
|
|
|
|
const normalizeGrantSource = function(value) {
|
|
return String(value || "").trim().toLowerCase();
|
|
};
|
|
|
|
const normalizeGrantName = function(value) {
|
|
return String(value || "").trim().toLowerCase();
|
|
};
|
|
|
|
const grantIsChecked = function(value) {
|
|
return value === "1" || value === 1 || value === true || value === "on" || value === "yes";
|
|
};
|
|
|
|
const hasDiffuseBackground = function(values) {
|
|
return grantIsChecked(values.diffuse_background) ||
|
|
normalizeGrantName(values.primarydefinitionname) === "diffuse background";
|
|
};
|
|
|
|
const keyLevelFromPrefix = function(key, keyPrefix) {
|
|
if(!key || key.indexOf(keyPrefix) !== 0) return null;
|
|
const level = parseInt(key.slice(keyPrefix.length), 10);
|
|
return isNaN(level) ? null : level;
|
|
};
|
|
|
|
const genericSourceAvailability = function(currentHD, grantedLevel) {
|
|
const level = parseInt(grantedLevel, 10);
|
|
if(isNaN(level) || level <= 0) return "1";
|
|
return currentHD >= level ? "1" : "0";
|
|
};
|
|
|
|
const makeGrantSpec = function(key, source, level, name, description, available, hidden = false) {
|
|
return { key, source, level, name, description, available, hidden };
|
|
};
|
|
|
|
const progressionSourceMatches = function(context, magicCurve, specialty) {
|
|
return normalizeGrantName(context.magicCurve) === normalizeGrantName(magicCurve) &&
|
|
normalizeGrantName(context.specialty) === normalizeGrantName(specialty);
|
|
};
|
|
|
|
const GRANT_SECTIONS = [
|
|
{
|
|
section: "repeating_feats",
|
|
nameAttr: "featsname",
|
|
descriptionAttr: "featsdescription",
|
|
universalKeyPrefix: "universal_feat_hd_",
|
|
universalName: level => `Universal Feat`,
|
|
universalDescription: level => `Universal feat slot gained at HD ${level}. Replace this text with the selected feat.`,
|
|
conditionalGrants: [
|
|
{
|
|
key: "versatile_bonus_feat",
|
|
source: VERSATILE_SOURCE_NAME,
|
|
level: 1,
|
|
name: "Versatile Bonus Feat",
|
|
description: "Bonus feat gained from the Versatile species option. Replace this text with the selected feat.",
|
|
isExpected: context => context.versatile
|
|
},
|
|
{
|
|
key: "diffuse_background_bonus_feat",
|
|
source: DIFFUSE_BACKGROUND_SOURCE_NAME,
|
|
level: 1,
|
|
name: "Diffuse Background Bonus Feat",
|
|
description: "Bonus feat gained from the Diffuse Background primary definition. Replace this text with the selected feat.",
|
|
isExpected: context => context.diffuseBackground
|
|
}
|
|
],
|
|
progressionGrants: [
|
|
{
|
|
keyPrefix: "null_combatant_feat_hd_",
|
|
source: NULL_COMBATANT_SOURCE_NAME,
|
|
magicCurve: "None",
|
|
specialty: "Combatant",
|
|
levels: nullCombatantFeatLevels,
|
|
name: level => `Null Combatant Feat`,
|
|
description: level => `Null Combatant feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "null_generalist_feat_hd_",
|
|
source: NULL_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "None",
|
|
specialty: "Generalist",
|
|
levels: nullGeneralistFeatLevels,
|
|
name: level => `Null Generalist Feat`,
|
|
description: level => `Null Generalist feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "basic_combatant_feat_hd_",
|
|
source: BASIC_COMBATANT_SOURCE_NAME,
|
|
magicCurve: "Basic",
|
|
specialty: "Combatant",
|
|
levels: basicCombatantFeatLevels,
|
|
name: level => `Basic Combatant Feat`,
|
|
description: level => `Basic Combatant feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "basic_generalist_feat_hd_",
|
|
source: BASIC_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "Basic",
|
|
specialty: "Generalist",
|
|
levels: basicGeneralistFeatLevels,
|
|
name: level => `Basic Generalist Feat`,
|
|
description: level => `Basic Generalist feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "standard_combatant_feat_hd_",
|
|
source: STANDARD_COMBATANT_SOURCE_NAME,
|
|
magicCurve: "Standard",
|
|
specialty: "Combatant",
|
|
levels: standardCombatantFeatLevels,
|
|
name: level => `Standard Combatant Feat`,
|
|
description: level => `Standard Combatant feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "standard_generalist_feat_hd_",
|
|
source: STANDARD_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "Standard",
|
|
specialty: "Generalist",
|
|
levels: standardGeneralistFeatLevels,
|
|
name: level => `Standard Generalist Feat`,
|
|
description: level => `Standard Generalist feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "advanced_combatant_feat_hd_",
|
|
source: ADVANCED_COMBATANT_SOURCE_NAME,
|
|
magicCurve: "Advanced",
|
|
specialty: "Combatant",
|
|
levels: advancedCombatantFeatLevels,
|
|
name: level => `Advanced Combatant Feat`,
|
|
description: level => `Advanced Combatant feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
},
|
|
{
|
|
keyPrefix: "advanced_generalist_feat_hd_",
|
|
source: ADVANCED_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "Advanced",
|
|
specialty: "Generalist",
|
|
levels: advancedGeneralistFeatLevels,
|
|
name: level => `Advanced Generalist Feat`,
|
|
description: level => `Advanced Generalist feat slot gained at HD ${level}. Replace this text with the selected feat.`
|
|
}
|
|
],
|
|
universalLevels: universalFeatLevels
|
|
},
|
|
{
|
|
section: "repeating_abilities",
|
|
nameAttr: "abilityname",
|
|
descriptionAttr: "abilitydescriptiontext",
|
|
universalKeyPrefix: "universal_ability_hd_",
|
|
universalName: level => `Universal Ability`,
|
|
universalDescription: level => `Universal ability slot gained at HD ${level}. Replace this text with the selected ability.`,
|
|
conditionalGrants: [
|
|
{
|
|
key: "mystic_bonus_ability",
|
|
source: MYSTIC_SOURCE_NAME,
|
|
level: 1,
|
|
name: "Mystic Ability",
|
|
description: "Bonus ability gained from the Mystic species option. Replace this text with the selected ability.",
|
|
isExpected: context => context.mystic
|
|
}
|
|
],
|
|
progressionGrants: [
|
|
{
|
|
keyPrefix: "null_generalist_ability_hd_",
|
|
source: NULL_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "None",
|
|
specialty: "Generalist",
|
|
levels: nullGeneralistAbilityLevels,
|
|
name: level => `Null Generalist Ability`,
|
|
description: level => `Null Generalist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "null_specialist_ability_hd_",
|
|
source: NULL_SPECIALIST_SOURCE_NAME,
|
|
magicCurve: "None",
|
|
specialty: "Specialist",
|
|
levels: nullSpecialistAbilityLevels,
|
|
name: level => `Null Specialist Ability`,
|
|
description: level => `Null Specialist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "basic_generalist_ability_hd_",
|
|
source: BASIC_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "Basic",
|
|
specialty: "Generalist",
|
|
levels: basicGeneralistAbilityLevels,
|
|
name: level => `Basic Generalist Ability`,
|
|
description: level => `Basic Generalist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "basic_specialist_ability_hd_",
|
|
source: BASIC_SPECIALIST_SOURCE_NAME,
|
|
magicCurve: "Basic",
|
|
specialty: "Specialist",
|
|
levels: basicSpecialistAbilityLevels,
|
|
name: level => `Basic Specialist Ability`,
|
|
description: level => `Basic Specialist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "standard_generalist_ability_hd_",
|
|
source: STANDARD_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "Standard",
|
|
specialty: "Generalist",
|
|
levels: standardGeneralistAbilityLevels,
|
|
name: level => `Standard Generalist Ability`,
|
|
description: level => `Standard Generalist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "standard_specialist_ability_hd_",
|
|
source: STANDARD_SPECIALIST_SOURCE_NAME,
|
|
magicCurve: "Standard",
|
|
specialty: "Specialist",
|
|
levels: standardSpecialistAbilityLevels,
|
|
name: level => `Standard Specialist Ability`,
|
|
description: level => `Standard Specialist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "advanced_generalist_ability_hd_",
|
|
source: ADVANCED_GENERALIST_SOURCE_NAME,
|
|
magicCurve: "Advanced",
|
|
specialty: "Generalist",
|
|
levels: advancedGeneralistAbilityLevels,
|
|
name: level => `Advanced Generalist Ability`,
|
|
description: level => `Advanced Generalist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
},
|
|
{
|
|
keyPrefix: "advanced_specialist_ability_hd_",
|
|
source: ADVANCED_SPECIALIST_SOURCE_NAME,
|
|
magicCurve: "Advanced",
|
|
specialty: "Specialist",
|
|
levels: advancedSpecialistAbilityLevels,
|
|
name: level => `Advanced Specialist Ability`,
|
|
description: level => `Advanced Specialist ability slot gained at HD ${level}. Replace this text with the selected ability.`
|
|
}
|
|
],
|
|
universalLevels: universalAbilityLevels
|
|
}
|
|
];
|
|
|
|
const buildUniversalGrantSpec = function(def, level, context) {
|
|
return makeGrantSpec(
|
|
`${def.universalKeyPrefix}${level}`,
|
|
UNIVERSAL_SOURCE_NAME,
|
|
level,
|
|
def.universalName(level),
|
|
def.universalDescription(level),
|
|
context.currentHD >= level
|
|
);
|
|
};
|
|
|
|
const buildProgressionGrantSpec = function(progression, level, context) {
|
|
const sourceMatches = progressionSourceMatches(context, progression.magicCurve, progression.specialty);
|
|
return makeGrantSpec(
|
|
`${progression.keyPrefix}${level}`,
|
|
progression.source,
|
|
level,
|
|
progression.name(level),
|
|
progression.description(level),
|
|
context.currentHD >= level && sourceMatches,
|
|
!sourceMatches
|
|
);
|
|
};
|
|
|
|
const buildExpectedGrantSpecs = function(def, context) {
|
|
const specs = def.universalLevels(context.currentHD).map(level => buildUniversalGrantSpec(def, level, context));
|
|
|
|
(def.conditionalGrants || []).forEach(grant => {
|
|
if(grant.isExpected(context)) {
|
|
specs.push(makeGrantSpec(
|
|
grant.key,
|
|
grant.source,
|
|
grant.level,
|
|
grant.name,
|
|
grant.description,
|
|
context.currentHD >= grant.level
|
|
));
|
|
}
|
|
});
|
|
|
|
(def.progressionGrants || []).forEach(progression => {
|
|
if(!progressionSourceMatches(context, progression.magicCurve, progression.specialty)) return;
|
|
|
|
progression.levels(context.currentHD).forEach(level => {
|
|
specs.push(buildProgressionGrantSpec(progression, level, context));
|
|
});
|
|
});
|
|
|
|
return specs;
|
|
};
|
|
|
|
const grantSpecFromKey = function(def, key, context) {
|
|
const universalLevel = keyLevelFromPrefix(key, def.universalKeyPrefix);
|
|
if(universalLevel) return buildUniversalGrantSpec(def, universalLevel, context);
|
|
|
|
const conditional = (def.conditionalGrants || []).find(grant => grant.key === key);
|
|
if(conditional) {
|
|
return makeGrantSpec(
|
|
conditional.key,
|
|
conditional.source,
|
|
conditional.level,
|
|
conditional.name,
|
|
conditional.description,
|
|
context.currentHD >= conditional.level && conditional.isExpected(context)
|
|
);
|
|
}
|
|
|
|
for(const progression of (def.progressionGrants || [])) {
|
|
const progressionLevel = keyLevelFromPrefix(key, progression.keyPrefix);
|
|
if(progressionLevel) return buildProgressionGrantSpec(progression, progressionLevel, context);
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
const inferGrantKeyFromMetadata = function(def, values, prefix) {
|
|
const source = normalizeGrantSource(values[`${prefix}granted_source`]);
|
|
const level = int(values, `${prefix}granted_level`, 0);
|
|
|
|
if(source === normalizeGrantSource(UNIVERSAL_SOURCE_NAME) && level > 0) {
|
|
return `${def.universalKeyPrefix}${level}`;
|
|
}
|
|
|
|
const conditional = (def.conditionalGrants || []).find(grant =>
|
|
source === normalizeGrantSource(grant.source)
|
|
);
|
|
|
|
if(conditional) return conditional.key;
|
|
|
|
const progression = (def.progressionGrants || []).find(grant =>
|
|
source === normalizeGrantSource(grant.source)
|
|
);
|
|
|
|
if(progression && level > 0) return `${progression.keyPrefix}${level}`;
|
|
|
|
return "";
|
|
};
|
|
|
|
const grantSortLevel = function(value) {
|
|
const level = parseInt(value, 10);
|
|
return isNaN(level) || level <= 0 ? 999999 : level;
|
|
};
|
|
|
|
const grantSortSourceRank = function(source) {
|
|
const normalized = normalizeGrantSource(source);
|
|
|
|
// HD is always the primary sort. This rank is only a tie-breaker inside the same HD.
|
|
if(normalized === normalizeGrantSource(UNIVERSAL_SOURCE_NAME)) return 0;
|
|
if(normalized) return 10;
|
|
return 50;
|
|
};
|
|
|
|
const buildGrantReporder = function(rows) {
|
|
return rows
|
|
.slice()
|
|
.sort((left, right) => {
|
|
const leftLevel = grantSortLevel(left.level);
|
|
const rightLevel = grantSortLevel(right.level);
|
|
|
|
// Primary: HD, lowest to highest.
|
|
if(leftLevel !== rightLevel) return leftLevel - rightLevel;
|
|
|
|
// Secondary: within the same HD, Universal goes first.
|
|
if(left.sourceRank !== right.sourceRank) return left.sourceRank - right.sourceRank;
|
|
|
|
// Tertiary: preserve existing order as much as possible.
|
|
return left.originalIndex - right.originalIndex;
|
|
})
|
|
.map(row => row.rowId)
|
|
.join(',');
|
|
};
|
|
|
|
const setGrantReporderAfterRowsExist = function(def, orderRows, duplicateRowIds, callback) {
|
|
// Intentionally do not write _reporder for automatic feat/ability grants.
|
|
// Writing _reporder_repeating_feats or _reporder_repeating_abilities makes Roll20
|
|
// snap the repeating sections back into the worker's sorted order after HD,
|
|
// progression, grant metadata, or row changes. New grant rows can still be
|
|
// created, updated, hidden, and de-duplicated; existing row order is left alone.
|
|
if(callback) callback();
|
|
};
|
|
|
|
const updateGrantedRowsForSection = function(def, context, callback) {
|
|
getSectionIDs(def.section, function(rowIds) {
|
|
const attrsToGet = [];
|
|
|
|
rowIds.forEach(rowId => {
|
|
attrsToGet.push(`${def.section}_${rowId}_grant_key`);
|
|
attrsToGet.push(`${def.section}_${rowId}_granted_level`);
|
|
attrsToGet.push(`${def.section}_${rowId}_granted_source`);
|
|
attrsToGet.push(`${def.section}_${rowId}_grant_hidden`);
|
|
});
|
|
|
|
getAttrs(attrsToGet, function(values) {
|
|
const attrsToSet = {};
|
|
const existingGrantKeys = {};
|
|
const duplicateRowsToRemove = [];
|
|
const duplicateRowIds = {};
|
|
const orderRows = [];
|
|
|
|
rowIds.forEach((rowId, originalIndex) => {
|
|
const prefix = `${def.section}_${rowId}_`;
|
|
let key = str(values, `${prefix}grant_key`);
|
|
|
|
if(!key) {
|
|
key = inferGrantKeyFromMetadata(def, values, prefix);
|
|
if(key) attrsToSet[`${prefix}grant_key`] = key;
|
|
}
|
|
|
|
const spec = grantSpecFromKey(def, key, context);
|
|
|
|
if(spec) {
|
|
if(existingGrantKeys[spec.key]) {
|
|
duplicateRowsToRemove.push(`${def.section}_${rowId}`);
|
|
duplicateRowIds[rowId] = true;
|
|
return;
|
|
}
|
|
|
|
existingGrantKeys[spec.key] = true;
|
|
attrsToSet[`${prefix}granted_level`] = spec.level;
|
|
attrsToSet[`${prefix}granted_source`] = spec.source;
|
|
attrsToSet[`${prefix}source_available`] = spec.available ? "1" : "0";
|
|
attrsToSet[`${prefix}grant_hidden`] = spec.hidden ? "1" : "0";
|
|
|
|
orderRows.push({
|
|
rowId,
|
|
level: grantSortLevel(spec.level),
|
|
sourceRank: grantSortSourceRank(spec.source),
|
|
source: spec.source,
|
|
originalIndex
|
|
});
|
|
return;
|
|
}
|
|
|
|
const manualLevel = int(values, `${prefix}granted_level`, 0);
|
|
const manualSource = str(values, `${prefix}granted_source`);
|
|
|
|
attrsToSet[`${prefix}source_available`] = genericSourceAvailability(
|
|
context.currentHD,
|
|
manualLevel
|
|
);
|
|
attrsToSet[`${prefix}grant_hidden`] = "0";
|
|
|
|
orderRows.push({
|
|
rowId,
|
|
level: grantSortLevel(manualLevel),
|
|
sourceRank: grantSortSourceRank(manualSource),
|
|
source: manualSource,
|
|
originalIndex
|
|
});
|
|
});
|
|
|
|
if(context.enableAutomaticGrants) {
|
|
buildExpectedGrantSpecs(def, context).forEach(spec => {
|
|
if(existingGrantKeys[spec.key]) return;
|
|
|
|
const rowId = generateRowID();
|
|
const prefix = `${def.section}_${rowId}_`;
|
|
|
|
existingGrantKeys[spec.key] = true;
|
|
attrsToSet[`${prefix}grant_key`] = spec.key;
|
|
attrsToSet[`${prefix}${def.nameAttr}`] = spec.name;
|
|
attrsToSet[`${prefix}${def.descriptionAttr}`] = spec.description;
|
|
attrsToSet[`${prefix}granted_level`] = spec.level;
|
|
attrsToSet[`${prefix}granted_source`] = spec.source;
|
|
attrsToSet[`${prefix}source_available`] = spec.available ? "1" : "0";
|
|
attrsToSet[`${prefix}grant_hidden`] = spec.hidden ? "1" : "0";
|
|
|
|
orderRows.push({
|
|
rowId,
|
|
level: grantSortLevel(spec.level),
|
|
sourceRank: grantSortSourceRank(spec.source),
|
|
source: spec.source,
|
|
originalIndex: orderRows.length + rowIds.length
|
|
});
|
|
});
|
|
}
|
|
|
|
duplicateRowsToRemove.forEach(rowName => {
|
|
removeRepeatingRow(rowName);
|
|
});
|
|
|
|
if(Object.keys(attrsToSet).length > 0) {
|
|
setAttrs(attrsToSet, function() {
|
|
setGrantReporderAfterRowsExist(def, orderRows, duplicateRowIds, callback);
|
|
});
|
|
} else {
|
|
setGrantReporderAfterRowsExist(def, orderRows, duplicateRowIds, callback);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
const updateGrantSectionsSequentially = function(context, index, callback) {
|
|
if(index >= GRANT_SECTIONS.length) {
|
|
if(callback) callback();
|
|
return;
|
|
}
|
|
|
|
updateGrantedRowsForSection(GRANT_SECTIONS[index], context, function() {
|
|
updateGrantSectionsSequentially(context, index + 1, callback);
|
|
});
|
|
};
|
|
|
|
const updateAutomaticGrants = function(callback) {
|
|
getAttrs(["HD", "MagicCurve", "Specialty", "Versatile", "mystic", "diffuse_background", "primarydefinitionname", "enable_automatic_grants"], function(values) {
|
|
const isNewSheet = values.HD === "" || values.HD === undefined;
|
|
const autoEnableNewSheet = isNewSheet && !grantIsChecked(values.enable_automatic_grants);
|
|
|
|
const context = {
|
|
currentHD: Math.max(0, int(values, "HD", 0)),
|
|
magicCurve: str(values, "MagicCurve"),
|
|
specialty: str(values, "Specialty"),
|
|
versatile: grantIsChecked(values.Versatile),
|
|
mystic: grantIsChecked(values.mystic),
|
|
diffuseBackground: hasDiffuseBackground(values),
|
|
enableAutomaticGrants: grantIsChecked(values.enable_automatic_grants) || autoEnableNewSheet
|
|
};
|
|
|
|
const finishUpdate = function() {
|
|
updateGrantSectionsSequentially(context, 0, callback);
|
|
};
|
|
|
|
if(autoEnableNewSheet) {
|
|
setAttrs({ enable_automatic_grants: "1" }, finishUpdate);
|
|
return;
|
|
}
|
|
|
|
finishUpdate();
|
|
});
|
|
};
|
|
|
|
let automaticGrantsRunning = false;
|
|
let automaticGrantsQueued = false;
|
|
|
|
const queueUpdateAutomaticGrants = function() {
|
|
if(automaticGrantsRunning) {
|
|
automaticGrantsQueued = true;
|
|
return;
|
|
}
|
|
|
|
automaticGrantsRunning = true;
|
|
updateAutomaticGrants(function() {
|
|
automaticGrantsRunning = false;
|
|
|
|
if(automaticGrantsQueued) {
|
|
automaticGrantsQueued = false;
|
|
queueUpdateAutomaticGrants();
|
|
}
|
|
});
|
|
};
|
|
|
|
on("change:hd change:magiccurve change:specialty change:versatile change:mystic change:diffuse_background change:primarydefinitionname change:enable_automatic_grants sheet:opened change:repeating_feats:granted_level change:repeating_feats:granted_source change:repeating_feats:grant_key change:repeating_feats:grant_hidden change:repeating_abilities:granted_level change:repeating_abilities:granted_source change:repeating_abilities:grant_key change:repeating_abilities:grant_hidden remove:repeating_feats remove:repeating_abilities", function() {
|
|
queueUpdateAutomaticGrants();
|
|
});
|
|
|
|
on("change:repeating_abilities:minimizeability " +
|
|
"change:repeating_abilities:absavethrow " +
|
|
"change:repeating_abilities:abilitytype " +
|
|
"change:repeating_abilities:abilitysrconfirm " +
|
|
"change:repeating_abilities:asprof " +
|
|
"change:repeating_abilities:abilityname", function(){
|
|
getAttrs(["repeating_abilities_absavethrow","repeating_abilities_abilitytype",
|
|
"repeating_abilities_abilitysrconfirm","repeating_abilities_asprof"],function(values){
|
|
let savethrow = (values.repeating_abilities_absavethrow);
|
|
let type = (values.repeating_abilities_abilitytype);
|
|
let sr = (values.repeating_abilities_abilitysrconfirm);
|
|
let SpellProf = (values.repeating_abilities_asprof);
|
|
let Macro = `&{template:custom}{{title=@{abilityname}}}{{subtitle=@{character_name}}}{{Range=@{abilityrange}}}`+
|
|
`{{Target=@{abilitytarget}}}{{Duration=@{abilityduration}}}`;
|
|
if(savethrow !== "N/A"){
|
|
Macro = Macro + `{{${savethrow} save=@{abilitydc}}}`;
|
|
}
|
|
if(type !== "0"){
|
|
Macro = Macro + `{{${type}=[[(@{abilitydicenum}@{abilitydicetype})]]}}`;
|
|
}
|
|
if(SpellProf === "1"){
|
|
Macro = Macro.replace(`{{${type}=[[(@{abilitydicenum}@{abilitydicetype})]]}}`,
|
|
`{{${type}=[[(@{abilitydicenum}@{abilitydicetype})+(@{SpellProf}*@{abilitydicenum})]]}}`);
|
|
}
|
|
if(sr === "1"){
|
|
Macro = Macro + `{{Spell Resistance=[[1d20+@{HD}+@{spellpenetrationbonus}+`+
|
|
`(0?{Do you have any Spell penetration Bonuses?|0})]]}}`;
|
|
}
|
|
Macro = Macro + `{{desc=@{abilitydescriptiontext}}}`
|
|
setAttrs({
|
|
repeating_abilities_abilityroll: Macro
|
|
});
|
|
});
|
|
});
|
|
|
|
on("change:hd sheet:opened",function(){
|
|
getAttrs(["HD","CloseRange","MediumRange","LongRange"],function(values){
|
|
let HD = parseFloat(values.HD)||0;
|
|
let Close = 25 + (Math.floor(HD/2)*5);
|
|
let Medium = 100 + (HD*10);
|
|
let Long = 400 + (HD*40);
|
|
setAttrs({
|
|
CloseRange: Close,
|
|
MediumRange: Medium,
|
|
LongRange: Long
|
|
});
|
|
}) ;
|
|
});
|
|
//</editor-fold>
|
|
|
|
// <editor-fold desc="Attack Bonuses">
|
|
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col} sheet:opened change:bab change:slow change:haste`,function(){
|
|
getAttrs(["BAB","slow","haste",`character_name`],function(values){
|
|
getSectionIDs(`repeating_weapons${col}`,function(array){
|
|
let rows = {};
|
|
for (let arrayID of array){
|
|
rows[`repeating_weapons${col}_` + arrayID + `_weaponbab`] = values.BAB;
|
|
rows[`repeating_weapons${col}_` + arrayID + `_`+`weaponhaste`] = values.haste;
|
|
rows[`repeating_weapons${col}_` + arrayID + `_`+`weaponslow`] = values.slow;
|
|
rows[`repeating_weapons${col}_` + arrayID + `_`+`character_name`] = values.character_name;
|
|
rows[`repeating_weapons${col}_` + arrayID + `_`+`ArrayID`] = arrayID;
|
|
}
|
|
if(rows){
|
|
setAttrs(rows);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
// WeaponCol.forEach(col =>{
|
|
// on(`change:repeating_weapons${col}:grandmaster change:repeating_weapons${col}:weaponminimize` +
|
|
// `change:repeating_weapons${col}:weaponhaste`,function(){
|
|
// getAttrs([`repeating_weapons${col}_grandmaster`],function(values){
|
|
// let grandmaster = parseFloat(values[`repeating_weapons${col}_grandmaster`]) || 0;
|
|
// if (grandmaster === 2){
|
|
// grandmaster =
|
|
// }
|
|
// })
|
|
// })
|
|
// })
|
|
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col}:bonustoattack change:repeating_weapons${col}:weaponhaste change:repeating_weapons${col}:weaponslow` +
|
|
` change:repeating_weapons${col}:critlow change:repeating_weapons${col}:weaponbab change:repeating_weapons${col}:weaponminimize` +
|
|
` change:repeating_weapons${col}:enhancetoattack change:repeating_weapons${col}:grandmaster`, function(){
|
|
getAttrs([`repeating_weapons${col}_bonustoattack`,`repeating_weapons${col}_critlow`,`repeating_weapons${col}_weaponhaste`
|
|
,`repeating_weapons${col}_weaponbab`,`repeating_weapons${col}_weaponslow`,`repeating_weapons${col}_enhancetoattack`,
|
|
`repeating_weapons${col}_grandmaster`],function(values){
|
|
let featbonus = values[`repeating_weapons${col}_bonustoattack`] || 0;
|
|
let enhance = parseFloat(values[`repeating_weapons${col}_enhancetoattack`]) || 0;
|
|
let mincrit = parseFloat(values[`repeating_weapons${col}_critlow`]) || 0;
|
|
let grandmaster = parseFloat(values[`repeating_weapons${col}_grandmaster`]) || 0;
|
|
let BAB = parseFloat(values[`repeating_weapons${col}_weaponbab`]);
|
|
let Macro = `&{template:custom}{{title=Attack(s)}}{{subtitle=@{character_name}'s @{weaponname}}}`+
|
|
`{{First Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]+@{weapontohit}[Key Attribute]+${featbonus}`+
|
|
`[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}[slow]]]}}`;
|
|
if(values[`repeating_weapons${col}_weaponhaste`] === `1`){
|
|
Macro = Macro + `{{Haste Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
if(values[`repeating_weapons${col}_weaponslow`] === `0`) {
|
|
if (BAB - 5 > 0) {
|
|
Macro = Macro + `{{Second Attack=[[1d20cs>${mincrit}+${BAB - 5}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
if (grandmaster === 2){
|
|
Macro = Macro + `{{Second Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
if (BAB - 10 > 0) {
|
|
Macro = Macro + `{{Third Attack=[[1d20cs>${mincrit}+${BAB - 10}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
if (grandmaster === 3){
|
|
Macro = Macro + `{{Third Attack=[[1d20cs>${mincrit}+${BAB - 5}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
if (BAB - 15 > 0) {
|
|
Macro = Macro + `{{Fourth Attack=[[1d20cs>${mincrit}+${BAB - 15}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
if (grandmaster === 4){
|
|
Macro = Macro + `{{Fourth Attack=[[1d20cs>${mincrit}+${BAB - 10}[Base Attack]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
}
|
|
let toSetAttrs = {};
|
|
toSetAttrs[`repeating_weapons${col}_fullattackroll`] = Macro;
|
|
setAttrs(toSetAttrs);
|
|
});
|
|
});
|
|
});
|
|
// </editor-fold>
|
|
|
|
// <editor-fold desc="Full Attack Custom Roll Parser">
|
|
|
|
const buildSingleAttackMacro = function(data) {
|
|
const attack = data.attacks[0] || { label: "Single Attack", base: 0, slowPenalty: 0 };
|
|
|
|
const damageAction = makeFullAttackActionTarget(data.section, data.rowId, "singleattackdamage");
|
|
const confirmAction = makeFullAttackActionTarget(data.section, data.rowId, "singleattackconfirm");
|
|
|
|
let macro = `&{template:custom}{{title=Single Attack}}{{subtitle=${data.characterName}'s ${data.weaponName}}}`;
|
|
macro += `{{fullattack=1}}{{characterid=@{character_id}}}`;
|
|
macro += `{{attack1_next=[[0]]}}`;
|
|
macro += `{{attack1_damage_action=${damageAction}}}`;
|
|
macro += `{{attack1_confirm_action=${confirmAction}}}`;
|
|
macro += `{{attack1_label=Attack}}`;
|
|
macro += `{{attack1=[[${buildFullAttackExpression(data, attack)}]]}}`;
|
|
|
|
return macro;
|
|
};
|
|
|
|
|
|
const rollSingleAttackConfirmation = function(col, eventInfo) {
|
|
getAttrs(getFullAttackAttrs(col), function(values) {
|
|
const data = buildFullAttackData(col, values, eventInfo);
|
|
const attack = data.attacks[0] || { label: "Single Attack", base: 0, slowPenalty: 0 };
|
|
|
|
const normalAction = makeFullAttackActionTarget(data.section, data.rowId, "singleattackdamage");
|
|
const criticalAction = makeFullAttackActionTarget(data.section, data.rowId, "singleattackcritdamage");
|
|
|
|
const macro =
|
|
`&{template:custom}` +
|
|
`{{title=Critical Confirmation}}` +
|
|
`{{subtitle=${data.characterName}'s ${data.weaponName} - Single Attack}}` +
|
|
`{{fullattackconfirm=1}}` +
|
|
`{{characterid=@{character_id}}}` +
|
|
`{{confirm_normal_action=${normalAction}}}` +
|
|
`{{confirm_critical_action=${criticalAction}}}` +
|
|
`{{confirm=[[${buildFullAttackExpression(data, attack)}]]}}`;
|
|
|
|
startRoll(macro, function(roll) {
|
|
finishRoll(roll.rollId);
|
|
});
|
|
});
|
|
};
|
|
|
|
const getRepeatingRowIdFromEvent = function(eventInfo, section) {
|
|
const source = eventInfo && (eventInfo.sourceAttribute || eventInfo.sourceButton || "");
|
|
const match = source.match(new RegExp(`repeating_${section}_([^_]+)_`));
|
|
return match ? match[1] : "";
|
|
};
|
|
|
|
const rollTerm = function(value, fallback = "0") {
|
|
if(value === undefined || value === null || value === "") return fallback;
|
|
return String(value);
|
|
};
|
|
|
|
const firstFilledValue = function(values, keys, fallback = "") {
|
|
for(const key of keys) {
|
|
if(values[key] !== undefined && values[key] !== null && values[key] !== "") return values[key];
|
|
}
|
|
return fallback;
|
|
};
|
|
|
|
const isChecked = function(value) {
|
|
return value === "1" || value === 1 || value === true || value === "on" || value === ".5";
|
|
};
|
|
|
|
const fullAttackCritThreshold = function(value) {
|
|
let threshold = parseInt(value, 10);
|
|
if(isNaN(threshold)) threshold = 20;
|
|
threshold = Math.max(2, threshold);
|
|
threshold = Math.min(20, threshold);
|
|
return threshold;
|
|
};
|
|
|
|
const getFirstDie = function(rollResult) {
|
|
if(rollResult && Array.isArray(rollResult.dice) && rollResult.dice.length > 0) {
|
|
return parseInt(rollResult.dice[0], 10) || 0;
|
|
}
|
|
if(rollResult && Array.isArray(rollResult.rolls)) {
|
|
for(const part of rollResult.rolls) {
|
|
if(part && Array.isArray(part.results) && part.results.length > 0) {
|
|
const dieResult = part.results[0];
|
|
if(typeof dieResult === "number") return dieResult;
|
|
if(dieResult && dieResult.v !== undefined) return parseInt(dieResult.v, 10) || 0;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
const makeFullAttackActionTarget = function(section, rowId, actionName) {
|
|
if(rowId) return `repeating_${section}_${rowId}_${actionName}`;
|
|
return `repeating_${section}_${actionName}`;
|
|
};
|
|
|
|
const getFullAttackAttrs = function(col) {
|
|
return [
|
|
`repeating_weapons${col}_ArrayID`,
|
|
`repeating_weapons${col}_weaponname`,
|
|
`repeating_weapons${col}_bonustoattack`,
|
|
`repeating_weapons${col}_critlow`,
|
|
`repeating_weapons${col}_weaponhaste`,
|
|
`repeating_weapons${col}_weaponbab`,
|
|
`repeating_weapons${col}_weaponslow`,
|
|
`repeating_weapons${col}_enhancetoattack`,
|
|
`repeating_weapons${col}_grandmaster`,
|
|
`repeating_weapons${col}_weapontohit`,
|
|
`repeating_weapons${col}_weapontodamage`,
|
|
`repeating_weapons${col}_dnum`,
|
|
`repeating_weapons${col}_dtype`,
|
|
`repeating_weapons${col}_bonustodamage`,
|
|
`repeating_weapons${col}_enchdamagedice`,
|
|
`repeating_weapons${col}_extraenchdicecrit`,
|
|
`repeating_weapons${col}_weaponcritmod`,
|
|
`repeating_weapons${col}_twohanded`,
|
|
`repeating_weapons${col}_weapondamagtype`,
|
|
`repeating_weapons${col}_weapondamage`,
|
|
`repeating_weapons${col}_critweapondamage`,
|
|
"character_name",
|
|
"BAB",
|
|
"haste",
|
|
"slow"
|
|
];
|
|
};
|
|
|
|
const buildFullAttackSequence = function(baseAttack, hasteToggle, slowToggle, grandmaster) {
|
|
const slowed = isChecked(slowToggle);
|
|
const attacks = [
|
|
{ label: "First Attack", base: baseAttack, slowPenalty: slowed ? 1 : 0 }
|
|
];
|
|
|
|
if(isChecked(hasteToggle)) {
|
|
attacks.push({ label: "Haste Attack", base: baseAttack, slowPenalty: 0 });
|
|
}
|
|
|
|
if(!slowed) {
|
|
if(baseAttack - 5 > 0 || grandmaster === 2) {
|
|
attacks.push({ label: "Second Attack", base: grandmaster === 2 ? baseAttack : baseAttack - 5, slowPenalty: 0 });
|
|
}
|
|
if(baseAttack - 10 > 0 || grandmaster === 3) {
|
|
attacks.push({ label: "Third Attack", base: grandmaster === 3 ? baseAttack - 5 : baseAttack - 10, slowPenalty: 0 });
|
|
}
|
|
if(baseAttack - 15 > 0 || grandmaster === 4) {
|
|
attacks.push({ label: "Fourth Attack", base: grandmaster === 4 ? baseAttack - 10 : baseAttack - 15, slowPenalty: 0 });
|
|
}
|
|
}
|
|
|
|
return attacks.slice(0, 5);
|
|
};
|
|
|
|
const buildFullAttackData = function(col, values, eventInfo) {
|
|
const prefix = `repeating_weapons${col}_`;
|
|
const section = `weapons${col}`;
|
|
const rowId = getRepeatingRowIdFromEvent(eventInfo, section) || rollTerm(values[`${prefix}ArrayID`], "");
|
|
const baseAttack = parseFloat(firstFilledValue(values, [`${prefix}weaponbab`, "BAB"], "0")) || 0;
|
|
const hasteToggle = firstFilledValue(values, [`${prefix}weaponhaste`, "haste"], "0");
|
|
const slowToggle = firstFilledValue(values, [`${prefix}weaponslow`, "slow"], "0");
|
|
const grandmaster = parseFloat(firstFilledValue(values, [`${prefix}grandmaster`], "0")) || 0;
|
|
|
|
const data = {
|
|
section,
|
|
rowId,
|
|
characterName: rollTerm(values.character_name, "Character"),
|
|
weaponName: rollTerm(values[`${prefix}weaponname`], "Weapon"),
|
|
critLow: fullAttackCritThreshold(firstFilledValue(values, [`${prefix}critlow`], "20")),
|
|
featAttack: rollTerm(values[`${prefix}bonustoattack`], "0"),
|
|
enhancement: rollTerm(values[`${prefix}enhancetoattack`], "0"),
|
|
attackKey: rollTerm(values[`${prefix}weapontohit`], "0"),
|
|
damageKey: rollTerm(values[`${prefix}weapontodamage`], "0"),
|
|
diceNumber: rollTerm(values[`${prefix}dnum`], "0"),
|
|
diceType: rollTerm(values[`${prefix}dtype`], "d6"),
|
|
featDamage: rollTerm(values[`${prefix}bonustodamage`], "0"),
|
|
magicDice: rollTerm(values[`${prefix}enchdamagedice`], ""),
|
|
bonusCriticalDice: rollTerm(values[`${prefix}extraenchdicecrit`], ""),
|
|
criticalMultiplier: parseFloat(values[`${prefix}weaponcritmod`]) || 0,
|
|
twoHanded: isChecked(values[`${prefix}twohanded`]),
|
|
damageType: rollTerm(values[`${prefix}weapondamagtype`], ""),
|
|
storedNormalDamage: rollTerm(values[`${prefix}weapondamage`], ""),
|
|
storedCriticalDamage: rollTerm(values[`${prefix}critweapondamage`], "")
|
|
};
|
|
data.attacks = buildFullAttackSequence(baseAttack, hasteToggle, slowToggle, grandmaster);
|
|
return data;
|
|
};
|
|
|
|
const buildFullAttackExpression = function(data, attack) {
|
|
let expression = `1d20cs>${data.critLow}+${attack.base}[Base Attack]+${data.attackKey}[Key Attribute]+${data.featAttack}`+
|
|
`[Feat Bonuses]+${data.enhancement}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})[Misc.]`;
|
|
if(attack.slowPenalty) {
|
|
expression += `-${attack.slowPenalty}[Slow]`;
|
|
}
|
|
return expression;
|
|
};
|
|
|
|
const buildFullAttackMacro = function(data) {
|
|
let macro = `&{template:custom}{{title=Full Attack}}{{subtitle=${data.characterName}'s ${data.weaponName}}}`+
|
|
`{{fullattack=1}}{{characterid=@{character_id}}}`;
|
|
data.attacks.forEach((attack, index) => {
|
|
const attackNumber = index + 1;
|
|
macro += `{{attack${attackNumber}_next=[[0]]}}`;
|
|
macro += `{{attack${attackNumber}_damage_action=${makeFullAttackActionTarget(data.section, data.rowId, "fullattackdamage")}}}`;
|
|
macro += `{{attack${attackNumber}_confirm_action=${makeFullAttackActionTarget(data.section, data.rowId, `fullattackconfirm${attackNumber}`)}}}`;
|
|
});
|
|
data.attacks.forEach((attack, index) => {
|
|
macro += `{{attack${index + 1}_label=${attack.label}}}`;
|
|
macro += `{{attack${index + 1}=[[${buildFullAttackExpression(data, attack)}]]}}`;
|
|
});
|
|
return macro;
|
|
};
|
|
|
|
const buildFallbackDamageMacro = function(data, critical = false) {
|
|
const magicDamageType = data.damageType ? data.damageType : "energy";
|
|
const miscDamage = `(0?{Do you have any miscellaneous bonuses?|0})[Misc.]`;
|
|
if(!critical) {
|
|
let macro = `&{template:custom}{{title=Damage}}{{subtitle=${data.characterName}'s ${data.weaponName}}}`;
|
|
if(data.twoHanded) {
|
|
macro += `{{desc=${data.characterName} deals [[${data.diceNumber}${data.diceType}+[[floor(${data.damageKey}*1.5)]]`+
|
|
`[Ability]+${data.featDamage}[Feats/Other]+${data.enhancement}[Enhancement]+${miscDamage}]] physical damage `;
|
|
} else {
|
|
macro += `{{desc=${data.characterName} deals [[${data.diceNumber}${data.diceType}+[[${data.damageKey}]][Ability]+`+
|
|
`${data.featDamage}[Feats/Other]+${data.enhancement}[Enhancement]+${miscDamage}]] physical damage `;
|
|
}
|
|
if(data.magicDice) {
|
|
macro += ` and [[${data.magicDice}[${magicDamageType}]]] ${magicDamageType} damage`;
|
|
}
|
|
macro += ` with ${data.weaponName}.}}`;
|
|
return macro;
|
|
}
|
|
|
|
let macro = `&{template:custom}{{title=Critical Damage}}{{subtitle=${data.characterName}'s ${data.weaponName}}}`;
|
|
if(data.twoHanded) {
|
|
macro += `{{desc=${data.characterName} deals an astonishing [[[[${data.diceNumber}*${data.criticalMultiplier}]]`+
|
|
`${data.diceType}+[[(floor(${data.damageKey}*1.5)*${data.criticalMultiplier})]][Ability]+[[(${data.featDamage}*`+
|
|
`${data.criticalMultiplier})]][Feats/Other]+[[(${data.enhancement}*${data.criticalMultiplier})]][Enhancement]+`+
|
|
`${miscDamage}]]`;
|
|
} else {
|
|
macro += `{{desc=${data.characterName} deals an astonishing [[[[${data.diceNumber}*${data.criticalMultiplier}]]`+
|
|
`${data.diceType}+[[(floor(${data.damageKey})*${data.criticalMultiplier})]][Ability]+[[(${data.featDamage}*`+
|
|
`${data.criticalMultiplier})]][Feats/Other]+[[(${data.enhancement}*${data.criticalMultiplier})]][Enhancement]+`+
|
|
`${miscDamage}]]`;
|
|
}
|
|
if(data.magicDice) {
|
|
macro += ` + [[${data.magicDice}[${magicDamageType}]]] ${magicDamageType} damage`;
|
|
}
|
|
if(data.bonusCriticalDice) {
|
|
macro += ` + [[${data.bonusCriticalDice}[Bonus Dice]]] bonus damage`;
|
|
}
|
|
macro += ` with ${data.weaponName}.}}`;
|
|
return macro;
|
|
};
|
|
|
|
const rollWeaponDamageFromFullAttack = function(col, critical, eventInfo) {
|
|
getAttrs(getFullAttackAttrs(col), function(values) {
|
|
const data = buildFullAttackData(col, values, eventInfo);
|
|
const macro = buildFallbackDamageMacro(data, critical);
|
|
startRoll(macro, function(roll) {
|
|
finishRoll(roll.rollId);
|
|
});
|
|
});
|
|
};
|
|
|
|
const rollFullAttackConfirmation = function(col, attackIndex, eventInfo) {
|
|
getAttrs(getFullAttackAttrs(col), function(values) {
|
|
const data = buildFullAttackData(col, values, eventInfo);
|
|
const attack = data.attacks[attackIndex - 1] || data.attacks[0];
|
|
const normalAction = makeFullAttackActionTarget(data.section, data.rowId, "fullattackdamage");
|
|
const criticalAction = makeFullAttackActionTarget(data.section, data.rowId, "fullattackcritdamage");
|
|
const macro = `&{template:custom}{{title=Critical Confirmation}}{{subtitle=${data.characterName}'s ${data.weaponName} - `+
|
|
`${attack.label}}}{{fullattackconfirm=1}}{{characterid=@{character_id}}}{{confirm_normal_action=${normalAction}}}`+
|
|
`{{confirm_critical_action=${criticalAction}}}{{confirm=[[${buildFullAttackExpression(data, attack)}]]}}`;
|
|
startRoll(macro, function(roll) {
|
|
finishRoll(roll.rollId);
|
|
});
|
|
});
|
|
};
|
|
|
|
const FOCUS_POINTS_QUERY = "?{Focus Points Spent|1|2|3|4}";
|
|
|
|
const clampFocusPoints = function(value) {
|
|
let focusPoints = parseInt(value, 10);
|
|
if(isNaN(focusPoints)) focusPoints = 1;
|
|
focusPoints = Math.max(1, focusPoints);
|
|
focusPoints = Math.min(4, focusPoints);
|
|
return focusPoints;
|
|
};
|
|
|
|
const rollResultTotal = function(rollResult, fallback = 0) {
|
|
if(rollResult && rollResult.result !== undefined) {
|
|
const parsed = parseFloat(rollResult.result);
|
|
return isNaN(parsed) ? fallback : parsed;
|
|
}
|
|
|
|
if(rollResult && rollResult.total !== undefined) {
|
|
const parsed = parseFloat(rollResult.total);
|
|
return isNaN(parsed) ? fallback : parsed;
|
|
}
|
|
|
|
return fallback;
|
|
};
|
|
|
|
const focusRowAttr = function(data, attr) {
|
|
if(data.rowId) return `repeating_${data.section}_${data.rowId}_${attr}`;
|
|
return `repeating_${data.section}_${attr}`;
|
|
};
|
|
|
|
const getFocusAttackAttrs = function(col) {
|
|
return getFullAttackAttrs(col).concat([
|
|
`repeating_weapons${col}_focus_points_used`
|
|
]);
|
|
};
|
|
|
|
const buildFocusAttackData = function(col, values, eventInfo) {
|
|
const data = buildFullAttackData(col, values, eventInfo);
|
|
const prefix = `repeating_weapons${col}_`;
|
|
|
|
data.focusPointsUsed = clampFocusPoints(values[`${prefix}focus_points_used`]);
|
|
|
|
return data;
|
|
};
|
|
|
|
const buildFocusAttackExpression = function(data, attack, focusPointsTerm) {
|
|
let expression =
|
|
`1d20cs>${data.critLow}` +
|
|
`+${attack.base}[Base Attack]` +
|
|
`+${data.attackKey}[Key Attribute]` +
|
|
`+${data.featAttack}[Feat Bonuses]` +
|
|
`+${data.enhancement}[Enhancement]` +
|
|
`+(${focusPointsTerm}*3)[Focus]` +
|
|
`+(0?{Do you have any miscellaneous bonuses?|0})[Misc.]`;
|
|
|
|
if(attack.slowPenalty) {
|
|
expression += `-${attack.slowPenalty}[Slow]`;
|
|
}
|
|
|
|
return expression;
|
|
};
|
|
|
|
const buildFocusAttackMacro = function(data) {
|
|
const attack = data.attacks[0] || {
|
|
label: "Focus Attack",
|
|
base: 0,
|
|
slowPenalty: 0
|
|
};
|
|
|
|
const damageAction = makeFullAttackActionTarget(data.section, data.rowId, "focusattackdamage");
|
|
const confirmAction = makeFullAttackActionTarget(data.section, data.rowId, "focusattackconfirm");
|
|
|
|
let macro =
|
|
`&{template:custom}` +
|
|
`{{title=Focus Attack}}` +
|
|
`{{subtitle=${data.characterName}'s ${data.weaponName}}}` +
|
|
`{{fullattack=1}}` +
|
|
`{{characterid=@{character_id}}}` +
|
|
`{{Focus Points=[[${FOCUS_POINTS_QUERY}]]}}` +
|
|
`{{attack1_next=[[0]]}}` +
|
|
`{{attack1_damage_action=${damageAction}}}` +
|
|
`{{attack1_confirm_action=${confirmAction}}}` +
|
|
`{{attack1_label=Focus Attack}}` +
|
|
`{{attack1=[[${buildFocusAttackExpression(data, attack, FOCUS_POINTS_QUERY)}]]}}`;
|
|
|
|
return macro;
|
|
};
|
|
|
|
const buildFocusDamageMacro = function(data, critical = false) {
|
|
const focusPoints = clampFocusPoints(data.focusPointsUsed);
|
|
const focusDamageBonus = focusPoints * 3;
|
|
const focusedDiceNumber = `[[${data.diceNumber}+${focusPoints}]]`;
|
|
const magicDamageType = data.damageType ? data.damageType : "energy";
|
|
const miscDamage = `(0?{Do you have any miscellaneous bonuses?|0})[Misc.]`;
|
|
const focusPointText = focusPoints === 1 ? "focus point" : "focus points";
|
|
|
|
if(!critical) {
|
|
let macro =
|
|
`&{template:custom}` +
|
|
`{{title=Focus Damage}}` +
|
|
`{{subtitle=${data.characterName}'s ${data.weaponName}}}`;
|
|
|
|
if(data.twoHanded) {
|
|
macro +=
|
|
`{{desc=${data.characterName} spends ${focusPoints} ${focusPointText} and deals ` +
|
|
`[[${focusedDiceNumber}${data.diceType}` +
|
|
`+[[floor(${data.damageKey}*1.5)]][Ability]` +
|
|
`+${data.featDamage}[Feats/Other]` +
|
|
`+${data.enhancement}[Enhancement]` +
|
|
`+${focusDamageBonus}[Focus]` +
|
|
`+${miscDamage}]] physical damage`;
|
|
} else {
|
|
macro +=
|
|
`{{desc=${data.characterName} spends ${focusPoints} ${focusPointText} and deals ` +
|
|
`[[${focusedDiceNumber}${data.diceType}` +
|
|
`+[[${data.damageKey}]][Ability]` +
|
|
`+${data.featDamage}[Feats/Other]` +
|
|
`+${data.enhancement}[Enhancement]` +
|
|
`+${focusDamageBonus}[Focus]` +
|
|
`+${miscDamage}]] physical damage`;
|
|
}
|
|
|
|
if(data.magicDice) {
|
|
macro += ` and [[${data.magicDice}[${magicDamageType}]]] ${magicDamageType} damage`;
|
|
}
|
|
|
|
macro += ` with ${data.weaponName}.}}`;
|
|
|
|
return macro;
|
|
}
|
|
|
|
let macro =
|
|
`&{template:custom}` +
|
|
`{{title=Focus Critical Damage}}` +
|
|
`{{subtitle=${data.characterName}'s ${data.weaponName}}}`;
|
|
|
|
if(data.twoHanded) {
|
|
macro +=
|
|
`{{desc=${data.characterName} spends ${focusPoints} ${focusPointText} and deals an astonishing ` +
|
|
`[[[[(${data.diceNumber}+${focusPoints})*${data.criticalMultiplier}]]${data.diceType}` +
|
|
`+[[(floor(${data.damageKey}*1.5)*${data.criticalMultiplier})]][Ability]` +
|
|
`+[[(${data.featDamage}*${data.criticalMultiplier})]][Feats/Other]` +
|
|
`+[[(${data.enhancement}*${data.criticalMultiplier})]][Enhancement]` +
|
|
`+[[(${focusDamageBonus}*${data.criticalMultiplier})]][Focus]` +
|
|
`+${miscDamage}]]`;
|
|
} else {
|
|
macro +=
|
|
`{{desc=${data.characterName} spends ${focusPoints} ${focusPointText} and deals an astonishing ` +
|
|
`[[[[(${data.diceNumber}+${focusPoints})*${data.criticalMultiplier}]]${data.diceType}` +
|
|
`+[[(floor(${data.damageKey})*${data.criticalMultiplier})]][Ability]` +
|
|
`+[[(${data.featDamage}*${data.criticalMultiplier})]][Feats/Other]` +
|
|
`+[[(${data.enhancement}*${data.criticalMultiplier})]][Enhancement]` +
|
|
`+[[(${focusDamageBonus}*${data.criticalMultiplier})]][Focus]` +
|
|
`+${miscDamage}]]`;
|
|
}
|
|
|
|
if(data.magicDice) {
|
|
macro += ` + [[${data.magicDice}[${magicDamageType}]]] ${magicDamageType} damage`;
|
|
}
|
|
|
|
if(data.bonusCriticalDice) {
|
|
macro += ` + [[${data.bonusCriticalDice}[Bonus Dice]]] bonus damage`;
|
|
}
|
|
|
|
macro += ` with ${data.weaponName}.}}`;
|
|
|
|
return macro;
|
|
};
|
|
|
|
const rollFocusDamage = function(col, critical, eventInfo) {
|
|
getAttrs(getFocusAttackAttrs(col), function(values) {
|
|
const data = buildFocusAttackData(col, values, eventInfo);
|
|
const macro = buildFocusDamageMacro(data, critical);
|
|
|
|
startRoll(macro, function(roll) {
|
|
finishRoll(roll.rollId);
|
|
});
|
|
});
|
|
};
|
|
|
|
const rollFocusAttackConfirmation = function(col, eventInfo) {
|
|
getAttrs(getFocusAttackAttrs(col), function(values) {
|
|
const data = buildFocusAttackData(col, values, eventInfo);
|
|
const attack = data.attacks[0] || {
|
|
label: "Focus Attack",
|
|
base: 0,
|
|
slowPenalty: 0
|
|
};
|
|
|
|
const normalAction = makeFullAttackActionTarget(data.section, data.rowId, "focusattackdamage");
|
|
const criticalAction = makeFullAttackActionTarget(data.section, data.rowId, "focusattackcritdamage");
|
|
|
|
const macro =
|
|
`&{template:custom}` +
|
|
`{{title=Focus Critical Confirmation}}` +
|
|
`{{subtitle=${data.characterName}'s ${data.weaponName}}}` +
|
|
`{{fullattackconfirm=1}}` +
|
|
`{{characterid=@{character_id}}}` +
|
|
`{{confirm_normal_action=${normalAction}}}` +
|
|
`{{confirm_critical_action=${criticalAction}}}` +
|
|
`{{confirm=[[${buildFocusAttackExpression(data, attack, data.focusPointsUsed)}]]}}`;
|
|
|
|
startRoll(macro, function(roll) {
|
|
finishRoll(roll.rollId);
|
|
});
|
|
});
|
|
};
|
|
|
|
WeaponCol.forEach(col => {
|
|
on(`clicked:repeating_weapons${col}:singleattack`, function(eventInfo) {
|
|
getAttrs(getFullAttackAttrs(col), function(values) {
|
|
const data = buildFullAttackData(col, values, eventInfo);
|
|
const macro = buildSingleAttackMacro(data);
|
|
|
|
startRoll(macro, function(roll) {
|
|
const naturalDie = getFirstDie(roll.results.attack1);
|
|
const computed = {
|
|
attack1_next: naturalDie >= data.critLow ? 1 : 0
|
|
};
|
|
|
|
finishRoll(roll.rollId, computed);
|
|
});
|
|
});
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:singleattackdamage`, function(eventInfo) {
|
|
rollWeaponDamageFromFullAttack(col, false, eventInfo);
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:singleattackcritdamage`, function(eventInfo) {
|
|
rollWeaponDamageFromFullAttack(col, true, eventInfo);
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:singleattackconfirm`, function(eventInfo) {
|
|
rollSingleAttackConfirmation(col, eventInfo);
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:fullattackroll`, function(eventInfo) {
|
|
getAttrs(getFullAttackAttrs(col), function(values) {
|
|
const data = buildFullAttackData(col, values, eventInfo);
|
|
const macro = buildFullAttackMacro(data);
|
|
startRoll(macro, function(roll) {
|
|
const computed = {};
|
|
data.attacks.forEach((attack, index) => {
|
|
const key = `attack${index + 1}`;
|
|
const naturalDie = getFirstDie(roll.results[key]);
|
|
computed[`${key}_next`] = naturalDie >= data.critLow ? 1 : 0;
|
|
});
|
|
finishRoll(roll.rollId, computed);
|
|
});
|
|
});
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:fullattackdamage`, function(eventInfo) {
|
|
rollWeaponDamageFromFullAttack(col, false, eventInfo);
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:fullattackcritdamage`, function(eventInfo) {
|
|
rollWeaponDamageFromFullAttack(col, true, eventInfo);
|
|
});
|
|
|
|
for(let attackIndex = 1; attackIndex <= 5; attackIndex++) {
|
|
on(`clicked:repeating_weapons${col}:fullattackconfirm${attackIndex}`, function(eventInfo) {
|
|
rollFullAttackConfirmation(col, attackIndex, eventInfo);
|
|
});
|
|
}
|
|
on(`clicked:repeating_weapons${col}:focusattack`, function(eventInfo) {
|
|
getAttrs(getFocusAttackAttrs(col), function(values) {
|
|
const data = buildFocusAttackData(col, values, eventInfo);
|
|
const macro = buildFocusAttackMacro(data);
|
|
|
|
startRoll(macro, function(roll) {
|
|
const naturalDie = getFirstDie(roll.results.attack1);
|
|
const focusPoints = clampFocusPoints(rollResultTotal(roll.results["Focus Points"], 1));
|
|
|
|
const computed = {
|
|
attack1_next: naturalDie >= data.critLow ? 1 : 0
|
|
};
|
|
|
|
const attrsToSet = {
|
|
[focusRowAttr(data, "focus_points_used")]: focusPoints
|
|
};
|
|
|
|
setAttrs(attrsToSet, function() {
|
|
finishRoll(roll.rollId, computed);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:focusattackdamage`, function(eventInfo) {
|
|
rollFocusDamage(col, false, eventInfo);
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:focusattackcritdamage`, function(eventInfo) {
|
|
rollFocusDamage(col, true, eventInfo);
|
|
});
|
|
|
|
on(`clicked:repeating_weapons${col}:focusattackconfirm`, function(eventInfo) {
|
|
rollFocusAttackConfirmation(col, eventInfo);
|
|
});
|
|
});
|
|
// </editor-fold>
|
|
|
|
// <editor-fold desc="Normal Damage">
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col}:weapontodamage change:repeating_weapons${col}:dnum change:repeating_weapons${col}:dtype` +
|
|
` change:repeating_weapons${col}:bonustodamage change:repeating_weapons${col}:enchdamagedice change:repeating_weapons${col}:weapondamagtype` +
|
|
` change:repeating_weapons${col}:twohanded change:repeating_weapons${col}:enhancetoattack change:repeating_weapons${col}:weaponminimize`, function(){
|
|
getAttrs([`repeating_weapons${col}_weapontodamage`,`repeating_weapons${col}_dnum`,`repeating_weapons${col}_dtype`,
|
|
`repeating_weapons${col}_bonustodamage`,`repeating_weapons${col}_enchdamagedice`,`repeating_weapons${col}_weapondamagtype`,
|
|
`repeating_weapons${col}_twohanded`,`repeating_weapons${col}_enhancetoattack`],function(values){
|
|
let numberOfDice = (values[`repeating_weapons${col}_dnum`]) || 0;
|
|
let dieType = values[`repeating_weapons${col}_dtype`] || 0;
|
|
let featBonus = values[`repeating_weapons${col}_bonustodamage`];
|
|
let magicBonus = values[`repeating_weapons${col}_enhancetoattack`];
|
|
let magicDice = values[`repeating_weapons${col}_enchdamagedice`];
|
|
let damageType = values[`repeating_weapons${col}_weapondamagtype`];
|
|
let twoHanded = values[`repeating_weapons${col}_twohanded`];
|
|
let macro = `&{template:custom}{{title=Damage}}{{subtitle=@{character_name}'s @{weaponname}}}`;
|
|
if (twoHanded === "on"){
|
|
macro = macro + `{{desc=@{character_name} deals [[${numberOfDice}${dieType}+[[floor(@{weapontodamage}*1.5)]][Ability]`+
|
|
`+${featBonus}[Feats/Other]+${magicBonus}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})[Misc.]]] physical damage `
|
|
}
|
|
if (twoHanded !=="on") {
|
|
macro = macro + `{{desc=@{character_name} deals [[${numberOfDice}${dieType}+[[@{weapontodamage}]][Ability]` +
|
|
`+${featBonus}[Feats/Other]+${magicBonus}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})[Misc.]]] physical damage `
|
|
}
|
|
if (magicDice){
|
|
macro = macro + ` and [[${magicDice}[${damageType}]]] ${damageType} damage`;
|
|
}
|
|
macro = macro + ` with @{weaponname}.}}`;
|
|
let toSetAttrs = {};
|
|
toSetAttrs[`repeating_weapons${col}_weapondamage`] = macro;
|
|
setAttrs(toSetAttrs);
|
|
});
|
|
});
|
|
});
|
|
// </editor-fold>
|
|
|
|
// <editor-fold desc="Critical Damage">
|
|
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col}:weapontodamage change:repeating_weapons${col}:dnum change:repeating_weapons${col}:dtype` +
|
|
` change:repeating_weapons${col}:bonustodamage change:repeating_weapons${col}:enchdamagedice change:repeating_weapons${col}:weapondamagtype` +
|
|
` change:repeating_weapons${col}:twohanded change:repeating_weapons${col}:enhancetoattack change:repeating_weapons${col}:weaponminimize` +
|
|
` change:repeating_weapons${col}:weaponcritmod change:repeating_weapons${col}:extraenchdicecrit`, function() {
|
|
getAttrs([`repeating_weapons${col}_weapontodamage`, `repeating_weapons${col}_dnum`, `repeating_weapons${col}_dtype`,
|
|
`repeating_weapons${col}_bonustodamage`, `repeating_weapons${col}_enchdamagedice`, `repeating_weapons${col}_weapondamagtype`,
|
|
`repeating_weapons${col}_twohanded`, `repeating_weapons${col}_enhancetoattack`, `repeating_weapons${col}_extraenchdicecrit`,
|
|
`repeating_weapons${col}_weaponcritmod`], function (values) {
|
|
let numberOfDice = (values[`repeating_weapons${col}_dnum`]) || 0;
|
|
let dieType = values[`repeating_weapons${col}_dtype`] || 0;
|
|
let featBonus = values[`repeating_weapons${col}_bonustodamage`];
|
|
let magicBonus = values[`repeating_weapons${col}_enhancetoattack`];
|
|
let magicDice = values[`repeating_weapons${col}_enchdamagedice`];
|
|
let bonusCriticalDice = values[`repeating_weapons${col}_extraenchdicecrit`];
|
|
let criticalMultiplier = parseFloat(values[`repeating_weapons${col}_weaponcritmod`]) || 0;
|
|
let damageType = values[`repeating_weapons${col}_weapondamagtype`];
|
|
let twoHanded = values[`repeating_weapons${col}_twohanded`];
|
|
let macro = `&{template:custom}{{title=Critical Damage}}{{subtitle=@{character_name}'s @{weaponname}}}`;
|
|
if (twoHanded ==="on"){
|
|
macro = macro + `{{desc=@{character_name} deals an astonishing [[[[${numberOfDice}*${criticalMultiplier}]]${dieType}+`
|
|
+`[[(floor(@{weapontodamage}*1.5)*${criticalMultiplier})]][Ability]+[[(${featBonus}*${criticalMultiplier})]]`
|
|
+`[Feats/Other]+[[(${magicBonus}*${criticalMultiplier})]][Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})[Misc.]]]`;
|
|
}
|
|
if (twoHanded !=="on") {
|
|
macro = macro + `{{desc=@{character_name} deals an astonishing [[[[${numberOfDice}*${criticalMultiplier}]]${dieType}+`
|
|
+`[[(floor(@{weapontodamage})*${criticalMultiplier})]][Ability]+[[(${featBonus}*${criticalMultiplier})]]`
|
|
+`[Feats/Other]+[[(${magicBonus}*${criticalMultiplier})]][Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})[Misc.]]]`;
|
|
}
|
|
if (magicDice){
|
|
macro = macro + ` + [[${magicDice}[${damageType}]]] ${damageType} damage`;
|
|
}
|
|
if (bonusCriticalDice){
|
|
macro = macro + ` + [[${bonusCriticalDice}[Bonus Dice]]] bonus damage`
|
|
}
|
|
macro = macro + ` with @{weaponname}.}}`
|
|
let toSetAttrs = {};
|
|
toSetAttrs[`repeating_weapons${col}_critweapondamage`] = macro;
|
|
setAttrs(toSetAttrs);
|
|
});
|
|
});
|
|
});
|
|
// </editor-fold>
|
|
|
|
// <editor-fold desc="Advanced Attacks">
|
|
|
|
// Twin Talon
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col}:bonustoattack change:repeating_weapons${col}:weaponhaste change:repeating_weapons${col}:weaponslow` +
|
|
` change:repeating_weapons${col}:critlow change:repeating_weapons${col}:weaponbab change:repeating_weapons${col}:weaponminimize` +
|
|
` change:repeating_weapons${col}:enhancetoattack change:repeating_weapons${col}:grandmaster`, function(){
|
|
getAttrs([`repeating_weapons${col}_bonustoattack`,`repeating_weapons${col}_critlow`,`repeating_weapons${col}_weaponhaste`
|
|
,`repeating_weapons${col}_weaponbab`,`repeating_weapons${col}_weaponslow`,`repeating_weapons${col}_enhancetoattack`,
|
|
`repeating_weapons${col}_grandmaster`],function(values){
|
|
let featbonus = values[`repeating_weapons${col}_bonustoattack`] || 0;
|
|
let enhance = parseFloat(values[`repeating_weapons${col}_enhancetoattack`]) || 0;
|
|
let mincrit = parseFloat(values[`repeating_weapons${col}_critlow`]) || 0;
|
|
let BAB = parseFloat(values[`repeating_weapons${col}_weaponbab`]);
|
|
let Macro = `&{template:custom}{{title=Twin Talon}}{{subtitle=@{character_name}'s @{weaponname}}}`+
|
|
`{{First Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Twin Talon Penalty]+@{weapontohit}[Key Attribute]`+
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}[slow]]]}}`+
|
|
`{{Second Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Twin Talon Penalty]+@{weapontohit}[Key Attribute]`+
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}[slow]]]}}`;
|
|
if(values[`repeating_weapons${col}_weaponhaste`] === `1`){
|
|
Macro = Macro + `{{Haste Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Twin Talon Penalty]+@{weapontohit}[Key Attribute]` +
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})]]}}`;
|
|
}
|
|
Macro = Macro + `{{desc=If damage is dealt, target must make a fortitude save against their wound DC. This roll has a ` +
|
|
`-2 circumstance penalty for each attack that dealt damage. If they fail, they receive a normal [*wound*]` +
|
|
`(https://tabletopdefined.com/Afflictions/#wound). On a second failure the wound becomes the severe variant.}}`
|
|
let toSetAttrs = {};
|
|
toSetAttrs[`repeating_weapons${col}_twintalon`] = Macro;
|
|
setAttrs(toSetAttrs);
|
|
});
|
|
});
|
|
});
|
|
|
|
// Crack Shot
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col}:bonustoattack change:repeating_weapons${col}:weaponhaste change:repeating_weapons${col}:weaponslow` +
|
|
` change:repeating_weapons${col}:critlow change:repeating_weapons${col}:weaponbab change:repeating_weapons${col}:weaponminimize` +
|
|
` change:repeating_weapons${col}:enhancetoattack change:repeating_weapons${col}:grandmaster`, function(){
|
|
getAttrs([`repeating_weapons${col}_bonustoattack`,`repeating_weapons${col}_critlow`,`repeating_weapons${col}_weaponhaste`
|
|
,`repeating_weapons${col}_weaponbab`,`repeating_weapons${col}_weaponslow`,`repeating_weapons${col}_enhancetoattack`,
|
|
`repeating_weapons${col}_grandmaster`],function(values){
|
|
let featbonus = values[`repeating_weapons${col}_bonustoattack`] || 0;
|
|
let enhance = parseFloat(values[`repeating_weapons${col}_enhancetoattack`]) || 0;
|
|
let mincrit = parseFloat(values[`repeating_weapons${col}_critlow`]) || 0;
|
|
let grandmaster = parseFloat(values[`repeating_weapons${col}_grandmaster`]) || 0;
|
|
let BAB = parseFloat(values[`repeating_weapons${col}_weaponbab`]);
|
|
let Macro = `&{template:custom}{{title=Crack Shot}}{{subtitle=@{character_name}'s @{weaponname}}}`+
|
|
`{{Bonus Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}[Key Attribute]`+
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}`+
|
|
`[slow]]]}}`+
|
|
`{{First Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}[Key Attribute]`+
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}`+
|
|
`[slow]]]}}`;
|
|
if(values[`repeating_weapons${col}_weaponhaste`] === `1`){
|
|
Macro = Macro + `{{Haste Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Crack Shot Penalty+@{weapontohit}[Key`+
|
|
` Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
if(values[`repeating_weapons${col}_weaponslow`] === `0`) {
|
|
if (BAB - 5 > 0) {
|
|
Macro = Macro + `{{Second Attack=[[1d20cs>${mincrit}+${BAB - 5}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
if (grandmaster === 2){
|
|
Macro = Macro + `{{Second Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
if (BAB - 10 > 0) {
|
|
Macro = Macro + `{{Third Attack=[[1d20cs>${mincrit}+${BAB - 10}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
if (grandmaster === 3){
|
|
Macro = Macro + `{{Third Attack=[[1d20cs>${mincrit}+${BAB - 5}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
if (BAB - 15 > 0) {
|
|
Macro = Macro + `{{Fourth Attack=[[1d20cs>${mincrit}+${BAB - 15}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
if (grandmaster === 4){
|
|
Macro = Macro + `{{Fourth Attack=[[1d20cs>${mincrit}+${BAB - 10}[Base Attack]-2[Crack Shot Penalty]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})]]}}`;
|
|
}
|
|
}
|
|
let toSetAttrs = {};
|
|
toSetAttrs[`repeating_weapons${col}_crackshot`] = Macro;
|
|
setAttrs(toSetAttrs);
|
|
});
|
|
});
|
|
});
|
|
|
|
//Deadly Assault
|
|
WeaponCol.forEach(col => {
|
|
on(`change:repeating_weapons${col}:bonustoattack change:repeating_weapons${col}:weaponhaste change:repeating_weapons${col}:weaponslow` +
|
|
` change:repeating_weapons${col}:critlow change:repeating_weapons${col}:weaponbab change:repeating_weapons${col}:weaponminimize` +
|
|
` change:repeating_weapons${col}:enhancetoattack change:repeating_weapons${col}:grandmaster`, function(){
|
|
getAttrs([`repeating_weapons${col}_bonustoattack`,`repeating_weapons${col}_critlow`,`repeating_weapons${col}_weaponhaste`
|
|
,`repeating_weapons${col}_weaponbab`,`repeating_weapons${col}_weaponslow`,`repeating_weapons${col}_enhancetoattack`,
|
|
`repeating_weapons${col}_grandmaster`],function(values){
|
|
let featbonus = values[`repeating_weapons${col}_bonustoattack`] || 0;
|
|
let enhance = parseFloat(values[`repeating_weapons${col}_enhancetoattack`]) || 0;
|
|
let mincrit = parseFloat(values[`repeating_weapons${col}_critlow`]) || 0;
|
|
let grandmaster = parseFloat(values[`repeating_weapons${col}_grandmaster`]) || 0;
|
|
let BAB = parseFloat(values[`repeating_weapons${col}_weaponbab`]);
|
|
let Macro = `&{template:custom}{{title=Deadly Assault}}{{subtitle=@{character_name}'s @{weaponname}}}`+
|
|
`{{Bonus Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]+@{weapontohit}[Key Attribute]`+
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}`+
|
|
`[slow]]]}}`+
|
|
`{{First Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]+@{weapontohit}[Key Attribute]`+
|
|
`+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous bonuses?|0})-@{slow}`+
|
|
`[slow]]]}}`;
|
|
if (BAB - 5 > 0) {
|
|
Macro = Macro + `{{Second Attack=[[1d20cs>${mincrit}+${BAB - 5}[Base Attack]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})-@{slow}[Slow]]]}}`;
|
|
}
|
|
if (grandmaster === 2){
|
|
Macro = Macro + `{{Second Attack=[[1d20cs>${mincrit}+${BAB}[Base Attack]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})-@{slow}[Slow]]]}}`;
|
|
}
|
|
if (BAB - 10 > 0) {
|
|
Macro = Macro + `{{Third Attack=[[1d20cs>${mincrit}+${BAB - 10}[Base Attack]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})-@{slow}[Slow]]]}}`;
|
|
}
|
|
if (grandmaster === 3){
|
|
Macro = Macro + `{{Third Attack=[[1d20cs>${mincrit}+${BAB - 5}[Base Attack]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})-@{slow}[Slow]]]}}`;
|
|
}
|
|
if (BAB - 15 > 0) {
|
|
Macro = Macro + `{{Fourth Attack=[[1d20cs>${mincrit}+${BAB - 15}[Base Attack]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})-@{slow}[Slow]]]}}`;
|
|
}
|
|
if (grandmaster === 4){
|
|
Macro = Macro + `{{Fourth Attack=[[1d20cs>${mincrit}+${BAB - 10}[Base Attack]+@{weapontohit}`+
|
|
`[Key Attribute]+${featbonus}[Feat Bonuses]+${enhance}[Enhancement]+(0?{Do you have any miscellaneous `+
|
|
`bonuses?|0})-@{slow}[Slow]]]}}`;
|
|
}
|
|
let toSetAttrs = {};
|
|
toSetAttrs[`repeating_weapons${col}_deadlyassault`] = Macro;
|
|
setAttrs(toSetAttrs);
|
|
});
|
|
});
|
|
});
|
|
|
|
//Focus <Pending>
|
|
// weapondamage is the name of the damage button
|
|
// Focus <Legacy>
|
|
// WeaponCol.forEach(col => {
|
|
// on(`clicked:repeating_weapons${col}:focusattack`, function(){
|
|
// getAttrs([
|
|
// `repeating_weapons${col}_bonustoattack`,
|
|
// `repeating_weapons${col}_critlow`,
|
|
// `repeating_weapons${col}_weaponhaste`,
|
|
// `repeating_weapons${col}_weaponbab`,
|
|
// `repeating_weapons${col}_enhancetoattack`,
|
|
// `repeating_weapons${col}_weapontodamage`,
|
|
// `repeating_weapons${col}_bonustodamage`,
|
|
// `repeating_weapons${col}_dnum`,
|
|
// `repeating_weapons${col}_dtype`,
|
|
// `repeating_weapons${col}_enchdamagedice`,
|
|
// `repeating_weapons${col}_extraenchdicecrit`,
|
|
// `repeating_weapons${col}_weaponcritmod`,
|
|
// `repeating_weapons${col}_twohanded`,
|
|
// `repeating_weapons${col}_weapontohit`,
|
|
// // `repeating_weapons${col}_character_name`,
|
|
// // `repeating_weapons${col}_arrayID`,
|
|
// `repeating_weapons${col}_weapondamagtype`], function(values){
|
|
// // const arrayID = values[`repeating_weapons${col}_arrayID`]
|
|
// // const characterName = values[`repeating_weapons${col}_character_name`];
|
|
// const featBonusToAttack = values[`repeating_weapons${col}_bonustoattack`] || 0;
|
|
// const featBonusToDamage = values[`repeating_weapons${col}_bonustodamage`] || 0;
|
|
// const dieQuantity = values[`repeating_weapons${col}_dnum`] || 1;
|
|
// const dieType = values[`repeating_weapons${col}_dtype`];
|
|
// const weaponEnhancement = values[`repeating_weapons${col}_enhancetoattack`] || 0;
|
|
// const baseAttack = values[`repeating_weapons${col}_weaponbab`] || 0;
|
|
// const minCritThreshold = values[`repeating_weapons${col}_critlow`]|| 20 ;
|
|
// const keyAttackAttribute = values[`repeating_weapons${col}_weapontohit`] || 0;
|
|
// const keyDamageAttribute = values[`repeating_weapons${col}_weapontodamage`] ;
|
|
// const twoHandedToggle = values[`repeating_weapons${col}_twohanded`];
|
|
// const magicDice = values[`repeating_weapons${col}_enchdamagedice`];
|
|
// const magicCriticalDice = values[`repeating_weapons${col}_extraenchdicecrit`];
|
|
// const magicDamageType = values[`repeating_weapons${col}_weapondamagtype`];
|
|
// const criticalModifier = values[`repeating_weapons${col}_weaponcritmod`];
|
|
// let macroRoll = `&{template:custom} {{title=Focus Attack}}{{Attack Roll=[[1d20cs>${minCritThreshold}+${baseAttack}`+
|
|
// `[BAB]+${keyAttackAttribute}[Key Attribute]+${featBonusToAttack}[Feats]+${weaponEnhancement}[Enhancement]`+
|
|
// `-@{slow}[Slow]+((0?{Focus Points Spent})*3)[Focus]+(0?{Miscellaneous attack bonuses?})[Misc.]]]}}`;
|
|
// if (twoHandedToggle === "on"){
|
|
// macroRoll = macroRoll + `{{Damage=[[[[${dieQuantity}+(0?{Focus Points Spent})]]${dieType}+floor(`+
|
|
// `(${keyDamageAttribute})*1.5)[Key Attribute]+${featBonusToDamage}[Feat]+${weaponEnhancement}[Magic]+((`+
|
|
// `0?{Focus Points Spent})*3)[Focus]]]}}`;
|
|
// }
|
|
// if (twoHandedToggle !== "on"){
|
|
// macroRoll = macroRoll + `{{Damage=[[[[${dieQuantity}+(0?{Focus Points Spent})]]${dieType}+floor(`+
|
|
// `${keyDamageAttribute})[Key Attribute]+${featBonusToDamage}[Feat]+${weaponEnhancement}[Magic]+((0?{`+
|
|
// `Focus Points Spent})*3)[Focus]]]}}`;
|
|
// }
|
|
// if (magicDice){
|
|
// macroRoll = macroRoll + `{{${magicDamageType} Damage=[[${magicDice}[${magicDamageType}]]]}}`;
|
|
// }
|
|
// macroRoll = macroRoll + `{{Critical Confirmation Roll=[[1d20cs>${minCritThreshold}+${baseAttack}`+
|
|
// `[BAB]+${keyAttackAttribute}[Key Attribute]+${featBonusToAttack}[Feats]+${weaponEnhancement}[Enhancement]`+
|
|
// `-@{slow}[Slow]+((0?{Focus Points Spent})*3)[Focus]+(0?{Miscellaneous attack bonuses?})[Misc.]]]}}`;
|
|
// if (twoHandedToggle === "on"){
|
|
// macroRoll = macroRoll + `{{Critical Damage=[[[[((${dieQuantity}+(0?{Focus Points Spent}))*${criticalModifier})]]`+
|
|
// `${dieType}+(floor(${keyDamageAttribute}*1.5)*${criticalModifier})[Key Attribute]+(`+
|
|
// `${featBonusToDamage}*${criticalModifier}[Feat])+(${weaponEnhancement}*${criticalModifier})+(((0?{Focus`+
|
|
// ` Points Spent})*3)*${criticalModifier})[Focus]]]}}`;
|
|
// }
|
|
// if (twoHandedToggle !== "on"){
|
|
// macroRoll = macroRoll + `{{Critical Damage=[[[[((${dieQuantity}+(0?{Focus Points Spent}))*${criticalModifier})]]`+
|
|
// `${dieType}+(${keyDamageAttribute}*${criticalModifier})[Key Attribute]+(`+
|
|
// `${featBonusToDamage}*${criticalModifier}[Feat])+(${weaponEnhancement}*${criticalModifier})+(((0?{Focus`+
|
|
// ` Points Spent})*3)*${criticalModifier})[Focus]]]}}`;
|
|
// }
|
|
// if (magicCriticalDice){
|
|
// macroRoll = macroRoll + `{{Bonus Critical Damage = [[${magicCriticalDice}]]}}`
|
|
// }
|
|
// startRoll(macroRoll,function(roll){
|
|
// finishRoll(roll.rollId);
|
|
// });
|
|
// });
|
|
// });
|
|
// })
|
|
// </editor-fold>
|
|
|
|
// <editor-fold desc="attr migration staging">
|
|
const CURRENT_SHEET_VERSION = 5;
|
|
|
|
|
|
const checkedLegacyCondition = function(value) {
|
|
return value === "1" || value === 1 || value === true || value === "on" || value === "yes";
|
|
};
|
|
|
|
const migrateFixedConditionsToRepeatingConditions = function(callback) {
|
|
getSectionIDs("repeating_conditions", function(existingRowIds) {
|
|
// If the new repeating section already has rows, do not duplicate anything.
|
|
if(existingRowIds && existingRowIds.length > 0) {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
const legacyAttrs = TTD_CONDITIONS.map(condition => condition.legacyAttr);
|
|
|
|
getAttrs(legacyAttrs, function(values) {
|
|
const attrsToSet = {};
|
|
|
|
TTD_CONDITIONS.forEach(condition => {
|
|
if(!checkedLegacyCondition(values[condition.legacyAttr])) return;
|
|
|
|
const rowId = generateRowID();
|
|
attrsToSet[`repeating_conditions_${rowId}_condition_type`] = condition.name;
|
|
attrsToSet[`repeating_conditions_${rowId}_condition_effect`] = condition.effect;
|
|
});
|
|
|
|
if(Object.keys(attrsToSet).length > 0) {
|
|
setAttrs(attrsToSet, callback);
|
|
return;
|
|
}
|
|
|
|
callback();
|
|
});
|
|
});
|
|
};
|
|
|
|
const migrateDamageReductionRepeatingSection = function(callback) {
|
|
getSectionIDs("repeating_damage_reduction", function(oldRowIds) {
|
|
if(!oldRowIds || oldRowIds.length === 0) {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
getSectionIDs("repeating_damagereduction", function(newRowIds) {
|
|
// Avoid duplicating rows if the user already recreated them after the section rename.
|
|
if(newRowIds && newRowIds.length > 0) {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
const attrsToGet = [];
|
|
oldRowIds.forEach(rowId => {
|
|
attrsToGet.push(`repeating_damage_reduction_${rowId}_damage_reduction_value`);
|
|
attrsToGet.push(`repeating_damage_reduction_${rowId}_damage_reduction_bypass`);
|
|
});
|
|
|
|
getAttrs(attrsToGet, function(oldValues) {
|
|
const attrsToSet = {};
|
|
|
|
oldRowIds.forEach(oldRowId => {
|
|
const newRowId = generateRowID();
|
|
attrsToSet[`repeating_damagereduction_${newRowId}_damage_reduction_value`] =
|
|
oldValues[`repeating_damage_reduction_${oldRowId}_damage_reduction_value`] || "";
|
|
attrsToSet[`repeating_damagereduction_${newRowId}_damage_reduction_bypass`] =
|
|
oldValues[`repeating_damage_reduction_${oldRowId}_damage_reduction_bypass`] || "";
|
|
});
|
|
|
|
setAttrs(attrsToSet, callback);
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
on("sheet:opened", function() {
|
|
getAttrs(["sheet_version"], function(values) {
|
|
const sheetVersion = int(values, "sheet_version", 0);
|
|
|
|
const finishMigrations = function() {
|
|
if(sheetVersion < CURRENT_SHEET_VERSION) {
|
|
setAttrs({
|
|
sheet_version: CURRENT_SHEET_VERSION
|
|
});
|
|
}
|
|
};
|
|
|
|
const runConditionMigration = function() {
|
|
if(sheetVersion < 5) {
|
|
migrateFixedConditionsToRepeatingConditions(finishMigrations);
|
|
return;
|
|
}
|
|
|
|
finishMigrations();
|
|
};
|
|
|
|
if(sheetVersion < 4) {
|
|
migrateDamageReductionRepeatingSection(runConditionMigration);
|
|
return;
|
|
}
|
|
|
|
runConditionMigration();
|
|
});
|
|
});
|
|
//</editor-fold>
|
|
|
|
</script>
|
|
|
|
<!--</editor-fold--> |