mirror of
https://github.com/Nighthawk42/roll20-character-sheets.git
synced 2026-08-30 19:52:29 +00:00
Added Value boxes for Action Points along with reset button. removed "readonly" from speed
1042 lines
38 KiB
HTML
1042 lines
38 KiB
HTML
<rolltemplate class="sheet-rolltemplate-check">
|
||
<div class="sheet-template-container">
|
||
<div class="sheet-template-title">{{name}}</div>
|
||
|
||
<div class="sheet-template-row">
|
||
<strong>Check:</strong> {{check}}
|
||
</div>
|
||
|
||
<div class="sheet-template-row">
|
||
<strong>Roll:</strong> {{roll}}
|
||
</div>
|
||
|
||
<div class="sheet-template-row">
|
||
<strong>Result:</strong> {{computed::result}}
|
||
</div>
|
||
|
||
<div class="sheet-template-row">
|
||
<strong>Degrees:</strong> {{computed::degrees}}
|
||
</div>
|
||
|
||
</div>
|
||
</rolltemplate>
|
||
|
||
|
||
<input type="hidden" class="sheet-tabstoggle" name="attr_sheetTab" value="core" />
|
||
<div>
|
||
<button type="action" name="act_core" class="sheet-button0">Core Stats</button>
|
||
<button type="action" name="act_inventory" class="sheet-button1">Inventory</button>
|
||
<button type="action" name="act_leveling" class="sheet-button2">Leveling</button>
|
||
<button type="action" name="act_magic" class="sheet-button3">Magic</button>
|
||
<button type="action" name="act_survival" class="sheet-button4">Survival</button>
|
||
</div>
|
||
|
||
<div class="sheet-core">
|
||
|
||
<!-- Ability Scores -->
|
||
<section class="ability-scores">
|
||
<h2>Character Info</h2>
|
||
<div class="score-grid">
|
||
|
||
<div>
|
||
<label>STRENGTH</label>
|
||
<input type="number" name="attr_str" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_str_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>PERCEPTION</label>
|
||
<input type="number" name="attr_per" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_per_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>ENDURANCE</label>
|
||
<input type="number" name="attr_end" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_end_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>INTELLIGENCE</label>
|
||
<input type="number" name="attr_int" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_int_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>AGILITY</label>
|
||
<input type="number" name="attr_agl" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_agl_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>ACCURACY</label>
|
||
<input type="number" name="attr_acc" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_acc_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>CHARISMA</label>
|
||
<input type="number" name="attr_cha" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_cha_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>LUCK</label>
|
||
<input type="number" name="attr_lck" min="10" max="70" step="5" value="20">
|
||
<input type="text" name="attr_lck_mod" placeholder="Modifier">
|
||
</div>
|
||
<div>
|
||
<label>Luck Points</label>
|
||
<input type="number" name="attr_luck_points_current" min="0" max="attr_luck_points_max" step="1">
|
||
<span>Luck Point Max</span>
|
||
<span name="attr_luck_points_max"></span>
|
||
<span>: +2 DoS, ignore 1 Wound</span>
|
||
</div>
|
||
<div>
|
||
<label>Name:</label>
|
||
<input type="text" name="attr_character_name">
|
||
|
||
</div>
|
||
<div>
|
||
<label>Race:</label>
|
||
<select name="attr_race">
|
||
<option value="Human">Human</option>
|
||
<option value="Aetherial">Aetherial</option>
|
||
<option value="Orc">Orc</option>
|
||
<option value="Dwarf">Dwarf</option>
|
||
<option value="Elf">Elf</option>
|
||
<option value="Halfling">Halfling</option>
|
||
<option value="Gnome">Gnome</option>
|
||
<option value="Granitetouched">Granitetouched</option>
|
||
<option value="Sylvan">Sylvan</option>
|
||
<option value="Lizardmen">Lizardmen</option>
|
||
<option value="Elemental">Elemental</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label>Racial Benefits:</label>
|
||
<span name="attr_racial_benefits">
|
||
</div>
|
||
<div>
|
||
<label>Weight:</label>
|
||
<input type="text" name="attr_weight">
|
||
</div>
|
||
<div>
|
||
<label>Height:</label>
|
||
<input type="text" name="attr_height">
|
||
</div>
|
||
<div>
|
||
<label>Reputation:</label>
|
||
<input type="text" name="attr_reputation">
|
||
</div>
|
||
<div>
|
||
<label>Features:</label>
|
||
<input type="text" name="attr_features">
|
||
</div>
|
||
<div>
|
||
<label>Critical Bonus:</label>
|
||
<input type="number" name="attr_lck_mod">
|
||
</div>
|
||
<div class="rest-actions">
|
||
<label>Rest Actions</label>
|
||
<button type="action" name="act_break">Break</button>
|
||
<button type="action" name="act_sleep">Sleep</button>
|
||
<!-- Hidden "Yes/No" buttons for confirmations -->
|
||
<button type="action" name="act_break_confirm" style="display:none;"></button>
|
||
<button type="action" name="act_sleep_confirm" style="display:none;"></button>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</section> <!-- end ability scores -->
|
||
|
||
<!-- Skills -->
|
||
<section>
|
||
<h2>Skills</h2>
|
||
<div class="skill-check">
|
||
<label for="attr_selected_skill">Skill:</label>
|
||
<select name="attr_selected_skill" id="attr_selected_skill">
|
||
<option value="athletics">Athletics (Phys)</option>
|
||
<option value="bows">Bows (ACC)</option>
|
||
<option value="carouse">Carouse (CHA)</option>
|
||
<option value="computers">*Computers (INT)</option>
|
||
<option value="disable">Disable (INT,AGL)</option>
|
||
<option value="drive">Drive (INT,AGL)</option>
|
||
<option value="engineer">*Engineer (INT)</option>
|
||
<option value="fly">*Fly (INT,AGL)</option>
|
||
<option value="guns">Guns (ACC)</option>
|
||
<option value="history">History (INT)</option>
|
||
<option value="intimidate">Intimidate (CHA)</option>
|
||
<option value="investigate">Investigate (INT,PER)</option>
|
||
<option value="melee">Melee Weapons (STR,AGL)</option>
|
||
<option value="medicine">*Medicine (INT,AGL)</option>
|
||
<option value="navigation">Navigation (PER)</option>
|
||
<option value="persuade">Persuade (CHA)</option>
|
||
<option value="repair">Repair (INT)</option>
|
||
<option value="science">*Science (INT)</option>
|
||
<option value="spellcraft">*Spellcraft (INT,PER)</option>
|
||
<option value="stealth">Stealth (AGL,PER)</option>
|
||
<option value="survival">Survival (INT,END)</option>
|
||
<option value="tactics">Tactics (INT)</option>
|
||
<option value="unarmed">Unarmed (STR,AGL)</option>
|
||
<option value="willpower">Willpower</option>
|
||
|
||
</select>
|
||
|
||
<label for="attr_selected_skill_ability">Ability:</label>
|
||
<select name="attr_selected_skill_ability" id="attr_selected_skill_ability">
|
||
<option value="str">STR</option>
|
||
<option value="agl">AGL</option>
|
||
<option value="end">END</option>
|
||
<option value="int">INT</option>
|
||
<option value="cha">CHA</option>
|
||
<option value="lck">LCK</option>
|
||
<option value="per">PER</option>
|
||
<option value="acc">ACC</option>
|
||
</select>
|
||
|
||
<button type="action" name="act_roll_selected_skill">Roll Skill Check</button>
|
||
</div>
|
||
|
||
<div class="skills-grid skills-align">
|
||
|
||
<div><label>Athletics (Phys.):</label><input type="number" name="attr_athletics" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Bows (ACC):</label><input type="number" name="attr_bows" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Carouse (CHA):</label><input type="number" name="attr_carouse" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>*Computers (INT):</label><input type="number" name="attr_computers" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Disable (INT, AGL):</label><input type="number" name="attr_disable" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Drive (INT, AGL):</label><input type="number" name="attr_drive" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>*Engineer (INT):</label><input type="number" name="attr_engineer" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>*Fly (INT, AGL):</label><input type="number" name="attr_fly" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Guns (ACC):</label><input type="number" name="attr_guns" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>History (INT):</label><input type="number" name="attr_history" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Intimidate (CHA):</label><input type="number" name="attr_intimidate" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Investigate (INT, PER):</label><input type="number" name="attr_investigate" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Melee Weapons (STR, AGL):</label><input type="number" name="attr_melee" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>*Medicine (INT, AGL):</label><input type="number" name="attr_medicine" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Navigation (PER):</label><input type="number" name="attr_navigation" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Persuade (CHA):</label><input type="number" name="attr_persuade" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Repair (INT):</label><input type="number" name="attr_repair" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>*Science (INT):</label><input type="number" name="attr_science" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>*Spellcraft (INT, PER):</label><input type="number" name="attr_spellcraft" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Stealth (AGL, PER):</label><input type="number" name="attr_stealth" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Survival (INT, END):</label><input type="number" name="attr_survival" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Tactics (INT):</label><input type="number" name="attr_tactics" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Unarmed (STR, AGL):</label><input type="number" name="attr_unarmed" min="0" max="30" step="5" value="0"></div>
|
||
<div><label>Willpower (INT, PER):</label><input type="number" name="attr_willpower" min="0" max="30" step="5" value="0">
|
||
</div>
|
||
</section> <!-- end skills -->
|
||
|
||
<!-- Combat Stats Section -->
|
||
<section class="combat-stats">
|
||
<h2>Combat Stats</h2>
|
||
<div class="stats-grid">
|
||
<label>Toughness:<input type="number" name="attr_toughness"></label>
|
||
<label>Total Wounds:<input type="number" name="attr_total_wounds" readonly></label>
|
||
<label>Current Wounds: <input type="number" name="attr_current_wounds"></label>
|
||
<input type="hidden" name="attr_current_wounds_max">
|
||
<label>Bonus Wounds:<input type="number" name="attr_bonus_wounds" value="0"></label>
|
||
<label>Armor Total:<input type="number" name="attr_armor_ar_total" readonly></label>
|
||
<label>Bonus Armor:<input type="number" name="attr_armor_bonus" value="0"></label>
|
||
<label>Speed:<input type="number" name="attr_speed"></label>
|
||
<label>Max Action Points:<input type="number" name="attr_actionpoints" value="6"></label>
|
||
<label>Current Action Points:<input type="number" name="attr_actionpoints_current"></label>
|
||
<div class="fatigue">
|
||
<label>Fatigue
|
||
<input type="number" name="attr_fatigue_value" min="0" max="50" value="0"></label>
|
||
<span name="attr_fatigue_status"></span>
|
||
</div>
|
||
|
||
|
||
<div class="wound-tracker">
|
||
<img src="https://images.squarespace-cdn.com/content/67dafda29b94da2a21600bce/ca339e87-bc65-49a0-9e29-e62bd7eac411/woundsSilouette.png?content-type=image%2Fpng" alt="Body Wound Tracker" class="wound-silhouette">
|
||
<!-- Head -->
|
||
<div class="wound-zone zone-head">
|
||
<div class="wound-boxes">
|
||
<input type="checkbox" name="attr_head_wound1">
|
||
<input type="checkbox" name="attr_head_wound2">
|
||
<input type="checkbox" name="attr_head_wound3">
|
||
<input type="checkbox" name="attr_head_wound4">
|
||
</div>
|
||
<span class="wound-status" name="attr_head_status">
|
||
</div>
|
||
|
||
<!-- Chest -->
|
||
<div class="wound-zone zone-chest">
|
||
<div class="wound-boxes">
|
||
<input type="checkbox" name="attr_chest_wound1">
|
||
<input type="checkbox" name="attr_chest_wound2">
|
||
<input type="checkbox" name="attr_chest_wound3">
|
||
<input type="checkbox" name="attr_chest_wound4">
|
||
</div>
|
||
<span class="wound-status" name="attr_chest_status">
|
||
</div>
|
||
|
||
|
||
<!-- Left Arm -->
|
||
<div class="wound-zone zone-larm">
|
||
<div class="wound-boxes">
|
||
<input type="checkbox" name="attr_larm_wound1">
|
||
<input type="checkbox" name="attr_larm_wound2">
|
||
<input type="checkbox" name="attr_larm_wound3">
|
||
<input type="checkbox" name="attr_larm_wound4">
|
||
</div>
|
||
<span class="wound-status" name="attr_larm_status">
|
||
</div>
|
||
|
||
<!-- Right Arm -->
|
||
<div class="wound-zone zone-rarm">
|
||
<div class="wound-boxes">
|
||
<input type="checkbox" name="attr_rarm_wound1">
|
||
<input type="checkbox" name="attr_rarm_wound2">
|
||
<input type="checkbox" name="attr_rarm_wound3">
|
||
<input type="checkbox" name="attr_rarm_wound4">
|
||
</div>
|
||
<span class="wound-status" name="attr_rarm_status">
|
||
</div>
|
||
|
||
<!-- Left Leg -->
|
||
<div class="wound-zone zone-lleg">
|
||
<div class="wound-boxes">
|
||
<input type="checkbox" name="attr_lleg_wound1">
|
||
<input type="checkbox" name="attr_lleg_wound2">
|
||
<input type="checkbox" name="attr_lleg_wound3">
|
||
<input type="checkbox" name="attr_lleg_wound4">
|
||
</div>
|
||
<span class="wound-status" name="attr_lleg_status">
|
||
</div>
|
||
|
||
<!-- Right Leg -->
|
||
<div class="wound-zone zone-rleg">
|
||
<div class="wound-boxes">
|
||
<input type="checkbox" name="attr_rleg_wound1">
|
||
<input type="checkbox" name="attr_rleg_wound2">
|
||
<input type="checkbox" name="attr_rleg_wound3">
|
||
<input type="checkbox" name="attr_rleg_wound4">
|
||
</div>
|
||
<span class="wound-status" name="attr_rleg_status">
|
||
</div>
|
||
</div> <!-- end wound tracker -->
|
||
|
||
</div> <!-- end stats grid -->
|
||
<div class="rest-actions">
|
||
<button type="action" name="act_resetap">Reset AP</button>
|
||
</div>
|
||
|
||
|
||
<div>
|
||
<h3>Weapons</h3>
|
||
<fieldset class="repeating_weapons">
|
||
<div class ="weapons-grid">
|
||
<label>Name:<input type="text" name="attr_wep_name"></label>
|
||
<label>Damage:<input type="number" name="attr_wep_dmg"></label>
|
||
<label>PEN:<input type="number" name="attr_wep_pen"></label>
|
||
<label>Burst/Combo:<input type="number" name="attr_wep_burst"></label>
|
||
<label>Auto:<input type="number" name="attr_wep_auto"></label>
|
||
<label>Heft/Recoil:<input type="number" name="attr_wep_recoil"></label>
|
||
<label>Magazine:<input type="number" name="attr_wep_mag"></label>
|
||
<label>Reload:<input type="number" name="attr_wep_reload"></label>
|
||
<label>Range:<input type="number" name="attr_wep_range"></label>
|
||
<label>Qualities:<input type="text" name="attr_wep_qualities"></label>
|
||
<label>Durability:<input type="number" name="attr_wep_durability" min="0" max="100"></label>
|
||
<label>Condition:<input type="number" name="attr_wep_condition" min="0" max="10"></label>
|
||
</div>
|
||
</fieldset> <!-- end weapons repeating -->
|
||
</div>
|
||
</section> <!-- end combat section -->
|
||
|
||
|
||
</div> <!-- end core sheet -->
|
||
|
||
<div class="sheet-survival">
|
||
<!-- Survival Stats -->
|
||
<section>
|
||
<h2>Survival Stats</h2>
|
||
<div class="survival-grid">
|
||
<label>Food:</label>
|
||
<div class="checkbox-group">
|
||
<label><input type="checkbox" name="attr_food1"> Healthy</label>
|
||
<label><input type="checkbox" name="attr_food2">
|
||
<label><input type="checkbox" name="attr_food3">
|
||
<label><input type="checkbox" name="attr_food4"> Starving</label>
|
||
</div>
|
||
<label>Water:</label>
|
||
<div class="checkbox-group">
|
||
<label><input type="checkbox" name="attr_water1"> Hydrated</label>
|
||
<label><input type="checkbox" name="attr_water2">
|
||
<label><input type="checkbox" name="attr_water3">
|
||
<label><input type="checkbox" name="attr_water4"> Dying</label>
|
||
</div>
|
||
<div class="radiation">
|
||
<label>Radiation (0–300):</label>
|
||
<input type="number" name="attr_radiation" min="0" max="300" step="1">
|
||
</div>
|
||
</div> <!-- end survival grid -->
|
||
</section>
|
||
</div><!-- end survival sheet -->
|
||
|
||
<div class="sheet-inventory">
|
||
<!-- Carry Slots Section -->
|
||
<section class="carry-slots">
|
||
<h2>Carrying Capacity</h2>
|
||
<div class="carry-info">
|
||
<label>Carry Slots (6+STR):
|
||
<input type="number" name="attr_carry_slots" readonly></label>
|
||
</div>
|
||
<div class="carry-info">
|
||
<label>Carry Slots Current:
|
||
<input type="number" name="attr_carry_current" readonly></label>
|
||
</div>
|
||
<div class="carry-info">
|
||
<label>Carry Overflow:
|
||
<input type="number" name="attr_carry_overflow" readonly></label>
|
||
</div>
|
||
<div class="encumbrance">
|
||
<label>Encumbrance
|
||
<input type="number" name="attr_encumbrance" min="0" max="20"></label>
|
||
<span name="attr_encumbrance_status"></span>
|
||
</div>
|
||
</section> <!-- end carry capacity section -->
|
||
|
||
|
||
<!-- Items & Equipment -->
|
||
<section class="inventory">
|
||
<h2>Items & Equipment</h2>
|
||
<div class="items_equipment">
|
||
<label>Items and Carry Slots</label>
|
||
<fieldset class="repeating_items">
|
||
<div>
|
||
<input type="text" name="attr_item_name" placeholder="Item Name">
|
||
<input type="number" name="attr_item_slots" placeholder="Slots">
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end items list -->
|
||
|
||
<!-- Armor Section -->
|
||
<div class="armor">
|
||
<h3>Armor</h3>
|
||
<fieldset class="repeating_armor">
|
||
<div class ="armor-grid">
|
||
<label>Name:<input type="text" name="attr_armor_name"></label>
|
||
<label>Encumbrance:<input type="number" name="attr_armor_enc"></label>
|
||
<label>Armor Rating:<input type="number" name="attr_armor_ar"></label>
|
||
<label>Qualities:<input type="text" name="attr_armor_qualities"></label>
|
||
<label>Durability:<input type="number" name="attr_armor_durability" min="0" max="100"></label>
|
||
<label>Condition:<input type="number" name="attr_armor_condition" min="0" max="10"></label>
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end armor -->
|
||
|
||
<!-- Currency Section -->
|
||
<div>
|
||
<h3>Currency</h3>
|
||
<fieldset class="repeating_currency">
|
||
<div>
|
||
<label>Type:</label>
|
||
<select name="attr_currency_type">
|
||
<option value="Credits">Credits</option>
|
||
<option value="Bits">Bits</option>
|
||
<option value="Silver">Silver</option>
|
||
<option value="Gold">Gold</option>
|
||
</select>
|
||
<input type="number" name="attr_currency_amount" placeholder="0" min="0">
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end currency -->
|
||
</section> <!-- end inventory section -->
|
||
</div> <!-- end inventory sheet -->
|
||
|
||
<div class="sheet-leveling">
|
||
|
||
<!-- Experience and Leveling -->
|
||
<section class="experience-leveling">
|
||
<h2>Experience and Leveling</h2>
|
||
<div>
|
||
<!-- Experience Section -->
|
||
<div class="experience">
|
||
<h3>Experience Tracker</h3>
|
||
<div class="xp-tracker">
|
||
<label>Experience Points:</label>
|
||
<input type="number" name="attr_xp_points" value="0" min="0" step="25">
|
||
<label>Total Experience Spent:</label>
|
||
<input type="number" name="attr_xp_spent" value="0" min="0" step="25">
|
||
|
||
</div> <!-- end exp tracker -->
|
||
</div> <!-- end exp div -->
|
||
<h3>Traits (Limit 3)</h3>
|
||
<fieldset class="repeating_traits">
|
||
<div>
|
||
<label>Trait</label>
|
||
<input type="text" name="attr_trait" placeholder="Trait">
|
||
<input type="text" name="attr_trait_desc" placeholder="Description">
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end traits div -->
|
||
<div>
|
||
<h3>Perks</h3>
|
||
<fieldset class="repeating_perks">
|
||
<div>
|
||
<label>Perk</label>
|
||
<input type="text" name="attr_perk" placeholder="New Perk">
|
||
<input type="text" name="attr_perk_desc" placeholder="Description">
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end perks div -->
|
||
<div>
|
||
<h3>Specializations (Limit 2)</h3>
|
||
<fieldset class="repeating_specializations">
|
||
<div>
|
||
<label>Specialization</label>
|
||
<input type="text" name="attr_specialization">
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end specializations div -->
|
||
<div>
|
||
<h3>Skill and Ability Boosts</h3>
|
||
<fieldset class="repeating_boosts">
|
||
<div>
|
||
<label>Boost</label>
|
||
<input type="text" name="attr_boost">
|
||
</div>
|
||
</fieldset>
|
||
</div> <!-- end boosts -->
|
||
|
||
</section> <!-- end exp and lvl section -->
|
||
</div> <!-- end leveling tab -->
|
||
|
||
<div class="sheet-magic">
|
||
|
||
<!-- Magic -->
|
||
<h2>Magic</h2>
|
||
<section>
|
||
|
||
<label>Casting Ability:
|
||
<select name="attr_casting_ability" id="attr_casting-ability">
|
||
<option value="">-- Select --</option>
|
||
<option value="int">Intelligence</option>
|
||
<option value="cha">Charisma</option>
|
||
<option value="per">Perception</option>
|
||
</select>
|
||
</label>
|
||
|
||
<div class="stats-grid">
|
||
<label>Max MP: <input type="number" name="attr_max_mp" value="0"></label>
|
||
<label>Current MP: <input type="number" name="attr_current_mp" id="attr_current-mp" value="0" min="0"></label>
|
||
<label>Recovery Rate: <input type="number" name="attr_recovery_rate" placeholder="Casting Modifier"></label>
|
||
<label>Spell Range: <input type="number" name="attr_spell_range" placeholder="2x Ability Score"></label>
|
||
<label>Spells Known: <input type="number" name="attr_spells_known" placeholder="Modifier+3+1 per 10 Spellcraft"></label>
|
||
<label>Efficacy: <input type="number" name="attr_efficacy" placeholder="Modifier OR 1 per 5 Spellcraft"></label>
|
||
<label>Spell Attack: <input type="number" name="attr_spellattack" placeholder="Spellcraft+ACC" readonly></label>
|
||
</div> <!-- end magic stats grid -->
|
||
<label>Spells:</label>
|
||
<div class="spells-inputs">
|
||
<fieldset class="repeating_spells">
|
||
<div>
|
||
<input type="number" name="attr_spell_cost" placeholder="MP Cost">
|
||
<input type="text" name="attr_spell" placeholder="New Spell">
|
||
<input type="text" name="attr_spell_desc" placeholder="Description">
|
||
</div>
|
||
</fieldset>
|
||
</section> <!-- end magic section -->
|
||
|
||
</div> <!-- end magic sheet -->
|
||
|
||
|
||
|
||
<!-- ADDED FOR ROLL20 COMPAT -->
|
||
<input type="hidden" name="attr_winded">
|
||
<input type="hidden" name="attr_tired">
|
||
<input type="hidden" name="attr_exhausted">
|
||
<input type="hidden" name="attr_unconscious">
|
||
<input type="hidden" name="attr_encumbered">
|
||
<input type="hidden" name="attr_overencumbered">
|
||
<input type="hidden" name="attr_encstatus_current">
|
||
<input type="hidden" name="attr_speed_base">
|
||
<input type="hidden" name="attr_carry_overflow">
|
||
<input type="hidden" name="attr_armor_enc_total">
|
||
<input type="hidden" name="attr_currency_total">
|
||
<!-- END ADDED FOR ROLL20 COMPAT -->
|
||
|
||
|
||
<script type="text/worker">
|
||
|
||
const buttonlist = ["core", "inventory", "magic", "leveling","survival"];
|
||
buttonlist.forEach(button => {
|
||
on(`clicked:${button}`, function() {
|
||
setAttrs({
|
||
sheetTab: button
|
||
});
|
||
});
|
||
});
|
||
|
||
/*Stat Worker*/
|
||
|
||
on("change:str change:cha change:int change:agl change:per change:end change:acc change:lck change:encumbrance sheet:opened",function() {
|
||
getAttrs(["str", "agl", "int", "cha", "acc", "end", "per", "lck"], function(values) {
|
||
let endMod = Math.floor(parseInt(values.end)/10);
|
||
let aglMod = Math.floor(parseInt(values.agl)/10);
|
||
let strMod = Math.floor(parseInt(values.str)/10);
|
||
|
||
|
||
setAttrs({
|
||
str_mod: Math.floor(parseInt(values.str)/10),
|
||
per_mod: Math.floor(parseInt(values.per)/10),
|
||
end_mod: endMod,
|
||
cha_mod: Math.floor(parseInt(values.cha)/10),
|
||
int_mod: Math.floor(parseInt(values.int)/10),
|
||
agl_mod: aglMod,
|
||
lck_mod: Math.floor(parseInt(values.lck)/10),
|
||
acc_mod: Math.floor(parseInt(values.acc)/10),
|
||
toughness: endMod,
|
||
luck_points_max: 1+Math.floor(parseInt(values.lck)/10),
|
||
winded: endMod,
|
||
tired: 2*endMod,
|
||
exhausted: 3*endMod,
|
||
unconscious: 4*endMod,
|
||
speed: 1+aglMod,
|
||
carry_slots: 6+strMod,
|
||
encumbered: 1+strMod,
|
||
overencumbered: 2*(1+strMod)
|
||
|
||
});
|
||
});
|
||
});
|
||
|
||
/*Fatigue Workers*/
|
||
|
||
on("change:fatigue_value change:end sheet:opened", function() {
|
||
getAttrs(["fatigue_value", "fatigue_status", "winded", "tired", "exhausted","unconscious"], function(values) {
|
||
let fatigue = parseInt(values.fatigue_value);
|
||
let fatigueStatus = "";
|
||
|
||
if (fatigue >= parseInt(values.unconscious))
|
||
fatigueStatus = "Unconscious";
|
||
|
||
else if (fatigue >= parseInt(values.exhausted))
|
||
fatigueStatus = "Exhausted: -3 to all STR, AGL, END, and INT DoS. -2 AP per round.";
|
||
|
||
else if (fatigue >= parseInt(values.tired))
|
||
fatigueStatus = "Tired: -1 to all Athletics, STR, AGL DoS. -2 Speed to Run and Sprint.";
|
||
|
||
else if (fatigue < parseInt(values.tired))
|
||
fatigueStatus = " ";
|
||
|
||
setAttrs({
|
||
fatigue_status: fatigueStatus
|
||
});
|
||
});
|
||
});
|
||
|
||
/*Encumbrance Workers*/
|
||
|
||
on("change:encumbrance change:str sheet:opened", function() {
|
||
getAttrs(["encumbrance", "encumbered", "overencumbered"], function(values) {
|
||
let encValue = parseInt(values.encumbrance);
|
||
let encStatus = "";
|
||
let encCurrent = "";
|
||
if (encValue >= parseInt(values.overencumbered))
|
||
encStatus = "Over-Encumbered: -2 to AGL, 1/2 Speed, +4 spell cost, gain triple Fatigue.";
|
||
|
||
else if (encValue >= parseInt(values.encumbered))
|
||
encStatus = "Encumbered: -1 Speed, cannot Run, +2 spell cost, gain double Fatigue";
|
||
|
||
else if (encValue < parseInt(values.encumbered))
|
||
encStatus = " ";
|
||
|
||
setAttrs({
|
||
encumbrance_status: encStatus
|
||
});
|
||
});
|
||
});
|
||
|
||
|
||
/*Wounds Calculator*/
|
||
|
||
function raceWounds(selection){
|
||
let raceWounds = 0;
|
||
let raceBenefit = "";
|
||
|
||
if (selection === "Human") {
|
||
raceWounds = 5;
|
||
raceBenefit = "+1 Luck Point";
|
||
}
|
||
|
||
else if (selection === "Dwarf") {
|
||
raceWounds = 5;
|
||
raceBenefit = "+1 Encumbrance limit; +1 DoS on Trip, Grapple, Disarm, Block; Subterrain Vision";
|
||
}
|
||
|
||
else if (selection === "Lizardmen") {
|
||
raceWounds = 5;
|
||
raceBenefit = "Swimmer, Keen Scent, Jungle Immunity, Cold Blooded";
|
||
}
|
||
|
||
else if (selection === "Elemental") {
|
||
raceWounds = 5;
|
||
raceBenefit = "Become Incorporeal, Death... Again, Strange Anatomy";
|
||
}
|
||
|
||
else if (selection === "Elf") {
|
||
raceWounds = 4;
|
||
raceBenefit = "+1 DoS on Survival (INT), +1 Movement Speed";
|
||
}
|
||
else if (selection === "Aetherial") {
|
||
raceWounds = 4;
|
||
raceBenefit = "Magical Training is free";
|
||
}
|
||
|
||
else if (selection === "Sylvan") {
|
||
raceWounds = 4;
|
||
raceBenefit = "Carnivore, Regeneration, +1 PEN on Unarmed";
|
||
}
|
||
else if (selection === "Halfling") {
|
||
raceWounds = 4;
|
||
raceBenefit = "+2 DoS on Dodge";
|
||
}
|
||
else if (selection === "Gnome") {
|
||
raceWounds = 4;
|
||
raceBenefit = "+2 DoS on crafting, +5 Magic Points";
|
||
}
|
||
else if (selection === "Orc") {
|
||
raceWounds = 6;
|
||
raceBenefit = "+1 DoS on Carouse, Penny Pincher";
|
||
}
|
||
|
||
else if (selection === "Granitetouched") {
|
||
raceWounds = 6;
|
||
raceBenefit = "+1 AR, Subterrane Vision";
|
||
}
|
||
|
||
return [raceWounds, raceBenefit]
|
||
|
||
};
|
||
|
||
on("change:race change:bonus_wounds change:willpower sheet:opened", function() {
|
||
|
||
getAttrs(["race", "bonus_wounds", "willpower"], function(values) {
|
||
|
||
let willpowerBonus = Math.floor(parseInt(values.willpower)/10);
|
||
const temp = raceWounds(values.race);
|
||
const raceWds = temp[0];
|
||
const raceBen = temp[1];
|
||
let bonusWds = parseInt(values.bonus_wounds);
|
||
|
||
setAttrs({
|
||
total_wounds: willpowerBonus+bonusWds+raceWds,
|
||
racial_benefits: raceBen
|
||
});
|
||
});
|
||
|
||
});
|
||
|
||
/*Armor Worker*/
|
||
|
||
|
||
on("change:repeating_armor:armor_ar change:repeating_armor:armor_enc remove:repeating_armor change:armor_bonus change:carry_overflow sheet:opened", function() {
|
||
getSectionIDs("repeating_armor", function(armorIds) {
|
||
const fields = ["armor_bonus", "carry_overflow"];
|
||
|
||
armorIds.forEach(id => {
|
||
fields.push(`repeating_armor_${id}_armor_ar`);
|
||
fields.push(`repeating_armor_${id}_armor_enc`);
|
||
});
|
||
|
||
getAttrs(fields, function(values) {
|
||
let arTotal = 0;
|
||
let encTotal = 0;
|
||
|
||
// === Armor AR & ENC ===
|
||
armorIds.forEach(id => {
|
||
const arVal = parseInt(values[`repeating_armor_${id}_armor_ar`], 10) || 0;
|
||
const encVal = parseInt(values[`repeating_armor_${id}_armor_enc`], 10) || 0;
|
||
arTotal += arVal;
|
||
encTotal += encVal;
|
||
});
|
||
|
||
// === Armor Bonus ===
|
||
const bonus = parseInt(values.armor_bonus, 10) || 0;
|
||
arTotal += bonus;
|
||
|
||
// === Carry Overflow ===
|
||
const overflow = parseInt(values.carry_overflow, 10) || 0;
|
||
encTotal += overflow;
|
||
|
||
// === Set results ===
|
||
setAttrs({
|
||
armor_ar_total: arTotal,
|
||
encumbrance: encTotal
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|
||
|
||
/*Carry Capacity Worker*/
|
||
|
||
on("change:repeating_items:item_slots remove:repeating_items change:carry_slots sheet:opened", function() {
|
||
getSectionIDs("repeating_items", function(itemIds) {
|
||
const fields = ["carry_slots"];
|
||
itemIds.forEach(id => fields.push(`repeating_items_${id}_item_slots`));
|
||
|
||
getAttrs(fields, function(values) {
|
||
let current = 0;
|
||
|
||
// === Sum item slots ===
|
||
itemIds.forEach(id => {
|
||
const val = parseInt(values[`repeating_items_${id}_item_slots`], 10) || 0;
|
||
current += val;
|
||
});
|
||
|
||
const maxSlots = parseInt(values.carry_slots, 10) || 0;
|
||
let overflow = 0;
|
||
|
||
if (current > maxSlots) {
|
||
overflow = current - maxSlots;
|
||
}
|
||
|
||
// === Set results ===
|
||
setAttrs({
|
||
carry_current: current,
|
||
carry_overflow: overflow
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|
||
on("change:total_wounds \
|
||
change:head_wound1 change:head_wound2 change:head_wound3 change:head_wound4 \
|
||
change:chest_wound1 change:chest_wound2 change:chest_wound3 change:chest_wound4 \
|
||
change:larm_wound1 change:larm_wound2 change:larm_wound3 change:larm_wound4 \
|
||
change:rarm_wound1 change:rarm_wound2 change:rarm_wound3 change:rarm_wound4 \
|
||
change:lleg_wound1 change:lleg_wound2 change:lleg_wound3 change:lleg_wound4 \
|
||
change:rleg_wound1 change:rleg_wound2 change:rleg_wound3 change:rleg_wound4 \
|
||
sheet:opened", function() {
|
||
|
||
// Explicit wound fields
|
||
const woundFields = [
|
||
"total_wounds",
|
||
"head_wound1","head_wound2","head_wound3","head_wound4",
|
||
"chest_wound1","chest_wound2","chest_wound3","chest_wound4",
|
||
"larm_wound1","larm_wound2","larm_wound3","larm_wound4",
|
||
"rarm_wound1","rarm_wound2","rarm_wound3","rarm_wound4",
|
||
"lleg_wound1","lleg_wound2","lleg_wound3","lleg_wound4",
|
||
"rleg_wound1","rleg_wound2","rleg_wound3","rleg_wound4"
|
||
];
|
||
|
||
getAttrs(woundFields, function(values) {
|
||
const total = parseInt(values.total_wounds, 10) || 0;
|
||
|
||
// Helper: determine status
|
||
const getStatus = (count) => {
|
||
switch(count) {
|
||
case 1: return "Roughed Up";
|
||
case 2: return "Injured";
|
||
case 3: return "Crippled";
|
||
case 4: return "Fatal";
|
||
default: return " ";
|
||
}
|
||
};
|
||
|
||
// Count per-zone
|
||
let headCount = 0, chestCount = 0, larmCount = 0, rarmCount = 0, llegCount = 0, rlegCount = 0;
|
||
|
||
if (values.head_wound1 === "on") headCount++;
|
||
if (values.head_wound2 === "on") headCount++;
|
||
if (values.head_wound3 === "on") headCount++;
|
||
if (values.head_wound4 === "on") headCount++;
|
||
|
||
if (values.chest_wound1 === "on") chestCount++;
|
||
if (values.chest_wound2 === "on") chestCount++;
|
||
if (values.chest_wound3 === "on") chestCount++;
|
||
if (values.chest_wound4 === "on") chestCount++;
|
||
|
||
if (values.larm_wound1 === "on") larmCount++;
|
||
if (values.larm_wound2 === "on") larmCount++;
|
||
if (values.larm_wound3 === "on") larmCount++;
|
||
if (values.larm_wound4 === "on") larmCount++;
|
||
|
||
if (values.rarm_wound1 === "on") rarmCount++;
|
||
if (values.rarm_wound2 === "on") rarmCount++;
|
||
if (values.rarm_wound3 === "on") rarmCount++;
|
||
if (values.rarm_wound4 === "on") rarmCount++;
|
||
|
||
if (values.lleg_wound1 === "on") llegCount++;
|
||
if (values.lleg_wound2 === "on") llegCount++;
|
||
if (values.lleg_wound3 === "on") llegCount++;
|
||
if (values.lleg_wound4 === "on") llegCount++;
|
||
|
||
if (values.rleg_wound1 === "on") rlegCount++;
|
||
if (values.rleg_wound2 === "on") rlegCount++;
|
||
if (values.rleg_wound3 === "on") rlegCount++;
|
||
if (values.rleg_wound4 === "on") rlegCount++;
|
||
|
||
// Total wounds lost
|
||
const woundsLost = headCount + chestCount + larmCount + rarmCount + llegCount + rlegCount;
|
||
const current = Math.max(0, total - woundsLost);
|
||
|
||
// Set individually
|
||
setAttrs({
|
||
current_wounds: current,
|
||
head_status: getStatus(headCount),
|
||
chest_status: getStatus(chestCount),
|
||
larm_status: getStatus(larmCount),
|
||
rarm_status: getStatus(rarmCount),
|
||
lleg_status: getStatus(llegCount),
|
||
rleg_status: getStatus(rlegCount)
|
||
});
|
||
});
|
||
});
|
||
|
||
// --- AP Reset button pressed ---
|
||
on("clicked:resetap", function() {
|
||
getAttrs(["actionpoints","actionpoints_current"], function(values) {
|
||
let maxAP = parseInt(values.actionpoints, 10) || 0;
|
||
setAttrs({
|
||
actionpoints_current: maxAP
|
||
});
|
||
});
|
||
});
|
||
|
||
// --- Break button pressed: ask in chat ---
|
||
on("clicked:break", function() {
|
||
startRoll("&{template:default} {{name=Take a Break?}} {{Click=[Yes](~break_confirm) / [No](~cancel)}}");
|
||
});
|
||
|
||
// --- Sleep button pressed: ask in chat ---
|
||
on("clicked:sleep", function() {
|
||
startRoll("&{template:default} {{name=Go to Sleep?}} {{Click=[Yes](~sleep_confirm) / [No](~cancel)}}");
|
||
});
|
||
|
||
// --- Break confirmed ---
|
||
on("clicked:break_confirm", function() {
|
||
getAttrs(["fatigue_value","end_mod","current_mp","max_mp","recovery_rate","character_name"], function(values) {
|
||
let fatigue = parseInt(values.fatigue_value, 10) || 0;
|
||
let endMod = parseInt(values.end_mod, 10) || 0;
|
||
let currentMP = parseInt(values.current_mp, 10) || 0;
|
||
let maxMP = parseInt(values.max_mp, 10) || 0;
|
||
let recovery = parseInt(values.recovery_rate, 10) || 0;
|
||
let charName = values.character_name || "This character";
|
||
|
||
const newFatigue = Math.max(0, fatigue - endMod);
|
||
const newMP = Math.min(maxMP, currentMP + recovery);
|
||
|
||
setAttrs({
|
||
fatigue_value: newFatigue,
|
||
current_mp: newMP
|
||
}, () => {
|
||
startRoll(`&{template:default} {{name=${charName}}} {{action=Took a Break}} {{Fatigue=${newFatigue}}} {{MP=${newMP}}}`);
|
||
});
|
||
});
|
||
});
|
||
|
||
// --- Sleep confirmed ---
|
||
on("clicked:sleep_confirm", function() {
|
||
getAttrs(["recovery_rate","current_mp","max_mp","character_name"], function(values) {
|
||
let recovery = parseInt(values.recovery_rate, 10) || 0;
|
||
let currentMP = parseInt(values.current_mp, 10) || 0;
|
||
let maxMP = parseInt(values.max_mp, 10) || 0;
|
||
let charName = values.character_name || "This character";
|
||
|
||
const newFatigue = 0;
|
||
const newMP = Math.min(maxMP, currentMP + (2 * recovery));
|
||
|
||
setAttrs({
|
||
fatigue_value: newFatigue,
|
||
current_mp: newMP
|
||
}, () => {
|
||
startRoll(`&{template:default} {{name=${charName}}} {{action=Went to Sleep}} {{Fatigue=${newFatigue}}} {{MP=${newMP}}}`);
|
||
});
|
||
});
|
||
});
|
||
|
||
// --- Cancel does nothing (but placeholder in chat) ---
|
||
on("clicked:cancel", function() {
|
||
startRoll("&{template:default} {{name=Action Cancelled}}");
|
||
});
|
||
|
||
on("change:casting_ability change:int change:int_mod change:cha change:cha_mod change:per change:per_mod change:spellcraft sheet:opened", function() {
|
||
getAttrs(["casting_ability","int","int_mod","cha","cha_mod","per","per_mod","spellcraft","acc"], function(values) {
|
||
let ability = values.casting_ability || "intelligence"; // default
|
||
let abilityVal = 0;
|
||
let abilityMod = 0;
|
||
|
||
// Pick correct ability & mod
|
||
switch(ability) {
|
||
case "cha":
|
||
abilityVal = parseInt(values.cha, 10) || 0;
|
||
abilityMod = parseInt(values.cha_mod, 10) || 0;
|
||
break;
|
||
case "per":
|
||
abilityVal = parseInt(values.per, 10) || 0;
|
||
abilityMod = parseInt(values.per_mod, 10) || 0;
|
||
break;
|
||
case "int":
|
||
default:
|
||
abilityVal = parseInt(values.int, 10) || 0;
|
||
abilityMod = parseInt(values.int_mod, 10) || 0;
|
||
break;
|
||
}
|
||
|
||
const spellcraft = parseInt(values.spellcraft, 10) || 0;
|
||
const spellcraftAlt = Math.floor(spellcraft / 5);
|
||
|
||
const recovery_rate = abilityMod;
|
||
const spell_range = 2*abilityVal;
|
||
const spells_known = 3 + abilityMod + Math.floor(spellcraft/10);
|
||
const efficacy = Math.max(abilityMod, spellcraftAlt);
|
||
const spellAttack = parseInt(values.spellcraft)+parseInt(values.acc);
|
||
|
||
setAttrs({
|
||
recovery_rate: recovery_rate,
|
||
spell_range: spell_range,
|
||
spells_known: spells_known,
|
||
efficacy: efficacy,
|
||
spellattack: spellAttack
|
||
});
|
||
});
|
||
});
|
||
|
||
on("clicked:roll_selected_skill", function() {
|
||
getAttrs(["selected_skill", "selected_skill_ability", "character_name"], function(sel) {
|
||
const skillKey = sel.selected_skill || "";
|
||
const abilityKey = sel.selected_skill_ability || "str";
|
||
const charName = sel.character_name || "Character";
|
||
|
||
getAttrs([skillKey, abilityKey, "lck_mod"], function(values) {
|
||
const skillVal = parseInt(values[skillKey], 10) || 0;
|
||
const abilityVal = parseInt(values[abilityKey], 10) || 0;
|
||
const check = Math.min(skillVal + abilityVal, 95);
|
||
const luckMod = parseInt(values.lck_mod);
|
||
|
||
startRoll(
|
||
"&{template:check} " +
|
||
"{{name=" + charName + ": " + skillKey.toUpperCase() + " + " + abilityKey.toUpperCase() + "}} " +
|
||
"{{check=" + check + "}} " +
|
||
"{{roll=[[1d100]]}} " + "{{degrees=[[0]]}} {{result=[[0]]}}", (results) => {
|
||
const roll = results.results.roll.result;
|
||
const success = roll <= check;
|
||
const tens = Math.floor(roll / 10);
|
||
const degSuccess = Math.max(1, tens);
|
||
const degFailure = 10 - tens;
|
||
const isDouble = (roll % 11 === 0) || roll === 100;
|
||
|
||
let resultText, degreesText;
|
||
let critBonus = 0;
|
||
if (success) {
|
||
resultText = isDouble ? "Critical Success!" : "Success";
|
||
degreesText = degSuccess;
|
||
critbonus = isDouble ? luckMod : 0;
|
||
} else {
|
||
resultText = isDouble ? "Critical Failure!" : "Failure";
|
||
degreesText = degFailure;
|
||
critbonus = isDouble ? 3 : 0;
|
||
}
|
||
|
||
finishRoll(results.rollId,
|
||
{
|
||
result: resultText,
|
||
degrees: degreesText+critbonus
|
||
});
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|
||
|
||
|
||
|
||
</script>
|