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
Starfinder RPG Basic
Author:
jax7778
Slug:
jsfrpg
System:
Starfinder RPG
DST Source Code
HTML Template
<div class="basicbox fancybox pin"> <h3 class="title">Basic Information</h3> <table width="100%"> <col width="125"/> <col /> <col /> <col /> <tr> <td rowspan="10"><div class="dsf dsf_avatar_image readonly"></div></td> <td class="dsf dsf_name readonly"></td> <td class="dsf dsf_race"></td> <td class="dsf dsf_player_name"></td> </tr><tr> <th>Character Name</th> <th>Race</th> <th>Player</th> </tr><tr> <td class="dsf dsf_gender"></td> <td class="dsf dsf_age"></td> <td class="dsf dsf_size"></td> </tr><tr> <th>Gender</th> <th>Age</th> <th>Size</th> </tr><tr> <td class="dsf dsf_alignment"></td> <td class="dsf dsf_deity"></td> <td class="dsf dsf_theme"></td> </tr><tr> <th>Alignment</th> <th>Deity</th> <th>Theme</th> </tr><tr> <td class="dsf dsf_level"></td> <td class="dsf dsf_experience_points"></td> <td class="dsf dsf_faction"></td> </tr><tr> <th>Class Levels</th> <th>Faction</th> <th>Experience Points</th> </tr><tr> <td colspan="4" class="dsf dsf_languages"></td> </tr><tr> <th colspan="4">Languages</th> </tr> </table> </div> <div class="corebox pin"> <div class="leftbox"> <div class="fancybox statsbox"> <h3 class="title">Abilities</h3> <table width="195"> <tr> <th>Name</th> <th>Score</th> <th>Mod</th> <th>Item</th> <th>Dmg</th> <th>Drain</th> <th>Temp.</th> </tr><tr> <th class="stat">Str</th> <td class="dsf dsf_str"></td> <td class="dsf dsf_str_mod readonly"></td> <td class="dsf dsf_str_magic"></td> <td class="dsf dsf_str_damage"></td> <td class="dsf dsf_str_drain"></td> <td class="dsf dsf_str_boost"></td> </tr><tr> <th class="stat">Dex</th> <td class="dsf dsf_dex"></td> <td class="dsf dsf_dex_mod readonly"></td> <td class="dsf dsf_dex_magic"></td> <td class="dsf dsf_dex_damage"></td> <td class="dsf dsf_dex_drain"></td> <td class="dsf dsf_dex_boost"></td> </tr><tr> <th class="stat">Con</th> <td class="dsf dsf_con"></td> <td class="dsf dsf_con_mod readonly"></td> <td class="dsf dsf_con_magic"></td> <td class="dsf dsf_con_damage"></td> <td class="dsf dsf_con_drain"></td> <td class="dsf dsf_con_boost"></td> </tr><tr> <th class="stat">Int</th> <td class="dsf dsf_int"></td> <td class="dsf dsf_int_mod readonly"></td> <td class="dsf dsf_int_magic"></td> <td class="dsf dsf_int_damage"></td> <td class="dsf dsf_int_drain"></td> <td class="dsf dsf_int_boost"></td> </tr><tr> <th class="stat">Wis</th> <td class="dsf dsf_wis"></td> <td class="dsf dsf_wis_mod readonly"></td> <td class="dsf dsf_wis_magic"></td> <td class="dsf dsf_wis_damage"></td> <td class="dsf dsf_wis_drain"></td> <td class="dsf dsf_wis_boost"></td> </tr><tr> <th class="stat">Cha</th> <td class="dsf dsf_cha"></td> <td class="dsf dsf_cha_mod readonly"></td> <td class="dsf dsf_cha_magic"></td> <td class="dsf dsf_cha_damage"></td> <td class="dsf dsf_cha_drain"></td> <td class="dsf dsf_cha_boost"></td> </tr> </table> </div> <div class="fancybox speedbox"> <h4 class="title">Speed</h4> <table width="100%"> <tr> <td class="dsf dsf_speed"></td> <td class="dsf dsf_speed_burrow"></td> <td class="dsf dsf_speed_climb"></td> <td class="dsf dsf_speed_fly"></td> <td class="dsf dsf_speed_swim"></td> </tr><tr> <th>Land</th> <th>Burrow</th> <th>Climb</th> <th>Fly</th> <th>Swim</th> </tr> </table> </div> </div> <div class="miscbox"> <div class="fancybox hpbox"> <h4 class="title">Stamina, HP & Resolve</h4> <table width="100%"> <tr> <td class="dsf dsf_hp"></td> <td class="dsf dsf_wounds"></td> <td class="dsf dsf_stamina_max"></td> <td class="dsf dsf_stamina"></td> <td class="dsf dsf_resolve"></td> <td class="dsf dsf_resolve_max"></td> </tr><tr> <th>HP Max</th> <th>HP Curr.</th> <th>Stam Max</th> <th>Stam Curr.</th> <th>Resol. Max</th> <th>Resol. Curr.</th> </tr> </table> </div> <div class="fancybox initbox"> <h4 class="title">Initiative</h4> <table width="100%"> <tr> <td class="dsf dsf_initative_total readonly"></td> <td class="dsf dsf_dex_mod readonly"></td> <td class="dsf dsf_misc_init_mod"></td> </tr><tr> <th>Total</th> <th>Dex Mod</th> <th>Misc</th> </tr> </table> </div> <div class="fancybox sensesbox"> <h4 class="title">Senses</h4> <table width="100%"> <tr> <td class="dsf dsf_senses"></td> </tr> </table> </div> <div class="fancybox defensebox"> <h4 class="title">Defenses</h4> <table width="100%"> <tr> <td class="dsf dsf_miss_chance"></td> <td class="dsf dsf_damage_reduction"></td> <td class="dsf dsf_sr"></td> <td class="dsf dsf_acid_resist"></td> <td class="dsf dsf_cold_resist"></td> <td class="dsf dsf_elec_resist"></td> <td class="dsf dsf_fire_resist"></td> <td class="dsf dsf_sonic_resist"></td> </tr><tr> <th>Miss %</th> <th>DR</th> <th>SR</th> <th>Acid</th> <th>Cold</th> <th>Elec.</th> <th>Fire</th> <th>Sonic</th> </tr> </table> </div> <div class="fancybox attackbox"> <h4 class="title">Attack Bonuses</h4> <table width="100%"> <col width="50" /> <col width="150" /> <col width="1" /> <col /> <col width="1" /> <col /> <col width="1" /> <col /> <col width="1" /> <col /> <tr> <td class="noborder">Melee</td> <td class="dsf dsf_attack_melee_total readonly"></td> <td class="collapse">=</td> <td class="dsf dsf_bab" rowspan="2"></td> <td class="collapse">+</td> <td class="dsf dsf_str_mod readonly"></td> <td class="collapse">+</td> <td class="dsf dsf_attack_melee_misc"></td> </tr><tr> <td class="noborder">Ranged</td> <td class="dsf dsf_attack_ranged_total readonly"></td> <td class="collapse">=</td> <td class="collapse">+</td> <td class="dsf dsf_dex_mod readonly"></td> <td class="collapse">+</td> <td class="dsf dsf_attack_ranged_misc"></td> </tr><tr> <td class="noborder"></td> <th class="noborder">Total</th> <td class="noborder"></td> <th class="noborder">Base Attack Bonus</th> <td class="noborder"></td> <th class="noborder">Abil. Mod</th> <td class="noborder"></td> <th class="noborder">Misc</th> </tr> </table> </div> </div> <div class="fancybox halfwidth savesbox"> <h3 class="title">Saving Throws</h3> <table> <tr> <th> </th> <th>Total</th> <th>Base</th> <th>Abil. Mod</th> <th>Magic</th> <th>Misc.</th> <th>Temp.</th> <th>Conditional</th> </tr><tr> <th class="stat">Fort</th> <td class="dsf dsf_fortitude_total readonly"></td> <td class="dsf dsf_base_fort_save"></td> <td class="dsf dsf_con_mod readonly"></td> <td class="dsf dsf_magic_fort_mod"></td> <td class="dsf dsf_misc_fort_mod"></td> <td class="dsf dsf_temp_fort_mod"></td> <td class="dsf dsf_saves_conditional" rowspan="3"></td> </tr><tr> <th class="stat">Reflex</th> <td class="dsf dsf_reflex_total readonly"></td> <td class="dsf dsf_base_reflex_save"></td> <td class="dsf dsf_dex_mod readonly"></td> <td class="dsf dsf_magic_reflex_mod"></td> <td class="dsf dsf_misc_reflex_mod"></td> <td class="dsf dsf_temp_reflex_mod"></td> </tr><tr> <th class="stat">Will</th> <td class="dsf dsf_willpower_total readonly"></td> <td class="dsf dsf_base_willpower_save"></td> <td class="dsf dsf_wis_mod readonly"></td> <td class="dsf dsf_magic_willpower_mod"></td> <td class="dsf dsf_misc_willpower_mod"></td> <td class="dsf dsf_temp_willpower_mod"></td> </tr> </table> </div> <div class="fancybox halfwidth"> <h3 class="title">Armor Class</h3> <table width="100%"> <tr> <td class="dsf dsf_kac readonly"></td> <td class="collapse" rowspan="2">=</td> <td class="dsf dsf_kac_armor_bonus"></td> <td class="collapse" rowspan="2">+</td> <td class="dsf dsf_dex_mod_kac_armor"></td> <td class="collapse" rowspan="2">+</td> <td class="dsf dsf_misc_kac_mod"></td> </tr><tr> <th>Total KAC</th> <th>Armor</th> <th>Dex Mod</th> <th>Misc</th> </tr><tr> <td class="dsf dsf_eac readonly"></td> <td class="collapse" rowspan="2">=</td> <td class="dsf dsf_eac_armor_bonus"></td> <td class="collapse" rowspan="2">+</td> <td class="dsf dsf_dex_mod_eac_armor"></td> <td class="collapse" rowspan="2">+</td> <td class="dsf dsf_misc_eac_mod"></td> </tr><tr> <th>Total EAC</th> <th>Armor</th> <th>Dex Mod</th> <th>Misc</th> </tr><tr> <td class="dsf dsf_accmb readonly"></td> <td class="collapse" rowspan="2">=</td> <td class="dsf dsf_kac readonly"></td> <td class="collapse" rowspan="2">+</td> <td class="collapse" rowspan="2"><b>8</b></td> </tr><tr> <th>AC vs. Combat Maneuvers</th> <th>KAC</th> </tr> </table> </div> </div> <div class="fancybox armorbox pin"> <h3 class="title">Armor<span class="ctlAddArmor addButton">+ Add</span></h3> <div class="dsf dsf_ctlArmorCount" style="display:none"></div> <table class="armorTable" prefix="armor" width="100%"> <tr> <th>Name</th> <th>Category</th> <th>Level</th> <th>EAC Bonus</th> <th>KAC Bonus</th> <th>Max Dex</th> <th>Check Penalty</th> <th>Max Speed</th> <th>Upgrade Slots</th> <th>Bulk</th> <th>Special Qualities</th> </tr> </table> </div> <div class="fancybox augmentationbox pin"> <h3 class="title">Augmentations<span class="ctlAddAugmentation addButton">+ Add</span></h3> <div class="dsf dsf_ctlAugmentationCount" style="display:none"></div> <table class="augmentationTable" prefix="augmentation"> <tr> <th>Name</th> <th>Level</th> <th>Type</th> <th>System</th> <th>Notes</th> </tr> </table> </div> <div class="fancybox weaponbox pin"> <h3 class="title">Weapons<span class="ctlAddWeapon addButton">+ Add</span></h3> <div class="dsf dsf_ctlWeaponCount" style="display:none"></div> <table class="weaponTable" prefix="weapon"> <tr> <th>Name</th> <th>Attack Bonus</th> <th>Damage</th> <th>Critical</th> <th>Range</th> <th>Level</th> <th>Capacity</th> <th>Usage</th> <th>Hands</th> <th>Bulk</th> <th>Special Qualities</th> </tr> </table> </div> <div class="skillfeatabilitybox pin"> <div class="fancybox halfwidth skillbox"> <h3 class="title">Skills<span class="ctlAddSkill addButton">+ Add</span></h3> <div class="dsf dsf_ctlSkillCount" style="display:none"></div> <table width="100%" class="skillTable" prefix="skill"> <tr> <th>CS</th> <th>Skill</th> <th>Key<br />Abil.</th> <th>Total</th> <th>Abil.<br />Mod</th> <th>Ranks</th> <th>Misc</th> </tr> </table> <table width="100%" class="skill-conditionals-table"> <tr> <th>Conditionals</th> </tr> <tr> <td class="dsf dsf_skill_conditionals"> </td> </tr> </table> </div> <div class="fancybox halfwidth featbox"> <h3 class="title">Feats and Proficiencies<span class="ctlAddFeat addButton">+ Add</span></h3> <div class="dsf dsf_ctlFeatCount" style="display:none"></div> <table width="100%" class="featTable" prefix="feat"> <tr><th>Feat/Prof.</th><th>Description</th></tr> </table> </div> <div class="fancybox halfwidth abilitybox"> <h3 class="title">Special Abilities<span class="ctlAddAbility addButton">+ Add</span></h3> <div class="dsf dsf_ctlAbilityCount" style="display:none"></div> <table width="100%" class="abilityTable" prefix="special_ability"> <tr><th>Ability</th><th>Description</th></tr> </table> </div> <div class="fancybox halfwidth traitbox"> <h3 class="title">Traits<span class="ctlAddTrait addButton">+ Add</span></h3> <div class="dsf dsf_ctlTraitCount" style="display:none"></div> <table width="100%" class="traitTable" prefix="trait"> <tr><th>Trait</th><th>Description</th></tr> </table> </div> </div> <div class="fancybox magicitembox pin"> <h3 class="title">Magic Items<span class="ctlAddMagicItem addButton">+ Add<span></h3> <div class="dsf dsf_ctlMagicItemCount" style="display:none"></div> <table class="magicItemTable" prefix="magicItem" width="100%"> <tr> <th>Name</th> <th>Slot</th> <th>Level</th> <th>Special Properties</th> </table> </div> <div class="fancybox inventorybox pin"> <h3 class="title">Equipment and Inventory<span class="ctlAddInventory addButton">+ Add</span></h3> <div class="dsf dsf_ctlInventoryCount" style="display:none"></div> <div class="fancybox subbox halfwidth" style="height:70px;"> <h4 class="title">Carrying Capacity</h4> <table width="100%"> <col /> <col width="20%" /> <col width="20%" /> <col width="20%" /> <col width="20%" /> <tr> <td style="text-align:center;"><span class="dsf dsf_unencumbered readonly"></span> or less</td> <td style="text-align:center;"><span class="dsf dsf_encumbered readonly"></span></td> <td style="text-align:center;"><span class="dsf dsf_overburdened readonly"></span>+</td> </tr><tr> <th>UnEncumbered Bulk</th> <th>Encumbered Bulk</th> <th>OverBurdened Bulk</th> </tr> </table> </div> <div class="fancybox subbox halfwidth" style="height:70px;"> <h4 class="title">Credits</h4> <table width="100%"> <col /> <col width="0%" /> <tr> <td style="text-align:center;" class="dsf dsf_credits"></td> </tr><tr> <th>Total</th> </tr> </table> </div> </div> <div class="fancybox spellbox pin"> <h3 class="title">Spells</h3> <div class="newSpellsDialog"><b>Spells Section:</b> <input type="checkbox" name="spontaneous" /><label for="spontaneous">Uses Spells</label> <input type="checkbox" name="connection" /><label for="connection">Connection</label> <input type="text" name="minSpellLevel" size="1" maxlength="1" value="0" />—<input type="text" name="maxSpellLevel" size="1" maxlength="1" value="6" /> Spell Levels<span class="ctlAddSpellSection addButton">+ Add</span></div> <div class="dsf dsf_ctlSpellSectionCount" style="display:none"></div> </div> <div class="biobox fancybox pin"> <h3 class="title">Description And Bio</h3> <table width="100%"> <col width="25%"/> <col width="25%"/> <col /> <tr> <td class="dsf dsf_height"></td> <td class="dsf dsf_weight"></td> <td class="dsf dsf_eyes"></td> </tr> <tr> <th>Height</th> <th>Weight</th> <th>Eyes</th> </tr> <tr> <td colspan="2" class="dsf dsf_hair"></td> <td class="dsf dsf_skin"></td> </tr> <tr> <th colspan="2">Hair</th> <th>Skin</th> </tr> </table> <div class="dsf dsf_bio readonly"></div> </div> <br /> <br /> <div class="campaign">Campaign: <span class="dsf readonly dsf_campaign"></span></div> <div>Starfinder RPG Basic Sheet by: <span class="dsf dsf_dst_author readonly"></span></div>
CSS
@import url(https://fonts.googleapis.com/css?family=Arapey%7CBitter); .ds_jsfrpg { line-height: 14px; font-size: 12px !important; } .ds_jsfrpg th, .ds_jsfrpg td { font-family: 'Bitter',georgia,times,'times new roman',serif !important; } .ds_jsfrpg .dsf { height: 14px; vertical-align: bottom; } .ds_jsfrpg.editable span.dsf { min-width: 20px; display: inline-block; } .ds_jsfrpg .noborder { border: none !important; } .ds_jsfrpg table { margin: 0; border-collapse: separate; border-spacing: 2px; border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; } .ds_jsfrpg th { font-size: 10px !important; border-top: 1px solid black; padding: 0 !important; text-align: center; background: none; vertical-align: top !important; line-height: 11px !important; } .ds_jsfrpg td { padding: 5px 5px 0 5px; text-align: center; font-size: 12px; } .ds_jsfrpg td, .ds_jsfrpg th { margin: 0 3px; } .ds_jsfrpg .title { width: 100%; color: #ddd !important; text-align: center; margin: -1px 0 0 !important; padding: 1px 0 5px !important; border-top-left-radius: inherit; border-top-right-radius: inherit; text-shadow: 1px 1px 1px #000 !important; line-height: normal !important; } .ds_jsfrpg .spellSection .title { border-top-left-radius: 0; border-top-right-radius: 0; } .ds_jsfrpg h3.title { font-family: Arapey,georgia,times,'times new roman',serif !important; background: #003c9f; /* Old browsers */ background: -moz-radial-gradient(center, ellipse cover, #008cff 0%, #000000 73%); /* FF3.6+ */ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#008cff), color-stop(73%,#000000)); /* Chrome,Safari4+ */ background: -webkit-radial-gradient(center, ellipse cover, #008cff 0%,#000000 73%); /* Chrome10+,Safari5.1+ */ background: -o-radial-gradient(center, ellipse cover, #008cff 0%,#000000 73%); /* Opera 12+ */ background: -ms-radial-gradient(center, ellipse cover, #008cff 0%,#000000 73%); /* IE10+ */ background: radial-gradient(center, ellipse cover, #008cff 0%,#000000 73%); /* W3C */ font-size: 18px; height: 18px; } .ds_jsfrpg h4.title { font-family: Arapey,georgia,times,'times new roman',serif !important; background: #3c008f; /* Old browsers */ background: -moz-radial-gradient(center, ellipse cover, #604ccf 0%, #000000 73%); /* FF3.6+ */ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#604ccf), color-stop(73%,#000000)); /* Chrome,Safari4+ */ background: -webkit-radial-gradient(center, ellipse cover, #604ccf 0%,#000000 73%); /* Chrome10+,Safari5.1+ */ background: -o-radial-gradient(center, ellipse cover, #604ccf 0%,#000000 73%); /* Opera 12+ */ background: -ms-radial-gradient(center, ellipse cover, #604ccf 0%,#000000 73%); /* IE10+ */ background: radial-gradient(center, ellipse cover, #604ccf 0%,#000000 73%); /* W3C */ font-size: 14px; height: 14px; } .ds_jsfrpg .newSpellsDialog { font-family: Arapey,georgia,times,'times new roman',serif !important; background: #008f00; /* Old browsers */ background: -moz-radial-gradient(center, ellipse cover, #009f00 0%, #000000 73%); /* FF3.6+ */ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#009f00), color-stop(73%,#000000)); /* Chrome,Safari4+ */ background: -webkit-radial-gradient(center, ellipse cover, #009f00 0%,#000000 73%); /* Chrome10+,Safari5.1+ */ background: -o-radial-gradient(center, ellipse cover, #009f00 0%,#000000 73%); /* Opera 12+ */ background: -ms-radial-gradient(center, ellipse cover, #009f00 0%,#000000 73%); /* IE10+ */ background: radial-gradient(center, ellipse cover, #009f00 0%,#000000 73%); /* W3C */ font-size: 14px; border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; width: 100%; color: #ddd; text-align: center; margin: 0; padding: 2px 0; text-shadow: 1px 1px 1px #000; } .ds_jsfrpg .newSpellsDialog label { display: inline; font: inherit; } .ds_jsfrpg .newSpellsDialog input { padding: 0 2px; font: inherit; } .ds_jsfrpg .collapse { width: 1px !important; padding: 0 !important; margin: 0 !important; border-spacing: 0 !important; border: none !important; } .ds_jsfrpg .addButton, .ds_jsfrpg .removeButton { display: none; } .ds_jsfrpg.editable .addButton { display: inline; float: right; min-width: 14px; height: 14px; margin: 1px 5px 1px 0; padding: 1px 5px 0 5px; border-radius: 8px; background-color: #272; color: #fff; cursor: pointer; font-weight: normal; font-size: 12px; } .ds_jsfrpg.editable .removeButton { display: inline; float: right; min-width: 14px; height: 14px; margin: 1px 5px 1px 0; padding: 1px 5px 0 5px; border-radius: 8px; background-color: #722; color: #fff; cursor: pointer; font-weight: normal; font-size: 12px; } .ds_jsfrpg.editable .dsf { background-color: #CDF; color: #000; border-radius: 2px; } .ds_jsfrpg.editable .dsf.readonly, .ds_jsfrpg.editable .dsf.checkbox { background-color: #fff; color: #000; border-radius: 0; } .ds_jsfrpg .fancybox { padding: 0 0 2px 0; margin: 5px 0 0 0; display: inline-block; width: 730px; vertical-align: top; border: 1px solid black; box-shadow: 3px 3px 3px #999; border-radius: 20px / 8px; background: #FFF; color: #000; } .ds_jsfrpg .statsbox { width: 240px; } .ds_jsfrpg .acbox { width: 49.5%; } .ds_jsfrpg .miscbox { width: 501px; display: inline-block; vertical-align: top; margin-left: 2px; } .ds_jsfrpg .defensebox { width: 100%; } .ds_jsfrpg .attackbox { width: 100%; } .ds_jsfrpg .hpbox { /*width: 192px; */ width: 70%; } .ds_jsfrpg .initbox { /*width: 100px; */ width: 28.5%; } .ds_jsfrpg .speedbox { /* width: 196px; */ width: 240px; } .ds_jsfrpg .halfwidth { width: 49.5%; /*362px;*/ display: inline-block; } .ds_jsfrpg .quarterwidth { width: 25%; /*180px;*/ display: inline-block; margin-top: 0; } .ds_jsfrpg .threequarterwidth { width: 75%; display: inline-block; margin-top: 0; } .ds_jsfrpg .domain { border-top-left-radius: 0; border-top-right-radius: 0; margin-left: -1px; margin-bottom: 3px; margin-top: -1px; width: 271px; box-shadow: none; min-height: 300px; } .ds_jsfrpg .dcbox { width: 185px; margin: 0; position: absolute; right: -1px; top: 24px; } .ds_jsfrpg .spellSection { border-top-left-radius: 0; border-top-right-radius: 0; position: relative; min-height: 327px; } .ds_jsfrpg .subbox.halfwidth { width: 365px; } .ds_jsfrpg .inventorybox .item { width: 237px; margin: 0 2px; display: inline-block; } .ds_jsfrpg .subbox { border-top-left-radius: 0; border-top-right-radius: 0; margin: -1px -2px 5px -1px; box-shadow: none; } .ds_jsfrpg .subbox + .subbox { margin-left: -2px; } .ds_jsfrpg .featbox, .ds_jsfrpg .abilitybox, .ds_jsfrpg .traitbox { margin-right: 0; } .ds_jsfrpg .skillbox { margin-right: 3px; float: left; } .ds_jsfrpg table tr:nth-of-type(2n) { background: transparent; } .ds_jsfrpg .statsbox table tr:nth-of-type(2n), .ds_jsfrpg .savesbox table tr:nth-of-type(2n), .ds_jsfrpg .armorbox table tr:nth-of-type(2n), .ds_jsfrpg .magicitembox table tr:nth-of-type(2n), .ds_jsfrpg .weaponbox table tr:nth-of-type(2n), .ds_jsfrpg .dcTable tr:nth-of-type(2n), .ds_jsfrpg .skillbox table tr:nth-of-type(2n), .ds_jsfrpg .featbox table tr:nth-of-type(2n), .ds_jsfrpg .abilitybox table tr:nth-of-type(2n), .ds_jsfrpg .augmentationbox table tr:nth-of-type(2n) { background: #f0f0f0; } .ds_jsfrpg .statsbox table, .ds_jsfrpg .savesbox table, .ds_jsfrpg .attackbox table, .ds_jsfrpg .armorbox table, .ds_jsfrpg .magicitembox table, .ds_jsfrpg .weaponbox table, .ds_jsfrpg .dcTable, .ds_jsfrpg .skillbox table, .ds_jsfrpg .featbox table, .ds_jsfrpg .abilitybox table, .ds_jsfrpg .augmentationbox table { border-spacing: 0 !important; border-collapse: collapse; width: 99%; margin-bottom: 4px; } .ds_jsfrpg .armorbox table, .ds_jsfrpg .weaponbox table, .ds_jsfrpg .augmentationbox table { margin-left: 3px; width: 99%; } .ds_jsfrpg .magicitembox table { margin-left: 3px; width: 99%; } .ds_jsfrpg .attackbox table { margin-top: 8px; margin-right: 0; } .ds_jsfrpg .dcTable { width: 182px; } .ds_jsfrpg .statsbox th, .ds_jsfrpg .savesbox th, .ds_jsfrpg .armorbox th, .ds_jsfrpg .magicitembox th, .ds_jsfrpg .featTable th, .ds_jsfrpg .traitTable th, .ds_jsfrpg .abilityTable th, .ds_jsfrpg .skillTable th, .ds_jsfrpg .weaponbox th, .ds_jsfrpg .dcTable th, .ds_jsfrpg .augmentationTable th { border: none !important; vertical-align: bottom !important; padding: 4px 2px !important; } .ds_jsfrpg .skillTable tr > td:first-child { text-align: left; } .ds_jsfrpg .statsbox th.stat, .ds_jsfrpg .savesbox th.stat { font-size: 12px; font-variant: small-caps; vertical-align: middle; } .ds_jsfrpg .statsbox td, .ds_jsfrpg .savesbox td, .ds_jsfrpg .attackbox td, .ds_jsfrpg .armorbox td, .ds_jsfrpg .magicitembox td, .ds_jsfrpg .weaponbox td, .ds_jsfrpg .dcTable td, .ds_jsfrpg .augmentationbox td, .ds_jsfrpg .skill-conditionals-table td { border: 1px solid black; padding: 3px; vertical-align: middle; } .ds_jsfrpg .dcTable tr > td:first-child { border: none; } .ds_jsfrpg .featTable td, .ds_jsfrpg .abilityTable td, .ds_jsfrpg .skillTable td, .ds_jsfrpg .traitTable td { border-bottom: 1px solid black; padding: 3px; vertical-align: middle; } .ds_jsfrpg .skillTable td { font-size: 11px; line-height: 10px; } .ds_jsfrpg .spellList { width: 100%; margin: 2px 1px 2px 2px; display: inline-block; border-bottom: 1px solid black; position: relative; min-height: 14px; } .ds_jsfrpg .spellList .dsf { height: 100%; margin-left: 15px; } .ds_jsfrpg .spellList .spellLevel { width: 15px; position: absolute; top: 0; left: 0; } .ds_jsfrpg .dsf_bio { height: 100%; padding: 5px; border-bottom-left-radius: inherit !important; border-bottom-right-radius: inherit !important; } .ds_jsfrpg .sideways { -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); text-align: left; vertical-align: top; display: block; margin: 10px 0 15px 0; font-size: 10px; } .ds_jsfrpg .dsf_avatar_image { display: block; height: 100%; max-width: 250px; } .ds_jsfrpg input, .ds_jsfrpg select { margin: 0; width: auto; height: auto; display: inline; } .ds_jsfrpg .pin { width: 99.5%; display: inline-block; background: #FFF; opacity: 1; } .ds_jsfrpg .dsf.dsf_cmd_total { font-weight: bold; border: 1px dashed #009900; } /* .dynamic_sheet_container { overflow: auto !important; max-width: 860px; } */ .ds_jsfrpg .leftbox { display:inline-block; width:240px; } .ds_jsfrpg .sensesbox { width: 100%; } .ds_jsfrpg .sensesbox table { margin: 0px 10px; width: 96%; } .ds_jsfrpg .dsf_senses { border-bottom: 1px solid black; }
Javascript
var $ = jQuery; aisleten.characters.jeditablePlaceholder = " "; var shouldRecalc = false; function jsfrpg_dataPreLoad(options) { //console.time("dataPreLoad"); if ($.browser.msie) { } var defaultSkills = { skill1: "Acrobatics", skill1_ability: "Dex", skill2: "Athletics", skill2_ability: "Str", skill3: "Bluff", skill3_ability: "Cha", skill4: "Computers", skill4_ability: "Int", skill5: "Culture", skill5_ability: "Int", skill6: "Diplomacy", skill6_ability: "Cha", skill7: "Disguise", skill7_ability: "Cha", skill8: "Engineering", skill8_ability: "Int", skill9: "Intimidate", skill9_ability: "Cha", skill10: "Life Science", skill10_ability: "Int", skill11: "Medicine", skill11_ability: "Int", skill12: "Mysticism", skill12_ability: "Wis", skill13: "Perception", skill13_ability: "Wis", skill14: "Physical Science", skill14_ability: "Int", skill15: "Piloting", skill15_ability: "Dex", skill16: "Sense Motive", skill16_ability: "Wis", skill17: "Sleight of Hand", skill17_ability: "Dex", skill18: "Stealth", skill18_ability: "Dex", skill19: "Survival", skill19_ability: "Wis", }; if(typeof dynamic_sheet_attrs == "undefined") dynamic_sheet_attrs = {}; var containerId = "#" + options['containerId']; //Set defaults to keep the editing fields from making the form gross var defaults = { str: "10", dex: "10", "con": "10", "int": "10", wis: "10", cha: "10", languages: "Common", ctlFeatCount: 2, //Default to give some room for new characters ctlAbilityCount: 2, //Default to give some room for new characters ctlInventoryCount: 12, //Four lines of three entries to start with ctlSkillCount: 0, //19 standard skill lines, Excluding Profession becuase it can be based on Cha, Int, or Wis. ctlTraitCount: 2, //A little extra padding to fill space ctlWeaponCount: 2, //Two rows, primary and backup ctlSpellSectionCount: 0, ctlMagicItemCount: 2, ctlAugmentationCount: 2, ctlArmorCount: 4 } dynamic_sheet_attrs = $.extend(defaults, dynamic_sheet_attrs); //Check for old skill format and transition to new if (dynamic_sheet_attrs.acrobatics_cs != undefined) { jsfrpg_transitionSkills(defaultSkills, dynamic_sheet_attrs.ctlSkillCount); shouldRecalc = true; } if (dynamic_sheet_attrs.ctlInventoryCount < 9) { dynamic_sheet_attrs.ctlInventoryCount = 9; } if (dynamic_sheet_attrs.ctlWeaponCount < 2) { dynamic_sheet_attrs.ctlWeaponCount = 2; } if (!options.isEditable) { //We're in read-only mode, so alter the sheet a little to make it more useful //Can't add if it's not an edit $(containerId + " .newSpellsDialog").hide(); if (dynamic_sheet_attrs.ctlSpellSectionCount <= 0) { //Not a wielder, so hide that section $(containerId + " .spellbox").hide(); } if (dynamic_sheet_attrs.ctlTraitCount <= 0) { //Not a wielder, so hide that section $(containerId + " .traitbox").hide(); } if (dynamic_sheet_attrs.ctlAugmentationCount <= 0) { $(containerId + " .augmentationbox").hide(); } if (dynamic_sheet_attrs.ctlMagicItemCount <= 0) { $(containerId + " .magicitembox").hide(); } if (dynamic_sheet_attrs.ctlFeatCount <= 0) { //Not a wielder, so hide that section $(containerId + " .featbox").hide(); } if (dynamic_sheet_attrs.ctlAbilityCount <= 0) { //Not a wielder, so hide that section $(containerId + " .abilitybox").hide(); } } else { //First, we ensure that all the dynamic tables show at least one row if (dynamic_sheet_attrs.ctlFeatCount < 2) { dynamic_sheet_attrs.ctlFeatCount = 2; } if (dynamic_sheet_attrs.ctlAbilityCount < 2) { dynamic_sheet_attrs.ctlAbilityCount = 2; } if (dynamic_sheet_attrs.ctlAugmentationCount < 2) { dynamic_sheet_attrs.ctlAugmentationCount = 2; } if (dynamic_sheet_attrs.ctlMagicItemCount < 2) { dynamic_sheet_attrs.ctlMagicItemCount = 2; } if (dynamic_sheet_attrs.ctlTraitCount < 2) { dynamic_sheet_attrs.ctlTraitCount = 2; } if (dynamic_sheet_attrs.ctlSkillCount < 5) { dynamic_sheet_attrs.ctlSkillCount = 19; dynamic_sheet_attrs = $.extend(defaultSkills, dynamic_sheet_attrs); shouldRecalc = true; } //Loading in editing mode, so wire up the event handlers $(containerId + " .ctlAddFeat").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlFeatCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addFeatRow('featTable', 'feat', count, containerId, true); }); $(containerId + " .ctlAddAbility").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlAbilityCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addFeatRow('abilityTable', 'special_ability', count, containerId, true); }); $(containerId + " .ctlAddTrait").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlTraitCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addFeatRow('traitTable', 'trait', count, containerId, true); }); $(containerId + " .ctlAddSkill").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlSkillCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addSkillRow('skillTable', count, containerId, true); }); $(containerId + " .ctlAddWeapon").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlWeaponCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addWeaponRow('weaponTable', count, containerId, true); }); $(containerId + " .ctlAddAugmentation").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlAugmentationCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addAugmentationRow('augmentationTable', count, containerId, true); }); $(containerId + " .ctlAddArmor").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlArmorCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addArmorRow('armorTable', count, containerId, true); }); $(containerId + " .ctlAddMagicItem").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlMagicItemCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addMagicItemRow('magicItemTable', count, containerId, true); }); $(containerId + " .ctlAddInventory").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlInventoryCount"); var count = Number(ctl.text())+1; ctl.text(count); jsfrpg_addInventoryRow('inventorybox', count, containerId, true); }); $(containerId + " .ctlAddSpellSection").bind("click.jsfrpg", function () { var ctl = $(containerId + " .dsf_ctlSpellSectionCount"); var count = Number(ctl.text()); ctl.text(count + 1); jsfrpg_addSpellSection('spellbox', count, containerId, true); }); $(containerId).on("click", ".ctlRemoveSpellSection", function () { var ctl = $(containerId + " .dsf_ctlSpellSectionCount"); var count = Number(ctl.text()) - 1; ctl.text(count); ctl = $(this).parents(".spellSectionContainer").next(); $(this).parents(".spellSectionContainer").remove(); jsfrpg_renumberSpellSections(ctl); }); $(containerId + " .skillTable").on("change.jsfrpg", "input[type=checkbox]", function() { var ctl = $(this).parent().next(); //Get the skill name because it's easier to parse var skill = ctl[0].className.substring(4); jsfrpg_updateSkill(containerId, skill); }); } //Now, we initialize the dynamic rows to hold the incoming data for (var i=1; i<=dynamic_sheet_attrs.ctlFeatCount; i++) { jsfrpg_addFeatRow('featTable', 'feat', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlAbilityCount; i++) { jsfrpg_addFeatRow('abilityTable', 'special_ability', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlTraitCount; i++) { jsfrpg_addFeatRow('traitTable', 'trait', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlSkillCount; i++) { jsfrpg_addSkillRow('skillTable', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlWeaponCount; i++) { jsfrpg_addWeaponRow('weaponTable', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlAugmentationCount; i++) { jsfrpg_addAugmentationRow('augmentationTable', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlArmorCount; i++) { jsfrpg_addArmorRow('armorTable', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlMagicItemCount; i++) { jsfrpg_addMagicItemRow('magicItemTable', i, containerId, options.isEditable); } for (var i=1; i<=dynamic_sheet_attrs.ctlInventoryCount; i++) { jsfrpg_addInventoryRow('inventorybox', i, containerId, options.isEditable); } for (var i=0; i<dynamic_sheet_attrs.ctlSpellSectionCount; i++) { jsfrpg_addSpellSection('spellbox', i, containerId, options.isEditable, dynamic_sheet_attrs["spsSec" + i + "_Spontaneous"] == '1', dynamic_sheet_attrs["spsSec" + i + "_Connections"] == '1', dynamic_sheet_attrs["spsSec" + i + "_MinLevel"], dynamic_sheet_attrs["spsSec" + i + "_MaxLevel"]); } //console.timeEnd("dataPreLoad"); } function jsfrpg_dataPostLoad(options) { // Called just after the data is loaded. //console.time("dataPostLoad"); var containerId = "#" + options['containerId']; if (shouldRecalc || options.isEditable) { //since we're editing, make sure that all the data is recalculated and correct jsfrpg_updateStat("str", containerId); jsfrpg_updateStat("dex", containerId); jsfrpg_updateStat("con", containerId); jsfrpg_updateStat("int", containerId); jsfrpg_updateStat("wis", containerId); jsfrpg_updateStat("cha", containerId); jsfrpg_updateInventoryStuff(containerId); } if (options.isEditable) { var fixHelper = function(e, ui) { ui.children().each(function() { $(this).width($(this).width()); }); return ui; }; //Wire up sortable tables $(containerId + " .featTable").sortable({ items: "tr:not(:first)", helper: fixHelper, update: jsfrpg_renumberTable }); $(containerId + " .skillTable").sortable({ items: "tr:not(:first)", helper: fixHelper, update: jsfrpg_renumberTable }); $(containerId + " .abilityTable").sortable({ items: "tr:not(:first)", helper: fixHelper, update: jsfrpg_renumberTable }); $(containerId + " .traitTable").sortable({ items: "tr:not(:first)", helper: fixHelper, update: jsfrpg_renumberTable }); $(containerId + " .inventorybox").sortable({ items: "div.item", helper: fixHelper, update: jsfrpg_renumberItems }); $(containerId + " .featTable tr, " + containerId + " .abilityTable tr, " + containerId + " .traitTable tr, " + containerId + " .inventorybox div.item").disableSelection(); } var skillBoxHeight = $(containerId + " .skillbox").height(); var featBox = $(containerId + " .featbox"); if (featBox.height() - skillBoxHeight >= -100) { featBox.after("<br style='clear:both' />"); } //console.timeEnd("dataPostLoad"); } function jsfrpg_dataChange(options) { // Called immediately after a data value is changed. // alert("dataChange. " + options['fieldName'] + " = " + options['fieldValue']); var field = options['fieldName']; var val = options['fieldValue']; var containerId = "#" + options['containerId']; //need to push the values to the other versions of the field //required due to how jEditable works //but exclude checkboxes if ((field.substr(field.length - 3) != '_cs')) { $(containerId + " .dsf_" + field).text(val); } switch (field) { case "str": case "str_damage": case "str_drain": case "str_magic": case "str_boost": jsfrpg_updateStat("str", containerId); jsfrpg_updateInventoryStuff(containerId); break; case "int": case "int_damage": case "int_drain": case "int_magic": case "int_boost": jsfrpg_updateStat("int", containerId); break; case "wis": case "wis_damage": case "wis_drain": case "wis_magic": case "wis_boost": jsfrpg_updateStat("wis", containerId); break; case "dex": case "dex_damage": case "dex_drain": case "dex_magic": case "dex_boost": jsfrpg_updateStat("dex", containerId); break; case "con": case "con_damage": case "con_drain": case "con_magic": case "con_boost": jsfrpg_updateStat("con", containerId); break; case "cha": case "cha_damage": case "cha_drain": case "cha_magic": case "cha_boost": jsfrpg_updateStat("cha", containerId); break; case "base_fort_save": case "magic_fort_mod": case "misc_fort_mod": case "temp_fort_mod": case "base_reflex_save": case "magic_reflex_mod": case "misc_reflex_mod": case "temp_reflex_mod": case "base_willpower_save": case "magic_willpower_mod": case "misc_willpower_mod": case "temp_willpower_mod": jsfrpg_updateSaves(containerId); break; case "misc_init_mod": jsfrpg_updateInit(containerId); break; case "bab": case "attack_melee_misc": case "attack_ranged_misc": jsfrpg_updateAttacks(containerId); break; case "kac_armor_bonus": case "dex_mod_kac_armor": case "misc_kac_mod": jsfrpg_updateKAC(containerId); jsfrpg_updateACCMB(containerId); break; case "eac_armor_bonus": case "dex_mod_eac_armor": case "misc_eac_mod": jsfrpg_updateEAC(containerId); break; } if ((field.substr(field.length - 6) == '_ranks')) { jsfrpg_updateSkill(containerId, "dsf_" + field.substr(0, field.length - 6)); } else if ((field.substr(field.length - 9) == '_misc_mod')) { jsfrpg_updateSkill(containerId, "dsf_" + field.substr(0, field.length - 9)); } else if ((field.substr(field.length - 3) == '_cs')) { jsfrpg_updateSkill(containerId, "dsf_" + field.substr(0, field.length - 3)); } else if ((field.substr(field.length - 8) == '_ability')) { jsfrpg_updateSkill(containerId, "dsf_" + field.substr(0, field.length - 8)); } else if ((field.length >= 14) && (field.substr(0, 6) == 'spsSec') && (field.substr(field.length - 6) == 'BaseDC')) { for (var l=0; l<=9; l++) { $(containerId + " .dsf_" + field.substr(0, 7) + "_DC" + l).text(Number(val) + l); } } } function jsfrpg_dataPreSave(options) { // Called just before the data is saved to the server. // alert("dataPreSave"); var containerId = "#" + options['containerId']; //Comb through the dynamic tables and remove empty values jsfrpg_cleanTable("feat", "Feat", containerId); jsfrpg_cleanTable("ability", "Ability", containerId); jsfrpg_cleanTable("trait", "Trait", containerId); jsfrpg_cleanSkillTable(containerId); jsfrpg_cleanTable("weapon", "Weapon", containerId); jsfrpg_cleanTable("magicItem", "MagicItem", containerId); jsfrpg_cleanInventoryTable(containerId); jsfrpg_cleanTable("augmentation", "Augmentation", containerId); jsfrpg_cleanArmor("armor", "Armor", containerId); } // You can define your own variables...just make sure to namespace them! function jsfrpg_updateStat(stat, containerId) { var value = Number($(containerId + " .dsf_" + stat).text()) - Number($(containerId + " .dsf_" + stat + "_damage").text()) - Number($(containerId + " .dsf_" + stat + "_drain").text()) + Number($(containerId + " .dsf_" + stat + "_magic").text()) + Number($(containerId + " .dsf_" + stat + "_boost").text()); if (jsfrpg_isNumeric(value)) { $(containerId + " .dsf_" + stat + "_mod").text(Math.floor((parseInt(value) - 10) / 2)); switch (stat) { case "str": jsfrpg_updateAttacks(containerId); break; case "wis": jsfrpg_updateSaves(containerId); break; case "dex": jsfrpg_updateSaves(containerId); jsfrpg_updateInit(containerId); jsfrpg_updateAttacks(containerId); jsfrpg_updateKAC(containerId); jsfrpg_updateEAC(containerId); jsfrpg_updateACCMB(containerId); break; case "con": jsfrpg_updateSaves(containerId); break; } jsfrpg_updateSkills(containerId, stat); } } function jsfrpg_updateSaves(containerId) { $(containerId + " .dsf_fortitude_total").text(Number($(containerId + " .dsf_base_fort_save").text()) + Number($(containerId + " .dsf_con_mod:first").text()) + Number($(containerId + " .dsf_magic_fort_mod").text()) + Number($(containerId + " .dsf_misc_fort_mod").text()) + Number($(containerId + " .dsf_temp_fort_mod").text())); $(containerId + " .dsf_willpower_total").text(Number($(containerId + " .dsf_base_willpower_save").text()) + Number($(containerId + " .dsf_wis_mod:first").text()) + Number($(containerId + " .dsf_magic_willpower_mod").text()) + Number($(containerId + " .dsf_misc_willpower_mod").text()) + Number($(containerId + " .dsf_temp_willpower_mod").text())); $(containerId + " .dsf_reflex_total").text(Number($(containerId + " .dsf_base_reflex_save").text()) + Number($(containerId + " .dsf_dex_mod:first").text()) + Number($(containerId + " .dsf_magic_reflex_mod").text()) + Number($(containerId + " .dsf_misc_reflex_mod").text()) + Number($(containerId + " .dsf_temp_reflex_mod").text())); } function jsfrpg_updateInit(containerId) { $(containerId + " .dsf_initative_total").text(Number($(containerId + " .dsf_dex_mod:first").text()) + Number($(containerId + " .dsf_misc_init_mod").text())); } function jsfrpg_updateKAC(containerId) { $(containerId + " .dsf_kac").text(10 + Number($(containerId + " .dsf_kac_armor_bonus").text()) + Number($(containerId + " .dsf_dex_mod_kac_armor").text()) + Number($(containerId + " .dsf_misc_kac_mod").text())); } function jsfrpg_updateEAC(containerId) { $(containerId + " .dsf_eac").text(10 + Number($(containerId + " .dsf_eac_armor_bonus").text()) + Number($(containerId + " .dsf_dex_mod_eac_armor").text()) + Number($(containerId + " .dsf_misc_eac_mod").text())); } function jsfrpg_updateACCMB(containerId) { var cmb = Number($(containerId + " .dsf_kac:first").text()); $(containerId + " .dsf_accmb").text(8 + cmb); } function jsfrpg_updateAttacks(containerId) { var bab = Number($(containerId + " .dsf_bab:first").text()); var ranged = bab + Number($(containerId + " .dsf_dex_mod:first").text()) + Number($(containerId + " .dsf_attack_ranged_misc").text()); var melee = bab + Number($(containerId + " .dsf_str_mod:first").text()) + Number($(containerId + " .dsf_attack_melee_misc").text()); $(containerId + " .dsf_attack_melee_total").text(jsfrpg_signedInt(melee)); $(containerId + " .dsf_attack_ranged_total").text(jsfrpg_signedInt(ranged)); } function jsfrpg_updateSkills(containerId, stat) { var id; stat = stat[0].toUpperCase() + stat.substr(1).toLowerCase(); $(containerId + " .skillTable td:contains(" + stat + ")").each(function (i, c) { id = jsfrpg_findDsfClass($(c).next()); if (id) { jsfrpg_updateSkill(containerId, id.substr(0, id.length - 4)); } }); } function jsfrpg_updateSkill(containerId, skill) { var modtype = $(containerId + " ." + skill + "_mod").prev().text().toLowerCase(); var classmod = Number($(containerId + " ." + skill + "_cs input").val()) ? 3 : 0; var ranks = Number($(containerId + " ." + skill + "_ranks").text()); var abilMod = Number($(containerId + " .dsf_" + modtype + "_mod:first").text()); if (ranks <= 0) { ranks = 0; classmod = 0; } var ctl = $(containerId + " ." + skill + "_ability_mod"); if (ctl.length) { //Custom field, so fill in the stat mod ctl.text(jsfrpg_signedInt(abilMod)); } $(containerId + " ." + skill + "_mod").text(jsfrpg_signedInt(classmod + ranks + Number($(containerId + " ." + skill + "_misc_mod").text()) + abilMod)); } function jsfrpg_updateTotal(countTitle, fieldName, containerId) { var count = Number($(containerId + " .dsf_ctl" + countTitle + "Count").text()); var sum = 0; for (var i=0; i<count; i++) { var val = Number($(containerId + " .dsf_" + fieldName + i).text()); if (!isNaN(val)) sum += val; } $(containerId + " .dsf_" + fieldName + "Total").text(Math.round(100.0 * sum) / 100.0); } function jsfrpg_updateInventoryStuff(containerId) { var val = $(containerId + " .dsf_str").text(); if (jsfrpg_isNumeric(val)) { val = Number(val); var heavy = Math.floor((val / 2)+1) var heavytop = val //hack to fix 33 * 3 = 100 if (heavy % 10 == 9) heavy++; dash = String.raw` - ` $(containerId + " .dsf_unencumbered").text(Math.floor(val / 2)); $(containerId + " .dsf_encumbered").text(heavy + dash + heavytop); $(containerId + " .dsf_overburdened").text(val + 1); } //$(containerId + " .dsf_wealth_total").text( //Math.round(100 * (Number($(containerId + " .dsf_pp").text()) * 10 + //Number($(containerId + " .dsf_gp").text()) + //Number($(containerId + " .dsf_sp").text()) / 10.0 + //Number($(containerId + " .dsf_cp").text()) / 100.0)) / 100.0 //); } function jsfrpg_bindRow(newRow, containerId) { //Force-bind the new elements. Ah, sweet hax containerId = containerId.replace("#", ""); newRow.find(".dsf").each(function (i, c) { var name = jsfrpg_findDsfClass(c); if (name) aisleten.characters.bindField(name.replace("dsf_", ""), containerId, 'jsfrpg'); }); } function jsfrpg_addFeatRow(table, prefix, num, containerId, isEditable) { var newRow = $('<tr class="jsfrpg_' + prefix + 'Row' + num +'"><td class="dsf dsf_' + prefix + num + '" /><td class="dsf dsf_' + prefix + 'Description' + num + '"> </td></tr>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addSkillRow(table, num, containerId, isEditable) { var newRow = $('<tr class="jsfrpg_skillRow' + num +'"><td class="dsf dsf_skill' + num + '_cs checkbox"></td><td class="dsf dsf_skill' + num + '" /><td class="dsf dsf_skill' + num + '_ability"> </td><td class="dsf dsf_skill' + num + '_mod readonly"> </td><td class="dsf dsf_skill' + num + '_ability_mod readonly"> </td><td class="dsf dsf_skill' + num + '_ranks"> </td><td class="dsf dsf_skill' + num + '_misc_mod"> </td></tr>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addMagicItemRow(table, num, containerId, isEditable) { var newRow = $('<tr class="jsfrpg_magicItemRow' + num +'"><td class="dsf dsf_protitem' + num + '"></td><td class="dsf dsf_protitem' + num + '_slot"></td><td class="dsf dsf_protitem' + num + '_type"></td><td class="dsf dsf_protitem' + num + '_special_properties"></td></tr>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addWeaponRow(table, num, containerId, isEditable) { var newRow = $('<tr class="jsfrpg_weaponRow' + num +'"><td class="dsf dsf_weapon' + num + '" /><td class="dsf dsf_weapon' + num + '_attack_bonus"> </td><td class="dsf dsf_weapon' + num + '_damage"> </td><td class="dsf dsf_weapon' + num + '_critical"> </td><td class="dsf dsf_weapon' + num + '_range"> </td><td class="dsf dsf_weapon' + num + '_level"> </td><td class="dsf dsf_weapon' + num + '_capacity"> </td><td class="dsf dsf_weapon' + num + '_usage"> </td><td class="dsf dsf_weapon' + num + '_hands"> </td><td class="dsf dsf_weapon' + num + '_bulk"> </td><td class="dsf dsf_weapon' + num + '_notes"> </td></tr>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addArmorRow(table, num, containerId, isEditable) { var newRow = $('<tr class="jsfrpg_armorRow' + num +'"><td class="dsf dsf_armor' + num + '"></td><td class="dsf dsf_armor' + num + '_type"></td><td class="dsf dsf_armor' + num + '_level"></td><td class="dsf dsf_armor' + num + '_eac_bonus"></td><td class="dsf dsf_armor' + num + '_kac_bonus"></td><td class="dsf dsf_armor' + num + '_max_dex"></td><td class="dsf dsf_armor' + num + '_penalty"></td><td class="dsf dsf_armor' + num + '_speed"></td><td class="dsf dsf_armor' + num + '_slots"></td><td class="dsf dsf_armor' + num + '_bulk"></td><td class="dsf dsf_armor' + num + '_special_properties"></td></tr>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addAugmentationRow(table, num, containerId, isEditable) { var newRow = $('<tr class="jsfrpg_augmentationRow' + num +'"><td class="dsf dsf_augmentation' + num + '"></td><td class="dsf dsf_augmentation' + num + '_level"></td><td class="dsf dsf_augmentation' + num + '_type"></td><td class="dsf dsf_augmentation' + num + '_slot"></td><td class="dsf dsf_augmentation' + num + '_notes"></td></tr>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addInventoryRow(table, num, containerId, isEditable) { var newRow = $('<div class="item jsfrpg_item' + num + '"><table><col /><col width="35" /><tr><td class="dsf dsf_item' + num + '" /><td class="dsf dsf_item' + num + '_weight"> </td></tr><tr><th>Name</th><th>Bulk</th></tr></table></div>'); $(containerId + " ." + table).append(newRow); if (isEditable) { newRow.disableSelection(); jsfrpg_bindRow(newRow, containerId); } } function jsfrpg_addSpellSection(table, num, containerId, isEditable, isSpontaneous, hasConnection, minLevel, maxLevel) { if (!maxLevel) { //new section, so pull the values from the add dialog isSpontaneous = $(containerId + " .newSpellsDialog input[name=spontaneous]")[0].checked; hasConnection = $(containerId + " .newSpellsDialog input[name=connection]")[0].checked; minLevel = Number($(containerId + " .newSpellsDialog input[name=minSpellLevel]").val()); maxLevel = Number($(containerId + " .newSpellsDialog input[name=maxSpellLevel]").val()); } //Make sure we have at least some rows to add if (!maxLevel || (maxLevel < 4)) maxLevel = 4; if (!minLevel || (minLevel < 0)) minLevel = 0; if (maxLevel > 6) maxLevel = 6; if (minLevel > maxLevel) { var tmp = minLevel; minLevel = maxLevel; maxLevel = tmp; } //Problem line isSpontaneous = "1"; var html = '<div class="spellSection spellSectionContainer jsfrpg_spellSection' + num + '"><div class="dsf dsf_spsSec' + num + '_Spontaneous" style="display:none;">' + (isSpontaneous ? '1' : '0') + '</div><div class="dsf dsf_spsSec' + num + '_Connections" style="display:none;">' + (hasConnection ? '1' : '0') + '</div><div class="dsf dsf_spsSec' + num + '_MaxLevel" style="display:none;">' + maxLevel + '</div><div class="dsf dsf_spsSec' + num + '_MinLevel" style="display:none;">' + minLevel + '</div><div class="spellSection"><h3 class="title"><span class="dsf dsf_spsSec' + num + '_Name"></span><span class="ctlRemoveSpellSection removeButton">- Remove</span></h3>'; var dcTable = '<div class="fancybox domain dcbox quarterwidth"><h4 class="title">DCs / Per-Day</h4><table><tr><td class="dsf dsf_spsSec' + num + '_BaseDC"></td><td class="dsf dsf_spsSec' + num + '_Concentration"></td></tr><tr><th>Base DC</th><th>Conc.</th></tr></table><table class="dcTable"><col width="15" /><col /><col /><col />'; if (isSpontaneous) dcTable += '<col />'; dcTable += '<tr><th>Lvl</th><th>DC</th>' if (isSpontaneous) dcTable += '<th>Known</th>'; dcTable += '<th>Per Day</th>'; if (isSpontaneous) dcTable += '<th>Left</th>' dcTable += '<th>Bonus</th></tr>'; for (var l=minLevel; l<=maxLevel; l++) { dcTable += '<tr><td class="spellLevel">' + l + ':</td><td class="dsf readonly dsf_spsSec' + num + '_DC' + l + '"></td>' if (isSpontaneous) dcTable += '<td class="dsf dsf_spsSec' + num + '_KnownNumber' + l + '"></td>'; if (l == 0) { dcTable += '<td>—</td><td>—</td>'; if (isSpontaneous) dcTable += '<td>—</td>'; } else { dcTable += '<td class="dsf dsf_spsSec' + num + '_PerDayNumber' + l + '"></td>' if (isSpontaneous) dcTable += '<td class="dsf dsf_spsSec' + num + '_Left' + l + '"></td>' dcTable += '<td class="dsf dsf_spsSec' + num + '_BonusNumber' + l + '"></td>'; } dcTable += '</tr>'; } dcTable += "</table>"; // Edit is here: if (hasConnection) { for (var f=0; f<1; f++) { html += '<div class="fancybox domain halfwidth"><h4 class="title"><span class="dsf dsf_spsSec' + num + '_Connection' + 1 + '_Name"></span></h4><table class="domainTable"><col width="13" /><col /><tr><td colspan="2" class="dsf dsf_spsSec' + num + '_Connection' + 1 + '_Power1"></td></tr><tr><th colspan="2">Connection Powers</th></tr>'; for (var l=Math.max(1, minLevel); l<=7; l++) { html += '<tr><td class="spellLevel">' + l + ':</td><td class="dsf dsf_spsSec' + num + '_Connection' + 1 + '_Spells' + l + '"></td></tr>'; } html += "</table></div>"; } } else ; if (hasConnection) { for (var d=0; d<1; d++) { html += '<div class="fancybox domain halfwidth"><h4 class="title"><span class="dsf dsf_spsSec' + num + '_Connection' + 2 + '_Name"></span></h4><table class="domainTable"><col width="13" /><col /><tr><td colspan="2" class="dsf dsf_spsSec' + num + '_Connection' + 2 + '_Power1"></td></tr><tr><th colspan="2">Connection Spells</th></tr>'; for (var l=Math.max(1, minLevel); l<=6; l++) { html += '<tr><td class="spellLevel">' + l + ':</td><td class="dsf dsf_spsSec' + num + '_Connection' + 2 + '_Spells' + l + '"></td></tr>'; } html += "</table></div>"; } html += dcTable + "</div>"; } else html += '<div class="threequarterwidth">'; if (isSpontaneous) html += '<h4 class="title">Spells Known</h4>'; else html += '<h4 class="title">Spells Known</h4>'; for (var l=minLevel; l<=maxLevel; l++) { html += '<div class="spellList"><div class="spellLevel">' + l + ':</div><div class="dsf dsf_spsSec' + num + '_Prepared' + l + '"></div></div>'; } if (!hasConnection) html += "</div>" + dcTable; var newSection = $(html); $(containerId + " ." + table).append(newSection); if (isEditable) { jsfrpg_bindRow(newSection, containerId); } } function jsfrpg_cleanTable(prefix, title, containerId) { var max = Number($(containerId + " .dsf_ctl" + title + "Count").text()); var rowPrefix = $(containerId + " ." + prefix + "Table").attr("prefix"); var count = 0; for (var i=1; i<=max; i++) { var row = $(containerId + " tr.jsfrpg_" + rowPrefix + "Row" + i); var obj = row.find("td.dsf:first"); if ("" == $.trim(obj.text())) { //This row is empty, so find the relevant tr tags and remove them row.remove(); } else { count++; } } //Nothing to renumber if we remove them all if (count > 0) jsfrpg_renumberTable(null, { item: $(containerId + " ." + prefix + "Table td:first") }); $(containerId + " .dsf_ctl" + title + "Count").text(count); } function jsfrpg_cleanSkillTable(containerId) { var max = Number($(containerId + " .dsf_ctlSkillCount").text()); var count = 0; for (var i=1; i<=max; i++) { var row = $(containerId + " tr.jsfrpg_skillRow" + i); var obj = row.find("td:nth(1)"); if ("" == $.trim(obj.text())) { //This row is empty, so find the relevant tr tags and remove them row.remove(); } else { count++; } } //Nothing to renumber if we remove them all if (count > 0) jsfrpg_renumberTable(null, { item: $(containerId + " .skillTable td:first") }); $(containerId + " .dsf_ctlSkillCount").text(count); } function jsfrpg_cleanInventoryTable(containerId) { var max = Number($(containerId + " .dsf_ctlInventoryCount").text()); var count = 0; for (var i=1; i<=max; i++) { var box = $(containerId + " div.jsfrpg_item" + i); var obj = box.find("td:first"); if ("" == $.trim(obj.text())) { //This row is empty, so find the relevant tr tags and remove them box.remove(); } else { count++; } } //Nothing to renumber if we remove them all if (count > 0) jsfrpg_renumberItems(null, { item: $(containerId + " .inventorybox div.item:first") }); $(containerId + " .dsf_ctlInventoryCount").text(count); } function jsfrpg_findDsfClass(element) { var classes = $(element).attr('class'); if (!classes) return null; classes = classes.split(/\s/); var fieldName = null; $.each(classes, function(i, className) { if(className.substr(0,4) == "dsf_") { fieldName = className; } }); return fieldName; } function jsfrpg_isNumeric(n) { return ($.isNumeric && $.isNumeric(n)) || (!isNaN(parseFloat(n)) && isFinite(n)); } function jsfrpg_signedInt(n) { return (n < 0) ? n : ("+" + n) } function jsfrpg_renumberTable(e, ui) { //ui.item is the tr tag that got moved var parent = ui.item.parents("table"); var prefix = parent.attr("prefix"); var partialClass = "jsfrpg_" + prefix + "Row"; var baserow = parent.find("tr[class*=" + partialClass + "]:first"); var rowId = "1"; var classNames = baserow[0].className.split(/\s+/); for (var i=0; i<classNames.length; i++) { if (classNames[i].indexOf(partialClass) == 0) { rowId = classNames[i].substring(partialClass.length); break; } } baserow = baserow.children(); baserow.each(function (i, c) { baserow[i] = $(c).prop("class").replace(rowId, "{0}"); }); //Now that we have the templates, reorder things parent.find("tr[class*=" + partialClass + "]").each(function (i, c) { $(c).prop("class", partialClass + (i+1)); $(c).find("td").each(function (j, cc) { var str = baserow[j]; $(cc).prop("class", str.replace(/\{0\}/g, (i+1))); }); }); } function jsfrpg_renumberItems(e, ui) { //ui.item is the tr tag that got moved var parent = ui.item.parents(".inventorybox"); var baserow = [ "dsf dsf_item{0}", "dsf dsf_item{0}_weight" ]; //Now that we have the templates, reorder things parent.find(".item").each(function (i, c) { $(c).prop("class", "item jsfrpg_item" + (i+1)); $(c).find("tr:first td").each(function (j, cc) { var str = baserow[j]; $(cc).prop("class", str.replace(/\{0\}/g, (i+1))); }); }); } function jsfrpg_renumberSpellSections(ctl) { //ctl is the div tag after the item that got removed if (!ctl.length) return; //Removed the last item, so nothing to do var parent = ctl.parents(".spellbox"); var count = Number(parent.find(".dsf_ctlSpellSectionCount").text()); var start = Number(ctl.prop("class").substr(54)); //Now that we have the templates, reorder things for (var i = start; i <= count; i++) { parent.find(".jsfrpg_spellSection" + i).each(function (j, c) { $(c).prop("class", "spellSection spellSectionContainer jsfrpg_spellSection" + (i-1)); $(c).find(".dsf").each(function (j, cc) { var str = $(cc).prop("class"); $(cc).prop("class", str.replace("dsf_spsSec" + i, "dsf_spsSec" + (i-1))); }); }); } } function jsfrpg_transitionSkills(defaultSkills, customSkillCount) { var max = dynamic_sheet_attrs.ctlSkillCount = 35 + (jsfrpg_isNumeric(customSkillCount) ? parseInt(customSkillCount) : 0); var oldSkills = [ "acrobatics", "appraise", "bluff", "climb", "craft1", "craft2", "craft3", "diplomacy", "disable_device", "disguise", "escape_artist", "fly", "handle_animal", "heal", "intimidate", "knowledge1", "knowledge2", "knowledge3", "knowledge4", "knowledge5", "linguistics", "perception", "perform1", "perform2", "perform3", "profession1", "profession2", "ride", "sense_motive", "sleght_of_hand", "spellcraft", "stealth", "survival", "use_magic_device" ]; //First, move the old custom skills to the end for (var i = 1; i <= customSkillCount; i++) { defaultSkills['skill' + (i + 35) + '_cs'] = dynamic_sheet_attrs['skill' + i + '_cs']; defaultSkills['skill' + (i + 35) + ''] = dynamic_sheet_attrs['skill' + i + '']; defaultSkills['skill' + (i + 35) + '_ability'] = dynamic_sheet_attrs['skill' + i + '_ability']; defaultSkills['skill' + (i + 35) + '_mod'] = dynamic_sheet_attrs['skill' + i + '_mod']; defaultSkills['skill' + (i + 35) + '_ability_mod'] = dynamic_sheet_attrs['skill' + i + '_ability_mod']; defaultSkills['skill' + (i + 35) + '_ranks'] = dynamic_sheet_attrs['skill' + i + '_ranks']; defaultSkills['skill' + (i + 35) + '_misc_mod'] = dynamic_sheet_attrs['skill' + i + '_misc_mod']; dynamic_sheet_attrs['skill' + i + '_cs'] = null; dynamic_sheet_attrs['skill' + i + ''] = null; dynamic_sheet_attrs['skill' + i + '_ability'] = null; dynamic_sheet_attrs['skill' + i + '_mod'] = null; dynamic_sheet_attrs['skill' + i + '_ability_mod'] = null; dynamic_sheet_attrs['skill' + i + '_ranks'] = null; dynamic_sheet_attrs['skill' + i + '_misc_mod'] = null; } for (var i = 1; i <= oldSkills.length; i++) { var skillName = oldSkills[i-1]; defaultSkills['skill' + i + '_cs'] = dynamic_sheet_attrs[skillName + '_cs']; defaultSkills['skill' + i + '_mod'] = dynamic_sheet_attrs[skillName + '_mod']; defaultSkills['skill' + i + '_ranks'] = dynamic_sheet_attrs[skillName + '_ranks']; defaultSkills['skill' + i + '_misc_mod'] = dynamic_sheet_attrs[skillName + '_misc_mod']; var subskill; if ((skillName.indexOf("craft") == 0) || (skillName.indexOf("knowledge")) == 0 || (skillName.indexOf("perform")) == 0 || (skillName.indexOf("profession") == 0)) { subskill = dynamic_sheet_attrs[skillName]; defaultSkills['skill' + i] = defaultSkills['skill' + i] + " (" + (subskill == undefined ? " " : subskill) + ")"; } } //Copy the new skills over the old custom skills dynamic_sheet_attrs = $.extend(dynamic_sheet_attrs, defaultSkills); }
Submit Notes
I have attempted to create a very basic Starfinder RPG DST. I did not create the sheet myself, I merely modified the existing Pathfinder RPG Universal Sheet by Karelzarath. I do not want or deserve any credit for this sheet, and I do not expect the 6 months of Ascendant. I just wanted to get a sheet up for Starfinder. I believe the sheet is finished now. I am a poor coder, but it appears to work as expected, and I left most of the code from Karelzarath intact. * The Change: This is a minor CSS change, the html and Javascript have not been touched. For some reason on the approved sheet, the corebox section kept displaying too far down the page, under the abilitybox while in edit mode. I have changed the width to percentages instead of fixed pixels for 3 boxes for HP, initiative, and speed, and changed the overall size of the miscbox. This is a VERY minor aesthetic change. No rush, it just bugged me. I am cool if it takes 3 months to approve.
Back