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
Unlikely Alliance System PC
Author:
AaronBonehart
Slug:
unlikelyalliance
Type:
GameCharacter
System:
other
DST Source Code
HTML Template
<div class="unlikelyalliance-container"> <div class="basicinfo cols-12 clearfix"> <div class="basicinfo-1"> <div class="row"> <label>Level: </label> <span class="dsf dsf_level"></span> </div> <div class="row"> <label>Current XP: </label> <span class="dsf dsf_xp"></span> </div> <div class="row"> <label>Skill Tree: </label> <span class="dsf dsf_skill_tree"></span> </div> <div class="row"> <label>Race: </label> <span class="dsf dsf_race"></span> </div> <div class="row"> <label>Size: </label> <span class="dsf dsf_size"></span> </div> <div class="row"> <label>Gender: </label> <span class="dsf dsf_gender"></span> </div> <div class="row"> <label>Age: </label> <span class="dsf dsf_age"></span> </div> <div class="row"> <label>Height: </label> <span class="dsf dsf_height"></span> </div> <div class="row"> <label>Weight: </label> <span class="dsf dsf_weight"></span> </div> <div class="row"> <label>Eyes: </label> <span class="dsf dsf_eyes"></span> </div> <div class="row"> <label>Skin: </label> <span class="dsf dsf_skin"></span> </div> <div class="row"> <label>Hair: </label> <span class="dsf dsf_hair"></span> </div> </div> <div class="basicinfo-2 clearfix"> <div class="image-display"> <span class="dst dst_avatar_image"></span> </div> </div> </div> <div class="biography cols-12 cols-border-box clearfix"> <h3>BIOGRAPHY</h3> <div class="bio-container"> <span class="dst dst_bio"></span> </div> </div> <div class="instructions cols-12 clearfix"> <p><strong>Tip:</strong> Press down the buttons marked by the letter "P" to show that your character is proficient with a given skill or save.</p> </div> <div class="battlestats cols-12 cols-border-box"> <div class="row"> <div class="statbox statbox-3"> <label class="statlabel">AC</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_armor_class"></span> </div> </div> <div class="statbox statbox-3"> <label class="statlabel">INIT</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_initiative"></span> </div> </div> <div class="statbox statbox-3"> <label class="statlabel">SPEED</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_speed"></span> </div> </div> <div class="statbox statbox-3"> <label class="statlabel">HP</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_max_hit_points"></span> </div> </div> </div> </div> <div class="miscstats cols-12 cols-border-box"> <div class="row"> <div class="statbox statbox-4"> <label class="statlabel">SHIELD HP</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_shield_hp"></span> </div> </div> <div class="statbox statbox-4"> <label class="statlabel">PROFICIENCY BONUS</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_proficiency_bonus"></span> </div> </div> <div class="statbox statbox-4"> <label class="statlabel">MP</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_mp"></span> </div> </div> </div> </div> <div class="abilities cols-12 cols-border-box"> <div class="row"> <div class="statbox statbox-2"> <label class="statlabel">STR</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_str"></span> </div> <div class="statmod"> <span class="mod str_mod">-</span> </div> <div class="hidden"> <span class="dsf dsf_str_mod str_mod"></span> </div> </div> <div class="statbox statbox-2"> <label class="statlabel">DEX</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_dex"></span> </div> <div class="statmod"> <span class="mod dex_mod">-</span> </div> <div class="hidden"> <span class="dsf dsf_dex_mod dex_mod"></span> </div> </div> <div class="statbox statbox-2"> <label class="statlabel">CON</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_con"></span> </div> <div class="statmod"> <span class="mod con_mod">-</span> </div> <div class="hidden"> <span class="dsf dsf_con_mod con_mod"></span> </div> </div> <div class="statbox statbox-2"> <label class="statlabel">ARCANA/TECH</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_int"></span> </div> <div class="statmod"> <span class="mod int_mod">-</span> </div> <div class="hidden"> <span class="dsf dsf_int_mod int_mod"></span> </div> </div> <div class="statbox statbox-2"> <label class="statlabel">PERCEPTION</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_wis"></span> </div> <div class="statmod"> <span class="mod wis_mod">-</span> </div> <div class="hidden"> <span class="dsf dsf_wis_mod wis_mod"></span> </div> </div> <div class="statbox statbox-2"> <label class="statlabel">CHA</label> <div class="stat"> <span class="dsf mdash-editable readonly dsf_cha"></span> </div> <div class="statmod"> <span class="mod cha_mod">-</span> </div> <div class="hidden"> <span class="dsf dsf_cha_mod cha_mod"></span> </div> </div> </div> <div class="row"> <label class="full-label cols-12">STAT CHECKS</label> <div class="statbox statbox-2"> <label class="statlabel-small">STR CHECK</label> <div class="stat-small"> <span class="dsf mdash-editable readonly dsf_str_save"></span> </div> <div class="toggle-container"> <button type="button" class="btn btn-default save-prof-btn toggle" data-fieldname="dsf_proficiency_str_save" title="Is Not Proficient with STR Save">P</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_proficiency_str_save"></span> </div> </div> </div> <div class="statbox statbox-2"> <label class="statlabel-small">DEX CHECK</label> <div class="stat-small"> <span class="dsf mdash-editable readonly dsf_dex_save"></span> </div> <div class="toggle-container"> <button type="button" class="btn btn-default save-prof-btn toggle" data-fieldname="dsf_proficiency_dex_save" title="Is Not Proficient with DEX Save">P</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_proficiency_dex_save"></span> </div> </div> </div> <div class="statbox statbox-2"> <label class="statlabel-small">CON CHECK</label> <div class="stat-small"> <span class="dsf mdash-editable readonly dsf_con_save"></span> </div> <div class="toggle-container"> <button type="button" class="btn btn-default save-prof-btn toggle" data-fieldname="dsf_proficiency_con_save" title="Is Not Proficient with CON Save">P</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_proficiency_con_save"></span> </div> </div> </div> <div class="statbox statbox-2"> <label class="statlabel-small">ARC/TECH CHECK</label> <div class="stat-small"> <span class="dsf mdash-editable readonly dsf_int_save"></span> </div> <div class="toggle-container"> <button type="button" class="btn btn-default save-prof-btn toggle" data-fieldname="dsf_proficiency_int_save" title="Is Not Proficient with INT Save">P</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_proficiency_int_save"></span> </div> </div> </div> <div class="statbox statbox-2"> <label class="statlabel-small">PERC CHECK</label> <div class="stat-small"> <span class="dsf mdash-editable readonly dsf_wis_save"></span> </div> <div class="toggle-container"> <button type="button" class="btn btn-default save-prof-btn toggle" data-fieldname="dsf_proficiency_wis_save" title="Is Not Proficient with WIS Save">P</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_proficiency_wis_save"></span> </div> </div> </div> <div class="statbox statbox-2"> <label class="statlabel-small">CHA CHECK</label> <div class="stat-small"> <span class="dsf mdash-editable readonly dsf_cha_save"></span> </div> <div class="toggle-container"> <button type="button" class="btn btn-default save-prof-btn toggle" data-fieldname="dsf_proficiency_cha_save" title="Is Not Proficient with CHA Save">P</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_proficiency_cha_save"></span> </div> </div> </div> </div> </div> <div class="row"> <div class="attacks left-col cols-border-box"> <label class="full-label">ATTACKS</label> <div class="attacks-list-container row"> <ul class="attacks-list clearfix"> <li class="header clearfix"> <div class="attack-stats"> <label class="attack-name">Attack</label> <label class="attack-bonus">Bonus</label> <label class="attack-damage">Damage</label> </div> </li> </ul> <button type="button" class="btn btn-default addbtn">Add Attack</button> <div class="attacks-list-field"> <span class="dsf dsf_attacks"></span> </div> </div> </div> <div class="other-profs right-col cols-border-box"> <label class="full-label">OTHER PROFICIENCIES</label> <div class="profs-list-container addlist-container row"> <ul class="profs-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Proficiency</button> <div class="addlist-field"> <span class="dsf dsf_other_proficiencies"></span> </div> </div> <label class="full-label languages-label">LANGUAGES KNOWN</label> <div class="languages-list-container addlist-container row"> <ul class="language-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Language</button> <div class="addlist-field"> <span class="dsf dsf_languages"></span> </div> </div> </div> </div> <div class="row"> <div class="racial-traits left-col cols-border-box"> <label class="full-label">FEATURES & TRAITS (RACE)</label> <div class="traits-list-container addlist-container row"> <ul class="traits-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Feature or Trait</button> <div class="addlist-field"> <span class="dsf dsf_race_features_and_traits"></span> </div> </div> </div> <div class="class-traits right-col cols-border-box"> <label class="full-label">FEATURES & TRAITS (ABILITIES)</label> <div class="traits-list-container addlist-container row"> <ul class="traits-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Feature or Trait</button> <div class="addlist-field"> <span class="dsf dsf_class_features_and_traits"></span> </div> </div> </div> </div> <div class="row"> <div class="feats left-col cols-border-box"> <label class="full-label">FEATURES & TRAITS (EQUIPMENT)</label> <div class="traits-list-container addlist-container row"> <ul class="traits-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Feat</button> <div class="addlist-field"> <span class="dsf dsf_feats"></span> </div> </div> </div> <div class="misc-traits right-col cols-border-box"> <label class="full-label">ADDITIONAL NOTES</label> <div class="traits-list-container addlist-container row"> <ul class="traits-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Note</button> <div class="addlist-field"> <span class="dsf dsf_additional_notes"></span> </div> </div> </div> </div> <div class="inventory row cols-border-box"> <label class="full-label">EQUIPMENT</label> <div class="inventory-col-1"> <ul class="col-1-list inventory-list clearfix"> </ul> </div> <div class="inventory-col-2"> <ul class="col-2-list inventory-list clearfix"> </ul> </div> <div class="inventory-col-3"> <ul class="col-3-list inventory-list clearfix"> </ul> </div> <button type="button" class="btn btn-default addbtn">Add Item</button> <div class="inventory-field"> <span class="dsf dsf_equipment"></span> </div> </div> <div class="spellcasting row cols-border-box"> <label class="full-label">SPELLCASTING</label> <div class="spellcasting-header row"> <div class="statbox statbox-3"> <label class="statlabel-small">Show this section?</label> <div class="use-spellcasting-toggle toggle-container"> <button type="button" class="btn btn-default toggle" data-fieldname="dsf_use_spellcasting" title="Character Is Not A Spellcaster">No</button> <div class="toggle-checkbox"> <span class="dsf checkbox dsf_use_spellcasting"></span> </div> </div> </div> <div class="statbox statbox-3"> <label class="statlabel-small">Spellcaster Ability</label> <div class="stat-small"> <span class="dsf dsf_spellcasting_ability"></span> </div> </div> <div class="statbox statbox-3"> <label class="statlabel-small">Spell Save DC</label> <div class="stat-small"> <span class="dsf dsf_spell_save_dc"></span> </div> </div> <div class="statbox statbox-3"> <label class="statlabel-small">Spell Attack Bonus</label> <div class="stat-small"> <span class="dsf dsf_spell_attack_bonus"></span> </div> </div> </div> <div class="spell-lists row"> <div class="column_1"> <div class="spellbox"> <label>Cantrips</label> <div class="cantrip-list-container addlist-container"> <ul class="cantrip-list addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Spell</button> <div class="addlist-field"> <span class="dsf dsf_cantrips"></span> </div> </div> </div> <div class="spellbox"> <label>Tier 3</label> <div class="addlist-container"> <ul class="addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Spell</button> <div class="addlist-field"> <span class="dsf dsf_tier_3_spells"></span> </div> </div> </div> </div> <div class="column_2"> <div class="spellbox"> <label>Tier 1</label> <div class="addlist-container"> <ul class="addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Spell</button> <div class="addlist-field"> <span class="dsf dsf_tier_1_spells"></span> </div> </div> </div> <div class="spellbox"> <label>Tier 4</label> <div class="addlist-container"> <ul class="addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Spell</button> <div class="addlist-field"> <span class="dsf dsf_tier_4_spells"></span> </div> </div> </div> </div> <div class="column_3"> <div class="spellbox"> <label>Tier 2</label> <div class="addlist-container"> <ul class="addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Spell</button> <div class="addlist-field"> <span class="dsf dsf_tier_2_spells"></span> </div> </div> </div> <div class="spellbox"> <label>Tier 5</label> <div class="addlist-container"> <ul class="addlist"> </ul> <button type="button" class="btn btn-default addbtn">Add Spell</button> <div class="addlist-field"> <span class="dsf dsf_tier_5_spells"></span> </div> </div> </div> </div> </div> </div> </div>
CSS
/* Unlikely Alliance CSS */ .ds_unlikelyalliance .unlikelyalliance-container { width: 100%; margin: 0 auto; font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif; color:#000; } .ds_unlikelyalliance label { font-size: 1em; color:#000; } .ds_unlikelyalliance a { text-decoration:none; } .ds_unlikelyalliance a:hover { text-decoration:underline; } .ds_unlikelyalliance .hidden { display: none; } .ds_unlikelyalliance .row { width: 100%; margin-top:5px; } .ds_unlikelyalliance .row:before, .ds_unlikelyalliance .row:after, .ds_unlikelyalliance .addlist-container li.addlist-item:before, .ds_unlikelyalliance .addlist-container li.addlist-item:after, .ds_unlikelyalliance .clearfix:before, .ds_unlikelyalliance .clearfix:after { display: table; content: " "; } .ds_unlikelyalliance .row:after, .ds_unlikelyalliance .clearfix:after, .ds_unlikelyalliance .addlist-container li.addlist-item:after { clear: both; } .ds_unlikelyalliance .full-label { width: 100%; display: block; margin-bottom: 10px; font-size: 87.5%; line-height: 1.5em; font-weight: bold; text-align: center; } .ds_unlikelyalliance button { position: static; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } .ds_unlikelyalliance .jeditable_input input { min-width:24px; min-height:24px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } .ds_unlikelyalliance .jeditable_input button { display: inline-block; margin: 5px 0 0 3px; padding: 6px 12px 5px; border: 1px solid #ccc; border-radius: 4px; overflow: visible; text-transform: none; font-family: inherit; font-size: 14px; font-weight: normal; line-height: 1.42857143; -webkit-appearance: button; cursor: pointer; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; text-align: center; white-space: nowrap; vertical-align: middle; color: #333; background-color: #fff; text-shadow: 0 1px 0 #fff; background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; transition:none; } .ds_unlikelyalliance .jeditable_input button::-moz-focus-inner { padding: 0; border: 0; } .ds_unlikelyalliance .jeditable_input button:hover, .ds_unlikelyalliance .jeditable_input button:focus, .ds_unlikelyalliance .jeditable_input button:active { background-color: #ebebeb; border-color: #adadad; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } /* BASIC INFO */ .ds_unlikelyalliance .basicinfo label, .ds_unlikelyalliance .basicinfo span.dsf { display:block; float:left; } .ds_unlikelyalliance .basicinfo label { min-width:100px; width: 8.33333333%; padding-right:8px; font-weight:bold; text-align:right; } .ds_unlikelyalliance .basicinfo .basicinfo-1 { width: 58.33333333%; float: left; } .ds_unlikelyalliance .basicinfo .basicinfo-2 { width: 41.66666667%; float: left; } .ds_unlikelyalliance .basicinfo .basicinfo-2 .image-display { float:right; margin:3px 7px 0 0; border:1px solid #000; } .ds_unlikelyalliance .basicinfo .basicinfo-2 .image-display img { max-width:226px; } @media (max-width: 649px) { .ds_unlikelyalliance .basicinfo .basicinfo-1 { width:100%; clear:both; padding:10px; } .ds_unlikelyalliance .basicinfo .basicinfo-2 { width:100%; clear:both; } .ds_unlikelyalliance .basicinfo .basicinfo-2 .image-display { width:100%; margin:0; padding:10px 0; border-top:1px solid #000; border-bottom:1px solid #000; border-left:none; border-right:none; } .ds_unlikelyalliance .basicinfo .basicinfo-2 .image-display img { display:block; margin:0 auto; } } /* BIO */ .ds_unlikelyalliance .biography { margin:12px auto 10px; padding:10px; border:1px solid #000; } .ds_unlikelyalliance .biography h3 { width:100%; margin-bottom:5px; padding-bottom:5px; border-bottom:1px inset #ccc; font-size:100%; line-height:1.5em; font-weight:bold; color:#000; } .ds_unlikelyalliance .biography .bio-container { font-size:87.5%; } /* INSTRUCTIONS */ .ds_unlikelyalliance .instructions { display:none; margin-top:10px; } .ds_unlikelyalliance .instructions p { width:75%; margin:0 auto; padding:10px; border:1px solid #000; font-size:0.875em; line-height:1.428; text-align:center; } /* ABILITIES */ .ds_unlikelyalliance .abilities, .ds_unlikelyalliance .battlestats { width: 100%; margin: 10px auto; } .ds_unlikelyalliance .abilities .row { margin-bottom: 10px; } .ds_unlikelyalliance .statbox { padding: 10px; border: 1px solid #000; display: block; float: left; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } @media (max-width: 649px) { .ds_unlikelyalliance .statbox { padding:7px; } } .ds_unlikelyalliance .statbox-2 { width: 15.66666667%; margin: 0 1% 0 0; } .ds_unlikelyalliance .statbox-2:last-child { margin:0; } .ds_unlikelyalliance .statbox-3 { width: 24%; margin: 0 1% 0 0; } .ds_unlikelyalliance .statbox-3:last-child { margin:0; } .ds_unlikelyalliance .statbox-4 { width: 32.33333333%; margin: 0 1% 0 0; } .ds_unlikelyalliance .statbox-4:last-child { margin:0; } .ds_unlikelyalliance .statbox .statlabel { width:100%; min-width:30px; display:block; font-size: 87.5%; line-height: 1.5em; font-weight: bold; text-align: center; } @media (max-width: 649px) { .ds_unlikelyalliance .statbox-4 .statlabel { font-size: 62.5%; } } .ds_unlikelyalliance .statbox .statlabel-small { width:100%; min-width:30px; display:block; font-size: 62.5%; line-height: 1.5em; font-weight: bold; text-align: center; } .ds_unlikelyalliance .statbox .stat { width:100%; font-size:150%; text-align:center; } .ds_unlikelyalliance .statbox .stat-small { width:100%; font-size:112.5%; text-align:center; } .ds_unlikelyalliance .statbox .statmod { width: 100%; font-size: 75%; margin-top: 7px; padding-top: 7px; border-top: 1px solid #333; text-align: center; } .ds_unlikelyalliance .statbox .toggle-container { width:100%; margin-top:3px; } .ds_unlikelyalliance .toggle-container button { font-family: Georgia, Times, "Times New Roman", serif; } .ds_unlikelyalliance .toggle-container .toggle-checkbox { display:none; } /* SKILLS */ @media (min-width: 650px) { .ds_unlikelyalliance .skillcol { width:14.66666667%; float: left; padding:0 1%; } .ds_unlikelyalliance .str_skills { border-left:none; } .ds_unlikelyalliance .skillcol-label { display:none; } .ds_unlikelyalliance .skillbox { width: 100%; padding: 5px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } .ds_unlikelyalliance .skill-label { width:100%; display:block; clear:both; font-size:87.5%; font-weight:bold; font-variant:small-caps; } .ds_unlikelyalliance .skillbox .stat { max-width:65%; min-width:20px; min-height:28px; float:left; margin:0 5%; padding-top:8px; font-size:112.5%; } .ds_unlikelyalliance .skillbox .stat .dsf { display:block; float:left; } .ds_unlikelyalliance .skillbox .stat .dsf input { min-width:30px; max-width:40%; float:left; position:relative; top:-4px; } .ds_unlikelyalliance .skillbox .stat .dsf button { min-width:20px; max-width:25%; margin-top:-8px; margin-left:2px; padding-left:3px!important; padding-right:3px!important; float:left; box-sizing: content-box; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; } .ds_unlikelyalliance .skillbox .toggle-container { width:25%; min-height:36px; float:left; } .ds_unlikelyalliance .skillbox .toggle-container .btn { width:100%; min-height:22px; font-weight: bold; } } @media (max-width: 649px) { .ds_unlikelyalliance .skillcol { width: 100%; } .ds_unlikelyalliance .skillcol-label { width: 100%; display: block; margin-bottom: 10px; font-size: 87.5%; line-height: 1.5em; font-weight: bold; font-variant:small-caps; } .ds_unlikelyalliance .skillbox { width: 100%; padding: 10px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } .ds_unlikelyalliance .skill-label { width:100%; display:block; clear:both; font-size:87.5%; font-weight:bold; font-variant:small-caps; } .ds_unlikelyalliance .skillbox .stat { max-width:65%; min-width:20px; min-height:28px; float:left; margin:0 5%; padding-top: 8px; font-size:112.5%; } .ds_unlikelyalliance .skillbox .stat .dsf input { min-width:30px; } .ds_unlikelyalliance .skillbox .toggle-container { width:25%; min-height:36px; float:left; } .ds_unlikelyalliance .skillbox .toggle-container .btn { width:100%; min-height:22px; font-weight: bold; } } /* ATTACKS AND OTHER PROFICIENCIES */ .ds_unlikelyalliance .left-col, .ds_unlikelyalliance .right-col { float:left; padding:10px; border:1px solid #000; } .ds_unlikelyalliance .left-col { width:50%; } .ds_unlikelyalliance .right-col { width:49%; margin:0 0 0 1%; } @media (max-width: 649px) { .ds_unlikelyalliance .left-col, .ds_unlikelyalliance .right-col { width:100%; float:none; clear:both; margin:5px 0 0; } } .ds_unlikelyalliance .languages-label { margin-top:30px; } .ds_unlikelyalliance .addlist-container ul.addlist { clear:both; padding:0 0 0 30px; } .ds_unlikelyalliance .addlist-container ul.addlist li.addlist-item { width:100%; display:block; padding-bottom:5px; } .ds_unlikelyalliance .addlist-container ul.addlist li.addlist-item .marker { width:5px; min-height:22px; display:block; float:left; padding-top:8px; padding-right:3px; } .ds_unlikelyalliance .addlist-container ul.addlist li.addlist-item .content { max-width:80%; min-height:22px; display:block; float:left; padding-top:8px; padding-right:4px; } .ds_unlikelyalliance .addlist-container ul.addlist li.addlist-item .removebtn { width:28px; display:block; float:left; } .ds_unlikelyalliance .addlist-container .addbtn { width:100%; display:block; } .ds_unlikelyalliance .addlist-container .addlist-field { display:none; } /* Attacks List */ .ds_unlikelyalliance .attacks-list-container ul.attacks-list { width:100%; display:block; padding:0; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li { width:100%; display:block; padding-bottom:5px; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li .attack-stats { width:100%; float:left; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li .attack-name { width: 41.66666667%; display:block; float:left; margin-right: 1%; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li .attack-bonus { width: 15.66666667%; display: block; float: left; margin-right: 1%; text-align: center; background-color:#eee; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li .attack-damage { width: 39.66666667%; display:block; float:left; text-align: right; padding-right: 1%; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li span input { max-width:50%; margin-right:2px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li span button { min-height:28px; box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list li span.attack-name, .ds_unlikelyalliance .attacks-list-container ul.attacks-list li span.attack-bonus, .ds_unlikelyalliance .attacks-list-container ul.attacks-list li span.attack-damage { min-height:28px; padding-top:8px; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list-editable li .attack-stats { width: 89.66666667%; margin-left: 1%; } .ds_unlikelyalliance .attacks-list-container ul.attacks-list-editable li .removebtn { width: 8.33333333%; display: block; float: left; } .ds_unlikelyalliance .attacks-list-container .addbtn { width:100%; display:block; } .ds_unlikelyalliance .attacks-list-container .attacks-list-field { display:none; } /* INVENTORY */ .ds_unlikelyalliance .inventory { width:100%; padding:10px; border:1px solid #000; } .ds_unlikelyalliance .inventory .inventory-col-1, .ds_unlikelyalliance .inventory .inventory-col-3 { width:33.33333333%; float:left; } .ds_unlikelyalliance .inventory .inventory-col-2 { width:31.33333333%; margin:0 1%; float:left; } .ds_unlikelyalliance .inventory ul { width:100%; min-height:40px; display:block; margin:0; padding:0; } .ds_unlikelyalliance .inventory ul li { min-height:40px; display:block; margin-bottom:5px; padding:0; border:1px solid #000; background-color:#fff; } .ds_unlikelyalliance .inventory ul li.sortable-placeholder { min-height:40px; background-color:#dedede; } .ds_unlikelyalliance .inventory ul li .handle { width: 36px; height:100%; min-height: 40px; display:block; float:left; border-right:1px solid #000; background-color:#ccc; cursor: pointer; text-align: center; vertical-align: middle; } .ds_unlikelyalliance .inventory ul li .handle .icon-unordered-list { min-width:16px; min-height:16px; margin-top:10px; } .ds_unlikelyalliance .inventory ul li .item { display:block; float:left; padding:5px; word-wrap:break-word; } .ds_unlikelyalliance .inventory ul li .item .jeditable_input { margin-bottom:0; } .ds_unlikelyalliance .inventory ul li .item .jeditable_input input { max-width:65%; position:relative; top:-2px; } .ds_unlikelyalliance .inventory ul li .item .jeditable_input button { position:relative; margin-top:-5px; } .ds_unlikelyalliance .inventory ul li .removebtn { display:block; float:right; margin:1px 1px 2px 0; } .ds_unlikelyalliance .inventory .addbtn { width:100%; display:block; clear:both; } .ds_unlikelyalliance .inventory .inventory-field { display:none; } @media (max-width: 649px) { .ds_unlikelyalliance .inventory .inventory-col-1, .ds_unlikelyalliance .inventory .inventory-col-2, .ds_unlikelyalliance .inventory .inventory-col-3 { width:100%; float:none; clear:both; margin:5px 0 0; } .ds_unlikelyalliance .inventory .inventory-col-2 { padding:5px 0; border-top:1px solid #ccc; border-bottom:1px solid #ccc; } } /* SPELLCASTING */ .ds_unlikelyalliance .spellcasting { width:100%; padding:10px; border:1px solid #000; } .ds_unlikelyalliance .spellcasting .spellcasting-header { width:100%; margin:5px 0; } .ds_unlikelyalliance .spellcasting .spellcasting-header .use-spellcasting-toggle button.toggle { width:100%; display:block; } .ds_unlikelyalliance .spellcasting .spell-lists { width:100%; } .ds_unlikelyalliance .spellcasting .spell-lists .column_1, .ds_unlikelyalliance .spellcasting .spell-lists .column_3 { width:33.33333333%; float:left; } .ds_unlikelyalliance .spellcasting .spell-lists .column_2 { width:31.33333333%; margin:0 1%; float:left; } @media (max-width: 649px) { .ds_unlikelyalliance .spellcasting .spell-lists .column_1, .ds_unlikelyalliance .spellcasting .spell-lists .column_2, .ds_unlikelyalliance .spellcasting .spell-lists .column_3 { width:100%; float:none; clear:both; margin:0; } } .ds_unlikelyalliance .spellcasting .spellbox { margin:0 auto 10px; padding:10px; border:1px solid #000; } .ds_unlikelyalliance .spellcasting .spellbox label { width:100%; text-align:center; font-variant:small-caps; font-weight:bold; } /* GRID CLASSES */ .ds_unlikelyalliance .cols-1, .ds_unlikelyalliance .cols-2, .ds_unlikelyalliance .cols-3, .ds_unlikelyalliance .cols-4, .ds_unlikelyalliance .cols-5, .ds_unlikelyalliance .cols-6, .ds_unlikelyalliance .cols-7, .ds_unlikelyalliance .cols-8, .ds_unlikelyalliance .cols-9, .ds_unlikelyalliance .cols-10, .ds_unlikelyalliance .cols-11, .ds_unlikelyalliance .cols-12 { float: left; } .ds_unlikelyalliance .cols-12 { width: 100%; } .ds_unlikelyalliance .cols-11 { width: 91.66666667%; } .ds_unlikelyalliance .cols-10 { width: 83.33333333%; } .ds_unlikelyalliance .cols-9 { width: 75%; } .ds_unlikelyalliance .cols-8 { width: 66.66666667%; } .ds_unlikelyalliance .cols-7 { width: 58.33333333%; } .ds_unlikelyalliance .cols-6 { width: 50%; } .ds_unlikelyalliance .cols-5 { width: 41.66666667%; } .ds_unlikelyalliance .cols-4 { width: 33.33333333%; } .ds_unlikelyalliance .cols-3 { width: 25%; } .ds_unlikelyalliance .cols-2 { width: 16.66666667%; } .ds_unlikelyalliance .cols-1 { width: 8.33333333%; } .ds_unlikelyalliance .cols-border-box { box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; } /** * BUTTON STYLES * Adapted from Twitter Bootstrap 3 * http://getbootstrap.com/ */ .ds_unlikelyalliance .btn { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 87.5%; font-weight: normal; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-image: none; border: 1px solid transparent; border-radius: 4px; transition:none; } .ds_unlikelyalliance .btn:focus, .ds_unlikelyalliance .btn:active:focus, .ds_unlikelyalliance .btn.active:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .ds_unlikelyalliance .btn:hover, .ds_unlikelyalliance .btn:focus { color: #333; text-decoration: none; } .ds_unlikelyalliance .btn:active, .ds_unlikelyalliance .btn.active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .ds_unlikelyalliance .btn.disabled, .ds_unlikelyalliance .btn[disabled] { pointer-events: none; cursor: not-allowed; filter: alpha(opacity=65); -webkit-box-shadow: none; box-shadow: none; opacity: .65; } .ds_unlikelyalliance .btn-default { color: #333; background-color: #fff; border-color: #ccc; } .ds_unlikelyalliance .btn-default:hover, .ds_unlikelyalliance .btn-default:focus, .ds_unlikelyalliance .btn-default:active, .ds_unlikelyalliance .btn-default.active { color: #333; background-color: #ebebeb; border-color: #adadad; } .ds_unlikelyalliance .btn-default:active, .ds_unlikelyalliance .btn-default.active { background-image: none; } .ds_unlikelyalliance .btn-default.disabled, .ds_unlikelyalliance .btn-default[disabled], .ds_unlikelyalliance .btn-default.disabled:hover, .ds_unlikelyalliance .btn-default[disabled]:hover, .ds_unlikelyalliance .btn-default.disabled:focus, .ds_unlikelyalliance .btn-default[disabled]:focus, .ds_unlikelyalliance .btn-default.disabled:active, .ds_unlikelyalliance .btn-default[disabled]:active, .ds_unlikelyalliance .btn-default.disabled.active, .ds_unlikelyalliance .btn-default[disabled].active { background-color: #fff; border-color: #ccc; } .ds_unlikelyalliance .btn-default { text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); } .ds_unlikelyalliance .btn-default:active { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .ds_unlikelyalliance .btn:active, .ds_unlikelyalliance .btn.active { background-image: none; } .ds_unlikelyalliance .btn-default { text-shadow: 0 1px 0 #fff; background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-color: #dbdbdb; border-color: #ccc; } .ds_unlikelyalliance .btn-default:hover, .ds_unlikelyalliance .btn-default:focus { background-color: #e0e0e0; background-position: 0 -15px; } .ds_unlikelyalliance .btn-default:active, .ds_unlikelyalliance .btn-default.active { background-color: #e0e0e0; border-color: #dbdbdb; } .ds_unlikelyalliance .save-prof-btn { width:100%; display:block; font-weight:bold; } .ds_unlikelyalliance .skill-prof-btn { padding: 6px!important; font-weight: bold; }
Javascript
// Unlikely Alliance JavaScript /** * TOGGLE BUTTON PLUGIN */ (function($) { var ToggleButton = function(element, options) { this.element = $(element); if (options.hasOwnProperty("isEditMode")) { this.isEditMode = options.isEditMode; } if (options.hasOwnProperty("changeButtonText")) { this.changeButtonText = options.changeButtonText; this.textTrue = options.textTrue; this.textFalse = options.textFalse; } this.init(); } ToggleButton.prototype = { name: "plugin.unlikelyalliance.ToggleButton", element: null, checkbox: null, isSelected: false, titleTrue: null, titleFalse: null, changeButtonText: false, textTrue: "", textFalse: "", isEditMode: false, init: function() { if (this.element) { var fieldName = this.element.attr("data-fieldname"); this.checkbox = this.element.parent(".toggle-container").find("." + fieldName + " input"); this.titleFalse = this.element.attr("title"); this.titleTrue = this.titleFalse.replace("Not ", ""); if (this.checkbox.is(":checked")) { this.isSelected = true; } else { this.isSelected = false; } this.updateView(); if (this.isEditMode) { this.element.on("click", null, {plugin:this}, function(event) { event.data.plugin.onClick(); }); } } }, onClick: function() { if (this.isSelected) { this.isSelected = false; } else { this.isSelected = true; } this.updateView(); this.updateCheckbox(); }, updateView: function() { if (this.isSelected) { this.element.addClass("active"); this.element.attr("title", this.titleTrue); if (this.changeButtonText) { this.element.text(this.textTrue); } } else { this.element.removeClass("active"); this.element.attr("title", this.titleFalse); if (this.changeButtonText) { this.element.text(this.textFalse); } if (!this.isEditMode) { this.element.hide(); } } }, updateCheckbox: function() { if (this.isSelected) { this.checkbox.attr("checked", "checked"); this.checkbox.val(1); } else { this.checkbox.attr("checked", null); this.checkbox.val(0); } this.checkbox.trigger("change"); }, destroy: function() { this.element.off("click"); this.name = null; this.titleFalse = null; this.titleTrue = null; this.textTrue = null; this.textFalse = null; this.changeButtonText = false; this.isEditMode = false; this.isSelected = false; this.checkbox = null; this.element = null; } } $.fn.basicRulesToggleButton = function(target) { return this.each(function() { var plugin = $.data(this, ToggleButton.prototype.name); if (!plugin) { $.data(this, ToggleButton.prototype.name, new ToggleButton(this, target)); } else { if (target == "destroy") { plugin.destroy(); $.removeData(this, ToggleButton.prototype.name); plugin = null; } } }); } })(jQuery); /** * EDITABLELIST PLUGIN */ (function($, window) { var EditableList = function(element, options) { this.element = $(element); this.defaults.editableSettings.placeholder = aisleten.characters.jeditablePlaceholder; this.options = $.extend({}, this.defaults, options); this.init(); } EditableList.prototype = { name: "plugin.unlikelyalliance.EditableList", options: null, element: null, list: null, addBtn: null, field: null, items: [], defaults: { isEditMode: true, itemMarkup: '<li class="addlist-item"> <span class="marker">-</span><span class="content" data-index="{{{INDEX}}}">{{{CONTENT}}}</span>{{{BUTTON}}}</li>', removeBtnMarkup: '<button type="button" class="btn btn-default removebtn" data-index="{{{INDEX}}}">✕</button>', confirmMessage: 'Are you sure you want to remove this item?', editableSettings: { submit: "OK", cssclass : 'jeditable_input', placeholder : aisleten.characters.jeditablePlaceholder } }, editableReturnFunc: function(value, settings) { return value; }, init: function() { if (this.element) { this.list = this.element.find("ul.addlist"); this.addBtn = this.element.find("button.addbtn"); this.field = this.element.find("div.addlist-field span.dsf"); this.items = []; var itemstr = this.field.text(); // set up button if (this.options.isEditMode) { this.addBtn.on("click", null, {plugin:this}, function(event) { event.data.plugin.onAddItem(); }); } else { this.addBtn.remove(); } // get items if (itemstr !== null && itemstr !== "" && itemstr !== aisleten.characters.jeditablePlaceholder) { this.items = JSON.parse(itemstr); } this.renderList(); } }, onAddItem: function() { var removeBtnMarkup = this.options.removeBtnMarkup.replace("{{{INDEX}}}", this.items.length), markup = this.options.itemMarkup.replace("{{{CONTENT}}}","").replace("{{{INDEX}}}", this.items.length).replace("{{{BUTTON}}}", removeBtnMarkup), newItem = $(markup).appendTo(this.list), editableOptions = $.extend({}, this.options.editableSettings); editableOptions.origin = this; editableOptions.callback = function(value, settings) { settings.origin.onUpdateItem(this, value); } newItem.find("span.content").editable(this.editableReturnFunc, editableOptions); newItem.find("button.removebtn").on("click", null, {plugin:this}, function(event) { event.data.plugin.onRemoveItem(this); }); }, renderList: function() { this.list.empty(); var len = this.items.length, markup = "", btnMarkup = "", totalMarkup = "", myItems = null; if (len > 0) { for (var i=0; i<len; i++) { markup = this.options.itemMarkup.replace("{{{CONTENT}}}", this.items[i]).replace("{{{INDEX}}}", i); if (this.options.isEditMode) { btnMarkup = this.options.removeBtnMarkup.replace("{{{INDEX}}}", i); markup = markup.replace("{{{BUTTON}}}", btnMarkup); } else { markup = markup.replace("{{{BUTTON}}}", ""); } totalMarkup += markup; } myItems = $(totalMarkup).appendTo(this.list); if (this.options.isEditMode) { myItems.find("button.removebtn").on("click", null, {plugin:this}, function(event) { event.data.plugin.onRemoveItem(this); }); var editableopts = $.extend({}, this.options.editableSettings); editableopts.origin = this; editableopts.callback = function(value, settings) { settings.origin.onUpdateItem(this, value); } myItems.find("span.content").editable(this.editableReturnFunc, editableopts); } } }, onUpdateItem: function(item, value) { var itemIndex = parseInt(item.getAttribute("data-index")); if (itemIndex !== null && !isNaN(itemIndex)) { this.items[itemIndex] = value; this._updateField(); } }, onRemoveItem: function(button) { var index = parseInt(button.getAttribute("data-index")), child = null, content = null, isConfirmed = true, isActualItem = true; if (index !== null && !isNaN(index)) { child = this.list.children("li.addlist-item").eq(index); content = child.find("span.content").text(); if (content !== "" && content !== aisleten.characters.jeditablePlaceholder) { isConfirmed = window.confirm(this.options.confirmMessage); isActualItem = false; } if (isConfirmed) { // remove view item child.remove(); // remove from array if (isActualItem) { this.items.splice(index, 1); this._updateField(); } this._updateListIndices(); } } }, destroy: function() { }, _updateListIndices: function() { var len = this.items.length, str = ""; if (len > 0) { for (var i=0; i<len; i++) { str = this.items[i]; this.list.find("span.content").each(function(myIndex) { if ($(this).text() === str) { this.setAttribute("data-index", i); $(this).parent().children("button.removebtn").attr("data-index", i); } }); } } }, _updateField: function() { var jsonText = JSON.stringify(this.items); this.field.text(jsonText); } } $.fn.basicRulesEditableList = function(target, options) { return this.each(function() { var plugin = $.data(this, EditableList.prototype.name); if (!plugin) { $.data(this, EditableList.prototype.name, new EditableList(this, target)); } else { if (target == "destroy") { plugin.destroy(); $.removeData(this, EditableList.prototype.name); plugin = null; } else if (target == "renderList") { plugin.renderList(); } } }); } })(jQuery, window); /** * ATTACKS LIST PLUGIN */ (function($, window) { var AttackList = function(element, options) { this.element = $(element); this.defaults.editableSettings.placeholder = aisleten.characters.jeditablePlaceholder; this.options = $.extend({}, this.defaults, options); this.init(); } AttackList.prototype = { name: "plugin.unlikelyalliance.AttackList", options: null, element: null, list: null, addBtn: null, field: null, items: [], defaults: { isEditMode: true, numPlaceholders: 3, itemMarkup: '<li class="clearfix" data-index="{{{INDEX}}}"><div class="attack-stats"><span class="attack-name">{{{NAME}}}</span><span class="attack-bonus">{{{BONUS}}}</span><span class="attack-damage">{{{DAMAGE}}}</span></div>{{{BUTTON}}}</li>', removeBtnMarkup: '<button class="btn btn-default removebtn">✕</button>', confirmMessage: 'Are you sure you want to remove this attack?', editableSettings: { submit: "OK", cssclass : 'jeditable_input', placeholder : aisleten.characters.jeditablePlaceholder } }, editableReturnFunc: function(value, settings) { return value; }, init: function() { if (this.element) { this.list = this.element.find("ul.attacks-list"); this.addBtn = this.element.find("button.addbtn"); this.field = this.element.find("div.attacks-list-field span.dsf"); var self = this, itemstr = this.field.text(); // set up button if (this.options.isEditMode) { this.list.addClass("attacks-list-editable"); this.addBtn.click(function(event) { self.onAddItem(); }); } else { this.addBtn.remove(); } // get items if (itemstr !== null && itemstr !== "" && itemstr !== aisleten.characters.jeditablePlaceholder) { var rawItems = JSON.parse(itemstr), len = rawItems.length; for (var i=0; i<len; i++) { if (rawItems[i] !== null) { var attack = new AttackObj(rawItems[i]); this.items[i] = attack; } } } this.renderList(); } }, onAddItem: function() { var markup = this.options.itemMarkup.replace("{{{INDEX}}}", this.items.length).replace("{{{NAME}}}","").replace("{{{BONUS}}}","").replace("{{{DAMAGE}}}","").replace("{{{BUTTON}}}", this.options.removeBtnMarkup), newItem = $(markup).appendTo(this.list), editableOpts = $.extend({}, this.options.editableSettings), self = this; editableOpts.callback = function(value, settings) { self.onUpdateItem($(this), value); } newItem.find("span.attack-name").editable(this.editableReturnFunc, $.extend({}, editableOpts, {'placeholder':'Click to edit name'})); newItem.find("span.attack-bonus").editable(this.editableReturnFunc, $.extend({}, editableOpts, {'placeholder':'bonus'})); newItem.find("span.attack-damage").editable(this.editableReturnFunc, $.extend({}, editableOpts, {'placeholder':'damage'})); newItem.find("button.removebtn").click(function() { self.onRemoveItem($(this)); }); if (this.items.length === 0) { this.list.children("li.header").show(); } }, renderList: function() { this.list.find("li").not(".header").remove(); var attack = null, markup = "", totalMarkup = "", len = this.items.length, self = this; if (len > 0) { for (var i=0; i<len; i++) { attack = this.items[i]; markup = this.options.itemMarkup.replace("{{{INDEX}}}", i).replace("{{{NAME}}}", attack.name); markup = markup.replace("{{{BONUS}}}", attack.bonus).replace("{{{DAMAGE}}}", attack.damage); if (this.options.isEditMode) { markup = markup.replace("{{{BUTTON}}}", this.options.removeBtnMarkup); } else { markup = markup.replace("{{{BUTTON}}}", ""); } totalMarkup += markup; } myItems = $(totalMarkup).appendTo(this.list); if (this.options.isEditMode) { myItems.find("button.removebtn").click(function() { self.onRemoveItem($(this)); }); var editableopts = $.extend({}, this.options.editableSettings); editableopts.callback = function(value, settings) { self.onUpdateItem($(this), value); } myItems.find("span.attack-name").editable(this.editableReturnFunc, editableopts); myItems.find("span.attack-bonus").editable(this.editableReturnFunc, editableopts); myItems.find("span.attack-damage").editable(this.editableReturnFunc, editableopts); } } else if (len === 0 && this.options.numPlaceholders > 0 && this.options.isEditMode) { for (var n=0; n<this.options.numPlaceholders; n++) { this.onAddItem(); this.items[n] = null; } this._updateListIndices(); } else if (len === 0) { this.list.children("li.header").hide(); } }, onUpdateItem: function(item, value) { var index = parseInt(item.parent().parent().attr("data-index")), attack = null; if (index > this.items.length || this.items[index] === undefined || this.items[index] === null) { attack = new AttackObj(null); } else { attack = this.items[index]; } if (item.hasClass("attack-bonus")) { attack.bonus = value; } else if (item.hasClass("attack-damage")) { attack.damage = value; } else { attack.name = value; } this.items[index] = attack; this._updateField(); }, onRemoveItem: function(button) { var li = button.parent(), index = parseInt(li.attr("data-index")), isConfirmed = window.confirm(this.options.confirmMessage); if (isConfirmed && index !== null && !isNaN(index)) { // remove list item li.remove(); // remove from array if (index < this.items.length) { this.items.splice(index, 1); this._updateField(); } this._updateListIndices(); // hide header if necessary if (this.items.length === 0) { this.list.children("li.header").hide(); } } }, destroy: function() { }, _updateListIndices: function() { this.list.find("li").not(".header").each(function(index) { this.setAttribute("data-index", index); }); }, _updateField: function() { var list = this.items.filter(function(element) { return (element !== null); }); if (list.length > 0) { var jsonText = JSON.stringify(list); this.field.text(jsonText); } else { this.field.text(""); } } } /* Attack Data Object */ var AttackObj = function(args) { if (args !== null) { this.name = args.name; this.bonus = args.bonus; this.damage = args.damage; } } AttackObj.prototype = { name:'', bonus:'', damage:'' } $.fn.basicRulesAttackList = function(target, options) { return this.each(function() { var plugin = $.data(this, AttackList.prototype.name); if (!plugin) { $.data(this, AttackList.prototype.name, new AttackList(this, target)); } else { if (target == "destroy") { plugin.destroy(); $.removeData(this, AttackList.prototype.name); plugin = null; } else if (target == "renderList") { plugin.renderList(); } } }); } })(jQuery, window); /** * INVENTORY LIST PLUGIN */ (function($, window) { var InventoryList = function(element, options) { this.element = $(element); this.isEditMode = options.isEditMode; this.editableSettings.placeholder = aisleten.characters.jeditablePlaceholder; this.editableSettings.inventoryList = this; this.init(); } InventoryList.prototype = { name: "plugin.unlikelyalliance.InventoryList", options: null, element: null, field: null, addBtn: null, itemMap: null, isEditMode: false, isMobile: false, itemMarkup: '<li class="inventory-item clearfix" data-id="{{{ID}}}">{{{HANDLE}}}<span class="item">{{{NAME}}}</span>{{{BTN}}}</li>', handleMarkup: '<span class="handle"><span class="pictonic icon-unordered-list"></span></span>', removeBtnMarkup: '<button class="btn btn-default removebtn">✕</button>', confirmMessage: 'Remove item {{{NAME}}} from inventory?', lastUpdateEvent: null, lastResizeEvent: null, editableSettings: { submit: "OK", cssclass: 'jeditable_input', placeholder: aisleten.characters.jeditablePlaceholder, inventoryList: null, callback: function(value, settings) { settings.inventoryList.onUpdateItemName($(this), value); } }, init: function() { var self = this; this.field = this.element.find(".dsf_equipment"); this.addBtn = this.element.find("button.addbtn"); this.itemMap = new InventoryItemMap(); this.itemMap.fromJson(this.getFieldData()); if (this.isEditMode) { this.element.find("ul.inventory-list").sortable({ connectWith: ".inventory-list", items: "li.inventory-item", opacity: 0.5, placeholder: "sortable-placeholder", handle: ".handle", stop: function(event, ui) { self.onListStop(this, event, ui); }, receive: function(event, ui) { self.onItemReceived(this, event, ui); }, update: function(event, ui) { self.onItemUpdated(this, event, ui); } }); this.addBtn.on("click", null, {plugin:this}, function(event) { event.data.plugin.onAddItem(); }); $(window).on("resize", null, {plugin:this}, function(event) { event.data.plugin.onResize(); }); this.isMobile = window.matchMedia("(max-width: 649px)").matches; } else { this.addBtn.hide(); } this.render(); }, render: function() { this.element.find("ul.inventory-list").empty(); if (this.itemMap.getItemCount() > 0) { this.itemMap.resortColumns(); var viewColumns = [this.element.find("ul.col-1-list"), this.element.find("ul.col-2-list"), this.element.find("ul.col-3-list")], modelColumns = this.itemMap.getColumns(), len = -1, viewColumn = null, modelColumn = [], item = "", html = null, items = null; for (var i=0; i<3; i++) { viewColumn = viewColumns[i]; modelColumn = modelColumns[i]; len = modelColumn.length; if (len > 0) { html = ""; for (var n=0; n<len; n++) { item = this.renderItem(modelColumn[n]); html += item; } items = $(html).appendTo(viewColumn); if (this.isEditMode) { this.addItemEventListeners(items); this.adjustElementDimensions(items, viewColumn); } } } } }, onAddItem: function() { var item = this.itemMap.createItem(), markup = this.renderItem(item), column = null; viewColumn = null; // decide which column to use if (!this.isMobile) { column = this.itemMap.getShortestColumn(); switch (column) { case 1: viewColumn = this.element.find(".col-1-list"); break; case 2: viewColumn = this.element.find(".col-2-list"); break; case 3: viewColumn = this.element.find(".col-3-list"); break; } } else { // just put everything in the first column column = 1; viewColumn = this.element.find(".col-1-list"); } // add to view var viewItem = $(markup).appendTo(viewColumn); this.addItemEventListeners(viewItem); this.adjustElementDimensions(viewItem, viewColumn); // add to model this.itemMap.addItem(item, column); this.setFieldData(); }, onRemoveItem: function(button) { var li = button.parent("li.inventory-item"), itemId = li.attr("data-id"), item = this.itemMap.getItem(itemId), isConfirmed = true; if (item.name !== null && item.name !== "") { isConfirmed = window.confirm(this.confirmMessage.replace("{{{NAME}}}", item.name.toUpperCase())); } if (isConfirmed) { li.find("button.removebtn").off("click"); li.remove(); this.itemMap.removeItem(item); this.setFieldData(); } }, onItemUpdated: function(list, event, ui) { if (this.lastUpdateEvent === null || this.lastUpdateEvent.item !== ui.item || (event.timeStamp - this.lastUpdateEvent.time) > 20) { this.lastUpdateEvent = {'from':list, 'item':ui.item, 'time':event.timeStamp, 'isTransfer':false}; } }, onItemReceived: function(list, event, ui) { if (this.lastUpdateEvent !== null && ui.item === this.lastUpdateEvent.item && (event.timeStamp - this.lastUpdateEvent.time) < 20) { this.lastUpdateEvent.isTransfer = true; this.lastUpdateEvent.to = list; } }, onListStop: function(list, event, ui) { if (this.lastUpdateEvent !== null && this.lastUpdateEvent.isTransfer && this.lastUpdateEvent.from === list && (event.timeStamp - this.lastUpdateEvent.time) < 20) { this.moveItem($(this.lastUpdateEvent.item), $(this.lastUpdateEvent.from), $(this.lastUpdateEvent.to)); } else if (this.lastUpdateEvent !== null) { this.updateItemIndex($(this.lastUpdateEvent.item), $(this.lastUpdateEvent.from)); } this.lastUpdateEvent = null; }, onResize: function() { if (this.lastResizeEvent === null || ($.now() - this.lastResizeEvent) > 20) { var columns = [this.element.find("ul.col-1-list"), this.element.find("ul.col-2-list"), this.element.find("ul.col-3-list")], column = null, children = null; for (var i=0; i<3; i++) { column = columns[i]; children = column.children("li.inventory-item"); this.adjustElementDimensions(children, column); } this.isMobile = window.matchMedia("(max-width: 649px)"); this.lastResizeEvent = $.now(); } }, onUpdateItemName: function(field, value) { var item = field.parent("li.inventory-item"), column = item.parent("ul.inventory-list"), itemId = item.attr("data-id"), itemObj = this.itemMap.getItem(itemId); if (itemObj !== null) { itemObj.name = value; this.setFieldData(); } this.adjustElementDimensions(item, column); }, moveItem: function(item, oldColumn, newColumn) { var itemId = parseInt(item.attr("data-id")), oldColumnNum = this.getColumnNumber(oldColumn), newColumnNum = this.getColumnNumber(newColumn); if (!isNaN(itemId) && oldColumn != newColumn && oldColumnNum > -1 && newColumnNum > -1) { var itemObj = this.itemMap.getItemFromColumn(itemId, oldColumnNum), newIndex = this.getItemIndexInColumn(item, newColumn); this.itemMap.removeItem(itemObj); itemObj.index = newIndex; this.itemMap.addItem(itemObj, newColumnNum); this.setFieldData(); this.adjustElementDimensions(item, newColumn); } }, updateItemIndex: function(item, column) { var itemId = parseInt(item.attr("data-id")), columnNo = this.getColumnNumber(column), newIndex = this.getItemIndexInColumn(item, column); if (!isNaN(itemId) && itemId > -1 && columnNo > -1 && newIndex > -1) { this.itemMap.changeItemIndex(itemId, columnNo, newIndex); this.setFieldData(); } }, renderItem: function(item) { var itemstr = this.itemMarkup.replace("{{{ID}}}", item.id).replace("{{{NAME}}}", item.name); if (this.isEditMode) { itemstr = itemstr.replace("{{{HANDLE}}}", this.handleMarkup).replace("{{{BTN}}}", this.removeBtnMarkup); } else { itemstr = itemstr.replace("{{{HANDLE}}}", "").replace("{{{BTN}}}", ""); } return itemstr; }, addItemEventListeners: function(item) { item.find("button.removebtn").on("click", null, {plugin:this}, function(event) { event.data.plugin.onRemoveItem($(this)); }); item.find("span.item").editable(this.editableFunc, this.editableSettings); }, adjustElementDimensions: function(item, column) { if (this.isEditMode) { var width = column.innerWidth()-94; item.find("span.item").width(width); var timeout = window.setTimeout(function() { item.each(function() { var height = $(this).height(), itemHeight = $(this).find("span.item").outerHeight(); if (itemHeight < 42) { $(this).find("span.handle").css("height",""); } else if ((height-itemHeight)>20) { $(this).find("span.handle").height(itemHeight+7); } else { $(this).find("span.handle").height(height); } }); }, 25); } }, editableFunc: function(value, settings) { return value; }, /** * gets column number, given the column's element as a jQuery object * @param {jQuery} viewColumn column element as jQuery object * @return {int} column number */ getColumnNumber: function(viewColumn) { if (viewColumn.hasClass("col-1-list")) { return 1; } else if (viewColumn.hasClass("col-2-list")) { return 2; } else if (viewColumn.hasClass("col-3-list")) { return 3; } return -1; }, /** * gets the index of the item element (li) within the given column (ul) element. * @param {jQuery} item item element as jQuery object * @param {jQuery} column column element as jQuery object * @return {int} item index if found, -1 otherwise */ getItemIndexInColumn: function(item, column) { var children = column.children("li"), len = children.length; for (var i=0; i<len; i++) { if (children[i].getAttribute("data-id") === item.attr("data-id")) { return i; } } return -1; }, getFieldData: function() { return this.field.text(); }, setFieldData: function() { var str = this.itemMap.toJson(); this.field.text(str); } } var InventoryItemMap = function() { this.column1 = []; this.column2 = []; this.column3 = []; itemsCreated = -1; } InventoryItemMap.prototype = { column1: null, column2: null, column3: null, itemsCreated: null, fromJson: function(str) { // read from json if (!$.unlikelyalliance.isValUnedited(str)) { var object = JSON.parse(str); if (object.hasOwnProperty("0")) { this.column1 = this.recoverColumn(this.column1, object["0"]); } if (object.hasOwnProperty("1")) { this.column2 = this.recoverColumn(this.column2, object["1"]); } if (object.hasOwnProperty("2")) { this.column3 = this.recoverColumn(this.column3, object["2"]); } this.itemsCreated = this.getHighestId(); } }, toJson: function() { return JSON.stringify({'0':this.column1, '1':this.column2, '2':this.column3}); }, getItemCount: function() { return this.column1.length + this.column2.length + this.column3.length; }, getColumns: function() { return [this.column1, this.column2, this.column3]; }, getShortestColumn: function() { var minlen = Math.min(this.column1.length, this.column2.length, this.column3.length); if (minlen === this.column1.length) { return 1; } else if (minlen === this.column2.length) { return 2; } else if (minlen === this.column3.length) { return 3; } return -1; }, resortColumns: function() { this.column1.sort(this.indexSort); this.column2.sort(this.indexSort); this.column3.sort(this.indexSort); }, createItem: function() { var item = new InventoryItem(); this.itemsCreated++; item.id = this.itemsCreated; return item; }, getItem: function(id) { var itemId = parseInt(id), item = null; item = this._getItemFromColumn(itemId, this.column1); if (item === null) { item = this._getItemFromColumn(itemId, this.column2); if (item === null) { item = this._getItemFromColumn(itemId, this.column3); } } return item; }, getItemFromColumn: function(id, columnNo) { var col = this.getColumnByNum(columnNo); if (col !== null) { return this._getItemFromColumn(id, col); } return null; }, _getItemFromColumn: function(id, column) { var len = column.length; for (var i=0; i<len; i++) { if (column[i].id === id) { return column[i]; } } return null; }, addItem: function(item, columnNo) { var col = this.getColumnByNum(columnNo); if (item.index < 0) { col.push(item); } else { col.splice(item.index, 0, item); } this.updateIndexes(col); }, removeItem: function(item) { if (this.column1.indexOf(item) > -1) { this.column1.splice(item.index, 1); this.updateIndexes(this.column1); } else if (this.column2.indexOf(item) > -1) { this.column2.splice(item.index, 1); this.updateIndexes(this.column2); } else if (this.column3.indexOf(item) > -1) { this.column3.splice(item.index, 1); this.updateIndexes(this.column3); } }, changeItemIndex: function(id, columnNo, newIndex) { var column = this.getColumnByNum(columnNo), item = this._getItemFromColumn(id, column); if (item !== null && item.index !== newIndex) { column.splice(item.index, 1); item.index = newIndex; column.splice(newIndex, 0, item); this.updateIndexes(column); } }, recoverColumn: function(column, json) { if (typeof json === "object") { for (var key in json) { column.push(json[key]); } column.sort(this.indexSort); } else if (typeof json === "array") { column = json; } return column; }, updateIndexes: function(column) { var len = column.length; for (var i=0; i<len; i++) { column[i].index = i; } }, getColumnByNum: function(columnNo) { switch (columnNo) { case 1: return this.column1; break; case 2: return this.column2; break; case 3: return this.column3; break; } return null; }, getHighestId: function() { var cols = this.getColumns(), col = null, len = -1, highestId = -1; for (var i=0; i<3; i++) { col = cols[i]; len = col.length; for (var n=0; n<len; n++) { if (col[n].id > highestId) { highestId = col[n].id; } } } return highestId; }, indexSort: function(a, b) { if (a.index > b.index) { return 1; } else if (b.index > a.index) { return -1; } return 0; } } var InventoryItem = function() { } InventoryItem.prototype = { id:-1, name:"", index:-1 } $.fn.basicRulesInventory = function(target, options) { return this.each(function() { var plugin = $.data(this, InventoryList.prototype.name); if (!plugin) { $.data(this, InventoryList.prototype.name, new InventoryList(this, target)); } else { if (target == "destroy") { plugin.destroy(); $.removeData(this, InventoryList.prototype.name); plugin = null; } } }); } })(jQuery, window); /** * UNLIKELY ALLIANCE MAIN SINGLETON */ (function($) { var unlikelyalliance= function() {} unlikelyalliance.prototype = { abilities: ["str","dex","con","int","wis","cha"], containerId: null, slug: null, isEditMode: false, init: function() { // note: this gets called AFTER onDataPreLoad and onDataPostLoad! if (this.isEditMode) { this.makeEditables(); } else { // at least fill in the values so that they don't look weird $(".ds_unlikelyalliance .mdash-editable").each(function() { if ($(this).text() === "") { $(this).text("––"); } }); } }, onDataPreLoad: function(args) { if (aisleten.characters) { aisleten.characters.jeditableSubmit = "OK"; aisleten.characters.jeditablePlaceholder = "click to edit"; } this.containerId = args.containerId; this.slug = args.slug; this.isEditMode = args.isEditable; }, onDataPostLoad: function(args) { this.updateAllAbilityModifiers(); $("button.toggle").not(".ds_unlikelyalliance .use-spellcasting-toggle button.toggle").basicRulesToggleButton({ 'isEditMode': this.isEditMode }); $("div.addlist-container").basicRulesEditableList({ 'isEditMode': this.isEditMode }); $("div.attacks-list-container").basicRulesAttackList({ 'isEditMode': this.isEditMode }); $("div.inventory").basicRulesInventory({ 'isEditMode': this.isEditMode, }); // get biography if (!this.isEditMode && dynamic_sheet_attrs && dynamic_sheet_attrs.hasOwnProperty("bio") && dynamic_sheet_attrs.hasOwnProperty("bio") !== "") { $(".ds_unlikelyalliance .dst_bio").html(dynamic_sheet_attrs["bio"]); } else { $(".ds_unlikelyalliance .biography").hide(); } // get image if (!this.isEditMode && dynamic_sheet_attrs && dynamic_sheet_attrs.hasOwnProperty("avatar_image") && dynamic_sheet_attrs["avatar_image"].indexOf("\"/images/icons/game_character_96x96.png\"") === -1) { $(".ds_unlikelyalliance .dst_avatar_image").html(dynamic_sheet_attrs["avatar_image"]); } else { $(".ds_unlikelyalliance .basicinfo-2").hide(); } // show instructions in edit mode if (this.isEditMode) { $(".ds_unlikelyalliance .instructions").show(); } this.initSpellcastingPage(); }, onDataChange: function(fieldName, fieldValue) { for (var i=0; i<6; i++) { if (this.abilities[i] === fieldName) { this.updateAbilityModifier(this.abilities[i], fieldValue); return; } } }, onPreSave: function() { var self = this; $(".ds_unlikelyalliance .dsf").not(".checkbox").not(".readonly").each(function() { var val = $(this).text(); if (self.isValUnedited(val)) { $(this).text(""); } }); }, initSpellcastingPage: function() { var isSpellcaster = $(".ds_unlikelyalliance .dsf_use_spellcasting input").val(); if (this.isEditMode || isSpellcaster == 1) { $(".ds_unlikelyalliance .spellcasting").show(); $(".ds_unlikelyalliance .use-spellcasting-toggle button.toggle").basicRulesToggleButton({ 'isEditMode': this.isEditMode, 'changeButtonText': true, 'textTrue': 'Yes', 'textFalse': 'No' }); } else { $(".ds_unlikelyalliance .spellcasting").hide(); } }, makeEditables: function() { var self = this; var editableFunc = function(value, settings) { return value; } var editableOpts = { 'submit': aisleten.characters.jeditableSubmit, 'cssclass': 'jeditable_input', 'placeholder':"––", 'callback': function(value, settings) { // let's just cut to the chase var fieldName = aisleten.characters.findDsfClass($(this)); self.onDataChange(fieldName, value); } } $(".ds_unlikelyalliance .mdash-editable").each(function() { $(this).removeClass("readonly"); $(this).editable(editableFunc, editableOpts); }); }, updateAllAbilityModifiers: function() { var statSelector = "", statVal = "", modSelector = ""; for (var i=0; i<6; i++) { statSelector = ".dsf_" + this.abilities[i]; statVal = $(statSelector).text(); this.updateAbilityModifier(this.abilities[i], statVal); } }, updateAbilityModifier: function(stat, newValue) { var val = parseInt(newValue); if (val && !isNaN(val)) { var mod = Math.floor((val-5)/1.0), modStr = "", modSelector = "." + stat + "_mod", saveSelector = ".dsf_" + stat + "_save", saveVal = $(saveSelector).text(), skillColumnSelector = "." + stat + "_skills .stat > span.dsf", skillVal = ""; // update modifier if (mod > 0) { modStr = "+" + mod; } else { modStr = mod + ""; } $(modSelector).text(modStr); // update save value if (this.isValUnedited(saveVal)) { // if save hasn't been set yet $(saveSelector).text(mod); } // update skills $(skillColumnSelector).each(function() { skillVal = $(this).text(); if ($.unlikelyalliance.isValUnedited(skillVal)) { $(this).text(mod); } }); } }, isValUnedited: function(val) { return (val === null || val === "" || val === "––" || val === aisleten.characters.jeditablePlaceholder); } } $.unlikelyalliance = new unlikelyalliance(); })(jQuery); function unlikelyalliance_dataChange(options) { $.unlikelyalliance.onDataChange(options['fieldName'], options['fieldValue']); } function unlikelyalliance_dataPreLoad(options) { $.unlikelyalliance.onDataPreLoad(options); } function unlikelyalliance_dataPostLoad(options) { $.unlikelyalliance.onDataPostLoad(options); } function unlikelyalliance_dataPreSave(options) { $.unlikelyalliance.onPreSave(); } /** * DOCUMENT READY FUNCTION */ $(document).ready(function() { var timeout = window.setTimeout(function() { $.unlikelyalliance.init(); }, 100); });
Submit Notes
This was created for a private RP that uses a modified version of D&D 5e's system. The code is a modified version of the Basic D&D 5e DST by jon_stout which was changed to suit the needs of the modified system.
Back