Obsidian Portal
Menu
Sign In / Create Account
JavaScript is currently disabled. Obsidian Portal has a lot of really cool features that use JavaScript. You should check them out. We think you'll have a much more enjoyable experience.
Home
Campaigns
Games Nearby
Plans
Community
Help
Resources
MultiversalD20
Author:
blgwever
Slug:
multiversald20
Type:
GameCharacter
System:
d20
DST Source Code
HTML Template
<div class="sheet-container csx multiversald20-root"> <!-- CSX's editor still looks for these buttons, so they stay in the page, but the format bar is hidden in the CSS and the Ctrl+B/I/U shortcuts are blocked in the JS - this sheet is plain text only. --> <div class="uicontainer"> <div class="formatBar"> <button type="button" class="boldButton" title="Bold (Ctrl+B)"></button> <button type="button" class="italicButton" title="Italic (Ctrl+I)"></button> <button type="button" class="underlineButton" title="Underline (Ctrl+U)"></button> <button type="button" class="indentButton" title="Indent (Ctrl+Tab)"></button> </div> </div> <div class="sheet-notes"><!-- NOTES --> Attention!<br> The Summary tab is built automatically from everything else on the sheet.<br> Areas bordered in red are only displayed when editing.<br> Areas shaded in blue require your input. Areas in white are labels or auto-calculated values.<br> Tap the red X on a list entry to delete it. </div> <div class="grid-tabs"><!-- TABS --> <div class="tab tab-1" onclick="multiversald20_tabClick(1);">Summary</div> <div class="tab tab-2" onclick="multiversald20_tabClick(2);">Combat</div> <div class="tab tab-3" onclick="multiversald20_tabClick(3);">Abilities</div> <div class="tab tab-4" onclick="multiversald20_tabClick(4);">Spells</div> <div class="tab tab-5" onclick="multiversald20_tabClick(5);">Inventory</div> <div class="tab tab-6" onclick="multiversald20_tabClick(6);">Vices</div> <div class="tab tab-7" onclick="multiversald20_tabClick(7);">Bio</div> </div> <div class="page page-1"><!-- SUMMARY (stat block) --> <div class="panel statblock-panel"> <div class="sb-head"> <div class="sb-avatar"><div class="dsf dsf_avatar_image readonly"></div></div> <div class="sb-title"> <div class="dsf dsf_name readonly sb-name"></div> <div class="sb-head-lines"></div> <div class="sb-player">Played by <span class="dsf dsf_player readonly inline-val">[NPC]</span></div> </div> </div> <div class="sb-body"></div> </div> <div class="edit-only"> <div class="edit-only-note">Everything below this line is only shown while editing. The stat block above is built from it and from the other tabs.</div> <div class="panel"><!-- BASIC INFORMATION --> <div class="panel-title">Basic Information</div> <div class="basic-info-grid"> <div class="input"> <div class="input-label">Race</div> <span class="dsf dsf_race singlerow"></span> </div> <div class="input bi-wide"> <div class="input-label">Class(es) & Levels (e.g. Warpriest 15 / Champion 5)</div> <span class="dsf dsf_class singlerow"></span> </div> <div class="input"> <div class="input-label">Character Level</div> <span class="dsf dsf_char_level singlerow"></span> </div> <div class="input"> <div class="input-label">Alignment</div> <span class="dsf dsf_alignment_flavor singlerow"></span> </div> <div class="input"> <div class="input-label">Size</div> <span class="dsf dsf_size singlerow"></span> </div> <div class="input"> <div class="input-label">Type (e.g. humanoid (dwarf))</div> <span class="dsf dsf_type singlerow"></span> </div> <div class="input"> <div class="input-label">Background / Profession</div> <span class="dsf dsf_background singlerow"></span> </div> <div class="input"> <div class="input-label">Deity / Faith</div> <span class="dsf dsf_deity singlerow"></span> </div> <div class="input"> <div class="input-label">Aura</div> <span class="dsf dsf_aura singlerow"></span> </div> <div class="input bi-wide"> <div class="input-label">Languages</div> <span class="dsf dsf_languages singlerow"></span> </div> <div class="input bi-full"> <div class="input-label">Senses (e.g. darkvision 60 ft.)</div> <span class="dsf dsf_senses singlerow"></span> </div> </div> <div class="panel-title panel-subtitle">Engine (sets Hit Die / Mana Die)</div> <div class="engine-grid"> <div class="one-engine"> <span class="dsf dsf_engine_fc check readonly group_engine"></span> <div class="engine-label">Full Combat<br><span class="engine-dice">d12 HP / d6 MP</span></div> </div> <div class="one-engine"> <span class="dsf dsf_engine_sc check readonly group_engine"></span> <div class="engine-label">Skilled/Combat<br><span class="engine-dice">d10 HP / d8 MP</span></div> </div> <div class="one-engine"> <span class="dsf dsf_engine_scast check readonly group_engine"></span> <div class="engine-label">Skilled/Caster<br><span class="engine-dice">d8 HP / d10 MP</span></div> </div> <div class="one-engine"> <span class="dsf dsf_engine_full check readonly group_engine"></span> <div class="engine-label">Full Caster<br><span class="engine-dice">d6 HP / d12 MP</span></div> </div> </div> </div> <div class="grid-2"> <div class="panel"><!-- ABILITY SCORES + ATTRACTIVENESS --> <div class="panel-title">Ability Scores (S.P.E.C.I.A.L.)</div> <div class="ability-label-grid"> <div class="ability-label-ability">Ability</div> <div class="ability-label-score">Score</div> <div class="ability-label-mod">Mod</div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Strength</div> <div class="abil-score include-box"><span class="dsf dsf_str singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_str_mod readonly"></span></div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Prowess</div> <div class="abil-score include-box"><span class="dsf dsf_pro singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_pro_mod readonly"></span></div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Endurance</div> <div class="abil-score include-box"><span class="dsf dsf_end singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_end_mod readonly"></span></div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Charisma</div> <div class="abil-score include-box"><span class="dsf dsf_cha singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_cha_mod readonly"></span></div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Intelligence</div> <div class="abil-score include-box"><span class="dsf dsf_int singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_int_mod readonly"></span></div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Awareness</div> <div class="abil-score include-box"><span class="dsf dsf_awa singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_awa_mod readonly"></span></div> </div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Luck</div> <div class="abil-score include-box"><span class="dsf dsf_luc singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_luc_mod readonly"></span></div> </div> <div class="panel-title panel-subtitle">Attractiveness (3d6, optional)</div> <div class="ability-score-grid"> <div class="grey-back"></div> <div class="attr-label">Attractiveness</div> <div class="abil-score include-box"><span class="dsf dsf_attractiveness singlerow"></span></div> <div class="abil-mod include-box"><span class="dsf dsf_attractiveness_mod readonly"></span></div> </div> </div> <div class="panel"><!-- SKILLS --> <div class="panel-title">Skills (The Universal 20)</div> <div class="skills-note">Total = Ability Mod + Ranks + Misc (+3 if ticked as a Class Skill and you have 1+ Rank). Max Ranks = Character Level. "Armor" applies your Armor Check Penalty (Inventory tab).</div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Acrobatics</div> <div class="skill-total value-total"><div class="dsf dsf_sk_acrobatics_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_acrobatics_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Pro</div><div class="include-box"><div class="dsf dsf_pro_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_acrobatics_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_acrobatics_item singlerow"></span></div></div> <div class="value-include"><div class="include-label">Armor</div><div class="include-box"><div class="dsf dsf_acp_display readonly"></div></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Athletics</div> <div class="skill-total value-total"><div class="dsf dsf_sk_athletics_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_athletics_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Str</div><div class="include-box"><div class="dsf dsf_str_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_athletics_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_athletics_item singlerow"></span></div></div> <div class="value-include"><div class="include-label">Armor</div><div class="include-box"><div class="dsf dsf_acp_display readonly"></div></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Perception</div> <div class="skill-total value-total"><div class="dsf dsf_sk_perception_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_perception_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Awa</div><div class="include-box"><div class="dsf dsf_awa_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_perception_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_perception_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Artistry</div> <div class="skill-total value-total"><div class="dsf dsf_sk_artistry_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_artistry_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int/Cha</div><div class="include-box"><span class="dsf dsf_sk_artistry_ability singlerow"></span></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_artistry_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_artistry_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Culture</div> <div class="skill-total value-total"><div class="dsf dsf_sk_culture_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_culture_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_culture_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_culture_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Handle Creature</div> <div class="skill-total value-total"><div class="dsf dsf_sk_handle_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_handle_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Cha</div><div class="include-box"><div class="dsf dsf_cha_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_handle_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_handle_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Influence</div> <div class="skill-total value-total"><div class="dsf dsf_sk_influence_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_influence_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Cha</div><div class="include-box"><div class="dsf dsf_cha_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_influence_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_influence_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Medicine</div> <div class="skill-total value-total"><div class="dsf dsf_sk_medicine_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_medicine_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_medicine_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_medicine_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Nature</div> <div class="skill-total value-total"><div class="dsf dsf_sk_nature_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_nature_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Awa</div><div class="include-box"><div class="dsf dsf_awa_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_nature_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_nature_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Occult</div> <div class="skill-total value-total"><div class="dsf dsf_sk_occult_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_occult_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_occult_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_occult_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Pilot</div> <div class="skill-total value-total"><div class="dsf dsf_sk_pilot_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_pilot_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Pro</div><div class="include-box"><div class="dsf dsf_pro_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_pilot_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_pilot_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Agility</div> <div class="skill-total value-total"><div class="dsf dsf_sk_agility_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_agility_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Pro</div><div class="include-box"><div class="dsf dsf_pro_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_agility_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_agility_item singlerow"></span></div></div> <div class="value-include"><div class="include-label">Armor</div><div class="include-box"><div class="dsf dsf_acp_display readonly"></div></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Science</div> <div class="skill-total value-total"><div class="dsf dsf_sk_science_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_science_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_science_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_science_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Technology</div> <div class="skill-total value-total"><div class="dsf dsf_sk_technology_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_technology_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_technology_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_technology_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Investigation</div> <div class="skill-total value-total"><div class="dsf dsf_sk_investigation_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_investigation_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_investigation_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_investigation_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Navigation</div> <div class="skill-total value-total"><div class="dsf dsf_sk_navigation_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_navigation_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Awa</div><div class="include-box"><div class="dsf dsf_awa_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_navigation_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_navigation_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Streetwise</div> <div class="skill-total value-total"><div class="dsf dsf_sk_streetwise_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_streetwise_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Cha</div><div class="include-box"><div class="dsf dsf_cha_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_streetwise_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_streetwise_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Tactics</div> <div class="skill-total value-total"><div class="dsf dsf_sk_tactics_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_tactics_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Int</div><div class="include-box"><div class="dsf dsf_int_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_tactics_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_tactics_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Endurance</div> <div class="skill-total value-total"><div class="dsf dsf_sk_endurance_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_endurance_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">End</div><div class="include-box"><div class="dsf dsf_end_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_endurance_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_endurance_item singlerow"></span></div></div> </div> <div class="skill-grid"> <div class="grey-back"></div><div class="save-label">Luck</div> <div class="skill-total value-total"><div class="dsf dsf_sk_luck_total readonly"></div></div> <div class="value-include cs-include"><div class="include-label">CS</div><div class="cs-box"><span class="dsf dsf_sk_luck_class check readonly"></span></div></div> <div class="value-include"><div class="include-label">Luc</div><div class="include-box"><div class="dsf dsf_luc_mod readonly"></div></div></div> <div class="value-include"><div class="include-label">Rank</div><div class="include-box"><span class="dsf dsf_sk_luck_ranks singlerow"></span></div></div> <div class="value-include"><div class="include-label">Misc</div><div class="include-box"><span class="dsf dsf_sk_luck_item singlerow"></span></div></div> </div> </div> </div> </div> </div> <div class="page page-2" style="display:none"><!-- COMBAT --> <div class="grid-3"> <div class="panel"><!-- K-DR / E-DR / CMB / CMD --> <div class="panel-title">Damage Reduction</div> <div class="dr-grid"> <div class="grey-back"></div> <div class="dr-label">K-DR</div> <div class="value-total"><div class="dsf dsf_kdr_total readonly"></div></div> <div class="value-include"> <div class="include-label">Base</div> <div class="include-box">10</div> </div> <div class="value-include"> <div class="include-label">Pro*</div> <div class="include-box"><div class="dsf dsf_max_prowess readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Armor</div> <div class="include-box"><div class="dsf dsf_armor_kdr_sum readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_kdr_misc singlerow"></span></div> </div> </div> <div class="dr-grid"> <div class="grey-back"></div> <div class="dr-label">E-DR</div> <div class="value-total"><div class="dsf dsf_edr_total readonly"></div></div> <div class="value-include"> <div class="include-label">Base</div> <div class="include-box">10</div> </div> <div class="value-include"> <div class="include-label">Pro*</div> <div class="include-box"><div class="dsf dsf_max_prowess readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Armor</div> <div class="include-box"><div class="dsf dsf_armor_edr_sum readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_edr_misc singlerow"></span></div> </div> </div> <div class="input"> <div class="input-label">*Torso Max Prowess Bonus (Light 4 / Medium 2 / Heavy 0; blank = Clothing, uncapped)</div> <span class="dsf dsf_max_prowess_input singlerow"></span> </div> <div class="panel-title panel-subtitle">Combat Maneuvers</div> <div class="cmb-grid"> <div class="grey-back"></div> <div class="dr-label">CMB</div> <div class="value-total small-total"><div class="dsf dsf_cmb_total readonly"></div></div> <div class="value-include"> <div class="include-label">BAB</div> <div class="include-box"><div class="dsf dsf_bab_mirror readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Str</div> <div class="include-box"><div class="dsf dsf_str_mod readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_cmb_misc singlerow"></span></div> </div> </div> <div class="cmb-grid"> <div class="grey-back"></div> <div class="dr-label">CMD</div> <div class="value-total small-total"><div class="dsf dsf_cmd_total readonly"></div></div> <div class="value-include"> <div class="include-label">Base</div> <div class="include-box">10</div> </div> <div class="value-include"> <div class="include-label">BAB</div> <div class="include-box"><div class="dsf dsf_bab_mirror readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Str</div> <div class="include-box"><div class="dsf dsf_str_mod readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Pro</div> <div class="include-box"><div class="dsf dsf_pro_mod readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_cmd_misc singlerow"></span></div> </div> </div> </div> <div class="panel"><!-- HP (+ HUMANITY) + MP --> <div class="panel-title">Hit Points & Humanity</div> <div class="pool-grid"> <div class="input"> <div class="input-label">HP Current</div> <span class="dsf dsf_current_hp singlerow"></span> </div> <div class="input"> <div class="input-label">HP Max</div> <span class="dsf dsf_max_hp singlerow"></span> </div> <div class="input"> <div class="input-label">Temp</div> <span class="dsf dsf_temporary_hp singlerow"></span> </div> </div> <div class="engine-info"><div class="dsf dsf_hp_die_info readonly"></div></div> <div class="input"> <div class="input-label">HP Notes</div> <span class="dsf dsf_hp_notes singlerow"></span> </div> <div class="resource-row humanity-row"> <div class="resource-name">Humanity</div> <div class="resource-value"> <div class="res-box"><span class="dsf dsf_humanity_current singlerow"></span></div> <div class="res-slash">/</div> <div class="res-box calc"><div class="dsf dsf_humanity_max readonly"></div></div> </div> <div class="resource-note">Max = (Awareness x4) minus total Humanity Drain from Augments (Inventory tab). Current takes damage from Psychic effects, like a second health bar. 40+ Stable, 30-39 Cold, 20-29 Unstable, 10-19 Pre-Psychosis, 0-9 Complete Madness. Restored via Vices (Vices tab).</div> </div> <div class="panel-title panel-subtitle">Mana Pool</div> <div class="pool-grid pool-grid-2"> <div class="input"> <div class="input-label">MP Current</div> <span class="dsf dsf_current_mp singlerow"></span> </div> <div class="input"> <div class="input-label">MP Max</div> <span class="dsf dsf_max_mp singlerow"></span> </div> </div> <div class="engine-info"><div class="dsf dsf_mp_die_info readonly"></div></div> <div class="input"> <div class="input-label">MP Notes</div> <span class="dsf dsf_mp_notes singlerow"></span> </div> </div> <div class="panel"><!-- SAVES + RESOURCES --> <div class="panel-title">Saving Throws</div> <div class="save-grid"> <div class="grey-back"></div> <div class="save-label">Fortitude</div> <div class="value-total"><div class="dsf dsf_fort_total readonly"></div></div> <div class="value-include"> <div class="include-label">End</div> <div class="include-box"><div class="dsf dsf_end_mod readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_fort_misc singlerow"></span></div> </div> </div> <div class="save-grid"> <div class="grey-back"></div> <div class="save-label">Reflex</div> <div class="value-total"><div class="dsf dsf_ref_total readonly"></div></div> <div class="value-include"> <div class="include-label">Pro</div> <div class="include-box"><div class="dsf dsf_pro_mod readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_ref_misc singlerow"></span></div> </div> </div> <div class="save-grid"> <div class="grey-back"></div> <div class="save-label">Will</div> <div class="value-total"><div class="dsf dsf_will_total readonly"></div></div> <div class="value-include"> <div class="include-label">Awa</div> <div class="include-box"><div class="dsf dsf_awa_mod readonly"></div></div> </div> <div class="value-include"> <div class="include-label">Misc</div> <div class="include-box"><span class="dsf dsf_will_misc singlerow"></span></div> </div> </div> <div class="panel-title panel-subtitle">Resources & Conditions</div> <div class="resource-row"> <div class="resource-name">Luck Pool</div> <div class="resource-value"> <div class="res-box"><span class="dsf dsf_luck_pool_current singlerow"></span></div> <div class="res-slash">/</div> <div class="res-box calc"><div class="dsf dsf_luck_pool_max readonly"></div></div> </div> <div class="resource-note">1pt=+1 own roll, 2pt=-1 enemy roll. Refills on Long Rest.</div> </div> <div class="resource-row"> <div class="resource-name">Recovery Dice</div> <div class="resource-value"> <div class="res-box"><span class="dsf dsf_recovery_current singlerow"></span></div> <div class="res-slash">/</div> <div class="res-box calc"><div class="dsf dsf_recovery_max readonly"></div></div> </div> <div class="resource-note">Max = Level. Spend on Short Rest: Hit Die (+End Mod) or Mana Die.</div> </div> <div class="resource-row"> <div class="resource-name">Fatigue Tier</div> <div class="resource-value"> <div class="res-box res-box-wide"><span class="dsf dsf_fatigue_tier singlerow"></span></div> </div> <div class="resource-note">/10. T1 -1 to K/E-DR+saves+d20s. T2 no Run/Charge. T4 pools halved. T5 speed halved, -2 all. T10 death.</div> </div> <div class="resource-row"> <div class="resource-name">Shock Tier</div> <div class="resource-value"> <div class="res-box res-box-wide"><span class="dsf dsf_shock_tier singlerow"></span></div> </div> <div class="resource-note">/10. T1 Unease. T2 Shaken. T4 Frightened. T6 Panicked. T10 Mind Break.</div> </div> </div> </div> <div class="grid-2"> <div class="panel"> <div class="panel-title">Initiative, Attack & Movement</div> <div class="resource-row"> <div class="resource-name">Initiative</div> <div class="resource-value"> <div class="res-box res-box-wide calc"><div class="dsf dsf_initiative_total readonly"></div></div> <div class="res-misc-inline"> <span class="dsf dsf_init_misc singlerow"></span> <div class="res-misc-label">misc</div> </div> </div> <div class="resource-note">= Prowess Mod + Misc</div> </div> <div class="resource-row"> <div class="resource-name">Base Attack Bonus</div> <div class="resource-value"> <div class="res-box res-box-wide"><span class="dsf dsf_bab singlerow"></span></div> </div> <div class="resource-note">Use paired game's BAB, or native: Full/Skilled Combat = Level; Skilled Caster = 3/4 Level; Full Caster = 1/2 Level.</div> </div> <div class="input-label speed-title">Movement (ft, in 5ft increments)</div> <div class="speed-grid"> <div class="input"> <div class="input-label">Land</div> <span class="dsf dsf_speed_land singlerow"></span> </div> <div class="input"> <div class="input-label">Burrow</div> <span class="dsf dsf_speed_burrow singlerow"></span> </div> <div class="input"> <div class="input-label">Climb</div> <span class="dsf dsf_speed_climb singlerow"></span> </div> <div class="input"> <div class="input-label">Fly</div> <span class="dsf dsf_speed_fly singlerow"></span> </div> <div class="input"> <div class="input-label">Swim</div> <span class="dsf dsf_speed_swim singlerow"></span> </div> <div class="input"> <div class="input-label">Reach</div> <span class="dsf dsf_reach singlerow"></span> </div> </div> </div> <div class="panel"><!-- SPECIAL DEFENSES & ATTACKS --> <div class="panel-title">Special Defenses & Attacks</div> <div class="power-dc-note">These show up in the Summary stat block exactly as you write them.</div> <div class="input"> <div class="input-label">Defensive Abilities (incl. DR, resistances, immunities)</div> <span class="dsf dsf_defensive_abilities"></span> </div> <div class="input"> <div class="input-label">Save Modifiers (e.g. +2 vs. poison, spells)</div> <span class="dsf dsf_save_notes"></span> </div> <div class="input"> <div class="input-label">Special Attacks</div> <span class="dsf dsf_special_attacks"></span> </div> <div class="input"> <div class="input-label">Other Combat Notes</div> <span class="dsf dsf_combat_notes"></span> </div> </div> </div> <div class="panel"><!-- ATTACKS --> <div class="panel-title">Attacks</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_attacks" title="Add an Attack"></span> </div> <ul class="group list list_attacks"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Name</div> <div class="edit dslf dslf_attack_name"></div> </div> <div class="row-3"> <div class="input"> <div class="input-label">Attack Bonus</div> <div class="edit dslf dslf_attack_attack"></div> </div> <div class="input"> <div class="input-label">Damage</div> <div class="edit dslf dslf_attack_damage"></div> </div> <div class="input"> <div class="input-label">Range</div> <div class="edit dslf dslf_attack_range"></div> </div> <div class="input"> <div class="input-label">Group</div> <div class="edit dslf dslf_attack_group"></div> </div> <div class="input"> <div class="input-label">Ammo</div> <div class="edit dslf dslf_attack_ammo"></div> </div> <div class="input"> <div class="input-label">Reload</div> <div class="edit dslf dslf_attack_reload"></div> </div> </div> <div class="check-group"> <span class="check-item"><span class="edit dslf dslf_attack_melee checkbox readonly check"></span><span class="check-label">Melee</span></span> <span class="check-item"><span class="edit dslf dslf_attack_ranged checkbox readonly check"></span><span class="check-label">Ranged</span></span> <span class="check-sep"></span> <span class="check-item"><span class="edit dslf dslf_attack_kinetic checkbox readonly check"></span><span class="check-label">vs K-DR</span></span> <span class="check-item"><span class="edit dslf dslf_attack_energy checkbox readonly check"></span><span class="check-label">vs E-DR</span></span> <span class="check-sep"></span> <span class="check-item"><span class="edit dslf dslf_attack_1hand checkbox readonly check"></span><span class="check-label">1 Hand</span></span> <span class="check-item"><span class="edit dslf dslf_attack_2hand checkbox readonly check"></span><span class="check-label">2 Hands</span></span> </div> <div class="input"> <div class="input-label">Properties / Traits</div> <div class="edit dslf dslf_attack_traits"></div> </div> </div> </li> <span class="oldfields hidden">[{"attack_name":"attack_name","attack_attack":"attack_attack","attack_melee":"attack_melee","attack_ranged":"attack_ranged","attack_damage":"attack_damage","attack_kinetic":"attack_kinetic","attack_energy":"attack_energy","attack_group":"attack_group","attack_1hand":"attack_1hand","attack_2hand":"attack_2hand","attack_range":"attack_range","attack_ammo":"attack_ammo","attack_reload":"attack_reload","attack_traits":"attack_traits"}]</span> <span class="dsf dsf_attacks readonly hidden"></span> </ul> </div> <div class="panel"><!-- CONDITIONS & INJURIES --> <div class="panel-title">Current Conditions</div> <div class="input"> <div class="input-label">Active Conditions (Shaken / Staggered / Stunned / Prone / Flat-Footed / Bleeding, etc.)</div> <span class="dsf dsf_conditions_notes singlerow"></span> </div> <div class="panel-title panel-subtitle">Injuries</div> <div class="power-dc-note">A hit for 50%+ of Max HP causes an Injury; a confirmed Called Shot crit causes a Severe Injury instead. Called Shot penalty: Torso -2, Limbs -4, Head -6. Injuries clear when treated; Severe Injuries need Regeneration or replacement (Chapter 9).</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_injuries" title="Add an Injury"></span> </div> <ul class="group list list_injuries"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="row-injury"> <div class="input"> <div class="input-label">Location</div> <select class="field-select" data-field="injury_location"> <option value="">- Choose -</option> <option>Head</option> <option>Torso</option> <option>Left Arm</option> <option>Right Arm</option> <option>Left Leg</option> <option>Right Leg</option> <option>Wing</option> <option>Tail / Tentacle</option> </select> <div class="edit dslf dslf_injury_location bound-field hide-when-editing"></div> </div> <div class="check-group"> <span class="check-item"><span class="edit dslf dslf_injury_treated checkbox readonly check"></span><span class="check-label">Treated</span></span> </div> </div> <div class="input input-tall"> <div class="input-label">Effect</div> <div class="edit dslf dslf_injury_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"injury_location":"injury_location","injury_severe":"injury_severe","injury_treated":"injury_treated","injury_desc":"injury_desc"}]</span> <span class="dsf dsf_injuries readonly hidden"></span> </ul> </div> </div> <div class="page page-3" style="display:none"><!-- ABILITIES --> <div class="grid-2"> <div class="one-column"> <div class="panel"> <div class="panel-title">Background Traits (2 free, +3 @ 1 LP)</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_bgtraits" title="Add a Background Trait"></span> </div> <ul class="group list list_bgtraits"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Trait</div> <div class="edit dslf dslf_bgtrait_name"></div> </div> <div class="input"> <div class="input-label">Effect</div> <div class="edit dslf dslf_bgtrait_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"bgtrait_name":"bgtrait_name","bgtrait_desc":"bgtrait_desc"}]</span> <span class="dsf dsf_bgtraits readonly hidden"></span> </ul> </div> <div class="panel"> <div class="panel-title">Racial Qualities</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_racial" title="Add a Racial Quality"></span> </div> <ul class="group list list_racial"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Quality</div> <div class="edit dslf dslf_racial_name"></div> </div> <div class="input"> <div class="input-label">Effect</div> <div class="edit dslf dslf_racial_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"racial_name":"racial_name","racial_desc":"racial_desc"}]</span> <span class="dsf dsf_racial readonly hidden"></span> </ul> </div> <div class="panel"> <div class="panel-title">Drawbacks (max 1 Minor + 1 Major)</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_drawbacks" title="Add a Drawback"></span> </div> <ul class="group list list_drawbacks"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Drawback</div> <div class="edit dslf dslf_drawback_name"></div> </div> <div class="check-group"> <span class="check-item"><span class="edit dslf dslf_drawback_minor checkbox readonly check"></span><span class="check-label">Minor (+1 LP)</span></span> <span class="check-item"><span class="edit dslf dslf_drawback_major checkbox readonly check"></span><span class="check-label">Major (+2 LP)</span></span> </div> <div class="input"> <div class="input-label">Effect</div> <div class="edit dslf dslf_drawback_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"drawback_name":"drawback_name","drawback_minor":"drawback_minor","drawback_major":"drawback_major","drawback_desc":"drawback_desc"}]</span> <span class="dsf dsf_drawbacks readonly hidden"></span> </ul> </div> </div> <div class="one-column"> <div class="panel"> <div class="panel-title">Feats (2 LP each, no limit)</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_feats" title="Add a Feat"></span> </div> <ul class="group list list_feats"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Feat</div> <div class="edit dslf dslf_feat_name"></div> </div> <div class="input"> <div class="input-label">Effect</div> <div class="edit dslf dslf_feat_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"feat_name":"feat_name","feat_desc":"feat_desc"}]</span> <span class="dsf dsf_feats readonly hidden"></span> </ul> </div> <div class="panel classfeatures-panel"> <div class="panel-title">Class Abilities</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_classabilities" title="Add a Class Ability"></span> </div> <ul class="group list list_classabilities"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Ability</div> <div class="edit dslf dslf_classability_name"></div> </div> <div class="input"> <div class="input-label">Gained At</div> <div class="edit dslf dslf_classability_level"></div> </div> <div class="input"> <div class="input-label">Effect</div> <div class="edit dslf dslf_classability_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"classability_name":"classability_name","classability_level":"classability_level","classability_desc":"classability_desc"}]</span> <span class="dsf dsf_classabilities readonly hidden"></span> </ul> </div> </div> </div> </div> <div class="page page-4" style="display:none"><!-- SPELLS --> <div class="panel"> <div class="panel-title">Spellcasting Traditions</div> <div class="power-dc-note">Tick every Tradition your character casts from. Spell Attack = BAB + that Tradition's modifier + Misc Atk. A spell's level = MP Cost ÷ 20, rounded up, minimum 1 (the rulebook calls this its Tier). Save DC = 10 + spell level + that Tradition's modifier + Misc DC (+ the spell's own DC Misc, e.g. Spell Focus for its school).</div> <div class="trad-table"> <div class="trad-head"> <div>Tradition</div><div>Mod</div><div>Misc Atk</div><div>Misc DC</div><div>Spell Atk</div><div>Base DC</div> </div> <div class="trad-row trad-row-arcane"> <div class="trad-name"><span class="dsf dsf_tradition_arcane check readonly"></span><span>Arcane <span class="tradition-sub">(Int)</span></span></div> <div class="include-box"><div class="dsf dsf_trad_arcane_mod readonly"></div></div> <div class="include-box"><span class="dsf dsf_trad_arcane_atkmisc singlerow"></span></div> <div class="include-box"><span class="dsf dsf_trad_arcane_dcmisc singlerow"></span></div> <div class="include-box"><div class="dsf dsf_trad_arcane_atk readonly"></div></div> <div class="include-box"><div class="dsf dsf_trad_arcane_dc readonly"></div></div> </div> <div class="trad-row trad-row-divine"> <div class="trad-name"><span class="dsf dsf_tradition_divine check readonly"></span><span>Divine <span class="tradition-sub">(Awa)</span></span></div> <div class="include-box"><div class="dsf dsf_trad_divine_mod readonly"></div></div> <div class="include-box"><span class="dsf dsf_trad_divine_atkmisc singlerow"></span></div> <div class="include-box"><span class="dsf dsf_trad_divine_dcmisc singlerow"></span></div> <div class="include-box"><div class="dsf dsf_trad_divine_atk readonly"></div></div> <div class="include-box"><div class="dsf dsf_trad_divine_dc readonly"></div></div> </div> <div class="trad-row trad-row-occult"> <div class="trad-name"><span class="dsf dsf_tradition_occult check readonly"></span><span>Occult <span class="tradition-sub">(Cha)</span></span></div> <div class="include-box"><div class="dsf dsf_trad_occult_mod readonly"></div></div> <div class="include-box"><span class="dsf dsf_trad_occult_atkmisc singlerow"></span></div> <div class="include-box"><span class="dsf dsf_trad_occult_dcmisc singlerow"></span></div> <div class="include-box"><div class="dsf dsf_trad_occult_atk readonly"></div></div> <div class="include-box"><div class="dsf dsf_trad_occult_dc readonly"></div></div> </div> </div> <div class="power-dc-note">*Base DC = 10 + modifier + Misc DC, before adding the spell's level. BAB used: <span class="dsf dsf_bab_mirror readonly inline-val"></span> (set on the Combat tab).</div> </div> <div class="panel"> <div class="panel-title">Spells</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_powers" title="Add a Spell"></span> </div> <ul class="group list list_powers"> <li class="proto item"> <div class="card spell-card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Spell</div> <div class="edit dslf dslf_power_name"></div> </div> <div class="row-3"> <div class="input"> <div class="input-label">Tradition</div> <select class="field-select" data-field="power_tradition"> <option value="">- Choose -</option> <option>Arcane</option> <option>Divine</option> <option>Occult</option> </select> <div class="edit dslf dslf_power_tradition bound-field hide-when-editing"></div> </div> <div class="input"> <div class="input-label">MP Cost</div> <div class="edit dslf dslf_power_mpcost"></div> </div> <div class="input"> <div class="input-label">DC Misc</div> <div class="edit dslf dslf_power_dcmisc"></div> </div> </div> <div class="spell-calc">Spell Level <span class="edit dslf dslf_power_level bound-field inline-val"></span> · Spell Atk <span class="edit dslf dslf_power_attack bound-field inline-val"></span> · Save DC <span class="edit dslf dslf_power_dc bound-field inline-val"></span></div> <div class="input"> <div class="input-label">School / Descriptors (e.g. transmutation [fire])</div> <div class="edit dslf dslf_power_school"></div> </div> <div class="card-sub">Casting</div> <div class="row-2"> <div class="input"> <div class="input-label">Casting Time</div> <div class="edit dslf dslf_power_casttime"></div> </div> <div class="input"> <div class="input-label">Components</div> <div class="edit dslf dslf_power_components"></div> </div> </div> <div class="card-sub">Effect</div> <div class="row-2"> <div class="input"> <div class="input-label">Range</div> <div class="edit dslf dslf_power_range"></div> </div> <div class="input"> <div class="input-label">Target / Area / Effect</div> <div class="edit dslf dslf_power_effect"></div> </div> </div> <div class="row-3"> <div class="input"> <div class="input-label">Duration</div> <div class="edit dslf dslf_power_duration"></div> </div> <div class="input"> <div class="input-label">Saving Throw</div> <div class="edit dslf dslf_power_save"></div> </div> <div class="input"> <div class="input-label">Spell Resistance</div> <div class="edit dslf dslf_power_sr"></div> </div> </div> <div class="card-sub">Description</div> <div class="input input-tall"> <div class="edit dslf dslf_power_description"></div> </div> </div> </li> <span class="oldfields hidden">[{"power_name":"power_name","power_tradition":"power_tradition","power_level":"power_level","power_mpcost":"power_mpcost","power_dcmisc":"power_dcmisc","power_attack":"power_attack","power_dc":"power_dc","power_school":"power_school","power_casttime":"power_casttime","power_components":"power_components","power_range":"power_range","power_effect":"power_effect","power_duration":"power_duration","power_save":"power_save","power_sr":"power_sr","power_description":"power_description"}]</span> <span class="dsf dsf_powers readonly hidden"></span> </ul> </div> </div> <div class="page page-5" style="display:none"><!-- INVENTORY --> <div class="grid-2"> <div class="panel"> <div class="panel-title">Encumbrance</div> <div class="input calc big-number"> <div class="input-label">Bulk Carried</div> <div class="dsf dsf_bulk readonly"></div> </div> <div class="input calc"> <div class="input-label">Unencumbered / Encumbered / Overloaded</div> <div class="threshold-readout"> <div class="dsf dsf_thresh_unenc readonly"></div><span>/</span><div class="dsf dsf_thresh_enc readonly"></div><span>/</span><div class="dsf dsf_thresh_over readonly"></div> </div> </div> <div class="input calc"> <div class="input-label">Armor Check Penalty (Worn Bulk x2)</div> <div class="dsf dsf_acp_display readonly"></div> </div> </div> <div class="panel"> <div class="panel-title">Currency</div> <div class="input"> <div class="input-label">Gold (or setting equivalent)</div> <span class="dsf dsf_currency_gold singlerow"></span> </div> <div class="input"> <div class="input-label">Notes</div> <span class="dsf dsf_currency_notes singlerow"></span> </div> </div> </div> <div class="panel"> <div class="panel-title">Modular Armor Loadout</div> <div class="armor-loadout-grid"> <div class="input-label">Slot</div> <div class="input-label">Armor Name</div> <div class="input-label">K-DR</div> <div class="input-label">E-DR</div> <div class="input-label">Bulk</div> <div class="armor-slot-name">Head</div> <div class="dsf dsf_armor_head_class singlerow"></div> <div class="dsf dsf_armor_head_kdr singlerow"></div> <div class="dsf dsf_armor_head_edr singlerow"></div> <div class="dsf dsf_armor_head_bulk singlerow"></div> <div class="armor-slot-name">Torso</div> <div class="dsf dsf_armor_torso_class singlerow"></div> <div class="dsf dsf_armor_torso_kdr singlerow"></div> <div class="dsf dsf_armor_torso_edr singlerow"></div> <div class="dsf dsf_armor_torso_bulk singlerow"></div> <div class="armor-slot-name">Left Arm</div> <div class="dsf dsf_armor_larm_class singlerow"></div> <div class="dsf dsf_armor_larm_kdr singlerow"></div> <div class="dsf dsf_armor_larm_edr singlerow"></div> <div class="dsf dsf_armor_larm_bulk singlerow"></div> <div class="armor-slot-name">Right Arm</div> <div class="dsf dsf_armor_rarm_class singlerow"></div> <div class="dsf dsf_armor_rarm_kdr singlerow"></div> <div class="dsf dsf_armor_rarm_edr singlerow"></div> <div class="dsf dsf_armor_rarm_bulk singlerow"></div> <div class="armor-slot-name">Left Leg</div> <div class="dsf dsf_armor_lleg_class singlerow"></div> <div class="dsf dsf_armor_lleg_kdr singlerow"></div> <div class="dsf dsf_armor_lleg_edr singlerow"></div> <div class="dsf dsf_armor_lleg_bulk singlerow"></div> <div class="armor-slot-name">Right Leg</div> <div class="dsf dsf_armor_rleg_class singlerow"></div> <div class="dsf dsf_armor_rleg_kdr singlerow"></div> <div class="dsf dsf_armor_rleg_edr singlerow"></div> <div class="dsf dsf_armor_rleg_bulk singlerow"></div> <div class="armor-slot-name">Shield</div> <div class="dsf dsf_armor_shield_class singlerow"></div> <div class="dsf dsf_armor_shield_kdr singlerow"></div> <div class="dsf dsf_armor_shield_edr singlerow"></div> <div class="dsf dsf_armor_shield_bulk singlerow"></div> <div class="armor-slot-name armor-mods-label">Mods</div> <div class="armor-mods-note">from the list below</div> <div class="dsf dsf_armormod_kdr_sum readonly"></div> <div class="dsf dsf_armormod_edr_sum readonly"></div> <div class="dsf dsf_armormod_bulk_sum readonly"></div> <div class="armor-slot-name armor-total-label">Totals</div> <div class="armor-total-spacer"></div> <div class="dsf dsf_armor_kdr_sum readonly armor-total-box"></div> <div class="dsf dsf_armor_edr_sum readonly armor-total-box"></div> <div class="dsf dsf_armor_worn_bulk readonly armor-total-box"></div> </div> <div class="input calc"> <div class="input-label">Prowess applied to K-DR/E-DR (Prowess Mod, capped by the Torso Max Prowess Bonus on the Combat tab)</div> <div class="dsf dsf_max_prowess readonly"></div> </div> </div> <div class="panel"><!-- ARMOR MODS / UPGRADES / SPECIAL MATERIALS --> <div class="panel-title">Armor Mods, Upgrades & Special Materials</div> <div class="power-dc-note">Anything done to a piece of armor after you got it: a bolted-on Mod, a slotted Upgrade, a Special Material (Featherweight: -1 Bulk; Lightweave: -1 Bulk, +1 Max Prowess; Hardened Alloy: +1 K-DR and +1 E-DR), or a custom Armor Creation Engine build. The K-DR, E-DR and Bulk you enter here are added to the loadout above; a Max Pro change on a Torso piece raises your Max Prowess cap.</div> <div class="sheet-notes-2"> <span class="interface trash inventory_trash"></span> <span class="interface add addto_armormods" title="Add an Armor Mod"></span> </div> <ul class="group list list_armormods"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Mod</div> <div class="edit dslf dslf_armormod_name"></div> </div> <div class="row-2"> <div class="input"> <div class="input-label">Applied To</div> <select class="field-select" data-field="armormod_slot"> <option value="">- Choose piece -</option> <option>Head</option> <option>Torso</option> <option>Left Arm</option> <option>Right Arm</option> <option>Left Leg</option> <option>Right Leg</option> <option>Shield</option> <option>Whole Suit</option> </select> <div class="edit dslf dslf_armormod_slot bound-field hide-when-editing"></div> </div> <div class="input"> <div class="input-label">Type</div> <select class="field-select" data-field="armormod_type"> <option value="">- Choose type -</option> <option>Mod</option> <option>Upgrade</option> <option>Special Material</option> <option>Custom Build (AP)</option> <option>Magic Enhancement</option> </select> <div class="edit dslf dslf_armormod_type bound-field hide-when-editing"></div> </div> </div> <div class="row-4"> <div class="input"> <div class="input-label">K-DR +/-</div> <div class="edit dslf dslf_armormod_kdr"></div> </div> <div class="input"> <div class="input-label">E-DR +/-</div> <div class="edit dslf dslf_armormod_edr"></div> </div> <div class="input"> <div class="input-label">Bulk +/-</div> <div class="edit dslf dslf_armormod_bulk"></div> </div> <div class="input"> <div class="input-label">Max Pro +/-</div> <div class="edit dslf dslf_armormod_maxpro"></div> </div> </div> <div class="input"> <div class="input-label">Effect / Notes</div> <div class="edit dslf dslf_armormod_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"armormod_name":"armormod_name","armormod_slot":"armormod_slot","armormod_type":"armormod_type","armormod_kdr":"armormod_kdr","armormod_edr":"armormod_edr","armormod_bulk":"armormod_bulk","armormod_maxpro":"armormod_maxpro","armormod_desc":"armormod_desc"}]</span> <span class="dsf dsf_armormods readonly hidden"></span> </ul> </div> <div class="panel"><!-- MAGIC ITEMS & WORN ACCESSORIES --> <div class="panel-title">Magic Items & Worn Accessories</div> <div class="power-dc-note">Rings, cloaks, boots, amulets, tech gadgets and so on. One equipped item per slot (Rings: max 2); slotless items (wands, ioun stones, charms) don't use a slot. Worn accessories don't conflict with Modular Armor.</div> <div class="input calc"> <div class="input-label">Slots in use (equipped items)</div> <div class="dsf dsf_magic_slots_used readonly"></div> </div> <div class="sheet-notes-2"> <span class="interface trash inventory_trash"></span> <span class="interface add addto_magicitems" title="Add a Magic Item"></span> </div> <ul class="group list list_magicitems"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Item</div> <div class="edit dslf dslf_magic_name"></div> </div> <div class="row-3"> <div class="input"> <div class="input-label">Slot</div> <select class="field-select" data-field="magic_slot"> <option value="">- Choose slot -</option> <option>Head</option> <option>Neck</option> <option>Shoulders / Back</option> <option>Chest / Vest</option> <option>Waist</option> <option>Wrists</option> <option>Hands</option> <option>Ring</option> <option>Feet</option> <option>Slotless / Held</option> </select> <div class="edit dslf dslf_magic_slot bound-field hide-when-editing"></div> </div> <div class="input"> <div class="input-label">Charges / Uses</div> <div class="edit dslf dslf_magic_charges"></div> </div> <div class="input"> <div class="input-label">Bulk</div> <div class="edit dslf dslf_magic_bulk"></div> </div> </div> <div class="check-group"> <span class="check-item"><span class="edit dslf dslf_magic_equipped checkbox readonly check"></span><span class="check-label">Equipped</span></span> <span class="check-item"><span class="edit dslf dslf_magic_identified checkbox readonly check"></span><span class="check-label">Identified</span></span> <span class="check-item"><span class="edit dslf dslf_magic_tech checkbox readonly check"></span><span class="check-label">Tech (not magic)</span></span> </div> <div class="input input-tall"> <div class="input-label">Effect / Bonuses</div> <div class="edit dslf dslf_magic_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"magic_name":"magic_name","magic_slot":"magic_slot","magic_charges":"magic_charges","magic_bulk":"magic_bulk","magic_equipped":"magic_equipped","magic_identified":"magic_identified","magic_tech":"magic_tech","magic_desc":"magic_desc"}]</span> <span class="dsf dsf_magicitems readonly hidden"></span> </ul> <div class="input"> <div class="input-label">Accessory Notes</div> <span class="dsf dsf_accessory_notes singlerow"></span> </div> </div> <div class="panel"><!-- INTERNAL AUGMENTS / CYBERWARE --> <div class="panel-title">Internal Augments & Cyberware</div> <div class="power-dc-note">Every installed augment permanently drains Max Humanity. Slots: Cranial, Ocular, Throat, Spine, Core, Arms (up to 2), Legs (up to 2).</div> <div class="gems-grid augments-header-grid"> <div class="input-label">Name</div> <div class="input-label">Slot</div> <div class="input-label">Drain</div> </div> <div class="sheet-notes-2"> <span class="interface trash inventory_trash"></span> <span class="interface add addto_augments" title="Add an Augment"></span> </div> <ul class="group list list_augments"> <li class="proto item"> <div class="one-gem"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_augment_name"></div> <div class="edit dslf dslf_augment_slot"></div> <div class="edit dslf dslf_augment_drain"></div> </div> </li> <span class="oldfields hidden">[{"augment_name":"augment_name","augment_slot":"augment_slot","augment_drain":"augment_drain"}]</span> <span class="dsf dsf_augments readonly hidden"></span> </ul> <div class="input calc"> <div class="input-label">Total Humanity Drain (subtracted from Max Humanity)</div> <div class="dsf dsf_augment_drain_sum readonly"></div> </div> </div> <div class="grid-2"> <div class="panel"> <div class="panel-title">Consumables</div> <div class="big-input"> <div class="consumables-grid"> <div class="input-label">Item</div> <div class="input-label">Qty</div> <div class="input-label">Bulk</div> </div> <div class="sheet-notes-2"> <span class="interface trash inventory_trash"></span> <span class="interface add addto_consumables" title="Add a Consumable"></span> </div> <ul class="group list list_consumables"> <li class="proto item"> <div class="one-consumable"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_consumable_name"></div> <div class="edit dslf dslf_consumable_qty"></div> <div class="edit dslf dslf_consumable_bulk"></div> </div> </li> <span class="oldfields hidden">[{"consumable_name":"consumable_name","consumable_qty":"consumable_qty","consumable_bulk":"consumable_bulk"}]</span> <span class="dsf dsf_consumables readonly hidden"></span> </ul> </div> </div> <div class="panel"> <div class="panel-title">Gems & Valuables</div> <div class="big-input"> <div class="gems-grid"> <div class="input-label">Item</div> <div class="input-label">Price</div> <div class="input-label">Bulk</div> </div> <div class="sheet-notes-2"> <span class="interface trash inventory_trash"></span> <span class="interface add addto_gems" title="Add a Gem or Valuable"></span> </div> <ul class="group list list_gems"> <li class="proto item"> <div class="one-gem"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_gem_name"></div> <div class="edit dslf dslf_gem_price"></div> <div class="edit dslf dslf_gem_bulk"></div> </div> </li> <span class="oldfields hidden">[{"gem_name":"gem_name","gem_price":"gem_price","gem_bulk":"gem_bulk"}]</span> <span class="dsf dsf_gems readonly hidden"></span> </ul> </div> </div> </div> <div class="panel"> <div class="panel-title">Permanent Items & Gear</div> <div class="sheet-notes-2"> <span class="interface trash inventory_trash"></span> <span class="interface add addto_inventory" title="Add an Inventory Item"></span> </div> <ul class="group list list_inventory"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Name</div> <div class="edit dslf dslf_item_name"></div> </div> <div class="row-2"> <div class="input"> <div class="input-label">Qty</div> <div class="edit dslf dslf_inventory_quantity"></div> </div> <div class="input"> <div class="input-label">Bulk</div> <div class="edit dslf dslf_inventory_bulk"></div> </div> </div> <div class="check-group"> <span class="check-item"><span class="edit dslf dslf_inventory_worn checkbox readonly check"></span><span class="check-label">Worn</span></span> <span class="check-item"><span class="edit dslf dslf_inventory_readied checkbox readonly check"></span><span class="check-label">Readied</span></span> <span class="check-item"><span class="edit dslf dslf_inventory_other checkbox readonly check"></span><span class="check-label">Stored</span></span> </div> <div class="input input-tall"> <div class="input-label">Notes / Description</div> <div class="edit dslf dslf_item_description"></div> </div> </div> </li> <span class="oldfields hidden">[{"item_name":"item_name","inventory_quantity":"inventory_quantity","inventory_bulk":"inventory_bulk","inventory_worn":"inventory_worn","inventory_readied":"inventory_readied","inventory_other":"inventory_other","item_description":"item_description"}]</span> <span class="dsf dsf_inventory readonly hidden"></span> </ul> </div> </div> <div class="page page-6" style="display:none"><!-- VICES --> <div class="panel"> <div class="panel-title">Alignment (-5 to +5)</div> <div class="resource-row"> <div class="resource-name">Order</div> <div class="resource-value"> <div class="res-box res-box-wide"><span class="dsf dsf_alignment_order singlerow"></span></div> </div> <div class="resource-note">Chaotic (-5) ↔ Neutral (0) ↔ Lawful (+5). Off-neutral: bonus/penalty = tier on Tactics/fear saves vs Initiative/Luck rolls.</div> </div> <div class="resource-row"> <div class="resource-name">Morality</div> <div class="resource-value"> <div class="res-box res-box-wide"><span class="dsf dsf_alignment_morality singlerow"></span></div> </div> <div class="resource-note">Evil (-5) ↔ Neutral (0) ↔ Good (+5). Off-neutral: bonus/penalty = tier on Medicine/Relief vs Intimidate/Helpless-crit.</div> </div> </div> <div class="panel"> <div class="panel-title">Vices & Indulgence</div> <div class="power-dc-note">During a Downtime Segment, roll a dice pool of d6s equal to your Lowest S.P.E.C.I.A.L. score (min 1d6). Restore Humanity equal to the highest single die (exploding on a 6, up to your Luck limit). If the highest die clears more Humanity than you were missing, pick up an Overindulgence.</div> <div class="grid-2"> <div class="input"> <div class="input-label">My Vice(s)</div> <span class="dsf dsf_vice_description singlerow"></span> </div> <div class="resource-row"> <div class="resource-name">Flashback Pts</div> <div class="resource-value"> <div class="res-box"><span class="dsf dsf_flashback_current singlerow"></span></div> <div class="res-slash">/</div> <div class="res-box calc">3</div> </div> <div class="resource-note">Forgo a Downtime Segment to bank 1 FP, max 3.</div> </div> </div> <div class="input"> <div class="input-label">Downtime Segments Logged / Notes</div> <span class="dsf dsf_downtime_notes singlerow"></span> </div> <div class="panel-title panel-subtitle">Overindulgences</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_overindulgences" title="Add an Overindulgence"></span> </div> <ul class="group list list_overindulgences"> <li class="proto item"> <div class="card"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="name-row"> <div class="action-label">Name</div> <div class="edit dslf dslf_overindulgence_name"></div> </div> <div class="input"> <div class="input-label">Effect</div> <div class="edit dslf dslf_overindulgence_desc"></div> </div> </div> </li> <span class="oldfields hidden">[{"overindulgence_name":"overindulgence_name","overindulgence_desc":"overindulgence_desc"}]</span> <span class="dsf dsf_overindulgences readonly hidden"></span> </ul> </div> </div> <div class="page page-7" style="display:none"><!-- BIO --> <div class="grid-4"> <div class="panel"> <div class="panel-title">Personality</div> <div class="personality"> <div class="input"> <div class="input-label">Attitude</div> <span class="dsf dsf_attitude singlerow"></span> </div> <div class="input"> <div class="input-label">Beliefs</div> <span class="dsf dsf_beliefs singlerow"></span> </div> <div class="input"> <div class="input-label">Likes</div> <span class="dsf dsf_likes singlerow"></span> </div> <div class="input"> <div class="input-label">Dislikes</div> <span class="dsf dsf_dislikes singlerow"></span> </div> <div class="input"> <div class="input-label">Catchphrases</div> <span class="dsf dsf_catchphrases singlerow"></span> </div> </div> </div> <div class="panel"> <div class="panel-title">Physical Details</div> <div class="physical-details-grid"> <div class="input pd-wide"> <div class="input-label">Ethnicity / Origin World</div> <span class="dsf dsf_ethnicity singlerow"></span> </div> <div class="input pd-wide"> <div class="input-label">Nationality / Faction</div> <span class="dsf dsf_nationality singlerow"></span> </div> <div class="input pd-wide"> <div class="input-label">Birthplace</div> <span class="dsf dsf_birthplace singlerow"></span> </div> <div class="input"> <div class="input-label">Height</div> <span class="dsf dsf_height singlerow"></span> </div> <div class="input"> <div class="input-label">Weight</div> <span class="dsf dsf_weight singlerow"></span> </div> <div class="input"> <div class="input-label">Age</div> <span class="dsf dsf_age singlerow"></span> </div> <div class="input"> <div class="input-label">Sex or Gender</div> <span class="dsf dsf_gender singlerow"></span> </div> </div> </div> </div> <div class="panel"> <div class="panel-title">Campaign Notes</div> <div class="grid-2"> <div class="one-column"> <div class="big-input"> <div class="npc-label-grid"> <div class="input-label">Allies & Companions</div> <div class="input-label">Location</div> </div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_npc_allies" title="Add an Ally or Companion"></span> </div> <ul class="group list list_npc_allies"> <li class="proto item"> <div class="one-npc-grid"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_ally_name"></div> <div class="edit dslf dslf_ally_location"></div> </div> </li> <span class="oldfields hidden">[{"ally_name":"ally_name","ally_location":"ally_location"}]</span> <span class="dsf dsf_npc_allies readonly hidden"></span> </ul> </div> <div class="big-input"> <div class="npc-label-grid"> <div class="input-label">Organizations / Factions</div> <div class="input-label">Heat</div> </div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_npc_organizations" title="Add an Organization"></span> </div> <ul class="group list list_npc_organizations"> <li class="proto item"> <div class="one-npc-grid"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_organization_name"></div> <div class="edit dslf dslf_organization_location"></div> </div> </li> <span class="oldfields hidden">[{"organization_name":"organization_name","organization_location":"organization_location"}]</span> <span class="dsf dsf_npc_organizations readonly hidden"></span> </ul> </div> </div> <div class="one-column"> <div class="big-input"> <div class="npc-label-grid"> <div class="input-label">Enemies</div> <div class="input-label">Location</div> </div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_npc_enemies" title="Add an Enemy"></span> </div> <ul class="group list list_npc_enemies"> <li class="proto item"> <div class="one-npc-grid"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_enemy_name"></div> <div class="edit dslf dslf_enemy_location"></div> </div> </li> <span class="oldfields hidden">[{"enemy_name":"enemy_name","enemy_location":"enemy_location"}]</span> <span class="dsf dsf_npc_enemies readonly hidden"></span> </ul> </div> <div class="big-input"> <div class="input-label">Notes / Other</div> <div class="sheet-notes-2"> <span class="interface trash"></span> <span class="interface add addto_npc_notes" title="Add a Note"></span> </div> <ul class="group list list_npc_notes"> <li class="proto item"> <div class="npc-name-container"> <div class="handle"><div></div></div> <div class="handle-space"></div> <div class="edit dslf dslf_note_name"></div> </div> </li> <span class="oldfields hidden">[{"note_name":"note_name"}]</span> <span class="dsf dsf_npc_notes readonly hidden"></span> </ul> </div> </div> </div> </div> <div class="panel"> <div class="panel-title">Appearance & Biography</div> <span class="dsf dsf_appearance"></span> <div class="sheet-notes"> Please use the Biography textfield below to insert the character's biography. </div> <div class="dsf dsf_bio"></div> </div> </div> <div class="footer"> <div class="dsf dsf_campaign readonly"></div> - A MultiversalD20 Campaign <br> Character Sheet Template by: <div class="dsf dsf_dst_author readonly"></div> </div> </div>
CSS
@import url(https://chainsawxiv.github.io/DST/common/css/csx_pathfinder_common.css); @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@600;700&family=Merriweather:wght@400;700&display=swap'); /* Border-box everywhere, so a box's border and padding never make it bigger than the width/height it was given. */ .multiversald20-root, .multiversald20-root *, .multiversald20-root *::before, .multiversald20-root *::after { box-sizing: border-box; } .multiversald20-root.sheet-container { background-color: #f4f1ea; width: 100%; font-family: 'Merriweather', georgia, times, 'times new roman', serif; } /* NO RICH TEXT: the CSX bold/italic/underline/indent bar is hidden (the JS also blocks Ctrl+B/I/U and pastes as plain text). The buttons stay in the HTML because the CSX editor script looks them up. */ .multiversald20-root .uicontainer, .multiversald20-root .formatBar, .csx .formatBar { display: none !important; } /* SHEET NOTES (edit mode only) */ .multiversald20-root .sheet-notes { display:none; border:1px solid #A52A2A; border-radius:6px; box-shadow:3px 3px 3px #999; text-align:center; font-size:16px; font-style:italic; margin-bottom:10px; font-variant: small-caps; padding: 0px 4px; } /* List toolbar: just the + (add) and trash icons, right-aligned, shown only while editing. */ .multiversald20-root .sheet-notes-2 { display: none; justify-content: flex-end; align-items: center; gap: 10px; height: 24px; margin-bottom: 4px; padding: 0 2px; border: 0; box-shadow: none; } .editable .multiversald20-root .sheet-notes { display: block; } .editable .multiversald20-root .sheet-notes-2 { display: flex; } .multiversald20-root .sheet-notes-2 .interface { float: none !important; margin: 0 !important; } /* GRID STRUCTURES */ .multiversald20-root .grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-gap: 6px; margin-bottom: 6px; } .multiversald20-root .grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 6px; margin-bottom: 6px; } .multiversald20-root .grid-4 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); grid-gap: 6px; margin-bottom: 6px; } .multiversald20-root .grid-tabs { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-gap: 3px; margin-bottom: 6px; } .multiversald20-root .one-column { display: grid; grid-template-columns: minmax(0, 1fr); grid-row-gap: 6px; align-content: start; } .multiversald20-root .row-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-gap: 6px; } .multiversald20-root .row-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 6px; } .multiversald20-root .row-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-gap: 6px; } /* TABS */ .multiversald20-root .tab { cursor: pointer; text-align: center; border: 1px solid #000; border-radius: 8px 8px 0px 0px; font-size: 15px; font-family: 'Cinzel', georgia, serif; font-variant: small-caps; padding: 4px 0; background: radial-gradient(ellipse at center, #A52A2A 0%, #000000 85%); color: #ddd; text-shadow: 1px 1px 1px #000; white-space: nowrap; overflow: hidden; } .multiversald20-root .tab-2, .multiversald20-root .tab-3, .multiversald20-root .tab-4, .multiversald20-root .tab-5, .multiversald20-root .tab-6, .multiversald20-root .tab-7 { background: #ccc; color: #333; text-shadow: none; } .multiversald20-root .page-2, .multiversald20-root .page-3, .multiversald20-root .page-4, .multiversald20-root .page-5, .multiversald20-root .page-6, .multiversald20-root .page-7 { display: none; } /* PANELS */ .multiversald20-root .panel { border: 1px solid #000; border-radius: 14px / 8px; box-shadow: 3px 3px 5px #999; background: #fff; padding: 0 6px 8px 6px; margin-bottom: 6px; overflow: hidden; min-width: 0; } .multiversald20-root .panel-title { font-family: 'Cinzel', georgia, serif; background: radial-gradient(ellipse at center, #A52A2A 0%, #000000 78%); font-size: 15px; line-height: 1.25; color: #ddd; text-align: center; text-shadow: 1px 1px 1px #000; margin: 0 -6px 6px -6px; padding: 4px 6px 6px 6px; border-radius: 13px 13px 0 0; } .multiversald20-root .panel-title.panel-subtitle { background: radial-gradient(ellipse at center, #B8860B 0%, #000000 78%); font-size: 13px; border-radius: 4px; margin: 8px 0 6px 0; padding: 3px 4px 4px 4px; } .multiversald20-root .classfeatures-panel { box-shadow: 3px 3px 8px #A52A2A; } .multiversald20-root .power-dc-note, .multiversald20-root .skills-note { font-size: 11px; font-style: italic; color: #555; line-height: 1.35; margin-bottom: 6px; } /* INPUT BOX: label on top, value underneath. Height grows with the content, so a label that wraps to two lines can never overlap the value or the next box. No inner padding, so the blue edit shading fills the box edge to edge. */ .multiversald20-root .input { border: 1px solid #000; box-shadow: 1px 1px 1px #ccc; background: #fff; min-height: 36px; display: flex; flex-direction: column; min-width: 0; margin-bottom: 6px; } .multiversald20-root .row-2 > .input, .multiversald20-root .row-3 > .input, .multiversald20-root .row-4 > .input, .multiversald20-root .row-injury > .input, .multiversald20-root .basic-info-grid > .input, .multiversald20-root .pool-grid > .input, .multiversald20-root .speed-grid > .input, .multiversald20-root .physical-details-grid > .input, .multiversald20-root .personality > .input, .multiversald20-root .card > .input { margin-bottom: 0; } .multiversald20-root .input-label { font-size: 10px; line-height: 13px; font-variant: small-caps; padding: 1px 4px 0 4px; color: #333; } .multiversald20-root .input > .dsf, .multiversald20-root .input > .edit, .multiversald20-root .input > .calc-value { flex: 1 1 auto; padding: 1px 6px 2px 6px; min-height: 21px; font-size: 15px; line-height: 1.3; } .multiversald20-root .input-tall > .edit { min-height: 44px; font-size: 13px; } .multiversald20-root .input.big-number > .dsf { font-size: 24px; text-align: center; line-height: 1.2; } /* Values the sheet works out for you stay white; you can't type in them. */ .multiversald20-root .bound-field { pointer-events: none; } .editable .multiversald20-root .bound-field, .editable .multiversald20-root .calc .dsf, .editable .multiversald20-root .calc .edit { background-color: transparent !important; cursor: default; } .editable .multiversald20-root .hide-when-editing { display: none !important; } .multiversald20-root .dsf.inline-val, .multiversald20-root .edit.inline-val, .editable .multiversald20-root .dsf.inline-val, .editable .multiversald20-root .edit.inline-val { display: inline !important; padding: 0 !important; min-height: 0 !important; background: transparent !important; } /* DROP-DOWNS (Injury location/effect, Spell tradition). Only shown while editing; in view mode the saved text underneath is shown instead. */ .multiversald20-root .field-select { display: none; } /* !important throughout: Obsidian Portal's own site CSS styles every <select> (big font, fixed height, grey gradient), which cut the text off. */ .editable .multiversald20-root .field-select { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 26px !important; margin: 0 !important; padding: 3px 4px !important; font-family: inherit !important; font-size: 14px !important; line-height: 1.3 !important; border: 0 !important; border-top: 1px solid #aab !important; border-radius: 0 !important; background: #cdf !important; color: #000 !important; box-shadow: none !important; text-overflow: ellipsis; } /* Tap-to-delete X on every list entry (edit mode only). */ .multiversald20-root.csx .list > li.item { position: relative; } .multiversald20-root .row-delete { display: none; } .editable .multiversald20-root.csx .list > li.item { padding-right: 28px; } .editable .multiversald20-root .row-delete { display: flex; align-items: center; justify-content: center; position: absolute; top: 2px; right: 0; width: 24px; height: 24px; border: 1px solid #722; border-radius: 50%; background: #fff; color: #A52A2A; font-size: 13px; font-weight: bold; line-height: 1; cursor: pointer; z-index: 2; user-select: none; } .editable .multiversald20-root .row-delete:hover { background: #A52A2A; color: #fff; } /* CHECKBOXES: every checkbox is a fixed 12x12 box, and each one sits in a .check-item next to its label. The group wraps onto a new line on narrow screens instead of spilling out of its border. */ .multiversald20-root .check, .editable .multiversald20-root .check { display: inline-block !important; flex: 0 0 12px; width: 12px; height: 12px; min-height: 0 !important; padding: 0 !important; margin: 0 !important; background-color: transparent !important; vertical-align: middle; position: relative; line-height: 0; overflow: visible; } .multiversald20-root .check .checkBorder { position: static !important; top: auto !important; left: auto !important; } .multiversald20-root .check-group { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 14px; border: 1px solid #000; background: #fff; padding: 5px 8px; min-height: 28px; } .multiversald20-root .check-item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; } .multiversald20-root .check-label { font-size: 12px; line-height: 14px; font-variant: small-caps; } .multiversald20-root .check-sep { width: 4px; } /* LIST CARDS (attacks, actions, spells, gear, traits, injuries, drawbacks) */ .multiversald20-root .card { position: relative; display: flex; flex-direction: column; gap: 6px; border: 2px outset #444; border-radius: 6px; box-shadow: 1px 1px 1px #ccc; background: #fff; padding: 6px 8px 8px 22px; min-width: 0; } .multiversald20-root .card > .handle, .multiversald20-root .card > .handle-space { position: absolute; left: 5px; top: 10px; } .multiversald20-root .handle-space { display: block; } .editable .multiversald20-root .handle-space { display: none; } .multiversald20-root .name-row { display: grid; grid-template-columns: 70px minmax(0, 1fr); } .multiversald20-root .action-label { background-color: #ccc; border: 1px solid #000; text-align: center; font-size: 12px; line-height: 24px; font-variant: small-caps; white-space: nowrap; overflow: hidden; } .multiversald20-root .name-row > .edit { border: 1px solid #000; border-left: 0; padding: 1px 6px; min-height: 26px; font-size: 16px; line-height: 1.4; } .multiversald20-root .row-injury { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-gap: 6px; align-items: stretch; } .multiversald20-root.csx .list li.item { margin-bottom: 6px; } .multiversald20-root .list_powers, .multiversald20-root .list_inventory, .multiversald20-root .list_attacks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-column-gap: 6px; } /* BASIC INFORMATION */ .multiversald20-root .basic-info { display: grid; grid-template-columns: 96px minmax(0, 1fr); grid-gap: 8px; align-items: start; } .multiversald20-root .avatar-cell .dsf_avatar_image { width: 96px; min-height: 120px; border: 1px solid #000; background-size: cover; background-position: center; } .multiversald20-root .avatar-cell img { max-width: 100%; height: auto; display: block; } .multiversald20-root .basic-info-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-gap: 4px; } .multiversald20-root .basic-info-grid .bi-name, .multiversald20-root .basic-info-grid .bi-player { grid-column: span 2; } .multiversald20-root .basic-info-grid .bi-wide { grid-column: span 2; } .multiversald20-root .basic-info-grid .bi-full { grid-column: 1 / -1; } .multiversald20-root .bi-name > .dsf { font-family: 'Cinzel', georgia, serif; font-size: 20px; } .multiversald20-root .bi-player > .dsf { font-size: 13px; } .multiversald20-root .calc-value { text-align: left; } /* ENGINE PICKER */ .multiversald20-root .engine-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-gap: 4px; margin-bottom: 4px; } .multiversald20-root .one-engine { border: 1px solid #000; box-shadow: 1px 1px 2px #999; display: flex; align-items: center; gap: 6px; padding: 4px 6px; background-color: white; border-radius: 6px; } .multiversald20-root .engine-label { flex: 1 1 auto; font-size: 11px; line-height: 13px; font-variant: small-caps; text-align: center; } .multiversald20-root .engine-dice { font-size: 9px; font-variant: normal; color: #555; } .multiversald20-root .engine-info { font-size: 11px; font-style: italic; color: #555; line-height: 1.3; margin: 0 0 6px 0; min-height: 14px; } /* ABILITY SCORES */ .multiversald20-root .ability-label-grid { display: grid; grid-template-columns: 110px 1fr 40px; grid-column-gap: 6px; } .multiversald20-root .ability-label-grid div { font-size: 10px; font-variant: small-caps; line-height: 12px; } .multiversald20-root .ability-score-grid { display: grid; grid-template-columns: 110px 1fr 40px; grid-template-rows: 3px 3px 12px 3px 3px; grid-column-gap: 6px; margin-bottom: 9px; } .multiversald20-root .ability-score-grid .attr-label { grid-area: 1/1/6/2; border: 1px solid #000; height: 24px; line-height: 22px; font-size: 15px; background-color: white; padding: 0px 4px; font-variant: small-caps; box-shadow: 1px 1px 1px #ccc; white-space: nowrap; overflow: hidden; } .multiversald20-root .ability-score-grid .abil-score { grid-area: 1/2/6/3; width: 100%; } .multiversald20-root .ability-score-grid .abil-mod { grid-area: 1/3/6/4; width: 100%; } .multiversald20-root .ability-score-grid .grey-back { grid-area: 2/1/3/4; height:16px; border:1px solid #000; background-color:#e2ddd2; } .multiversald20-root .abil-score .dsf, .multiversald20-root .abil-mod .dsf { text-align: center; font-size: 16px; line-height: 22px; height: 22px; } /* SMALL NUMBER BOXES */ .multiversald20-root .value-total { border: 1px solid #000; height: 34px; width: 34px; font-size: 20px; line-height: 32px; text-align: center; box-shadow: 1px 1px 1px #ccc; background-color: white; flex: 0 0 auto; } .multiversald20-root .value-total.small-total { height: 30px; width: 30px; font-size: 17px; line-height: 28px; } .multiversald20-root .value-include { width: 32px; text-align: center; flex: 0 0 auto; } .multiversald20-root .include-label { height: 12px; font-size: 9px; line-height: 11px; font-variant: small-caps; text-align: center; white-space: nowrap; } .multiversald20-root .include-box { height: 24px; width: 30px; border: 1px solid #000; text-align: center; font-size: 15px; line-height: 22px; background-color: white; box-shadow: 1px 1px 1px #ccc; margin: 0 auto; } .multiversald20-root .include-box > .dsf { height: 22px; line-height: 22px; text-align: center; } /* K-DR / E-DR, CMB / CMD, SAVES, SKILLS: label, total, then the parts that add up to it. The label box shrinks first on narrow screens so the whole row always fits inside its panel. */ .multiversald20-root .dr-grid, .multiversald20-root .cmb-grid, .multiversald20-root .save-grid, .multiversald20-root .skill-grid { display: flex; align-items: flex-end; gap: 6px; margin-bottom: 6px; position: relative; padding-bottom: 3px; min-width: 0; } .multiversald20-root .dr-grid .grey-back, .multiversald20-root .cmb-grid .grey-back, .multiversald20-root .save-grid .grey-back, .multiversald20-root .skill-grid .grey-back { position: absolute; left: 0; right: 0; bottom: 3px; height: 16px; border: 1px solid #000; background-color: #e2ddd2; z-index: 0; } .multiversald20-root .dr-label, .multiversald20-root .save-label { position: relative; z-index: 1; border: 1px solid #000; background-color: white; flex: 1 1 68px; min-width: 42px; max-width: 110px; height: 24px; line-height: 22px; font-size: 13px; font-variant: small-caps; box-shadow: 1px 1px 1px #ccc; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 3px; } .multiversald20-root .skill-grid .save-label { max-width: 130px; flex-basis: 110px; text-align: left; } .multiversald20-root .dr-grid > *:not(.grey-back), .multiversald20-root .cmb-grid > *:not(.grey-back), .multiversald20-root .save-grid > *:not(.grey-back), .multiversald20-root .skill-grid > *:not(.grey-back) { position: relative; z-index: 1; } .multiversald20-root .skill-grid .value-include.cs-include { width: 20px; } .multiversald20-root .cs-box { height: 24px; width: 20px; border: 1px solid #000; background-color: white; box-shadow: 1px 1px 1px #ccc; display: flex; align-items: center; justify-content: center; } /* HP / MP POOLS */ .multiversald20-root .pool-grid { display: grid; grid-gap: 4px; margin-bottom: 6px; grid-template-columns: repeat(3, minmax(0, 1fr)); } .multiversald20-root .pool-grid.pool-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .multiversald20-root .pool-grid .input > .dsf { font-size: 22px; text-align: center; line-height: 28px; min-height: 28px; padding: 0 2px; } /* RESOURCE ROWS (Humanity, Luck, Recovery, Fatigue, Shock, Initiative, BAB) */ .multiversald20-root .resource-row { display: grid; grid-template-columns: 96px auto minmax(0, 1fr); align-items: center; grid-gap: 8px; margin-bottom: 6px; } .multiversald20-root .resource-row.humanity-row { border-top: 2px double #A52A2A; padding-top: 6px; margin-top: 4px; } .multiversald20-root .resource-name { font-size: 12px; font-variant: small-caps; font-weight: bold; line-height: 1.2; } .multiversald20-root .resource-value { display: flex; align-items: center; gap: 3px; } .multiversald20-root .res-box { border: 1px solid #000; box-shadow: 1px 1px 1px #ccc; background: #fff; width: 34px; height: 28px; text-align: center; font-size: 15px; line-height: 26px; } .multiversald20-root .res-box.res-box-wide { width: 50px; } .multiversald20-root .res-box > .dsf { height: 26px; line-height: 26px; text-align: center; padding: 0; } .multiversald20-root .res-slash { font-size: 14px; } .multiversald20-root .res-misc-inline { display: flex; flex-direction: column; align-items: center; } .multiversald20-root .res-misc-inline .dsf { border: 1px solid #000; background: white; width: 30px; height: 20px; line-height: 18px; text-align: center; font-size: 13px; box-shadow: 1px 1px 1px #ccc; } .multiversald20-root .res-misc-label { font-size: 8px; font-variant: small-caps; line-height: 9px; } .multiversald20-root .resource-note { font-size: 10px; color: #555; line-height: 1.2; } /* MOVEMENT */ .multiversald20-root .speed-title { padding: 0; margin: 4px 0 2px 0; font-size: 11px; } .multiversald20-root .speed-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-gap: 4px; } .multiversald20-root .speed-grid .input > .dsf { text-align: center; padding: 1px 2px; } /* SPELLCASTING TRADITIONS TABLE */ .multiversald20-root .trad-table { display: grid; grid-row-gap: 5px; margin-bottom: 6px; } .multiversald20-root .trad-head, .multiversald20-root .trad-row { display: grid; grid-template-columns: minmax(0, 1fr) 44px 56px 56px 64px 64px; grid-column-gap: 6px; align-items: center; } .multiversald20-root .trad-head div { font-size: 10px; font-variant: small-caps; text-align: center; } .multiversald20-root .trad-head div:first-child { text-align: left; } .multiversald20-root .trad-row .include-box { width: 100%; } .multiversald20-root .trad-name { display: flex; align-items: center; gap: 8px; border: 1px solid #000; border-radius: 6px; padding: 3px 8px; font-size: 14px; font-variant: small-caps; background: #fff; white-space: nowrap; overflow: hidden; } .multiversald20-root .tradition-sub { font-size: 10px; font-variant: normal; color: #555; } .multiversald20-root .trad-row.trad-inactive .include-box { opacity: 0.4; } /* INVENTORY */ .multiversald20-root .threshold-readout { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: 2px 4px 4px 4px; font-size: 14px; } .multiversald20-root .threshold-readout .dsf { border: 1px solid #000; background: white; min-width: 38px; padding: 0 4px; text-align: center; box-shadow: 1px 1px 1px #ccc; white-space: nowrap; } .multiversald20-root .armor-loadout-grid { display: grid; grid-template-columns: 80px minmax(0, 1fr) 52px 52px 52px; grid-gap: 4px; align-items: center; margin-bottom: 6px; } .multiversald20-root .armor-loadout-grid .input-label { text-align: center; padding: 0; } .multiversald20-root .armor-slot-name { font-size: 13px; font-variant: small-caps; font-weight: bold; white-space: nowrap; } .multiversald20-root .armor-loadout-grid .dsf { border: 1px solid #000; background: #cdf; text-align: center; height: 24px; line-height: 22px; box-shadow: 1px 1px 1px #ccc; overflow: hidden; white-space: nowrap; padding: 0 3px; } .multiversald20-root .armor-loadout-grid .dsf.readonly { background: white; font-weight: bold; } /* The armor-name column holds free text (e.g. "Scorched Raider Plate"), so it wraps onto extra lines instead of being cut off. */ .multiversald20-root .armor-loadout-grid .dsf[class*="_class"] { height: auto; min-height: 24px; white-space: normal; overflow: visible; text-align: left; line-height: 1.25; padding: 2px 5px; } .multiversald20-root .armor-total-label, .multiversald20-root .armor-total-box, .multiversald20-root .armor-total-spacer { margin-top: 4px; } .multiversald20-root .armor-mods-note { font-size: 10px; font-style: italic; color: #555; } .multiversald20-root .armor-loadout-grid .dsf[class*="dsf_armormod_"] { font-weight: normal; } .multiversald20-root .augments-header-grid { margin-bottom: 3px; } .multiversald20-root .consumables-grid { display: grid; grid-template-columns: minmax(0, 1fr) 40px 40px; } .multiversald20-root .gems-grid { display: grid; grid-template-columns: minmax(0, 1fr) 60px 40px; padding-left: 14px; } .multiversald20-root .consumables-grid { padding-left: 14px; } .multiversald20-root .one-consumable { display: grid; grid-template-columns: 8px minmax(0, 1fr) 40px 40px; padding: 2px 3px; border-bottom: 1px solid #ccc; grid-gap: 3px; } .multiversald20-root .one-gem { display: grid; grid-template-columns: 8px minmax(0, 1fr) 60px 40px; padding: 2px 3px; border-bottom: 1px solid #ccc; grid-gap: 3px; } .multiversald20-root .one-consumable .dslf_consumable_qty, .multiversald20-root .one-consumable .dslf_consumable_bulk, .multiversald20-root .one-gem .dslf_gem_price, .multiversald20-root .one-gem .dslf_gem_bulk, .multiversald20-root .one-gem .dslf_augment_slot, .multiversald20-root .one-gem .dslf_augment_drain { border-left: 1px solid #ccc; text-align: center; } .multiversald20-root.csx .big-input .list li.item { margin-bottom: 0px; } /* BIO */ .multiversald20-root .personality { display: grid; grid-gap: 4px; } .multiversald20-root .physical-details-grid { display: grid; grid-gap: 4px; grid-template-columns: repeat(2, minmax(0, 1fr)); } .multiversald20-root .physical-details-grid .pd-wide { grid-column: span 2; } .multiversald20-root .big-input { border: 1px solid #000; box-shadow:1px 1px 1px #ccc; padding: 0px 3px 10px 3px; border-radius: 6px; } .multiversald20-root .npc-name-container { border-bottom: 1px solid #ccc; padding: 2px 3px; } .multiversald20-root .npc-label-grid { display: grid; grid-template-columns: minmax(0, 1fr) 120px; padding-left: 14px; } .multiversald20-root .one-npc-grid { display: grid; grid-template-columns: 8px minmax(0, 1fr) 120px; grid-gap: 3px; padding: 2px 3px; border-bottom: 1px solid #ccc; } .multiversald20-root .one-npc-grid [class*="_location"] { border-left: 1px solid #ccc; padding-left: 6px; } .multiversald20-root .dslf_note_name { margin-left: 10px; } .multiversald20-root .dsf_bio, .multiversald20-root .dsf_appearance { font-size: 14px; padding: 6px; border: 1px solid #000; box-shadow: 1px 1px 1px #ccc; min-height: 120px; margin-bottom: 6px; border-radius: 6px; } /* FOOTER */ .multiversald20-root .footer { text-align: center; font-variant: small-caps; font-size: 12px; } .multiversald20-root.csx .footer .dsf { display: inline; } .multiversald20-root ul { margin-bottom: 0px; padding-left: 0; } /* Short number cells clip rather than wrap, so an over-long value can't push into the next box. */ .multiversald20-root .include-box, .multiversald20-root .value-total, .multiversald20-root .res-box, .multiversald20-root .res-misc-inline .dsf, .multiversald20-root .pool-grid .input > .dsf, .multiversald20-root .speed-grid .input > .dsf { overflow: hidden; white-space: nowrap; } /* Free-text fields wrap, including very long unbroken words. */ .multiversald20-root .dsf, .multiversald20-root .edit { overflow-wrap: break-word; word-wrap: break-word; min-width: 0; } /* EDITING */ .multiversald20-root.csx .dsf, .multiversald20-root.csx .edit { display: block; } .editable .multiversald20-root .dsf, .editable .multiversald20-root .edit { background-color:#cdf; cursor:pointer; display: block; } .editable .multiversald20-root .dsf.readonly { background-color:transparent; cursor: default; } .multiversald20-root .dsf input, .multiversald20-root .dsf select, .multiversald20-root .edit input, .multiversald20-root .edit select { width: 100%; height: 100%; box-sizing: border-box; font: inherit; padding: 0; margin: 0; border: 0; } .multiversald20-root .dsf textarea, .multiversald20-root .edit textarea { width: 100%; min-height: 100%; box-sizing: border-box; font: inherit; resize: vertical; border: 0; } .multiversald20-root .jeditable_input button { display: none; } .editable .multiversald20-root .dsf_bio { display: none; } .multiversald20-root .dsf b, .multiversald20-root .dsf strong, .multiversald20-root .edit b, .multiversald20-root .edit strong { font-weight: inherit; } .multiversald20-root .dsf i, .multiversald20-root .dsf em, .multiversald20-root .edit i, .multiversald20-root .edit em { font-style: inherit; } .multiversald20-root .dsf u, .multiversald20-root .edit u { text-decoration: none; } /* CSX SETTINGS */ .multiversald20-root.csx .list li.item:nth-of-type(2n+1) { background-color: transparent; } .multiversald20-root.csx .check .checkBorder { background-image: url('https://blog.obsidianportal.com/wp-content/uploads/2019/10/check-border-1.png'); background-size:12px 12px; } .multiversald20-root.csx .check .checkOff, .multiversald20-root.csx .check .checkOff:hover { background-image: url('https://blog.obsidianportal.com/wp-content/uploads/2019/10/check-off.png'); background-position:1px 1px; } .multiversald20-root.csx .check .checkOn, .multiversald20-root.csx .check .checkOn:hover { background-image: url('https://blog.obsidianportal.com/wp-content/uploads/2019/10/check-on.png'); background-position:1px 1px; } .multiversald20-root.csx .hidden { display: none; } .editable .multiversald20-root.csx .dsf:hover:not(.readonly), .editable .multiversald20-root.csx .edit:hover:not(.readonly):not(.bound-field), .editable .multiversald20-root.csx .dsf:focus, .editable .multiversald20-root.csx .edit:focus:not(.bound-field) { background-color: #CDF; } /* TABLET */ @media only screen and (max-width: 900px) { .multiversald20-root .grid-3 { grid-template-columns: minmax(0, 1fr); } .multiversald20-root .list_powers, .multiversald20-root .list_inventory, .multiversald20-root .list_attacks { grid-template-columns: minmax(0, 1fr); } .multiversald20-root .ability-score-grid, .multiversald20-root .ability-label-grid { grid-template-columns: 100px 1fr 40px; } } /* PHONE */ @media only screen and (max-width: 600px) { .multiversald20-root .grid-tabs { grid-template-columns: repeat(4, minmax(0, 1fr)); } .multiversald20-root .tab { font-size: 13px; margin-bottom: 3px; } .multiversald20-root .grid-2, .multiversald20-root .grid-4, .multiversald20-root .engine-grid { grid-template-columns: minmax(0, 1fr); } .multiversald20-root .engine-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .multiversald20-root .basic-info { grid-template-columns: 72px minmax(0, 1fr); } .multiversald20-root .avatar-cell .dsf_avatar_image { width: 72px; min-height: 90px; } .multiversald20-root .basic-info-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .multiversald20-root .basic-info-grid .bi-wide { grid-column: span 2; } .multiversald20-root .sb-avatar { width: 72px; } .multiversald20-root .sb-avatar .dsf_avatar_image { width: 72px; min-height: 90px; } .multiversald20-root .sb-name { font-size: 20px !important; } .multiversald20-root .bi-name > .dsf { font-size: 17px; } .multiversald20-root .row-3, .multiversald20-root .row-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .multiversald20-root .speed-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } .multiversald20-root .dr-grid, .multiversald20-root .cmb-grid, .multiversald20-root .save-grid, .multiversald20-root .skill-grid { gap: 3px; } .multiversald20-root .value-include { width: 28px; } .multiversald20-root .include-box { width: 26px; font-size: 14px; } .multiversald20-root .value-total { width: 30px; height: 30px; font-size: 17px; line-height: 28px; } .multiversald20-root .dr-label, .multiversald20-root .save-label { font-size: 12px; } .multiversald20-root .resource-row { grid-template-columns: 80px auto minmax(0, 1fr); grid-gap: 6px; } .multiversald20-root .armor-loadout-grid { grid-template-columns: 62px minmax(0, 1fr) 40px 40px 40px; font-size: 12px; } .multiversald20-root .armor-slot-name { font-size: 11px; white-space: normal; line-height: 1.1; } .multiversald20-root .trad-head, .multiversald20-root .trad-row { grid-template-columns: minmax(0, 1fr) 30px 36px 36px 40px 40px; grid-column-gap: 3px; } .multiversald20-root .trad-head div { font-size: 8px; white-space: normal; line-height: 1.1; } .multiversald20-root .trad-row .include-box { font-size: 13px; } .multiversald20-root .trad-name { padding: 3px 5px; gap: 5px; font-size: 13px; } .multiversald20-root .npc-label-grid { grid-template-columns: minmax(0, 1fr) 90px; } .multiversald20-root .one-npc-grid { grid-template-columns: 8px minmax(0, 1fr) 90px; } } @media only screen and (max-width: 380px) { .multiversald20-root .resource-note { display: none; } .multiversald20-root .name-row { grid-template-columns: 58px minmax(0, 1fr); } } /* EDIT-ONLY SECTIONS (the stat block's source fields on the Summary tab) */ .multiversald20-root .edit-only { display: none; } .editable .multiversald20-root .edit-only { display: block; } .multiversald20-root .edit-only-note { border-top: 3px double #A52A2A; margin: 10px 0 6px 0; padding-top: 6px; font-size: 12px; font-style: italic; color: #722; text-align: center; } /* SUMMARY STAT BLOCK (Pathfinder-style) */ .multiversald20-root .statblock-panel { padding: 10px 12px 12px 12px; font-size: 14px; line-height: 1.45; } .multiversald20-root .sb-head { display: flex; gap: 12px; align-items: flex-start; border-bottom: 2px solid #722; padding-bottom: 8px; margin-bottom: 4px; } .multiversald20-root .sb-title { flex: 1 1 auto; min-width: 0; order: 1; } .multiversald20-root .sb-avatar { flex: 0 0 auto; width: 96px; order: 2; } .multiversald20-root .sb-avatar .dsf_avatar_image { width: 96px; min-height: 110px; border: 1px solid #000; background-size: cover; background-position: center; } .multiversald20-root .sb-avatar img { max-width: 100%; height: auto; display: block; } .multiversald20-root .sb-name, .editable .multiversald20-root .sb-name { font-family: 'Cinzel', georgia, serif; font-size: 24px; font-weight: 700; line-height: 1.2; color: #3a0d0d; background: transparent !important; } .multiversald20-root .sb-head-lines { font-size: 14px; } .multiversald20-root .sb-head-lines div:first-child { font-weight: bold; } .multiversald20-root .sb-player { font-size: 11px; color: #555; margin-top: 2px; } .multiversald20-root .sb-sec { font-family: 'Cinzel', georgia, serif; font-weight: 700; font-size: 13px; letter-spacing: 1px; text-transform: uppercase; color: #3a0d0d; border-top: 1px solid #722; border-bottom: 1px solid #722; margin: 8px 0 3px 0; padding: 1px 0; } .multiversald20-root .sb-line { margin: 1px 0; padding-left: 12px; text-indent: -12px; overflow-wrap: break-word; } .multiversald20-root .sb-bullet { padding-left: 24px; text-indent: -12px; } .multiversald20-root .sb-k { font-weight: bold; } /* SPELL CARDS */ .multiversald20-root .card-sub { font-family: 'Cinzel', georgia, serif; font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: #3a0d0d; border-bottom: 1px solid #722; margin-top: 2px; } .multiversald20-root .spell-calc { font-size: 13px; font-variant: small-caps; padding: 2px 4px; border: 1px solid #000; background: #fff; } .multiversald20-root .spell-calc .inline-val { font-weight: bold; font-variant: normal; }
JavaScript
var $ = jQuery; csx_opts = { 'setupCallback': function(item){multiversald20_setup(item);}, 'uiContainer': function(){return document;}, 'defaultFieldValue':' ', 'imagePath':'https://chainsawxiv.github.io/DST/common/images/', 'preloadFiles':[ 'add.png', 'add_hover.png', 'balance.png', 'balance_hover.png', 'bullet.png', 'fb_back_bottom.png', 'fb_back_main.png', 'fb_back_top.png', 'grab.png', 'grab_hover.png', 'tip.png', 'tip_hover.png', 'trash.png', 'trash_active.png', 'trash_hover.png', ], }; /* The 20 skills and the ability class each one reads its base modifier from. "artistry" is intentionally absent -- its ability box is a manual entry (Int or Cha, player's choice) instead of a mirrored ability modifier. */ var MVD20_SKILLS = { acrobatics: 'pro', athletics: 'str', perception: 'awa', culture: 'int', handle: 'cha', influence: 'cha', medicine: 'int', nature: 'awa', occult: 'int', pilot: 'pro', agility: 'pro', science: 'int', technology: 'int', investigation:'int', navigation: 'awa', streetwise: 'cha', tactics: 'int', endurance: 'end', luck: 'luc' }; /* Skills that suffer the Armor Check Penalty (Acrobatics, Athletics, Agility). */ var MVD20_ACP_SKILLS = ['acrobatics', 'athletics', 'agility']; /* The 7 modular armor slots + shield, used for the K-DR/E-DR/Bulk sums. */ var MVD20_ARMOR_SLOTS = ['head', 'torso', 'larm', 'rarm', 'lleg', 'rleg', 'shield']; /* Class Skill bonus (Chapter 4): flat +3, only once the skill has 1+ Rank. */ var MVD20_CLASS_SKILL_BONUS = 3; function multiversald20_dataPreLoad(opts){ aisleten.characters.jeditablePlaceholder = csx_opts.defaultFieldValue; if (typeof dynamic_sheet_attrs == "undefined") { dynamic_sheet_attrs = {}; } } function multiversald20_dataPostLoad(options) { csx_opts.defaultContext = document.getElementById(options.containerId); csx_opts.uiContainer = csx_opts.defaultContext.querySelector('.uicontainer'); csx_opts.isEditable = options.isEditable; csx_opts.containerId = "#" + options.containerId; if (options.isEditable) { multiversald20_recalcAll(csx_opts.containerId); } var includes = document.createElement('script'); includes.type = 'text/javascript'; includes.src = 'https://chainsawxiv.github.io/DST/common/js/csx_pathfinder_common.js'; includes.onload = function(){ csx_opts.setupCallback(); // Checkboxes only expose value() once csx_check() has run, so the // checkbox-driven values (Tradition, Engine, Class Skills) need a // second pass now that setup is done. if (csx_opts.isEditable) { multiversald20_recalcAll(csx_opts.containerId); } }; document.body.appendChild(includes); } /* Every derived value on the sheet, in dependency order. */ function multiversald20_recalcAll(containerId) { var stats = ["str", "pro", "end", "cha", "int", "awa", "luc", "attractiveness"]; for (var i = 0; i < stats.length; i++) { multiversald20_updateStat(stats[i], containerId); } multiversald20_updateBAB(containerId); multiversald20_updateArmorTotals(containerId); multiversald20_updateAllSkills(containerId); multiversald20_updateSave("fort", "end", containerId); multiversald20_updateSave("ref", "pro", containerId); multiversald20_updateSave("will", "awa", containerId); multiversald20_updateInitiative(containerId); multiversald20_updateEngine(containerId); multiversald20_updateThresholds(containerId); multiversald20_calc_bulk(); multiversald20_calc_augment_drain(); multiversald20_updateMagicSlots(); multiversald20_updateLuckPool(containerId); multiversald20_updateRecoveryDice(containerId); } function multiversald20_dataChange(options) { var field = this.className.match(/dsf_([\d\w_]+)/)[1]; var containerId = csx_opts.containerId; // Modular armor slots (7 slots x kdr/edr/bulk/class) share one handler. if (field.indexOf("armor_") === 0) { multiversald20_updateArmorTotals(containerId); multiversald20_calc_bulk(); return; } // Per-skill Rank/Misc inputs share one handler, keyed off the skill name. for (var skillName in MVD20_SKILLS) { if (field === "sk_" + skillName + "_ranks" || field === "sk_" + skillName + "_item") { multiversald20_updateSkill(skillName, MVD20_SKILLS[skillName], containerId); return; } } if (field === "sk_artistry_ability" || field === "sk_artistry_ranks" || field === "sk_artistry_item") { multiversald20_updateArtistry(containerId); return; } if (/^trad_\w+_(atkmisc|dcmisc)$/.test(field)) { multiversald20_updateTradition(containerId); return; } switch (field) { case "str": multiversald20_updateStat("str", containerId); multiversald20_updateSkill("athletics", "str", containerId); multiversald20_updateThresholds(containerId); multiversald20_updateCMB_CMD(containerId); break; case "pro": multiversald20_updateStat("pro", containerId); multiversald20_updateSkill("acrobatics", "pro", containerId); multiversald20_updateSkill("pilot", "pro", containerId); multiversald20_updateSkill("agility", "pro", containerId); multiversald20_updateSave("ref", "pro", containerId); multiversald20_updateInitiative(containerId); multiversald20_updateCMB_CMD(containerId); multiversald20_updateDR(containerId); break; case "end": multiversald20_updateStat("end", containerId); multiversald20_updateSkill("endurance", "end", containerId); multiversald20_updateSave("fort", "end", containerId); multiversald20_updateEngine(containerId); break; case "cha": multiversald20_updateStat("cha", containerId); multiversald20_updateSkill("handle", "cha", containerId); multiversald20_updateSkill("influence", "cha", containerId); multiversald20_updateSkill("streetwise", "cha", containerId); multiversald20_updateTradition(containerId); break; case "int": multiversald20_updateStat("int", containerId); multiversald20_updateSkill("culture", "int", containerId); multiversald20_updateSkill("medicine", "int", containerId); multiversald20_updateSkill("occult", "int", containerId); multiversald20_updateSkill("science", "int", containerId); multiversald20_updateSkill("technology", "int", containerId); multiversald20_updateSkill("investigation", "int", containerId); multiversald20_updateSkill("tactics", "int", containerId); multiversald20_updateTradition(containerId); break; case "awa": multiversald20_updateStat("awa", containerId); multiversald20_updateSkill("perception", "awa", containerId); multiversald20_updateSkill("nature", "awa", containerId); multiversald20_updateSkill("navigation", "awa", containerId); multiversald20_updateSave("will", "awa", containerId); multiversald20_updateHumanity(containerId); multiversald20_updateTradition(containerId); break; case "luc": multiversald20_updateStat("luc", containerId); multiversald20_updateSkill("luck", "luc", containerId); multiversald20_updateLuckPool(containerId); break; case "attractiveness": multiversald20_updateStat("attractiveness", containerId); break; case "fort_misc": multiversald20_updateSave("fort", "end", containerId); break; case "ref_misc": multiversald20_updateSave("ref", "pro", containerId); break; case "will_misc": multiversald20_updateSave("will", "awa", containerId); break; case "kdr_misc": case "edr_misc": case "max_prowess_input": multiversald20_updateDR(containerId); break; case "cmb_misc": case "cmd_misc": multiversald20_updateCMB_CMD(containerId); break; case "bab": multiversald20_updateBAB(containerId); break; case "init_misc": multiversald20_updateInitiative(containerId); break; case "char_level": multiversald20_updateRecoveryDice(containerId); break; case "recovery_current": // The Basic Info copy is a read-only mirror of the Combat tab field. $(containerId + " .dsf_recovery_current.readonly").text($(this).text()); break; } } function multiversald20_setup(context){ if (context == undefined) context = csx_opts.defaultContext; csx_check(context); csx_edit(context); csx_list(context); var edits = context.querySelectorAll(".dsf"); for (var e = 0; e < edits.length; e++) { edits[e].update = multiversald20_dataChange; } // Bulk: every repeating-list field whose class contains "_bulk" rolls up // into the Bulk Carried total. The fixed armor-slot bulk fields are .dsf // and already go through dataChange (which also re-runs the bulk total), // so they're skipped here to keep the armor/ACP recalculation intact. var bulk_items = context.querySelectorAll("[class*='_bulk']"); for (var j = 0; j < bulk_items.length; j++) { if (!bulk_items[j].classList.contains("dsf")) { bulk_items[j].update = multiversald20_calc_bulk; } } var drain_items = context.querySelectorAll("[class*='_drain']"); for (var k = 0; k < drain_items.length; k++) { if (!drain_items[k].classList.contains("dsf")) { drain_items[k].update = multiversald20_calc_augment_drain; } } // Armor Mods feed the armor loadout totals (and Bulk Carried, for bulk). var mod_items = context.querySelectorAll(".dslf_armormod_kdr, .dslf_armormod_edr, .dslf_armormod_maxpro, .dslf_armormod_bulk"); for (var q = 0; q < mod_items.length; q++) { mod_items[q].update = function() { multiversald20_updateArmorTotals(csx_opts.containerId); multiversald20_calc_bulk(); }; } // Spells list: MP Cost sets the Tier; Tier and DC Misc feed the Save DC. var mp_items = context.querySelectorAll(".dslf_power_mpcost, .dslf_power_dcmisc"); for (var p = 0; p < mp_items.length; p++) { mp_items[p].update = function() { multiversald20_updatePowerRow(this); }; } var trashBins = context.querySelectorAll('.inventory_trash'); for (var x = 0; x < trashBins.length; x++) { trashBins[x].addEventListener('drop', function (e) { multiversald20_calc_bulk(); multiversald20_calc_augment_drain(); multiversald20_updateArmorTotals(csx_opts.containerId); multiversald20_updateMagicSlots(); }); } var checks = context.querySelectorAll(".check"); for (var i = 0; i < checks.length; i++) { checks[i].onUpdate = function() { if (this.className.match("group_") && this.value()) { var key = this.className.match(/group_[\w\d]+/)[0]; var members = document.querySelectorAll("." + key); for (var m = 0; m < members.length; m++) { if (members[m].value() && members[m] != this) members[m].click(); } } if (this.className.match("dslf_magic_equipped")) { multiversald20_updateMagicSlots(); } if (this.className.match("dsf_tradition_")) { multiversald20_updateTradition(csx_opts.containerId); } if (this.className.match("group_engine")) { multiversald20_updateEngine(csx_opts.containerId); } var classSkill = this.className.match(/dsf_sk_(\w+?)_class/); if (classSkill) { if (classSkill[1] === "artistry") { multiversald20_updateArtistry(csx_opts.containerId); } else { multiversald20_updateSkill(classSkill[1], MVD20_SKILLS[classSkill[1]], csx_opts.containerId); } } }; } multiversald20_setupSelects(context); multiversald20_setupDeleteButtons(context); var root = csx_opts.defaultContext; if (root && !root.mvd20StatBlock) { root.mvd20StatBlock = true; root.addEventListener("focusout", multiversald20_scheduleStatBlock, true); root.addEventListener("change", multiversald20_scheduleStatBlock, true); root.addEventListener("click", multiversald20_scheduleStatBlock, true); } multiversald20_scheduleStatBlock(); multiversald20_blockFormatting(csx_opts.defaultContext); // A freshly added spell row gets its Spell Atk / Tier / DC straight away. if (context !== csx_opts.defaultContext && context.querySelector) { var spellField = context.querySelector(".dslf_power_mpcost"); if (spellField) multiversald20_updatePowerRow(spellField); } } function multiversald20_dataPreSave(){ var context = csx_opts.defaultContext; var edits = context.querySelectorAll('.dsf:not(.readonly),.edit'); for (var i = 0; i < edits.length; i++) edits[i].unrender(); var checks = context.querySelectorAll('.check'); for (var i = 0; i < checks.length; i++) checks[i].unrender(); var lists = context.querySelectorAll('.list'); for (var i = 0; i < lists.length; i++) lists[i].unrender(); } function multiversald20_tabClick(pageNum) { var root = csx_opts.defaultContext; for (var i = 1; i <= 7; i++) { var page = root.querySelector('.page-' + i); var tab = root.querySelector('.tab-' + i); if (!page || !tab) continue; // "background" shorthand, not backgroundColor, so the gradient on the // first tab is cleared when another tab is picked. if (i === pageNum) { page.style.display = 'block'; tab.style.background = 'radial-gradient(ellipse at center, #A52A2A 0%, #000000 85%)'; tab.style.color = '#ddd'; tab.style.textShadow = '1px 1px 1px #000'; } else { page.style.display = 'none'; tab.style.background = '#ccc'; tab.style.color = '#333'; tab.style.textShadow = 'none'; } } if (pageNum === 1) multiversald20_scheduleStatBlock(); } function multiversald20_isNumeric(n) { return ($.isNumeric && $.isNumeric(n)) || (!isNaN(parseFloat(n)) && isFinite(n)); } function multiversald20_num(containerId, cls) { var v = Number($(containerId + " " + cls + ":first").text()); return multiversald20_isNumeric(v) ? v : 0; } /* Reads a CSX checkbox. jQuery objects have no value() method, so this has to go through the raw DOM element; before csx_check() has run there is no value() at all yet, so fall back to the stored text. */ function multiversald20_isChecked(containerId, cls) { var el = $(containerId + " " + cls)[0]; if (!el) return false; var v = (typeof el.value === "function") ? el.value() : String(el.textContent).trim(); return v == 1 || v === true || v === "true"; } /* Ability Score Modifier = floor((Score-10)/2). Attractiveness uses the identical formula, so it's driven through this same function. */ function multiversald20_updateStat(stat, containerId) { var value = Number($(containerId + " .dsf_" + stat + ":first").text()); if (multiversald20_isNumeric(value)) { $(containerId + " .dsf_" + stat + "_mod").text(Math.floor((parseInt(value) - 10) / 2)); } } /* Skill Total = Ability Mod + Ranks + Misc (+3 Class Skill once Ranks >= 1) (+ Armor Check Penalty for Acrobatics/Athletics/Agility). */ function multiversald20_classSkillBonus(skill, containerId) { if (multiversald20_num(containerId, ".dsf_sk_" + skill + "_ranks") < 1) return 0; return multiversald20_isChecked(containerId, ".dsf_sk_" + skill + "_class") ? MVD20_CLASS_SKILL_BONUS : 0; } function multiversald20_updateSkill(skill, abilityStat, containerId) { var total = multiversald20_num(containerId, ".dsf_" + abilityStat + "_mod"); total += multiversald20_num(containerId, ".dsf_sk_" + skill + "_ranks"); total += multiversald20_num(containerId, ".dsf_sk_" + skill + "_item"); total += multiversald20_classSkillBonus(skill, containerId); if (MVD20_ACP_SKILLS.indexOf(skill) !== -1) { total += multiversald20_num(containerId, ".dsf_acp_display"); } $(containerId + " .dsf_sk_" + skill + "_total").text(total); } function multiversald20_updateArtistry(containerId) { var total = multiversald20_num(containerId, ".dsf_sk_artistry_ability"); total += multiversald20_num(containerId, ".dsf_sk_artistry_ranks"); total += multiversald20_num(containerId, ".dsf_sk_artistry_item"); total += multiversald20_classSkillBonus("artistry", containerId); $(containerId + " .dsf_sk_artistry_total").text(total); } function multiversald20_updateAllSkills(containerId) { for (var skillName in MVD20_SKILLS) { multiversald20_updateSkill(skillName, MVD20_SKILLS[skillName], containerId); } multiversald20_updateArtistry(containerId); } function multiversald20_updateSave(save, abilityStat, containerId) { var total = multiversald20_num(containerId, ".dsf_" + abilityStat + "_mod"); total += multiversald20_num(containerId, ".dsf_" + save + "_misc"); $(containerId + " .dsf_" + save + "_total").text(total); } /* K-DR / E-DR = 10 (base) + Prowess Mod (capped by the Torso's Max Prowess Bonus; leave the cap blank for Clothing/uncapped) + Armor sum + Misc. */ function multiversald20_updateDR(containerId) { var proMod = multiversald20_num(containerId, ".dsf_pro_mod"); var capText = $(containerId + " .dsf_max_prowess_input:first").text().trim(); var applied = proMod; if (capText !== "" && multiversald20_isNumeric(capText)) { applied = Math.min(proMod, Number(capText) + multiversald20_armorModSum("maxpro", /^(torso|whole suit|)$/i)); } $(containerId + " .dsf_max_prowess").text(applied); var kdr = 10 + applied + multiversald20_num(containerId, ".dsf_armor_kdr_sum") + multiversald20_num(containerId, ".dsf_kdr_misc"); $(containerId + " .dsf_kdr_total").text(kdr); var edr = 10 + applied + multiversald20_num(containerId, ".dsf_armor_edr_sum") + multiversald20_num(containerId, ".dsf_edr_misc"); $(containerId + " .dsf_edr_total").text(edr); } /* CMB = BAB + Str Mod + Misc. CMD = 10 + BAB + Str Mod + Prowess Mod + Misc. */ function multiversald20_updateCMB_CMD(containerId) { var bab = multiversald20_num(containerId, ".dsf_bab"); var str = multiversald20_num(containerId, ".dsf_str_mod"); var pro = multiversald20_num(containerId, ".dsf_pro_mod"); var cmb = bab + str + multiversald20_num(containerId, ".dsf_cmb_misc"); $(containerId + " .dsf_cmb_total").text(cmb); var cmd = 10 + bab + str + pro + multiversald20_num(containerId, ".dsf_cmd_misc"); $(containerId + " .dsf_cmd_total").text(cmd); } function multiversald20_updateInitiative(containerId) { var total = multiversald20_num(containerId, ".dsf_pro_mod") + multiversald20_num(containerId, ".dsf_init_misc"); $(containerId + " .dsf_initiative_total").text(total); } /* BAB is a manual entry (most tables import it from a paired d20 game -- see Chapter 3) but is mirrored read-only into CMB/CMD and Power Attack. */ function multiversald20_updateBAB(containerId) { var bab = multiversald20_num(containerId, ".dsf_bab"); $(containerId + " .dsf_bab_mirror").text(bab); multiversald20_updateCMB_CMD(containerId); multiversald20_updateTradition(containerId); } function multiversald20_updateLuckPool(containerId) { var mod = multiversald20_num(containerId, ".dsf_luc_mod"); $(containerId + " .dsf_luck_pool_max").text(Math.max(0, mod)); } /* Max Humanity = Awareness Score x 4 (Chapter 11) minus augment drain. */ function multiversald20_updateHumanity(containerId) { var score = multiversald20_num(containerId, ".dsf_awa"); var drain = multiversald20_num(containerId, ".dsf_augment_drain_sum"); $(containerId + " .dsf_humanity_max").text(Math.max(0, score * 4 - drain)); } /* Sums every augment-list field whose class contains "_drain" into Total Humanity Drain, then re-runs the Humanity max calc -- same wildcard convention as Bulk below, since list rows come and go. */ function multiversald20_calc_augment_drain() { var containerId = csx_opts.containerId; var total = 0; var drain_items = document.querySelectorAll("[class*='_drain']"); for (var i = 0; i < drain_items.length; i++) { if (!drain_items[i].className.match("dsf_augment_drain_sum")) { var n = Number(drain_items[i].value ? drain_items[i].value() : drain_items[i].textContent); total += multiversald20_isNumeric(n) ? n : 0; } } $(containerId + " .dsf_augment_drain_sum").text(total); multiversald20_updateHumanity(containerId); } function multiversald20_updateRecoveryDice(containerId) { var level = multiversald20_num(containerId, ".dsf_char_level"); $(containerId + " .dsf_recovery_max").text(level); } /* Carrying thresholds read straight off the raw Strength score (not the modifier) -- Unencumbered 0..Str, Encumbered Str+1..Str+5, Overloaded Str+6..Str x2. */ function multiversald20_updateThresholds(containerId) { var str = multiversald20_num(containerId, ".dsf_str"); $(containerId + " .dsf_thresh_unenc").text("0-" + str); $(containerId + " .dsf_thresh_enc").text((str + 1) + "-" + (str + 5)); $(containerId + " .dsf_thresh_over").text((str + 6) + "-" + (str * 2)); } /* Sums the 7 modular armor slots (Head/Torso/L-R Arm/L-R Leg/Shield) into Total Armor K-DR and E-DR, and their Bulk into the Armor Check Penalty (Worn Bulk x2) -- separate from the whole-inventory Bulk total below. */ function multiversald20_updateArmorTotals(containerId) { var kdrSum = 0, edrSum = 0, wornBulk = 0; for (var i = 0; i < MVD20_ARMOR_SLOTS.length; i++) { var slot = MVD20_ARMOR_SLOTS[i]; kdrSum += multiversald20_num(containerId, ".dsf_armor_" + slot + "_kdr"); edrSum += multiversald20_num(containerId, ".dsf_armor_" + slot + "_edr"); wornBulk += multiversald20_num(containerId, ".dsf_armor_" + slot + "_bulk"); } var modKdr = multiversald20_armorModSum("kdr"); var modEdr = multiversald20_armorModSum("edr"); var modBulk = multiversald20_armorModSum("bulk"); $(containerId + " .dsf_armormod_kdr_sum").text(modKdr); $(containerId + " .dsf_armormod_edr_sum").text(modEdr); $(containerId + " .dsf_armormod_bulk_sum").text(modBulk); kdrSum += modKdr; edrSum += modEdr; wornBulk = Math.max(0, wornBulk + modBulk); $(containerId + " .dsf_armor_kdr_sum").text(kdrSum); $(containerId + " .dsf_armor_edr_sum").text(edrSum); $(containerId + " .dsf_armor_worn_bulk").text(wornBulk); $(containerId + " .dsf_acp_display").text(-(wornBulk * 2)); multiversald20_updateDR(containerId); for (var s = 0; s < MVD20_ACP_SKILLS.length; s++) { var skillName = MVD20_ACP_SKILLS[s]; multiversald20_updateSkill(skillName, MVD20_SKILLS[skillName], containerId); } } /* Sum one column of the Armor Mods list (kdr / edr / bulk / maxpro), optionally only for mods whose "Applied To" matches slotFilter. */ function multiversald20_armorModSum(column, slotFilter) { var total = 0; var rows = document.querySelectorAll(csx_opts.containerId + " .list_armormods li.item:not(.proto)"); for (var i = 0; i < rows.length; i++) { if (slotFilter && !slotFilter.test(multiversald20_fieldText(rows[i].querySelector(".dslf_armormod_slot")))) continue; var n = Number(multiversald20_fieldText(rows[i].querySelector(".dslf_armormod_" + column))); total += multiversald20_isNumeric(n) ? n : 0; } return total; } /* Worn Accessory slots (Chapter 5): one equipped item per slot, Rings max 2. Lists what's in use and flags any slot that's over its limit. */ var MVD20_MAGIC_SLOT_LIMITS = { "Ring": 2 }; function multiversald20_updateMagicSlots() { var counts = {}, order = []; var rows = document.querySelectorAll(csx_opts.containerId + " .list_magicitems li.item:not(.proto)"); for (var i = 0; i < rows.length; i++) { var eq = rows[i].querySelector(".dslf_magic_equipped"); var on = eq && (typeof eq.value === "function" ? eq.value() == 1 : multiversald20_fieldText(eq) === "1"); var slot = multiversald20_fieldText(rows[i].querySelector(".dslf_magic_slot")); if (!on || slot === "" || /^slotless/i.test(slot)) continue; if (!counts[slot]) { counts[slot] = 0; order.push(slot); } counts[slot]++; } var parts = []; for (var j = 0; j < order.length; j++) { var limit = MVD20_MAGIC_SLOT_LIMITS[order[j]] || 1; var text = order[j] + (limit > 1 ? " " + counts[order[j]] + "/" + limit : ""); if (counts[order[j]] > limit) text += " (TOO MANY)"; parts.push(text); } $(csx_opts.containerId + " .dsf_magic_slots_used").text(parts.length ? parts.join(", ") : "None"); } /* Whole-carried-load Bulk: sums every field whose class contains "_bulk" anywhere on the sheet (armor slots, consumables, gems, permanent items alike). Worn armor counts toward the load (Chapter 5). "L" = 0.1 Bulk. */ function multiversald20_calc_bulk() { var containerId = csx_opts.containerId; var total = 0; var bulk_items = document.querySelectorAll(containerId + " [class*='_bulk']"); for (var i = 0; i < bulk_items.length; i++) { if (!bulk_items[i].classList.contains("readonly")) { var value = bulk_items[i].value ? bulk_items[i].value() : bulk_items[i].textContent; value = String(value).trim(); if (value === "L" || value === "l") { total += 0.1; } else { var n = Number(value); total += multiversald20_isNumeric(n) ? n : 0; } } } total = total.toFixed(1); $(containerId + " .dsf_bulk").text(total); } /* Spellcasting Traditions. A character may cast from any number of them, so each ticked Tradition gets its own row: Mod, Spell Attack (BAB + Mod) and Base DC (10 + Mod). Each spell then picks its Tradition and gets its own Spell Attack and Save DC (10 + Tier + Mod). */ var MVD20_TRADITIONS = { arcane: 'int', divine: 'awa', occult: 'cha' }; function multiversald20_traditionMod(containerId, tradition) { var stat = MVD20_TRADITIONS[tradition]; return stat ? multiversald20_num(containerId, ".dsf_" + stat + "_mod") : 0; } /* The Tradition a spell uses: its own drop-down pick, or else the first Tradition ticked at the top of the tab. */ function multiversald20_spellTradition(containerId, picked) { picked = String(picked || "").trim().toLowerCase(); if (MVD20_TRADITIONS[picked]) return picked; for (var t in MVD20_TRADITIONS) { if (multiversald20_isChecked(containerId, ".dsf_tradition_" + t)) return t; } return null; } function multiversald20_updateTradition(containerId) { var bab = multiversald20_num(containerId, ".dsf_bab"); for (var t in MVD20_TRADITIONS) { var mod = multiversald20_traditionMod(containerId, t); $(containerId + " .dsf_trad_" + t + "_mod").text(mod); var atkMisc = multiversald20_num(containerId, ".dsf_trad_" + t + "_atkmisc"); var dcMisc = multiversald20_num(containerId, ".dsf_trad_" + t + "_dcmisc"); $(containerId + " .dsf_trad_" + t + "_atk").text(multiversald20_signed(bab + mod + atkMisc)); $(containerId + " .dsf_trad_" + t + "_dc").text(10 + mod + dcMisc); $(containerId + " .trad-row-" + t).toggleClass("trad-inactive", !multiversald20_isChecked(containerId, ".dsf_tradition_" + t)); } var rows = document.querySelectorAll(containerId + " .list_powers li.item:not(.proto)"); for (var i = 0; i < rows.length; i++) { multiversald20_updatePowerRow(rows[i]); } } /* One spell row: Spell Atk = BAB + Tradition Mod + Tradition Misc Atk; Tier (this system's spell level) = MP Cost / 20, rounded up, minimum 1; Save DC = 10 + Tier + Tradition Mod + Tradition Misc DC + the spell's own DC Misc (Chapter 10). The Tier is stored in the power_level field. */ function multiversald20_updatePowerRow(el) { var containerId = csx_opts.containerId; var row = $(el).closest("li"); if (!row.length || row.hasClass("proto")) return; var tradition = multiversald20_spellTradition(containerId, multiversald20_fieldText(row.find(".dslf_power_tradition")[0])); var mod = tradition ? multiversald20_traditionMod(containerId, tradition) : 0; var atkMisc = tradition ? multiversald20_num(containerId, ".dsf_trad_" + tradition + "_atkmisc") : 0; var dcMisc = tradition ? multiversald20_num(containerId, ".dsf_trad_" + tradition + "_dcmisc") : 0; row.find(".dslf_power_attack:first").text(tradition ? multiversald20_signed(multiversald20_num(containerId, ".dsf_bab") + mod + atkMisc) : "-"); var raw = multiversald20_fieldText(row.find(".dslf_power_mpcost")[0]); var mp = Number(raw); if (raw === "" || !multiversald20_isNumeric(mp)) { row.find(".dslf_power_level:first").text("-"); row.find(".dslf_power_dc:first").text("-"); return; } var level = Math.max(1, Math.ceil(mp / 20)); row.find(".dslf_power_level:first").text(level); var spellMisc = Number(multiversald20_fieldText(row.find(".dslf_power_dcmisc")[0])); if (!multiversald20_isNumeric(spellMisc)) spellMisc = 0; row.find(".dslf_power_dc:first").text(10 + level + mod + dcMisc + spellMisc); } /* The text currently stored in a field (list or single). */ function multiversald20_fieldText(el) { if (!el) return ""; var v = (typeof el.value === "function") ? el.value() : el.textContent; v = String(v == null ? "" : v).replace(/<[^>]*>/g, "").replace(/ /g, " "); return v.trim(); } /* DROP-DOWNS: a <select data-field="x"> writes its choice into the matching .dslf_x field in the same list row, which is what actually gets saved. */ function multiversald20_setField(el, text) { if (!el) return; el.innerHTML = text === "" ? csx_opts.defaultFieldValue : $('<div>').text(text).html(); } function multiversald20_setupSelects(context) { var selects = context.querySelectorAll ? context.querySelectorAll("select.field-select") : []; for (var i = 0; i < selects.length; i++) { var select = selects[i]; var row = $(select).closest("li"); if (row.hasClass("proto")) continue; var field = row.find(".dslf_" + select.getAttribute("data-field"))[0]; var stored = multiversald20_fieldText(field); var match = ""; for (var o = 0; o < select.options.length; o++) { if (select.options[o].value.toLowerCase() === stored.toLowerCase()) match = select.options[o].value; } select.value = match; if (select.mvd20Bound) continue; select.mvd20Bound = true; select.addEventListener("change", function() { var r = $(this).closest("li"); var f = r.find(".dslf_" + this.getAttribute("data-field"))[0]; multiversald20_setField(f, this.value); var name = this.getAttribute("data-field"); if (name === "power_tradition") { multiversald20_updatePowerRow(this); } else if (name === "magic_slot") { multiversald20_updateMagicSlots(); } else if (name === "armormod_slot") { multiversald20_updateArmorTotals(csx_opts.containerId); } }); } } /* DELETE BUTTONS: CSX deletes list entries by dragging them onto the trash can, and phone browsers don't support that kind of drag-and-drop. So every list entry also gets a tap-able X (shown only while editing). Removing the entry from the page is enough - on Save, CSX only stores the entries that are still there. */ function multiversald20_setupDeleteButtons(context) { var items = []; if (context.matches && context.matches("ul.list > li.item")) items.push(context); var found = context.querySelectorAll ? context.querySelectorAll("ul.list > li.item") : []; for (var i = 0; i < found.length; i++) items.push(found[i]); for (var j = 0; j < items.length; j++) { var li = items[j]; if (li.classList.contains("proto") || li.querySelector(":scope > .row-delete")) continue; var btn = document.createElement("span"); btn.className = "row-delete"; btn.title = "Delete this entry"; btn.innerHTML = "✕"; btn.addEventListener("click", function(e) { e.preventDefault(); e.stopPropagation(); var item = this.parentNode; var nameField = item.querySelector("[class*='_name']"); var name = nameField ? multiversald20_fieldText(nameField) : ""; if (!window.confirm(name ? 'Delete "' + name + '"?' : "Delete this entry?")) return; item.parentNode.removeChild(item); multiversald20_recalcAll(csx_opts.containerId); }); li.insertBefore(btn, li.firstChild); } } /* Plain text only: block the Ctrl/Cmd+B/I/U shortcuts and paste without formatting. */ function multiversald20_blockFormatting(root) { if (!root || root.mvd20NoFormat) return; root.mvd20NoFormat = true; root.addEventListener("keydown", function(e) { if ((e.ctrlKey || e.metaKey) && /^[biu]$/i.test(e.key || "")) { e.preventDefault(); e.stopPropagation(); } }, true); root.addEventListener("paste", function(e) { var t = e.target; if (!t || !t.isContentEditable || !e.clipboardData) return; e.preventDefault(); document.execCommand("insertText", false, e.clipboardData.getData("text/plain")); }, true); } /* Engine picker (Full Combat / Skilled-Combat / Skilled-Caster / Full Caster) fills in the read-only Hit Die / Mana Die reference lines -- HP and MP themselves stay manually tracked (they're rolled and accumulated), and the player's own HP/MP notes fields are never overwritten. */ function multiversald20_updateEngine(containerId) { var hp = "", mp = "", label = ""; if (multiversald20_isChecked(containerId, ".dsf_engine_fc")) { hp = "d12"; mp = "d6"; label = "Full Combat"; } else if (multiversald20_isChecked(containerId, ".dsf_engine_sc")) { hp = "d10"; mp = "d8"; label = "Skilled/Combat"; } else if (multiversald20_isChecked(containerId, ".dsf_engine_scast")) { hp = "d8"; mp = "d10"; label = "Skilled/Caster"; } else if (multiversald20_isChecked(containerId, ".dsf_engine_full")) { hp = "d6"; mp = "d12"; label = "Full Caster"; } var death = "Dies at -" + multiversald20_num(containerId, ".dsf_end") + " HP (Endurance Score)."; if (label !== "") { $(containerId + " .dsf_hp_die_info").text(label + ": " + hp + " + End Mod per level. " + death); $(containerId + " .dsf_mp_die_info").text(label + ": " + mp + " per level (+ primary stat mod if a Power Specialist)."); } else { $(containerId + " .dsf_hp_die_info").text("Pick an Engine (Basic Information). " + death); $(containerId + " .dsf_mp_die_info").text("Pick an Engine (Basic Information)."); } } /* SUMMARY STAT BLOCK. Built fresh from the rest of the sheet every time the sheet loads, the Summary tab is opened, or a field changes. It's plain page content (not a saved field), so it can never go out of date or be edited by hand. */ var MVD20_SKILL_LABELS = { acrobatics: "Acrobatics", athletics: "Athletics", perception: "Perception", artistry: "Artistry", culture: "Culture", handle: "Handle Creature", influence: "Influence", medicine: "Medicine", nature: "Nature", occult: "Occult", pilot: "Pilot", agility: "Agility", science: "Science", technology: "Technology", investigation: "Investigation", navigation: "Navigation", streetwise: "Streetwise", tactics: "Tactics", endurance: "Endurance", luck: "Luck" }; function multiversald20_esc(s) { return String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); } function multiversald20_signed(n) { n = Number(n); if (!multiversald20_isNumeric(n)) return "+0"; return (n >= 0 ? "+" : "") + n; } function multiversald20_ordinal(n) { n = Number(n); var s = ["th", "st", "nd", "rd"], v = n % 100; return n + (s[(v - 20) % 10] || s[v] || s[0]); } function multiversald20_elChecked(el) { if (!el) return false; var v = (typeof el.value === "function") ? el.value() : String(el.textContent).trim(); return v == 1 || v === true || v === "true"; } function multiversald20_buildStatBlock() { var c = csx_opts.containerId; var root = csx_opts.defaultContext; if (!root) return; var body = root.querySelector(".sb-body"); var head = root.querySelector(".sb-head-lines"); if (!body || !head) return; var t = function(cls) { return multiversald20_fieldText(root.querySelector(".dsf_" + cls)); }; var n = function(cls) { var v = Number(t(cls)); return multiversald20_isNumeric(v) ? v : 0; }; var rows = function(list) { return root.querySelectorAll(".list_" + list + " > li.item:not(.proto)"); }; var rt = function(row, cls) { return multiversald20_fieldText(row.querySelector(".dslf_" + cls)); }; var E = multiversald20_esc; var html = []; var line = function(label, value) { if (value === "" || value == null) return; html.push('<div class="sb-line"><span class="sb-k">' + label + '</span> ' + value + '</div>'); }; var section = function(name) { html.push('<div class="sb-sec">' + name + '</div>'); }; var names = function(list, field) { var out = [], r = rows(list); for (var i = 0; i < r.length; i++) { var v = rt(r[i], field); if (v) out.push(E(v)); } return out.join(", "); }; // Header lines under the name. var level = t("char_level"), cls = t("class"), heads = []; var l1 = [t("race"), cls].filter(Boolean).join(" "); if (level && !/\d/.test(cls)) l1 += " " + level; if (l1) heads.push(E(l1)); var l2 = [t("alignment_flavor"), t("size"), t("type")].filter(Boolean).join(" "); if (l2) heads.push(E(l2)); var l3 = []; if (t("background")) l3.push(E(t("background"))); if (t("deity")) l3.push("Faith: " + E(t("deity"))); if (l3.length) heads.push(l3.join("; ")); head.innerHTML = heads.map(function(h) { return '<div>' + h + '</div>'; }).join(""); // Top block. var top = '<span class="sb-k">Init</span> ' + multiversald20_signed(n("initiative_total")); top += '; <span class="sb-k">Senses</span> ' + (t("senses") ? E(t("senses")) + "; " : "") + "Perception " + multiversald20_signed(n("sk_perception_total")); html.push('<div class="sb-line">' + top + '</div>'); line("Aura", E(t("aura"))); var hum = t("humanity_current"); line("Humanity", (hum !== "" ? E(hum) + "/" : "") + n("humanity_max")); // DEFENSE section("Defense"); var pro = n("max_prowess"); var drParts = function(armor, misc) { var p = ["10 base"]; if (armor) p.push(multiversald20_signed(armor) + " armor"); if (pro) p.push(multiversald20_signed(pro) + " Prowess"); if (misc) p.push(multiversald20_signed(misc) + " misc"); return " (" + p.join(", ") + ")"; }; line("K-DR", n("kdr_total") + drParts(n("armor_kdr_sum"), n("kdr_misc")) + ', <span class="sb-k">E-DR</span> ' + n("edr_total") + drParts(n("armor_edr_sum"), n("edr_misc"))); var hp = t("current_hp"), hpMax = t("max_hp"), die = t("hp_die_info"); var hpText = (hp !== "" ? E(hp) + "/" : "") + (hpMax !== "" ? E(hpMax) : "?"); if (t("temporary_hp")) hpText += " (+" + E(t("temporary_hp")) + " temp)"; var dieMatch = die.match(/^([^:]+): (d\d+)/); if (dieMatch) hpText += " (" + E(dieMatch[2]) + " Hit Die, " + E(dieMatch[1]) + ")"; line("hp", hpText); var saves = '<span class="sb-k">Fort</span> ' + multiversald20_signed(n("fort_total")) + ', <span class="sb-k">Ref</span> ' + multiversald20_signed(n("ref_total")) + ', <span class="sb-k">Will</span> ' + multiversald20_signed(n("will_total")); if (t("save_notes")) saves += "; " + E(t("save_notes")); html.push('<div class="sb-line">' + saves + '</div>'); line("Defensive Abilities", E(t("defensive_abilities"))); var conds = []; if (t("conditions_notes")) conds.push(E(t("conditions_notes"))); if (n("fatigue_tier")) conds.push("Fatigue tier " + n("fatigue_tier")); if (n("shock_tier")) conds.push("Shock tier " + n("shock_tier")); line("Conditions", conds.join("; ")); var inj = [], ir = rows("injuries"); for (var i = 0; i < ir.length; i++) { var loc = rt(ir[i], "injury_location"), eff = rt(ir[i], "injury_desc"); if (!loc && !eff) continue; var s = E(loc || "Injury"); if (multiversald20_elChecked(ir[i].querySelector(".dslf_injury_treated"))) s += " (treated)"; if (eff) s += " – " + E(eff); inj.push(s); } line("Injuries", inj.join("; ")); // OFFENSE section("Offense"); var speed = []; if (t("speed_land")) speed.push(E(t("speed_land")) + " ft."); var kinds = ["burrow", "climb", "fly", "swim"]; for (var k = 0; k < kinds.length; k++) { if (t("speed_" + kinds[k])) speed.push(kinds[k] + " " + E(t("speed_" + kinds[k])) + " ft."); } line("Speed", speed.join(", ") + (t("reach") ? '; <span class="sb-k">Reach</span> ' + E(t("reach")) + " ft." : "")); var melee = [], ranged = [], ar = rows("attacks"); for (var a = 0; a < ar.length; a++) { var nm = rt(ar[a], "attack_name"); if (!nm) continue; var atk = rt(ar[a], "attack_attack"), dmg = rt(ar[a], "attack_damage"), extra = []; var s2 = E(nm) + (atk ? " " + E(/^[+-]/.test(atk) ? atk : "+" + atk) : ""); if (dmg) extra.push(E(dmg)); if (rt(ar[a], "attack_traits")) extra.push(E(rt(ar[a], "attack_traits"))); if (extra.length) s2 += " (" + extra.join(", ") + ")"; if (rt(ar[a], "attack_range")) s2 += " [" + E(rt(ar[a], "attack_range")) + "]"; if (multiversald20_elChecked(ar[a].querySelector(".dslf_attack_ranged"))) ranged.push(s2); else melee.push(s2); } line("Melee", melee.join(", ")); line("Ranged", ranged.join(", ")); line("Special Attacks", E(t("special_attacks"))); line("Other", E(t("combat_notes"))); // Spells, grouped by Tradition, then by level (highest first). var groups = {}, order = [], sr = rows("powers"); for (var p = 0; p < sr.length; p++) { var sn = rt(sr[p], "power_name"); if (!sn) continue; var trad = rt(sr[p], "power_tradition") || "Other"; trad = trad.charAt(0).toUpperCase() + trad.slice(1).toLowerCase(); if (!groups[trad]) { groups[trad] = {}; order.push(trad); } var lv = rt(sr[p], "power_level"); lv = multiversald20_isNumeric(lv) ? Number(lv) : "?"; if (!groups[trad][lv]) groups[trad][lv] = []; var bits = []; if (rt(sr[p], "power_mpcost")) bits.push(E(rt(sr[p], "power_mpcost")) + " MP"); var save = rt(sr[p], "power_save"); if (save && !/^(none|no|-)$/i.test(save) && rt(sr[p], "power_dc") && rt(sr[p], "power_dc") !== "-") bits.push("DC " + E(rt(sr[p], "power_dc"))); groups[trad][lv].push(E(sn.toLowerCase()) + (bits.length ? " (" + bits.join(", ") + ")" : "")); } if (order.length) { var mp = t("current_mp"), mpMax = t("max_mp"); line("Mana Pool", (mp !== "" ? E(mp) + "/" : "") + (mpMax !== "" ? E(mpMax) : "?")); } for (var g = 0; g < order.length; g++) { var key = order[g].toLowerCase(), hdr = E(order[g]) + " Spells"; if (MVD20_TRADITIONS[key]) hdr += " (spell atk " + multiversald20_signed(n("trad_" + key + "_atk")) + ")"; html.push('<div class="sb-line"><span class="sb-k">' + hdr + '</span></div>'); var levels = Object.keys(groups[order[g]]).sort(function(x, y) { return (Number(y) || -1) - (Number(x) || -1); }); for (var L = 0; L < levels.length; L++) { var label = levels[L] === "?" ? "Level ?" : multiversald20_ordinal(levels[L]) + " Level"; html.push('<div class="sb-line sb-bullet">• ' + label + '—' + groups[order[g]][levels[L]].join(", ") + '</div>'); } } // STATISTICS section("Statistics"); var stats = [["Str", "str"], ["Pro", "pro"], ["End", "end"], ["Cha", "cha"], ["Int", "int"], ["Awa", "awa"], ["Luc", "luc"]]; var st = stats.map(function(s) { return '<span class="sb-k">' + s[0] + '</span> ' + (t(s[1]) || "—"); }).join(", "); if (t("attractiveness")) st += '; <span class="sb-k">Attractiveness</span> ' + E(t("attractiveness")); html.push('<div class="sb-line">' + st + '</div>'); html.push('<div class="sb-line"><span class="sb-k">Base Atk</span> ' + multiversald20_signed(n("bab")) + '; <span class="sb-k">CMB</span> ' + multiversald20_signed(n("cmb_total")) + '; <span class="sb-k">CMD</span> ' + n("cmd_total") + '</div>'); var res = ['Luck Pool ' + (t("luck_pool_current") !== "" ? E(t("luck_pool_current")) + "/" : "") + n("luck_pool_max"), 'Recovery Dice ' + (t("recovery_current") !== "" ? E(t("recovery_current")) + "/" : "") + n("recovery_max")]; if (t("flashback_current")) res.push("Flashback Points " + E(t("flashback_current")) + "/3"); line("Resources", res.join("; ")); line("Traits", names("bgtraits", "bgtrait_name")); line("Drawbacks", names("drawbacks", "drawback_name")); line("Feats", names("feats", "feat_name")); var sk = []; for (var key2 in MVD20_SKILL_LABELS) { sk.push(MVD20_SKILL_LABELS[key2] + " " + multiversald20_signed(n("sk_" + key2 + "_total"))); } line("Skills", sk.join(", ")); line("Languages", E(t("languages"))); var sq = [names("racial", "racial_name"), names("classabilities", "classability_name")].filter(Boolean).join(", "); line("SQ", sq); // Gear: armor worn, mods, magic items, other gear, money. var gear = [], slotNames = { head: "head", torso: "torso", larm: "left arm", rarm: "right arm", lleg: "left leg", rleg: "right leg", shield: "shield" }; for (var sl in slotNames) { var an = t("armor_" + sl + "_class"); if (an) gear.push(E(an) + " (" + slotNames[sl] + ")"); } var mr = rows("armormods"); for (var m = 0; m < mr.length; m++) { var mn = rt(mr[m], "armormod_name"); if (mn) gear.push(E(mn) + (rt(mr[m], "armormod_slot") ? " (on " + E(rt(mr[m], "armormod_slot").toLowerCase()) + ")" : "")); } var mi = rows("magicitems"); for (var q = 0; q < mi.length; q++) { var qn = rt(mi[q], "magic_name"); if (qn) gear.push(E(qn) + (rt(mi[q], "magic_charges") ? " (" + E(rt(mi[q], "magic_charges")) + ")" : "")); } var gr = rows("inventory"); for (var w = 0; w < gr.length; w++) { var wn = rt(gr[w], "item_name"), wq = rt(gr[w], "inventory_quantity"); if (wn) gear.push(E(wn) + (wq && wq !== "1" ? " (×" + E(wq) + ")" : "")); } var cr = rows("consumables"); for (var z = 0; z < cr.length; z++) { var zn = rt(cr[z], "consumable_name"), zq = rt(cr[z], "consumable_qty"); if (zn) gear.push(E(zn) + (zq && zq !== "1" ? " (×" + E(zq) + ")" : "")); } var gm = names("gems", "gem_name"); if (gm) gear.push(gm); line("Gear", gear.join(", ")); line("Augments", names("augments", "augment_name")); var money = []; if (t("currency_gold")) money.push(E(t("currency_gold")) + " gold"); if (t("currency_notes")) money.push(E(t("currency_notes"))); line("Money", money.join("; ")); body.innerHTML = html.join(""); } /* Rebuild the stat block shortly after any edit (debounced). */ var mvd20_sbTimer = null; function multiversald20_scheduleStatBlock() { if (mvd20_sbTimer) clearTimeout(mvd20_sbTimer); mvd20_sbTimer = setTimeout(function() { mvd20_sbTimer = null; try { multiversald20_buildStatBlock(); } catch (e) { if (window.console) console.log("MultiversalD20 stat block:", e); } }, 150); }
Submit Notes
Re adjusted the text boxes so never gets cut off. Also added some rule changes and tried.making it look and feel cleaner.
Back