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
daggerheart Hope and Fear CS
Author:
desfriday
Slug:
daggerheart_hope_fear
Type:
GameCharacter
System:
Daggerheart
DST Source Code
HTML Template
<!-- Daggerheart: Hope & Fear | slug: daggerheart_hope_fear --> <div class="ds_daggerheart_hope_fear"> <!-- HEADER --> <div class="dh-header"> <div class="dh-title-block"> <div class="dh-template-name">Daggerheart: Hope & Fear</div> <h1><span class="dsf dsf_name dst_character_name_link"></span></h1> <div class="dh-meta-sub"> <span>Player: <span class="dsf dsf_player dst_player_link"></span></span> | <span>Campaign: <span class="dsf dsf_campaign dst_campaign_link"></span></span> | <span>Author: <span class="dsf dsf_dst_author dst_dst_author_link"></span></span> </div> </div> <div class="dh-avatar-container"> <span class="dsf dsf_avatar_image avatar_image"></span> </div> </div> <div class="dh-sheet-columns"> <div class="dh-col-main"> <!-- IDENTITY BAR --> <div class="dh-section dh-identity-bar"> <div class="dh-identity-fields"> <div class="dh-field"> <label>CLASS</label> <select class="dh-class-select-input" data-dsf="dsf_class"> <option value="">-- Select Class --</option> <option value="assassin">Assassin</option> <option value="bard">Bard</option> <option value="brawler">Brawler</option> <option value="druid">Druid</option> <option value="guardian">Guardian</option> <option value="ranger">Ranger</option> <option value="rogue">Rogue</option> <option value="seraph">Seraph</option> <option value="sorcerer">Sorcerer</option> <option value="warlock">Warlock</option> <option value="warrior">Warrior</option> <option value="witch">Witch</option> <option value="wizard">Wizard</option> </select> <span class="dsf dsf_class dh-hidden-dsf"></span> </div> <div class="dh-field"> <label>SUBCLASS</label> <select class="dh-subclass-select-input" data-dsf="dsf_subclass"> <option value="">-- Select Subclass --</option> </select> <span class="dsf dsf_subclass dh-hidden-dsf"></span> </div> <div class="dh-field"> <label>HERITAGE</label> <select class="dh-heritage-select-input" data-dsf="dsf_heritage"> <option value="">-- Select Heritage --</option> <option value="hybrid">Hybrid</option> <option value="aetheris">Aetheris</option> <option value="clank">Clank</option> <option value="drakona">Drakona</option> <option value="dwarf">Dwarf</option> <option value="earthkin">Earthkin</option> <option value="elf">Elf</option> <option value="emberkin">Emberkin</option> <option value="faerie">Faerie</option> <option value="faun">Faun</option> <option value="firbolg">Firbolg</option> <option value="fungril">Fungril</option> <option value="galapa">Galapa</option> <option value="giant">Giant</option> <option value="gnome">Gnome</option> <option value="goblin">Goblin</option> <option value="halfling">Halfling</option> <option value="human">Human</option> <option value="infernis">Infernis</option> <option value="katari">Katari</option> <option value="orc">Orc</option> <option value="ribbet">Ribbet</option> <option value="simiah">Simiah</option> <option value="skykin">Skykin</option> <option value="tidekin">Tidekin</option> </select> <span class="dsf dsf_heritage dh-hidden-dsf"></span> </div> <div class="dh-field"> <label>COMMUNITY</label> <select class="dh-community-select-input" data-dsf="dsf_community"> <option value="">-- Select Community --</option> <option value="duneborne">Duneborne</option> <option value="freeborne">Freeborne</option> <option value="frostborne">Frostborne</option> <option value="hearthborne">Hearthborne</option> <option value="highborne">Highborne</option> <option value="loreborne">Loreborne</option> <option value="orderborne">Orderborne</option> <option value="reborne">Reborne</option> <option value="ridgeborne">Ridgeborne</option> <option value="seaborne">Seaborne</option> <option value="slyborne">Slyborne</option> <option value="underborne">Underborne</option> <option value="wanderborne">Wanderborne</option> <option value="warborne">Warborne</option> <option value="wildborne">Wildborne</option> </select> <span class="dsf dsf_community dh-hidden-dsf"></span> </div> <div class="dh-field"><label>PRONOUNS</label><div class="dh-field-val"><span class="dsf dsf_pronouns"></span></div></div> </div> <!-- LEVEL, EVASION, ARMOR SCORE, PROFICIENCY --> <div class="dh-grid-4 dh-mt-10"> <div class="dh-trait-card"> <div class="dh-trait-title">LEVEL</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_level"></span></div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">EVASION</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_evasion"></span></div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">ARMOR SCORE</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_armor_score"></span></div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">PROFICIENCY</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_proficiency"></span></div> </div> </div> <div class="dh-origin-features dh-mt-10"> <div class="dh-heritage-features dh-is-hidden"> <div class="dh-group-title">HERITAGE FEATURES</div> <div class="dh-hybrid-trait-picks dh-is-hidden"> <div class="dh-field"> <label>FIRST TRAIT</label> <select class="dh-hybrid-trait-1-input" data-dsf="dsf_hybrid_trait_1"> <option value="">-- Select Trait --</option> </select> <span class="dsf dsf_hybrid_trait_1 dh-hidden-dsf"></span> </div> <div class="dh-field"> <label>SECOND TRAIT</label> <select class="dh-hybrid-trait-2-input" data-dsf="dsf_hybrid_trait_2"> <option value="">-- Select Trait --</option> </select> <span class="dsf dsf_hybrid_trait_2 dh-hidden-dsf"></span> </div> </div> <div class="dh-heritage-feature-body"></div> </div> <div class="dh-community-features dh-is-hidden"> <div class="dh-group-title">COMMUNITY FEATURE</div> <div class="dh-community-feature-body"></div> </div> </div> </div> <!-- CHARACTER TRAITS --> <div class="dh-section dh-mt-15"> <h2 class="dh-section-title">CHARACTER TRAITS</h2> <div class="dh-grid-6"> <div class="dh-trait-card"> <div class="dh-trait-title">AGILITY</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_trait_agility"></span></div> <div class="dh-trait-sub">Sprint • Leap • Maneuver</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">STRENGTH</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_trait_strength"></span></div> <div class="dh-trait-sub">Smash • Lift • Grapple</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">FINESSE</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_trait_finesse"></span></div> <div class="dh-trait-sub">Control • Hide • Tinker</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">INSTINCT</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_trait_instinct"></span></div> <div class="dh-trait-sub">Perceive • Sense • Navigate</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">PRESENCE</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_trait_presence"></span></div> <div class="dh-trait-sub">Charm • Perform • Deceive</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">KNOWLEDGE</div> <div class="dh-trait-val"><span class="dsfu dsf dsf_trait_knowledge"></span></div> <div class="dh-trait-sub">Recall • Analyze • Comprehend</div> </div> </div> </div> <!-- DAMAGE & HEALTH --> <div class="dh-section dh-mt-15"> <h2 class="dh-section-title">DAMAGE & HEALTH</h2> <div class="dh-damage-chart-container dh-mb-15"> <div class="dh-chart-subtitle">Add your current level to your damage thresholds.</div> <div class="dh-threshold-flow"> <div class="dh-thresh-box"> <div class="dh-thresh-head">MINOR DAMAGE</div> <div class="dh-thresh-sub">Mark 1 HP</div> </div> <div class="dh-thresh-input-wrap"> <span class="dsfu dsf dsf_threshold_minor dh-mini-input"></span> </div> <div class="dh-thresh-box"> <div class="dh-thresh-head">MAJOR DAMAGE</div> <div class="dh-thresh-sub">Mark 2 HP</div> </div> <div class="dh-thresh-input-wrap"> <span class="dsfu dsf dsf_threshold_major dh-mini-input"></span> </div> <div class="dh-thresh-box"> <div class="dh-thresh-head">SEVERE DAMAGE</div> <div class="dh-thresh-sub">Mark 3 HP</div> </div> </div> </div> <div class="dh-grid-4"> <div class="dh-trait-card"> <div class="dh-trait-title">HIT POINTS (HP)</div> <div class="dh-trait-val"> <span class="dsfu dsf dsf_hp_current dh-mini-input"></span> / <span class="dsfu dsf dsf_hp_max dh-mini-input"></span> </div> <div class="dh-trait-sub">Current / Max HP</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">STRESS</div> <div class="dh-trait-val"> <span class="dsfu dsf dsf_stress_current dh-mini-input"></span> / <span class="dsfu dsf dsf_stress_max dh-mini-input"></span> </div> <div class="dh-trait-sub">Current / Max Stress</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">HOPE</div> <div class="dh-trait-val"> <span class="dsfu dsf dsf_hope_current dh-mini-input"></span> / <span class="dsfu dsf dsf_hope_max dh-mini-input"></span> </div> <div class="dh-trait-sub">Spend Hope for Experiences</div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">ARMOR</div> <div class="dh-trait-val"> <span class="dsfu dsf dsf_armor_active_current dh-mini-input"></span> / <span class="dsfu dsf dsf_armor_active_max dh-mini-input"></span> </div> <div class="dh-trait-sub">Current / Armor Score</div> </div> </div> </div> <!-- EXPERIENCES --> <div class="dh-section dh-mt-15"> <h2 class="dh-section-title">CHARACTER EXPERIENCES</h2> <div class="dh-box"> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_exp1_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_exp1_name"></span></div> </div> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_exp2_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_exp2_name"></span></div> </div> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_exp3_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_exp3_name"></span></div> </div> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_exp4_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_exp4_name"></span></div> </div> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_exp5_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_exp5_name"></span></div> </div> </div> </div> <!-- CLASS & SUBCLASS FEATURES --> <div class="dh-section dh-mt-15"> <div class="dh-features-split"> <div class="dh-features-col"> <h2 class="dh-section-title">CLASS FEATURES</h2> <p class="dh-class-features-empty dh-rule-text">Select a class to show its features.</p> <div class="dh-class-feature-panel" data-class="assassin"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">MARKED FOR DEATH</div> <p class="dh-feature-text">On a successful weapon attack, mark a Stress to make the target Marked for Death. Attacks you make against that target gain +1d4 damage per tier. You can only have one adversary Marked for Death at a time. The GM can spend Fear equal to your Proficiency to remove it; otherwise it ends when you rest or the target is defeated.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">GET IN & GET OUT</div> <p class="dh-feature-text">Spend a Hope to ask the GM for either a quick or inconspicuous way into or out of a building or structure you can see. The next roll you make that capitalizes on this information has advantage.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">GRIM RESOLVE</div> <p class="dh-feature-text">Spend 3 Hope to clear 2 Stress.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="bard"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">RALLY</div> <p class="dh-feature-text">Once per session, describe how you rally the party and give yourself and each ally a Rally Die (d6 at level 1, d8 at level 5). A PC can spend their Rally Die to add the result to an action, reaction, or damage roll, or to clear that much Stress. Clear unspent Rally Dice at the end of the session.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">MAKE A SCENE</div> <p class="dh-feature-text">Spend 3 Hope to temporarily Distract a target within Close range, giving them a −2 penalty to their Difficulty.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="brawler"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">I AM THE WEAPON</div> <p class="dh-feature-text">While you don't have any equipped weapons: gain a +1 bonus to Evasion, and your unarmed strikes are a Melee weapon that use the trait of your choice and deal d8+d6 phy damage using your Proficiency.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">COMBO STRIKES</div> <p class="dh-feature-text">After a Melee damage roll but before dealing that damage, mark a Stress to start a combo strike. Roll your Combo Die, then keep rolling while each new roll is equal to or greater than the previous. Total all rolled values and add that amount to the weapon's damage. Combo Die starts as a d4; once per tier you may use an advancement option to increase it.</p> <div class="dh-inline-stat"> <label>COMBO DIE</label> <span class="dsfu dsf dsf_combo_die dh-mini-input"></span> </div> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">STAGGERING STRIKE</div> <p class="dh-feature-text">Spend 3 Hope when you succeed on an attack to temporarily Stagger your target and force them to mark a Stress. While Staggered, they have disadvantage on attack rolls.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="druid"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">BEASTFORM</div> <p class="dh-feature-text">Mark a Stress to magically transform into a creature of your tier or lower from the Beastform list. You can drop out at any time. While transformed, you can't use weapons or cast spells from domain cards, but other features still work. You gain the Beastform's features, add their Evasion bonus, and use their specified trait for attacks. If you mark your last Hit Point, you drop out of this form.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">WILDTOUCH</div> <p class="dh-feature-text">You can perform harmless, subtle effects that involve nature—such as causing a flower to rapidly grow, summoning a slight gust of wind, or starting a campfire—at will.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">EVOLUTION</div> <p class="dh-feature-text">Spend 3 Hope to transform into Beastform without marking a Stress. When you do, choose one trait to raise by +1 until you drop out of that Beastform.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="guardian"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">UNSTOPPABLE</div> <p class="dh-feature-text">Once per long rest, become Unstoppable and place your Unstoppable Die here (d4 at level 1, d6 at level 5), starting at 1. After you deal 1 or more HP, increase the die by one. When it would exceed its max or the scene ends, drop out of Unstoppable. While Unstoppable: reduce physical damage by one threshold, add the die's current value to damage, and you can't be Restrained or Vulnerable.</p> <div class="dh-inline-stat"> <label>UNSTOPPABLE DIE</label> <span class="dsfu dsf dsf_unstoppable_die dh-mini-input"></span> </div> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">FRONTLINE TANK</div> <p class="dh-feature-text">Spend 3 Hope to clear 2 Armor Slots.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="ranger"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">RANGER'S FOCUS</div> <p class="dh-feature-text">Spend a Hope and make an attack against a target. On a success, deal your attack's normal damage and temporarily make them your Focus. Until this ends or you Focus a different creature: you know precisely what direction they are in; when you deal damage to them they must mark a Stress; when you fail an attack against them, you can end Ranger's Focus to reroll your Duality Dice.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">HOLD THEM OFF</div> <p class="dh-feature-text">Spend 3 Hope when you succeed on an attack with a weapon to use that same roll against two additional adversaries within range of the attack.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="rogue"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">CLOAKED</div> <p class="dh-feature-text">Any time you would be Hidden, you are instead Cloaked. In addition to Hidden's benefits, while Cloaked you remain unseen if you are stationary when an adversary moves to where they would normally see you. After you make an attack or end a move within line of sight of an adversary, you are no longer Cloaked.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">SNEAK ATTACK</div> <p class="dh-feature-text">When you succeed on an attack while Cloaked or while an ally is within Melee range of your target, add a number of d6s equal to your tier to your damage roll. Level 1 is Tier 1; levels 2–4 are Tier 2; 5–7 are Tier 3; 8–10 are Tier 4.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">ROGUE'S DODGE</div> <p class="dh-feature-text">Spend 3 Hope to gain a +2 bonus to your Evasion until the next time an attack succeeds against you. Otherwise, this bonus lasts until your next rest.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="seraph"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">PRAYER DICE</div> <p class="dh-feature-text">At the beginning of each session, roll a number of d4s equal to your subclass's Spellcast trait. You can spend any number of Prayer Dice to aid yourself or an ally within Far range: use a spent die's value to reduce incoming damage, add to a roll after it is made, or gain Hope equal to the result. Clear unspent Prayer Dice at the end of the session.</p> <div class="dh-field-line dh-mt-6"> <label>PRAYER DICE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_prayer_dice"></span></div> </div> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">LIFE SUPPORT</div> <p class="dh-feature-text">Spend 3 Hope to clear a Hit Point on an ally within Close range.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="sorcerer"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">ARCANE SENSE</div> <p class="dh-feature-text">You can sense the presence of magical people and objects within Close range.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">MINOR ILLUSION</div> <p class="dh-feature-text">Make a Spellcast Roll (10). On a success, you create a minor visual illusion no larger than yourself within Close range. This illusion is convincing to anyone at Close range or farther.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">CHANNEL RAW POWER</div> <p class="dh-feature-text">Once per long rest, place a domain card from your loadout into your vault and either gain Hope equal to the card's level, or enhance a damaging spell with a bonus to the damage roll equal to twice the card's level.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">VOLATILE MAGIC</div> <p class="dh-feature-text">Spend 3 Hope to reroll any number of your damage dice on an attack that deals magic damage.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="warlock"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">WARLOCK PATRON</div> <p class="dh-feature-text">You have committed yourself to a patron in exchange for power. Record their name, then choose their spheres of influence at GM discretion and set those values to +2. Anytime you increase your tier, these spheres gain a permanent +1. Before an action roll that relates to a sphere, spend a Favor to add its value to the roll.</p> <div class="dh-field-line dh-mt-6"> <label>PATRON NAME</label> <div class="dh-field-val"><span class="dsfu dsf dsf_warlock_patron"></span></div> </div> <div class="dh-grid-2 dh-mt-6"> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_warlock_sphere1_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_warlock_sphere1_name"></span></div> </div> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_warlock_sphere2_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_warlock_sphere2_name"></span></div> </div> </div> <div class="dh-inline-stat dh-mt-6"> <label>FAVOR</label> <span class="dsfu dsf dsf_warlock_favor dh-mini-input"></span> <span class="dh-trait-sub">Start with 3. During a rest, spend a downtime move to tithe and gain Favor equal to your Presence. If you forgo this offering, the GM gains a Fear.</span> </div> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">PATRON'S BOON</div> <p class="dh-feature-text">Spend 3 Hope to call out to your patron for help, gaining 1d4 Favor.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="warrior"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">ATTACK OF OPPORTUNITY</div> <p class="dh-feature-text">When an adversary within Melee range attempts to leave that range, make a reaction roll using a trait of your choice against their Difficulty. Choose one effect on a success, or two if you critically succeed: they can't move from where they are; you deal damage equal to your primary weapon's damage; or you move with them.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">COMBAT TRAINING</div> <p class="dh-feature-text">You ignore burden when equipping weapons. When you deal physical damage, you gain a bonus to your damage roll equal to your level.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">NO MERCY</div> <p class="dh-feature-text">Spend 3 Hope to gain a +1 bonus to your attack rolls until your next rest.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="witch"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">HEX</div> <p class="dh-feature-text">When a creature causes you or an ally within Close range to mark any number of Hit Points, mark a Stress to Hex them. Action and damage rolls against a Hexed creature gain a bonus equal to your tier. This lasts until the GM spends Fear equal to your Spellcast trait to remove it, you Hex another creature, or the scene ends.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">COMMUNE</div> <p class="dh-feature-text">Once per long rest, during a moment of calm, commune with an ancestor, deity, nature spirit, or otherworldly being. Ask a question, then roll a number of d6s equal to your Spellcast trait and choose one result: 1–3 you taste, smell, or feel something relevant; 4–5 you hear sounds or see a vision; 6 you psychically experience a scene as if you were there.</p> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">WITCH'S CHARM</div> <p class="dh-feature-text">When you or an ally within Far range rolls a failure on an action roll, spend 3 Hope to change it into a success with Fear instead.</p> </div> </div> </div> <div class="dh-class-feature-panel" data-class="wizard"> <div class="dh-box"> <div class="dh-feature"> <div class="dh-feature-name">PRESTIDIGITATION</div> <p class="dh-feature-text">You can perform harmless, subtle magical effects at will. For example, you can change an object's color, create a smell, light a candle, cause a tiny object to float, illuminate a room, or repair a small object.</p> </div> <div class="dh-feature"> <div class="dh-feature-name">STRANGE PATTERNS</div> <p class="dh-feature-text">Choose a number between 1 and 12. When you roll that number on a Duality Die, gain a Hope or clear a Stress. You can change this number when you take a long rest.</p> <div class="dh-inline-stat"> <label>PATTERN NUMBER</label> <span class="dsfu dsf dsf_wizard_pattern dh-mini-input"></span> </div> </div> <div class="dh-feature dh-feature-hope"> <div class="dh-feature-name">NOT THIS TIME</div> <p class="dh-feature-text">Spend 3 Hope to force an adversary within Far range to reroll an attack or damage roll.</p> </div> </div> </div> </div> <div class="dh-features-col"> <h2 class="dh-section-title">SUBCLASS FEATURES</h2> <p class="dh-subclass-features-empty dh-rule-text">Select a subclass to show its features.</p> <div class="dh-subclass-feature-panel dh-is-hidden"> <div class="dh-box"> <div class="dh-spellcast-line dh-is-hidden"></div> <div class="dh-subclass-feature-body"></div> <div class="dh-subclass-extras"> <div class="dh-inline-stat dh-subclass-extra dh-extra-focus dh-is-hidden"> <label>FOCUS</label> <span class="dsfu dsf dsf_ma_focus dh-mini-input"></span> <span class="dh-trait-sub">Max 6</span> </div> <div class="dh-inline-stat dh-subclass-extra dh-extra-slayer dh-is-hidden"> <label>SLAYER DICE</label> <span class="dsfu dsf dsf_slayer_dice"></span> </div> <div class="dh-inline-stat dh-subclass-extra dh-extra-poison dh-is-hidden"> <label>POISON TOKENS</label> <span class="dsfu dsf dsf_poison_tokens dh-mini-input"></span> </div> <div class="dh-inline-stat dh-subclass-extra dh-extra-moon dh-is-hidden"> <label>LUNAR PHASE</label> <span class="dsfu dsf dsf_moon_phase dh-mini-input"></span> </div> <div class="dh-inline-stat dh-subclass-extra dh-extra-hedge dh-is-hidden"> <label>TALISMAN TOKENS</label> <span class="dsfu dsf dsf_hedge_tokens dh-mini-input"></span> </div> </div> </div> </div> </div> </div> </div> <!-- DYNAMIC SUBCLASS PANELS --> <div class="dh-section dh-class-dynamic-wrapper dh-mt-15"> <!-- RANGER BEASTBOUND PANEL --> <div class="dh-subclass-panel dh-panel-beastbound"> <h2 class="dh-section-title">RANGER COMPANION (BEASTBOUND ONLY)</h2> <div class="dh-box"> <p class="dh-rule-text">Make a Spellcast Roll to connect with your companion and command them. Spend a Hope to add an applicable Companion Experience. When you command them to attack, they gain benefits that would normally only apply to you (such as Ranger's Focus). On a success, their damage roll uses your Proficiency and their damage die. When they would take damage, they mark a Stress instead.</p> <div class="dh-companion-top-row"> <div class="dh-field-line dh-companion-name-wrap"> <label>COMPANION NAME</label> <div class="dh-field-val"> <span class="dsfu dsf dsf_companion_name"></span> </div> </div> <div class="dh-companion-stats-grid"> <div class="dh-trait-card"> <div class="dh-trait-title">EVASION</div> <div class="dh-trait-val"> <span class="dsfu dsf dsf_companion_evasion dh-mini-input"></span> </div> </div> <div class="dh-trait-card"> <div class="dh-trait-title">STRESS</div> <div class="dh-trait-val"> <span class="dsfu dsf dsf_companion_stress_current dh-mini-input"></span> / <span class="dsfu dsf dsf_companion_stress_max dh-mini-input"></span> </div> </div> </div> </div> <div class="dh-mt-15"> <div class="dh-group-title">COMPANION EXPERIENCES (+2 BASE)</div> <div class="dh-exp-line dh-mt-6"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_comp_exp1_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_comp_exp1_name"></span></div> </div> <div class="dh-exp-line"> <div class="dh-exp-mod"><span class="dsfu dsf dsf_comp_exp2_mod"></span></div> <div class="dh-exp-text"><span class="dsfu dsf dsf_comp_exp2_name"></span></div> </div> </div> <div class="dh-mt-15"> <div class="dh-group-title">ATTACK & DAMAGE</div> <div class="dh-grid-2 dh-mt-6"> <div class="dh-field-line"> <label>STANDARD ATTACK RANGE</label> <div class="dh-field-val"> <span class="dsfu dsf dsf_companion_attack_range"></span> </div> </div> <div class="dh-field-line"> <label>DAMAGE DIE</label> <div class="dh-field-val"> <span class="dsfu dsf dsf_companion_damage_die"></span> </div> </div> </div> </div> </div> </div> <!-- BRAWLER MARTIAL ARTIST PANEL --> <div class="dh-subclass-panel dh-panel-martial-artist"> <h2 class="dh-section-title">BRAWLER: MARTIAL ARTIST (MARTIAL FORM)</h2> <div class="dh-box"> <p class="dh-rule-text">Spend a Focus to activate or shift into a different stance. It lasts until you mark your last Hit Point, you take Severe damage, the scene ends, or you shift into another martial stance.</p> <!-- TIER 1 STANCES --> <div class="dh-tier-group"> <div class="dh-tier-header">TIER 1 STANCES</div> <div class="dh-stance-grid"> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t1_s1_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t1_s1"> <option value="">-- Select Stance --</option> <option value="Brutal">Brutal: When you roll the maximum value on a damage die, roll an additional damage die</option> <option value="Defensive">Defensive: Attack rolls against you have disadvantage unless the adversary marks a Stress</option> <option value="Grappling">Grappling: On a successful attack, spend a Focus to make the target temporarily Restrained</option> <option value="Steady">Steady: -1 Evasion. Roll an additional damage die and drop the lowest</option> <option value="Precise">Precise: +1 bonus to attack rolls</option> <option value="Quick">Quick: When making an attack roll, spend a Focus to include an additional target within range</option> </select> <span class="dsf dsf_ma_t1_s1 dh-hidden-dsf"></span> </div> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t1_s2_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t1_s2"> <option value="">-- Select Stance --</option> <option value="Brutal">Brutal: When you roll the maximum value on a damage die, roll an additional damage die</option> <option value="Defensive">Defensive: Attack rolls against you have disadvantage unless the adversary marks a Stress</option> <option value="Grappling">Grappling: On a successful attack, spend a Focus to make the target temporarily Restrained</option> <option value="Steady">Steady: -1 Evasion. Roll an additional damage die and drop the lowest</option> <option value="Precise">Precise: +1 bonus to attack rolls</option> <option value="Quick">Quick: When making an attack roll, spend a Focus to include an additional target within range</option> </select> <span class="dsf dsf_ma_t1_s2 dh-hidden-dsf"></span> </div> </div> </div> <!-- TIER 2 STANCES --> <div class="dh-tier-group dh-mt-10"> <div class="dh-tier-header">TIER 2 STANCES</div> <div class="dh-stance-grid"> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t2_s1_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t2_s1"> <option value="">-- Select Stance --</option> <option value="Deadly">Deadly: When you deal Severe damage, the target marks an additional HP</option> <option value="Hindering">Hindering: On a successful attack, spend a Focus to make the target temporarily Hindered (-2 to attacks)</option> <option value="Invigorating">Invigorating: On a successful attack, roll a d4; on a 4, gain a Focus</option> <option value="Immovable">Immovable: +2 damage thresholds and you cannot be moved unwillingly</option> <option value="Nimble">Nimble: Spend Focus up to your Tier; roll d6s equal to 1 + Focus spent; matching values negate the attack's damage</option> <option value="Otherworldly">Otherworldly: Choose whether to deal Physical or Magic damage</option> <option value="Scary">Scary: Successful attacks also force the target to mark a Stress</option> </select> <span class="dsf dsf_ma_t2_s1 dh-hidden-dsf"></span> </div> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t2_s2_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t2_s2"> <option value="">-- Select Stance --</option> <option value="Deadly">Deadly: When you deal Severe damage, the target marks an additional HP</option> <option value="Hindering">Hindering: On a successful attack, spend a Focus to make the target temporarily Hindered (-2 to attacks)</option> <option value="Invigorating">Invigorating: On a successful attack, roll a d4; on a 4, gain a Focus</option> <option value="Immovable">Immovable: +2 damage thresholds and you cannot be moved unwillingly</option> <option value="Nimble">Nimble: Spend Focus up to your Tier; roll d6s equal to 1 + Focus spent; matching values negate the attack's damage</option> <option value="Otherworldly">Otherworldly: Choose whether to deal Physical or Magic damage</option> <option value="Scary">Scary: Successful attacks also force the target to mark a Stress</option> </select> <span class="dsf dsf_ma_t2_s2 dh-hidden-dsf"></span> </div> </div> </div> <!-- TIER 3 STANCES --> <div class="dh-tier-group dh-mt-10"> <div class="dh-tier-header">TIER 3 STANCES</div> <div class="dh-stance-grid"> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t3_s1_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t3_s1"> <option value="">-- Select Stance --</option> <option value="Deflecting">Deflecting: Spend 2 Focus for an Evasion bonus equal to your Armor Score against an attack</option> <option value="Devastating">Devastating: Spend a Focus before your attack roll to use d20s as your damage dice</option> <option value="Dueling">Dueling: Gain advantage on attack rolls when no other adversaries or allies are in Very Close range of you or your target</option> <option value="Compounding">Compounding: Max Combo Die roll increases the size of subsequent combo dice (max d12s)</option> <option value="Inexorable">Inexorable: Attacks against you have disadvantage if more than two adversaries are within Melee of you</option> <option value="Favored">Favored: Add the trait of your choice to your damage roll</option> <option value="Sheltering">Sheltering: When you mark an Armor Slot, it reduces damage for you and all allies within Melee who took the same damage</option> </select> <span class="dsf dsf_ma_t3_s1 dh-hidden-dsf"></span> </div> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t3_s2_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t3_s2"> <option value="">-- Select Stance --</option> <option value="Deflecting">Deflecting: Spend 2 Focus for an Evasion bonus equal to your Armor Score against an attack</option> <option value="Devastating">Devastating: Spend a Focus before your attack roll to use d20s as your damage dice</option> <option value="Dueling">Dueling: Gain advantage on attack rolls when no other adversaries or allies are in Very Close range of you or your target</option> <option value="Compounding">Compounding: Max Combo Die roll increases the size of subsequent combo dice (max d12s)</option> <option value="Inexorable">Inexorable: Attacks against you have disadvantage if more than two adversaries are within Melee of you</option> <option value="Favored">Favored: Add the trait of your choice to your damage roll</option> <option value="Sheltering">Sheltering: When you mark an Armor Slot, it reduces damage for you and all allies within Melee who took the same damage</option> </select> <span class="dsf dsf_ma_t3_s2 dh-hidden-dsf"></span> </div> </div> </div> <!-- TIER 4 STANCES --> <div class="dh-tier-group dh-mt-10"> <div class="dh-tier-header">TIER 4 STANCES</div> <div class="dh-stance-grid"> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t4_s1_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t4_s1"> <option value="">-- Select Stance --</option> <option value="Crushing">Crushing: When you roll a 1 on a damage die, treat it as the highest value instead</option> <option value="Infuriating">Infuriating: On a successful attack, the target becomes Furious (Vulnerable and -2 to attacks until they succeed on an attack against you)</option> <option value="Sweeping">Sweeping: Your attack targets all adversaries within Very Close range; deal half damage to those you succeed against</option> <option value="Discerning">Discerning: Choose the target after making your attack roll; the GM tells you who the attack would succeed against</option> </select> <span class="dsf dsf_ma_t4_s1 dh-hidden-dsf"></span> </div> <div class="dh-stance-row"> <label class="dh-active-toggle"><span class="dsfu dsf dsf_ma_t4_s2_active checkbox"></span> ACTIVE</label> <select class="dh-stance-select" data-dsf="dsf_ma_t4_s2"> <option value="">-- Select Stance --</option> <option value="Crushing">Crushing: When you roll a 1 on a damage die, treat it as the highest value instead</option> <option value="Infuriating">Infuriating: On a successful attack, the target becomes Furious (Vulnerable and -2 to attacks until they succeed on an attack against you)</option> <option value="Sweeping">Sweeping: Your attack targets all adversaries within Very Close range; deal half damage to those you succeed against</option> <option value="Discerning">Discerning: Choose the target after making your attack roll; the GM tells you who the attack would succeed against</option> </select> <span class="dsf dsf_ma_t4_s2 dh-hidden-dsf"></span> </div> </div> </div> </div> </div> </div> <div class="dh-section dh-mt-15"> <h2 class="dh-section-title">BIO</h2> <div class="dh-bio-body"> <span class="dsfu dsf dsf_bio"></span> </div> </div> </div> <div class="dh-col-gear"> <!-- WEAPONS & ARMOR SECTION --> <div class="dh-section"> <h2 class="dh-section-title">ACTIVE WEAPONS & ARMOR</h2> <div class="dh-equipment-group"> <div class="dh-group-title">PRIMARY WEAPON</div> <div class="dh-row-3col"> <div class="dh-field-line"> <label>NAME</label> <div class="dh-field-val"><span class="dsfu dsf dsf_primary_weapon_name"></span></div> </div> <div class="dh-field-line"> <label>TRAIT & RANGE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_primary_weapon_range"></span></div> </div> <div class="dh-field-line"> <label>DAMAGE DICE & TYPE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_primary_weapon_damage"></span></div> </div> </div> <div class="dh-field-line dh-mt-6"> <label>FEATURE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_primary_weapon_feature"></span></div> </div> </div> <div class="dh-equipment-group dh-mt-15"> <div class="dh-group-title">SECONDARY WEAPON</div> <div class="dh-row-3col"> <div class="dh-field-line"> <label>NAME</label> <div class="dh-field-val"><span class="dsfu dsf dsf_secondary_weapon_name"></span></div> </div> <div class="dh-field-line"> <label>TRAIT & RANGE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_secondary_weapon_range"></span></div> </div> <div class="dh-field-line"> <label>DAMAGE DICE & TYPE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_secondary_weapon_damage"></span></div> </div> </div> <div class="dh-field-line dh-mt-6"> <label>FEATURE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_secondary_weapon_feature"></span></div> </div> </div> <div class="dh-equipment-group dh-mt-15"> <div class="dh-group-title">ACTIVE ARMOR</div> <div class="dh-row-3col"> <div class="dh-field-line"> <label>NAME</label> <div class="dh-field-val"><span class="dsfu dsf dsf_armor_name"></span></div> </div> <div class="dh-field-line"> <label>BASE THRESHOLDS</label> <div class="dh-field-val"><span class="dsfu dsf dsf_armor_thresholds"></span></div> </div> <div class="dh-field-line"> <label>BASE SCORE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_armor_score_val"></span></div> </div> </div> <div class="dh-field-line dh-mt-6"> <label>FEATURE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_armor_feature"></span></div> </div> </div> </div> <!-- INVENTORY SECTION --> <div class="dh-section dh-mt-20"> <h2 class="dh-section-title">INVENTORY</h2> <div class="dh-gold-row dh-mb-10"> <div class="dh-gold-cell"> <label>HANDFULS</label> <span class="dsfu dsf dsf_gold_handfuls dh-mini-input"></span> </div> <div class="dh-gold-cell"> <label>BAGS</label> <span class="dsfu dsf dsf_gold_bags dh-mini-input"></span> </div> <div class="dh-gold-cell"> <label>CHEST</label> <span class="dsfu dsf dsf_gold_chest dh-mini-input"></span> </div> </div> <div class="dh-inventory-lines"> <div class="dh-inv-line"><span class="dsfu dsf dsf_inv_line_1"></span></div> <div class="dh-inv-line"><span class="dsfu dsf dsf_inv_line_2"></span></div> <div class="dh-inv-line"><span class="dsfu dsf dsf_inv_line_3"></span></div> <div class="dh-inv-line"><span class="dsfu dsf dsf_inv_line_4"></span></div> <div class="dh-inv-line"><span class="dsfu dsf dsf_inv_line_5"></span></div> </div> <div class="dh-equipment-group dh-mt-15"> <div class="dh-inv-weapon-header"> <span class="dh-group-title">INVENTORY WEAPON</span> <div class="dh-weapon-options"> <label><span class="dsfu dsf dsf_inv_w1_is_primary checkbox"></span> PRIMARY</label> <label><span class="dsfu dsf dsf_inv_w1_is_secondary checkbox"></span> SECONDARY</label> </div> </div> <div class="dh-row-3col"> <div class="dh-field-line"> <label>NAME</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w1_name"></span></div> </div> <div class="dh-field-line"> <label>TRAIT & RANGE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w1_range"></span></div> </div> <div class="dh-field-line"> <label>DAMAGE DICE & TYPE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w1_damage"></span></div> </div> </div> <div class="dh-field-line dh-mt-6"> <label>FEATURE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w1_feature"></span></div> </div> </div> <div class="dh-equipment-group dh-mt-15"> <div class="dh-inv-weapon-header"> <span class="dh-group-title">INVENTORY WEAPON</span> <div class="dh-weapon-options"> <label><span class="dsfu dsf dsf_inv_w2_is_primary checkbox"></span> PRIMARY</label> <label><span class="dsfu dsf dsf_inv_w2_is_secondary checkbox"></span> SECONDARY</label> </div> </div> <div class="dh-row-3col"> <div class="dh-field-line"> <label>NAME</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w2_name"></span></div> </div> <div class="dh-field-line"> <label>TRAIT & RANGE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w2_range"></span></div> </div> <div class="dh-field-line"> <label>DAMAGE DICE & TYPE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w2_damage"></span></div> </div> </div> <div class="dh-field-line dh-mt-6"> <label>FEATURE</label> <div class="dh-field-val"><span class="dsfu dsf dsf_inv_w2_feature"></span></div> </div> </div> </div> </div> </div> </div>
CSS
/* Daggerheart: Hope & Fear | slug: daggerheart_hope_fear */ /* RESET & CONTAINER */ div.ds_daggerheart_hope_fear { font-family: 'Georgia', 'Times New Roman', serif; color: #2c2523; background-color: #faf6f0; padding: 12px; border: 2px solid #3d2f2b; box-sizing: border-box; max-width: 1240px; margin: 0 auto; } div.ds_daggerheart_hope_fear .dh-sheet-columns { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.85fr); gap: 14px; align-items: start; } div.ds_daggerheart_hope_fear .dh-col-main, div.ds_daggerheart_hope_fear .dh-col-gear { min-width: 0; } div.ds_daggerheart_hope_fear .dh-col-gear .dh-row-3col { grid-template-columns: 1fr; gap: 4px; } div.ds_daggerheart_hope_fear .dh-col-gear .dh-field-line { min-height: 32px; } div.ds_daggerheart_hope_fear .dh-col-gear .dh-section-title { font-size: 1.05em; margin-bottom: 8px; } div.ds_daggerheart_hope_fear .dh-col-gear .dh-mt-20 { margin-top: 12px; } div.ds_daggerheart_hope_fear .dh-col-gear .dh-mt-15 { margin-top: 10px; } div.ds_daggerheart_hope_fear *, div.ds_daggerheart_hope_fear *::before, div.ds_daggerheart_hope_fear *::after { box-sizing: border-box; } div.ds_daggerheart_hope_fear .dh-hidden-dsf { display: none !important; } div.ds_daggerheart_hope_fear .dh-is-hidden { display: none !important; } div.ds_daggerheart_hope_fear span.dsf:not(.checkbox):not(.dh-hidden-dsf):not(.dsf_avatar_image) { min-width: 1.5em; min-height: 1.35em; max-width: 100%; } div.ds_daggerheart_hope_fear span.dsfu:not(.checkbox):not(.dh-hidden-dsf) { cursor: pointer; } /* In-place DST editor: stay inside the field box; one value at a time. */ div.ds_daggerheart_hope_fear .dsf form { display: block; position: relative; margin: 0; padding: 0; width: 100%; max-width: 100%; } div.ds_daggerheart_hope_fear .dsf input[type="text"], div.ds_daggerheart_hope_fear .dsf input[type="number"], div.ds_daggerheart_hope_fear .dsf input:not([type]), div.ds_daggerheart_hope_fear .dsf textarea { display: inline-block; width: 100%; max-width: 100%; min-width: 0; min-height: 22px; box-sizing: border-box; font-family: inherit; font-size: inherit; color: #1a1a1a; background: #ffffff; border: 1px solid #7a6b5d; outline: none; padding: 2px 6px; margin: 0; } div.ds_daggerheart_hope_fear .dh-mini-input form { width: 38px; max-width: 38px; } div.ds_daggerheart_hope_fear .dh-mini-input input[type="text"], div.ds_daggerheart_hope_fear .dh-mini-input input:not([type]) { width: 38px; min-width: 0; max-width: 38px; text-align: center; } div.ds_daggerheart_hope_fear .dsf button, div.ds_daggerheart_hope_fear .dsf input[type="submit"] { position: absolute !important; left: -9999px !important; width: 1px !important; height: 1px !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; opacity: 0 !important; pointer-events: none !important; } /* MINI AND INLINE INPUTS */ div.ds_daggerheart_hope_fear .dh-mini-input { min-width: 2em; text-align: center; font-weight: bold; display: inline-block; } /* HEADER */ div.ds_daggerheart_hope_fear .dh-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #5a1e1e; padding-bottom: 8px; margin-bottom: 15px; } div.ds_daggerheart_hope_fear .dh-title-block h1 { margin: 0; color: #5a1e1e; font-size: 2em; } div.ds_daggerheart_hope_fear .dh-template-name { font-size: 0.68em; font-weight: 800; letter-spacing: 1px; text-transform: uppercase; color: #5a1e1e; margin-bottom: 2px; } div.ds_daggerheart_hope_fear .dh-meta-sub { font-size: 0.85em; color: #555; margin-top: 4px; } /* DROPDOWNS */ div.ds_daggerheart_hope_fear select.dh-class-select-input, div.ds_daggerheart_hope_fear select.dh-subclass-select-input, div.ds_daggerheart_hope_fear select.dh-heritage-select-input, div.ds_daggerheart_hope_fear select.dh-community-select-input, div.ds_daggerheart_hope_fear select.dh-hybrid-trait-1-input, div.ds_daggerheart_hope_fear select.dh-hybrid-trait-2-input, div.ds_daggerheart_hope_fear select.dh-stance-select { width: 100%; padding: 4px; font-size: 0.85em; font-weight: bold; border: 1px solid #7a6b5d; background-color: #fff; outline: none; } div.ds_daggerheart_hope_fear select:disabled { opacity: 1; color: #1a1a1a; background-color: #fff; } div.ds_daggerheart_hope_fear .dh-field { display: flex; flex-direction: column; min-width: 0; } div.ds_daggerheart_hope_fear .dh-field label { font-size: 0.65em; font-weight: 800; color: #4a3e3d; letter-spacing: 0.5px; text-transform: uppercase; margin-bottom: 2px; } /* GRIDS */ div.ds_daggerheart_hope_fear .dh-identity-fields { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; } div.ds_daggerheart_hope_fear .dh-identity-fields .dh-field label { font-size: 0.58em; } div.ds_daggerheart_hope_fear .dh-identity-fields select, div.ds_daggerheart_hope_fear .dh-identity-fields input[type="text"], div.ds_daggerheart_hope_fear .dh-identity-fields span.dsf { font-size: 0.78em !important; font-weight: bold !important; padding: 3px 4px !important; box-sizing: border-box; } div.ds_daggerheart_hope_fear .dh-identity-fields .dh-field-val { min-height: 28px; height: 28px; border: 1px solid #7a6b5d; background: #fff; } div.ds_daggerheart_hope_fear .dh-identity-fields .dh-field-val span.dsf { display: flex; align-items: center; width: 100%; height: 100%; background: transparent; border: none; overflow: hidden; white-space: nowrap; } div.ds_daggerheart_hope_fear .dh-identity-fields .dh-field-val .dsf input[type="text"], div.ds_daggerheart_hope_fear .dh-identity-fields .dh-field-val .dsf input:not([type]) { display: block; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0 4px !important; font-family: inherit !important; font-size: 0.78em !important; font-weight: bold !important; color: #1a1a1a !important; background: transparent !important; border: none !important; } div.ds_daggerheart_hope_fear .dh-grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; } div.ds_daggerheart_hope_fear .dh-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; } div.ds_daggerheart_hope_fear .dh-grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; } div.ds_daggerheart_hope_fear .dh-grid-6 { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; } div.ds_daggerheart_hope_fear .dh-row-3col { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 15px; width: 100%; } /* RANGER COMPANION TOP ROW & BOXES */ div.ds_daggerheart_hope_fear .dh-companion-top-row { display: flex; gap: 15px; align-items: flex-end; } div.ds_daggerheart_hope_fear .dh-companion-name-wrap { flex: 1; } div.ds_daggerheart_hope_fear .dh-companion-stats-grid { display: flex; gap: 10px; width: 260px; } div.ds_daggerheart_hope_fear .dh-companion-stats-grid .dh-trait-card { flex: 1; } /* BRAWLER MARTIAL ARTIST STANCE STYLES */ div.ds_daggerheart_hope_fear .dh-rule-text { font-size: 0.85em; font-style: italic; margin-bottom: 12px; color: #4a3e3d; } div.ds_daggerheart_hope_fear .dh-tier-group { background: #faf4eb; border: 1px solid #d2c4b4; padding: 8px 10px; border-radius: 4px; } div.ds_daggerheart_hope_fear .dh-tier-header { font-size: 0.8em; font-weight: 800; color: #5a1e1e; letter-spacing: 0.5px; margin-bottom: 6px; border-bottom: 1px solid #d2c4b4; padding-bottom: 2px; } div.ds_daggerheart_hope_fear .dh-stance-grid { display: flex; flex-direction: column; gap: 6px; } div.ds_daggerheart_hope_fear .dh-stance-row { display: flex; align-items: center; gap: 10px; } div.ds_daggerheart_hope_fear .dh-active-toggle { display: flex; align-items: center; gap: 4px; font-size: 0.75em; font-weight: 800; color: #2c2523; white-space: nowrap; cursor: pointer; min-width: 75px; } /* BOXED STAT CARDS */ div.ds_daggerheart_hope_fear .dh-trait-card { background: #f0e6d8; border: 1px solid #b8a695; border-radius: 4px; text-align: center; padding: 6px 4px; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 56px; min-width: 0; overflow: hidden; box-sizing: border-box; } div.ds_daggerheart_hope_fear .dh-grid-4 .dh-trait-card { min-height: 72px; } div.ds_daggerheart_hope_fear .dh-grid-6 .dh-trait-card { min-height: 86px; } div.ds_daggerheart_hope_fear .dh-trait-title { font-size: 0.75em; font-weight: bold; color: #4a3429; text-transform: uppercase; } div.ds_daggerheart_hope_fear .dh-trait-val { font-size: 1.2em; font-weight: bold; color: #1a1a1a; margin: 2px 0; width: 100%; display: flex; align-items: center; justify-content: center; min-height: 26px; } div.ds_daggerheart_hope_fear .dh-trait-val span.dsf:not(.dh-mini-input) { text-align: center !important; font-weight: bold !important; font-size: 1em !important; display: block; width: 100%; min-height: 1.2em; background: transparent; border: none; box-sizing: border-box; padding: 0; } div.ds_daggerheart_hope_fear .dh-trait-val .dsf input[type="text"], div.ds_daggerheart_hope_fear .dh-trait-val .dsf input:not([type]) { text-align: center !important; font-weight: bold !important; width: 100%; background: #fff; border: 1px solid #7a6b5d; } div.ds_daggerheart_hope_fear .dh-trait-val span.dh-mini-input { width: 2.4em; max-width: 2.8em; display: inline-block; } div.ds_daggerheart_hope_fear .dh-trait-sub { font-size: 0.65em; color: #6a584c; } /* SECTION HEADERS */ div.ds_daggerheart_hope_fear .dh-section-title { font-size: 1.1em; font-weight: 800; letter-spacing: 0.5px; color: #2c2523; border-bottom: 2px solid #2c2523; margin-top: 0; margin-bottom: 12px; padding-bottom: 3px; text-transform: uppercase; } div.ds_daggerheart_hope_fear .dh-banner-divider { text-align: center; font-weight: 800; font-size: 1em; letter-spacing: 1.5px; color: #2c2523; border-top: 2px solid #6b2424; border-bottom: 2px solid #6b2424; padding: 4px 0; margin: 15px 0 10px 0; text-transform: uppercase; } div.ds_daggerheart_hope_fear .dh-group-title { font-size: 0.85em; font-weight: 800; letter-spacing: 0.5px; color: #2c2523; text-transform: uppercase; margin-bottom: 4px; } div.ds_daggerheart_hope_fear .dh-equipment-group > .dh-group-title, div.ds_daggerheart_hope_fear .dh-inv-weapon-header .dh-group-title { display: inline-block; width: fit-content; max-width: 100%; background: #efe0a8; padding: 1px 6px; text-decoration: none; } div.ds_daggerheart_hope_fear .dh-equipment-group > .dh-group-title { margin-bottom: 6px; } /* UNDERLINED FIELD CONTAINERS */ div.ds_daggerheart_hope_fear .dh-field-line { display: flex; flex-direction: column; justify-content: flex-end; width: 100%; min-height: 40px; } div.ds_daggerheart_hope_fear .dh-field-line label { font-size: 0.65em; font-weight: 800; color: #4a3e3d; letter-spacing: 0.5px; text-transform: uppercase; margin-bottom: 2px; display: block; } div.ds_daggerheart_hope_fear .dh-field-val, div.ds_daggerheart_hope_fear .dh-trait-val, div.ds_daggerheart_hope_fear .dh-exp-text, div.ds_daggerheart_hope_fear .dh-exp-mod, div.ds_daggerheart_hope_fear .dh-inv-line { position: relative; } div.ds_daggerheart_hope_fear .dh-field-val { border-bottom: 1px solid #7a6b5d; min-height: 24px; display: flex; align-items: center; width: 100%; } div.ds_daggerheart_hope_fear .dh-field-val span.dsf, div.ds_daggerheart_hope_fear .dh-exp-text span.dsf, div.ds_daggerheart_hope_fear .dh-inv-line span.dsf { display: block; width: 100%; min-height: 1.2em; background: transparent; border: none; padding: 0; } /* INVENTORY LINES */ div.ds_daggerheart_hope_fear .dh-inventory-lines .dh-inv-line { display: flex; flex-direction: column; margin-bottom: 8px; border-bottom: 1px solid #c5b8ab; min-height: 24px; } /* INVENTORY WEAPON OPTIONS HEADER */ div.ds_daggerheart_hope_fear .dh-inv-weapon-header { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 6px; } div.ds_daggerheart_hope_fear .dh-inv-weapon-header .dh-group-title { margin-bottom: 0; } div.ds_daggerheart_hope_fear .dh-weapon-options { display: flex; flex-shrink: 0; gap: 12px; font-size: 0.7em; font-weight: bold; } div.ds_daggerheart_hope_fear .dh-weapon-options label { display: flex; align-items: center; gap: 4px; cursor: pointer; white-space: nowrap; } div.ds_daggerheart_hope_fear span.dsf.checkbox { display: inline-block; width: 14px; height: 14px; border: 1px solid #2c2523; background: #fff; cursor: pointer; flex-shrink: 0; overflow: hidden; color: transparent; font-size: 0; line-height: 0; vertical-align: middle; box-sizing: border-box; } div.ds_daggerheart_hope_fear span.dsf.checkbox.is-checked { background: #fff; position: relative; } div.ds_daggerheart_hope_fear span.dsf.checkbox.is-checked::after { content: ""; position: absolute; left: 2px; top: 2px; width: 8px; height: 4px; border-left: 2px solid #2c2523; border-bottom: 2px solid #2c2523; transform: rotate(-45deg); } div.ds_daggerheart_hope_fear span.dsf.checkbox.dh-op-checkbox { width: auto; height: auto; border: none; background: transparent; box-shadow: none; overflow: visible; color: inherit; font-size: inherit; } div.ds_daggerheart_hope_fear input[type="checkbox"] { display: inline-block !important; visibility: visible !important; opacity: 1 !important; pointer-events: auto !important; width: 14px !important; height: 14px !important; margin: 0 !important; padding: 0 !important; flex-shrink: 0; accent-color: #2c2523; } /* DAMAGE CHART BANNER */ div.ds_daggerheart_hope_fear .dh-damage-chart-container { text-align: center; } div.ds_daggerheart_hope_fear .dh-chart-subtitle { font-size: 0.8em; font-style: italic; margin-bottom: 6px; } div.ds_daggerheart_hope_fear .dh-threshold-flow { display: flex; align-items: center; justify-content: center; gap: 6px; } div.ds_daggerheart_hope_fear .dh-thresh-box { background-color: #4a4a4a; color: #fff; padding: 8px 12px; border-radius: 4px; min-width: 120px; } div.ds_daggerheart_hope_fear .dh-thresh-head { font-size: 0.8em; font-weight: bold; } div.ds_daggerheart_hope_fear .dh-thresh-sub { font-size: 0.65em; color: #ddd; } div.ds_daggerheart_hope_fear .dh-thresh-input-wrap { border-bottom: 2px solid #4a4a4a; padding: 0 6px; display: flex; align-items: center; justify-content: center; } /* EXPERIENCES & GOLD */ div.ds_daggerheart_hope_fear .dh-exp-line { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } div.ds_daggerheart_hope_fear .dh-exp-mod { width: 45px; min-width: 45px; height: 32px; background-color: #f0e6d8; border: 1px solid #b8a695; border-radius: 3px; display: flex; align-items: center; justify-content: center; } div.ds_daggerheart_hope_fear .dh-exp-mod input[type="text"], div.ds_daggerheart_hope_fear .dh-exp-mod span.dsf { text-align: center !important; font-weight: bold !important; display: block; width: 100%; min-height: 1.2em; } div.ds_daggerheart_hope_fear .dh-exp-text { flex-grow: 1; border-bottom: 1px solid #b8a695; min-height: 24px; display: flex; align-items: center; } div.ds_daggerheart_hope_fear .dh-gold-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; background: #eae1d2; padding: 8px; border: 1px solid #c4b6a5; border-radius: 4px; } div.ds_daggerheart_hope_fear .dh-gold-cell { display: flex; flex-direction: column; align-items: center; min-width: 0; } div.ds_daggerheart_hope_fear .dh-gold-cell label { font-size: 0.65em; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; color: #4a3e3d; margin-bottom: 2px; } div.ds_daggerheart_hope_fear .dh-gold-cell .dh-mini-input { width: 42px !important; } div.ds_daggerheart_hope_fear .dh-box { background: #ffffff; border: 1px solid #d8ccbe; padding: 12px; border-radius: 4px; } div.ds_daggerheart_hope_fear .dh-subclass-panel { display: none; } div.ds_daggerheart_hope_fear .dh-subclass-panel.is-visible { display: block; } div.ds_daggerheart_hope_fear .dh-class-feature-panel { display: none; } div.ds_daggerheart_hope_fear .dh-class-feature-panel.is-visible { display: block; } div.ds_daggerheart_hope_fear .dh-features-split { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; } div.ds_daggerheart_hope_fear .dh-features-col { min-width: 0; } div.ds_daggerheart_hope_fear .dh-features-col .dh-section-title { margin-bottom: 8px; } div.ds_daggerheart_hope_fear .dh-features-split .dh-feature-text, div.ds_daggerheart_hope_fear .dh-features-split .dh-feature-list { font-size: 0.78em; line-height: 1.32; } div.ds_daggerheart_hope_fear .dh-spellcast-line { font-size: 0.72em; font-weight: 800; letter-spacing: 0.6px; color: #5a1e1e; text-transform: uppercase; background: #efe0a8; display: inline-block; padding: 2px 7px; margin-bottom: 8px; } div.ds_daggerheart_hope_fear .dh-subclass-tier { margin-bottom: 10px; } div.ds_daggerheart_hope_fear .dh-subclass-tier:last-child { margin-bottom: 0; } div.ds_daggerheart_hope_fear .dh-feature-list { margin: 4px 0 0 16px; padding: 0; } div.ds_daggerheart_hope_fear .dh-feature-list li { margin-bottom: 3px; } div.ds_daggerheart_hope_fear .dh-subclass-extras { margin-top: 8px; } div.ds_daggerheart_hope_fear .dh-subclass-extra.dh-is-hidden { display: none !important; } div.ds_daggerheart_hope_fear .dh-feature { margin-bottom: 12px; } div.ds_daggerheart_hope_fear .dh-feature:last-child { margin-bottom: 0; } div.ds_daggerheart_hope_fear .dh-feature-name { font-size: 0.8em; font-weight: 800; letter-spacing: 0.5px; color: #5a1e1e; text-transform: uppercase; margin-bottom: 3px; } div.ds_daggerheart_hope_fear .dh-feature-text { margin: 0; font-size: 0.85em; line-height: 1.35; color: #3a322f; } div.ds_daggerheart_hope_fear .dh-feature-hope { background: #faf4eb; border: 1px solid #d2c4b4; border-radius: 4px; padding: 8px 10px; } div.ds_daggerheart_hope_fear .dh-inline-stat { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 8px; } div.ds_daggerheart_hope_fear .dh-inline-stat label { font-size: 0.65em; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; color: #4a3e3d; } div.ds_daggerheart_hope_fear .dh-origin-features { display: grid; grid-template-columns: 1fr; gap: 8px; } div.ds_daggerheart_hope_fear .dh-origin-features.dh-origin-split { grid-template-columns: 1fr 1fr; } div.ds_daggerheart_hope_fear .dh-heritage-features, div.ds_daggerheart_hope_fear .dh-community-features { background: #ffffff; border: 1px solid #d8ccbe; padding: 10px 12px; border-radius: 4px; } div.ds_daggerheart_hope_fear .dh-hybrid-trait-picks { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; } @media (max-width: 980px) { div.ds_daggerheart_hope_fear .dh-hybrid-trait-picks { grid-template-columns: 1fr; } } div.ds_daggerheart_hope_fear .dh-bio-body { min-height: 4em; border: 1px solid #d8ccbe; background: #ffffff; padding: 8px 10px; border-radius: 4px; } div.ds_daggerheart_hope_fear .dh-bio-body .dsf_bio { display: block; min-height: 3em; } div.ds_daggerheart_hope_fear .dh-mt-6 { margin-top: 6px; } div.ds_daggerheart_hope_fear .dh-mt-10 { margin-top: 10px; } div.ds_daggerheart_hope_fear .dh-mt-15 { margin-top: 15px; } div.ds_daggerheart_hope_fear .dh-mt-20 { margin-top: 20px; } div.ds_daggerheart_hope_fear .dh-mb-10 { margin-bottom: 10px; } div.ds_daggerheart_hope_fear .dh-mb-15 { margin-bottom: 15px; } @media (max-width: 980px) { div.ds_daggerheart_hope_fear .dh-sheet-columns { grid-template-columns: 1fr; } div.ds_daggerheart_hope_fear .dh-identity-fields { grid-template-columns: repeat(3, minmax(0, 1fr)); } div.ds_daggerheart_hope_fear .dh-origin-features.dh-origin-split { grid-template-columns: 1fr; } div.ds_daggerheart_hope_fear .dh-col-gear .dh-row-3col { grid-template-columns: 1.2fr 1fr 1fr; gap: 10px; } div.ds_daggerheart_hope_fear .dh-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } div.ds_daggerheart_hope_fear .dh-features-split { grid-template-columns: 1fr; } }
JavaScript
(function () { /* Daggerheart: Hope & Fear | slug: daggerheart_hope_fear */ function daggerheart_hope_fear_patch_jeditable() { var jq = window.jQuery; var original; var patched; if (!jq || !jq.fn || typeof jq.fn.editable !== "function") return false; if (jq.fn.editable.defaults) { jq.fn.editable.defaults.submit = false; jq.fn.editable.defaults.onblur = "submit"; } if (jq.fn.editable.daggerheart_hope_fear_patched) return true; original = jq.fn.editable; patched = function (target, options) { var settings; if (typeof target === "string" && (target === "disable" || target === "enable" || target === "destroy")) { return original.apply(this, arguments); } if (typeof options === "object" && options !== null) { settings = jq.extend({}, options); settings.submit = false; settings.onblur = "submit"; return original.call(this, target, settings); } if (typeof target === "function") { settings = { submit: false, onblur: "submit" }; return original.call(this, target, settings); } if (typeof target === "object" && target !== null && !jq.isFunction(target)) { settings = jq.extend({}, target); settings.submit = false; settings.onblur = "submit"; return original.call(this, settings); } return original.apply(this, arguments); }; jq.extend(patched, original); patched.daggerheart_hope_fear_patched = true; jq.fn.editable = patched; if (patched.defaults) { patched.defaults.submit = false; patched.defaults.onblur = "submit"; } return true; } daggerheart_hope_fear_patch_jeditable(); setTimeout(daggerheart_hope_fear_patch_jeditable, 0); setTimeout(daggerheart_hope_fear_patch_jeditable, 200); setTimeout(daggerheart_hope_fear_patch_jeditable, 800); var SUBCLASSES = { assassin: [ { value: "executioners-guild", label: "Executioner's Guild" }, { value: "poisoners-guild", label: "Poisoner's Guild" } ], bard: [ { value: "troubadour", label: "Troubadour" }, { value: "wordsmith", label: "Wordsmith" } ], brawler: [ { value: "juggernaut", label: "Juggernaut" }, { value: "martial-artist", label: "Martial Artist" } ], druid: [ { value: "warden-of-the-elements", label: "Warden of the Elements" }, { value: "warden-of-renewal", label: "Warden of Renewal" } ], guardian: [ { value: "stalwart", label: "Stalwart" }, { value: "vengeance", label: "Vengeance" } ], ranger: [ { value: "beastbound", label: "Beastbound" }, { value: "wayfinder", label: "Wayfinder" } ], rogue: [ { value: "nightwalker", label: "Nightwalker" }, { value: "syndicate", label: "Syndicate" } ], seraph: [ { value: "divine-wielder", label: "Divine Wielder" }, { value: "winged-sentinel", label: "Winged Sentinel" } ], sorcerer: [ { value: "elemental-origin", label: "Elemental Origin" }, { value: "primal-origin", label: "Primal Origin" } ], warlock: [ { value: "pact-of-the-endless", label: "Pact of the Endless" }, { value: "pact-of-the-wrathful", label: "Pact of the Wrathful" } ], warrior: [ { value: "call-of-the-brave", label: "Call of the Brave" }, { value: "call-of-the-slayer", label: "Call of the Slayer" } ], witch: [ { value: "hedge", label: "Hedge" }, { value: "moon", label: "Moon" } ], wizard: [ { value: "school-of-knowledge", label: "School of Knowledge" }, { value: "school-of-war", label: "School of War" } ] }; var CLASS_EVASION = { assassin: "12", bard: "10", brawler: "10", druid: "10", guardian: "9", ranger: "12", rogue: "12", seraph: "9", sorcerer: "10", warlock: "11", warrior: "11", witch: "10", wizard: "11" }; var SUBCLASS_FEATURES = { "executioners-guild": { spellcast: "Agility", extras: [], foundation: [ { name: "First Strike", text: "The first time in a scene you succeed on an attack, you deal double damage." }, { name: "Ambush", text: "Your Marked for Death feature uses d6s instead of d4s." } ], specialization: [ { name: "Death Strike", text: "When you deal Severe damage to a creature, you can mark a Stress to force them to mark an additional Hit Point." }, { name: "Scorpion's Poise", text: "You gain a +2 bonus to your Evasion against attacks made by a creature you've Marked for Death." } ], mastery: [ { name: "True Strike", text: "Once per long rest when you fail an attack, you can spend a Hope to make it a success instead." }, { name: "Backstab", text: "Your Marked for Death feature uses d8s instead of d6s." } ] }, "poisoners-guild": { spellcast: "Knowledge", extras: ["poison"], foundation: [ { name: "Toxic Concoctions", text: "Mark a Stress to place 1d4+1 tokens on this card. When you make a successful weapon attack, you can spend a token to afflict the target with a poison. When you take a long rest, clear all unspent tokens. You know these poisons:", items: ["Ghost Petal: The target becomes temporarily Vulnerable.", "Grave Spore: The target must also mark a Stress.", "Leech Weed: You deal an extra 1d6 damage on this attack."] } ], specialization: [ { name: "Poison Compendium", text: "You also know these poisons:", items: ["Midnight Vine: The target has disadvantage on attack rolls until it marks a Stress to clear this condition.", "Gorgon Root: The target becomes temporarily Restrained."] }, { name: "Twin Fang", text: "When you afflict a target Marked for Death with a poison you know, you can spend an additional token to also inflict the effect of a second poison you know." } ], mastery: [ { name: "Venomancer", text: "You also know these poisons:", items: ["Blight Seed: The target gains a −3 penalty to their damage thresholds until the end of the scene. This effect can't stack.", "Fear Leaf: You deal extra damage equal to the result of your Fear Die on this attack.", "Corpse Thorn: The target gains disadvantage on reaction rolls until the end of the scene."] }, { name: "Adder's Blessing", text: "You are immune to poisons and other toxins." } ] }, troubadour: { spellcast: "Presence", extras: [], foundation: [ { name: "Gifted Performer", text: "Describe how you perform for others. You can play each song once per long rest:", items: ["Relaxing Song: You and all allies within Close range clear a Hit Point.", "Epic Song: Make a target within Close range temporarily Vulnerable.", "Heartbreaking Song: You and all allies within Close range gain a Hope."] } ], specialization: [ { name: "Maestro", text: "Your rallying songs steel the courage of those who listen. When you give a Rally Die to an ally, they can gain a Hope or clear a Stress." } ], mastery: [ { name: "Virtuoso", text: "You can perform each of your Gifted Performer songs twice instead of once per long rest." } ] }, wordsmith: { spellcast: "Presence", extras: [], foundation: [ { name: "Rousing Speech", text: "Once per long rest, you can give a heartfelt, inspiring speech. All allies within Far range clear 2 Stress." }, { name: "Heart of a Poet", text: "After you make an action roll to impress, persuade, or offend someone, you can spend a Hope to add a d4 to the roll." } ], specialization: [ { name: "Eloquent", text: "Once per session, when you encourage an ally, you can do one of the following:", items: ["Allow them to find a mundane object or tool they need.", "Help an Ally without spending Hope.", "Give them an additional downtime move during their next rest."] } ], mastery: [ { name: "Epic Poetry", text: "Your Rally Die increases to a d10. Additionally, when you Help an Ally, you can narrate the moment as if you were writing the tale of their heroism. When you do, roll a d10 as your advantage die." } ] }, juggernaut: { spellcast: "", extras: [], foundation: [ { name: "Rugged", text: "Gain a permanent +3 bonus to your Severe damage threshold." }, { name: "Overwhelm", text: "When you succeed on an attack against a target, you can spend a Hope to throw the target within Close range or to force them to mark a Stress." } ], specialization: [ { name: "Surrounded", text: "When you make an attack with a Melee weapon, you can spend any number of Hope to target an equal number of additional creatures within Melee range." }, { name: "Eye for an Eye", text: "Once per rest when an adversary within Melee range forces you to mark any number of Hit Points, you can mark a Stress to force them to mark the same number of Hit Points." } ], mastery: [ { name: "Pummeljoy", text: "When you critically succeed on a Melee weapon attack, you gain an additional Hope, clear an additional Stress, and gain a +1 bonus to your Proficiency for that attack." }, { name: "Not Done Yet", text: "When you take Severe damage, you can gain a Hope or clear a Stress." } ] }, "martial-artist": { spellcast: "", extras: ["focus"], foundation: [ { name: "Focus", text: "Once per rest during a moment of calm, clear your Focus track, then roll a number of d6s equal to your Instinct and gain Focus equal to the highest result. You can hold a maximum of 6 Focus." }, { name: "Stance Fighter", text: "Take the Martial Stances sheet and choose two martial stances from Tier 1. Each time you level up, choose an additional stance from your tier or lower. Spend a Focus to shift into a known stance until you take Severe damage, mark your last Hit Point, shift into a different stance, or the scene ends." } ], specialization: [ { name: "Keen Defenses", text: "When you're targeted by an attack, you can spend a Focus to gain a bonus to your Evasion equal to your tier against the attack." }, { name: "Focus Cannon", text: "Spend a Focus to make an Instinct Roll against an adversary within Far range. On a success, deal d20+3 magic damage using your Proficiency." } ], mastery: [ { name: "Limit Breaker", text: "Once per rest, you can perform an unbelievable feat of athletic prowess—such as running across water, leaping between distant rooftops, or scaling a building—without needing to roll. When you do, gain a Hope and clear a Stress." }, { name: "Flow State", text: "You can mark a Stress instead of spending a Focus to shift into a different stance. Additionally, you can spend a Focus instead of marking a Stress to start a combo strike." } ] }, "warden-of-the-elements": { spellcast: "Instinct", extras: [], foundation: [ { name: "Elemental Incarnation", text: "Mark a Stress to Channel one of the following elements until you take Severe damage or until your next rest:", items: ["Fire: When an adversary within Melee range deals damage to you, they take 1d10 magic damage.", "Earth: Gain a bonus to your damage thresholds equal to your Proficiency.", "Water: When you deal damage to an adversary within Melee range, all other adversaries within Very Close range must mark a Stress.", "Air: You can hover, gaining advantage on Agility Rolls."] } ], specialization: [ { name: "Elemental Aura", text: "Once per rest while Channeling, you can assume an aura matching your element. It affects targets within Close range until your Channeling ends:", items: ["Fire: When an adversary marks 1 or more Hit Points, they must also mark a Stress.", "Earth: Your allies gain a +1 bonus to Strength.", "Water: When an adversary deals damage to you, you can mark a Stress to move them anywhere within Very Close range of where they are.", "Air: When you or an ally takes damage from an attack beyond Melee range, reduce the damage by 1d8."] } ], mastery: [ { name: "Elemental Dominion", text: "While Channeling, you gain the following benefit:", items: ["Fire: You gain a +1 bonus to your Proficiency for attacks and spells that deal damage.", "Earth: When you would mark Hit Points, roll a d6 per Hit Point marked. For each result of 6, reduce the number of Hit Points you mark by 1.", "Water: When an attack against you succeeds, you can mark a Stress to make the attacker temporarily Vulnerable.", "Air: You gain a +1 bonus to your Evasion and can fly."] } ] }, "warden-of-renewal": { spellcast: "Instinct", extras: [], foundation: [ { name: "Clarity of Nature", text: "Once per long rest, you can create a space of natural serenity within Close range. When you spend a few minutes resting within the space, clear Stress equal to your Instinct, distributed as you choose between you and your allies." }, { name: "Regeneration", text: "Touch a creature and spend 3 Hope. That creature clears 1d4 Hit Points." } ], specialization: [ { name: "Regenerative Reach", text: "You can target creatures within Very Close range with your Regeneration feature." }, { name: "Warden's Protection", text: "Once per long rest, spend 2 Hope to clear 2 Hit Points on 1d4 allies within Close range." } ], mastery: [ { name: "Defender", text: "When you're in Beastform and an ally within Close range marks 2 or more Hit Points, you can mark a Stress to reduce the number of Hit Points they mark by 1." } ] }, stalwart: { spellcast: "", extras: [], foundation: [ { name: "Unwavering", text: "Gain a permanent +1 bonus to your damage thresholds." }, { name: "Iron Will", text: "When you take physical damage, you can mark an additional Armor Slot to reduce the severity." } ], specialization: [ { name: "Unrelenting", text: "Gain a permanent +2 bonus to your damage thresholds." }, { name: "Partners-in-Arms", text: "When an ally within Very Close range takes damage, you can mark an Armor Slot to reduce the severity by one threshold." } ], mastery: [ { name: "Undaunted", text: "Gain a permanent +3 bonus to your damage thresholds." }, { name: "Loyal Protector", text: "When an ally within Close range has 2 or fewer Hit Points and would take damage, you can mark a Stress to sprint to their side and take the damage instead." } ] }, vengeance: { spellcast: "", extras: [], foundation: [ { name: "At Ease", text: "Gain an additional Stress slot." }, { name: "Revenge", text: "When an adversary within Melee range succeeds on an attack against you, you can mark 2 Stress to force the attacker to mark a Hit Point." } ], specialization: [ { name: "Act of Reprisal", text: "When an adversary damages an ally within Melee range, you gain a +1 bonus to your Proficiency for the next successful attack you make against that adversary." } ], mastery: [ { name: "Nemesis", text: "Spend 2 Hope to Prioritize an adversary until your next rest. When you make an attack against your Prioritized adversary, you can swap the results of your Hope and Fear Dice. You can only Prioritize one adversary at a time." } ] }, beastbound: { spellcast: "Agility", extras: [], foundation: [ { name: "Companion", text: "You have an animal companion of your choice (at the GM's discretion). They stay by your side unless you tell them otherwise. Take the Ranger Companion sheet. When you level up your character, choose a level-up option for your companion from that sheet as well." } ], specialization: [ { name: "Expert Training", text: "Choose an additional level-up option for your companion." }, { name: "Battle-Bonded", text: "When an adversary attacks you while they're within your companion's Melee range, you gain a +2 bonus to your Evasion against the attack." } ], mastery: [ { name: "Advanced Training", text: "Choose two additional level-up options for your companion." }, { name: "Loyal Friend", text: "Once per long rest, when the damage from an attack would mark your companion's last Stress or your last Hit Point and you're within Close range of each other, you or your companion can rush to the other's side and take that damage instead." } ] }, wayfinder: { spellcast: "Agility", extras: [], foundation: [ { name: "Ruthless Predator", text: "When you make a damage roll, you can mark a Stress to gain a +1 bonus to your Proficiency. Additionally, when you deal Severe damage to an adversary, they must mark a Stress." }, { name: "Path Forward", text: "When you're traveling to a place you've previously visited or you carry an object that has been at the location before, you can identify the shortest, most direct path to your destination." } ], specialization: [ { name: "Elusive Predator", text: "When your Focus makes an attack against you, you gain a +2 bonus to your Evasion against the attack." } ], mastery: [ { name: "Apex Predator", text: "Before you make an attack roll against your Focus, you can spend a Hope. On a successful attack, you remove a Fear from the GM's Fear pool." } ] }, nightwalker: { spellcast: "Finesse", extras: [], foundation: [ { name: "Shadow Stepper", text: "When you move into an area of darkness or a shadow cast by another creature or object, you can mark a Stress to disappear from where you are and reappear inside another shadow within Far range. When you reappear, you are Cloaked." } ], specialization: [ { name: "Dark Cloud", text: "Make a Spellcast Roll (15). On a success, create a temporary dark cloud that covers any area within Close range. Anyone in this cloud can't see outside of it, and anyone outside of it can't see in. You're considered Cloaked from any adversary for whom the cloud blocks line of sight." }, { name: "Adrenaline", text: "While you're Vulnerable, add your level to your damage rolls." } ], mastery: [ { name: "Fleeting Shadow", text: "Gain a permanent +1 bonus to your Evasion. You can use Shadow Stepper to move within Very Far range." }, { name: "Vanishing Act", text: "Mark a Stress to become Cloaked at any time. When Cloaked from this feature, you automatically clear the Restrained condition if you have it. You remain Cloaked in this way until you roll with Fear or until your next rest." } ] }, syndicate: { spellcast: "Finesse", extras: [], foundation: [ { name: "Well-Connected", text: "When you arrive in a prominent town or environment, you know somebody who calls this place home. Give them a name, note how you think they could be useful, and choose one fact:", items: ["They owe me a favor, but they'll be hard to find.", "They're going to ask for something in exchange.", "They're always in a great deal of trouble.", "We used to be together. It's a long story.", "We didn't part on great terms."] } ], specialization: [ { name: "Contacts Everywhere", text: "Once per session, you can briefly call on a shady contact. Choose one of the following benefits and describe what brought them here:", items: ["They provide 1 handful of gold, a unique tool, or a mundane object that the situation requires.", "On your next action roll, their help provides a +3 bonus to the result of your Hope or Fear Die.", "The next time you deal damage, they snipe from the shadows, adding 2d8 to your damage roll."] } ], mastery: [ { name: "Reliable Backup", text: "You can use Contacts Everywhere three times per session. The following options are added to the list of benefits:", items: ["When you mark 1 or more Hit Points, they can rush out to shield you, reducing the Hit Points marked by 1.", "When you make a Presence Roll in conversation, they back you up. You can roll a d20 as your Hope Die."] } ] }, "divine-wielder": { spellcast: "Strength", extras: [], foundation: [ { name: "Spirit Weapon", text: "When you have an equipped weapon with a range of Melee or Very Close, it can fly from your hand to attack an adversary within Close range and then return to you. You can mark a Stress to target an additional adversary within range with the same attack roll." }, { name: "Sparing Touch", text: "Once per long rest, touch a creature and clear 2 Hit Points or 2 Stress from them." } ], specialization: [ { name: "Devout", text: "When you roll your Prayer Dice, you can roll an additional die and discard the lowest result. Additionally, you can use Sparing Touch twice instead of once per long rest." } ], mastery: [ { name: "Sacred Resonance", text: "When you roll damage for Spirit Weapon, if any of the die results match, double the value of each matching die. For example, if you roll two 5s, they count as two 10s." } ] }, "winged-sentinel": { spellcast: "Strength", extras: [], foundation: [ { name: "Wings of Light", text: "You can fly. While flying, you can do the following:", items: ["Mark a Stress to pick up and carry another willing creature approximately your size or smaller.", "Spend a Hope to deal an extra 1d8 damage on a successful attack."] } ], specialization: [ { name: "Ethereal Visage", text: "While flying, you have advantage on Presence Rolls. When you succeed with Hope on a Presence Roll, you can remove a Fear from the GM's Fear pool instead of gaining Hope." } ], mastery: [ { name: "Ascendant", text: "Gain a permanent +4 bonus to your Severe damage threshold." }, { name: "Power of the Gods", text: "While flying, you deal an extra 1d12 damage instead of 1d8 from Wings of Light." } ] }, "elemental-origin": { spellcast: "Instinct", extras: [], foundation: [ { name: "Elementalist", text: "Choose one of the following elements at character creation: Air, Earth, Fire, Lightning, Water. You can shape this element into harmless effects. Additionally, spend a Hope and describe how your control over this element helps an action roll you're about to make, then either gain a +2 bonus to the roll or a +3 bonus to the roll's damage." } ], specialization: [ { name: "Natural Evasion", text: "When an attack roll against you succeeds, you can mark a Stress and describe how you use your element to defend you. When you do, roll a d6 and add its result to your Evasion against the attack." } ], mastery: [ { name: "Transcendence", text: "Once per long rest, you can transform into a physical manifestation of your element. Describe your transformation and choose two of the following benefits until your next rest:", items: ["+4 bonus to your Severe threshold", "+1 bonus to a character trait of your choice", "+1 bonus to your Proficiency", "+2 bonus to your Evasion"] } ] }, "primal-origin": { spellcast: "Instinct", extras: [], foundation: [ { name: "Manipulate Magic", text: "After you cast a spell or make an attack using a weapon that deals magic damage, you can mark a Stress to do one of the following:", items: ["Extend the spell or attack's reach by one range", "Gain a +2 bonus to the action roll's result", "Double a damage die of your choice", "Hit an additional target within range"] } ], specialization: [ { name: "Enchanted Aid", text: "When you Help an Ally with a Spellcast Roll, you can roll a d8 as your advantage die. Once per long rest, after an ally has made a Spellcast Roll with your help, you can swap the results of their Duality Dice." } ], mastery: [ { name: "Arcane Charge", text: "When you take magic damage, you become Charged. Alternatively, you can spend 2 Hope to become Charged. When you successfully make an attack that deals magic damage while Charged, you can clear your Charge to either gain a +10 bonus to the damage roll or gain a +3 bonus to the Difficulty of a reaction roll the spell causes the target to make. You stop being Charged at your next long rest." } ] }, "pact-of-the-endless": { spellcast: "Presence", extras: [], foundation: [ { name: "Patron's Mantle", text: "Spend a Favor to cloak yourself in a terrifying aspect of your Patron until you take Severe damage or the scene ends. While this effect is active, you gain a bonus to your damage thresholds equal to your tier and have advantage on action rolls to intimidate a target." }, { name: "Deathless Embrace", text: "Once per rest, spend any number of Favor to roll an equal number of Patron Dice. For each result of 4 or higher, clear a Hit Point." } ], specialization: [ { name: "Harrowing Invocation", text: "When an adversary targets you or an ally within Very Close range with an attack, you can spend a Favor to give them disadvantage on the roll. If the adversary fails the roll, they must also mark a Stress." }, { name: "Damage Sink", text: "Once per rest, you can spend a Favor to halve incoming damage." } ], mastery: [ { name: "Dark Aegis", text: "Once per rest when you would take damage, you can spend a Favor instead of marking Hit Points." }, { name: "Draining Bane", text: "When an adversary targets you or an ally within Very Close range with an attack, you can spend a Favor to Drain them. They must mark a Stress, and you can clear a Stress. While Drained, the target uses a d12 instead of a d20 for attack rolls (including for advantage or disadvantage) until they fail a roll." } ] }, "pact-of-the-wrathful": { spellcast: "Presence", extras: [], foundation: [ { name: "Patron's Fury", text: "Spend a Favor to imbue your attacks with your Patron's power until you deal Severe damage or the scene ends. When you roll damage while this effect is active, you also roll a number of Patron Dice equal to your tier and add their total to the damage dealt." }, { name: "Deadly Vengeance", text: "When you mark any number of Hit Points from an attack, you can spend a Favor to roll an equal number of Patron Dice. For each result of 4 or higher, the attacker marks a Hit Point." } ], specialization: [ { name: "Menacing Reach", text: "Spend a Favor to increase the range of your primary weapon by one step (such as Melee to Very Close) to a maximum of Very Far range. This effect ends when you make a successful attack with that weapon." }, { name: "Diminish My Foes", text: "When you succeed with Hope on an action roll against a target, you can spend any number of Favor to force the target to mark an equal number of Stress." } ], mastery: [ { name: "Fearsome Attack", text: "Spend a Favor to reroll any number of your damage dice. You can continue spending Favor to use this feature on the same damage roll." }, { name: "Otherworldly Ire", text: "Once per rest when you take damage, you can spend any number of Favor to roll that many Patron Dice and target a number of creatures within Close range equal to the highest result. Each target must mark a Hit Point." } ] }, "call-of-the-brave": { spellcast: "", extras: [], foundation: [ { name: "Courage", text: "When you fail a roll with Fear, you gain a Hope." }, { name: "Battle Ritual", text: "Once per long rest, before you attempt something incredibly dangerous or face off against a foe who clearly outmatches you, describe what ritual you perform or preparations you make. When you do, clear 2 Stress and gain 2 Hope." } ], specialization: [ { name: "Rise to the Challenge", text: "While you have 2 or fewer Hit Points unmarked, you can roll a d20 as your Hope Die." } ], mastery: [ { name: "Camaraderie", text: "You can initiate a Tag Team Roll one additional time per session. Additionally, when an ally initiates a Tag Team Roll with you, they only need to spend 2 Hope to do so." } ] }, "call-of-the-slayer": { spellcast: "", extras: ["slayer"], foundation: [ { name: "Slayer", text: "You gain a pool of Slayer Dice. On a roll with Hope, you can place a d6 on this card instead of gaining a Hope, adding the die to the pool. You can store a number of Slayer Dice equal to your Proficiency. When you make an attack or damage roll, you can spend any number of these dice, rolling them and adding their result to the total. At the end of each session, clear unspent Slayer Dice and gain a Hope per die cleared." } ], specialization: [ { name: "Weapon Specialist", text: "When you succeed on an attack, you can spend a Hope to add one of the damage dice from your secondary weapon to the damage roll. Additionally, once per long rest when you roll your Slayer Dice, reroll any 1s." } ], mastery: [ { name: "Martial Preparation", text: "Your party gains access to the Martial Preparation downtime move. During a rest, describe how you instruct and train with your party. You and each ally who chooses this move gain a d6 Slayer Die they can spend to add the result to an attack or damage roll." } ] }, hedge: { spellcast: "Knowledge", extras: ["hedge"], foundation: [ { name: "Herbal Remedies", text: "When you or an ally in the scene clears 1 or more Hit Points or Stress as the result of using a consumable, increase the number cleared by 1." }, { name: "Enchanted Talisman", text: "Once per rest, you can imbue a small item with your protective essence. Spend any number of Hope to place an equal number of tokens on this card. When the person holding the talisman takes damage, spend a token to reduce the number of Hit Points they mark by one. Clear all tokens when you take a rest." } ], specialization: [ { name: "Walk Between Worlds", text: "During a moment of calm, make a Spellcast Roll (13). Once per rest on a success, you can mark a Stress to step beyond the veil of death and converse with any nearby spirits. Place a number of tokens equal to your Spellcast trait on this card and remove one each time a spirit answers a question. When the last token is removed or at the end of the scene, you return to the Mortal Realm in the same spot you left." }, { name: "Vexing Malison", text: "You have advantage on attacks against Hexed creatures." } ], mastery: [ { name: "Circle of Power", text: "Once per rest, mark a circle on the ground outlining a Very Close area around you, and place a number of tokens equal to your Spellcast trait on this card. While within this circle, you and your allies gain a +2 bonus to damage thresholds, attack rolls, and Evasion. Remove a token each time you or an ally within the circle makes an action roll or evades an attack. This lasts until the last token is removed or you exit the circle." } ] }, moon: { spellcast: "Instinct", extras: ["moon"], foundation: [ { name: "Night's Glamour", text: "Make a Spellcast Roll (13) to Glamour yourself in a bewitching facade. While Glamoured, you have advantage on rolls that leverage your illusory appearance. Additionally, adversaries within Close range must mark a Stress to attack you. Unless you mark a Stress to maintain your Glamour, it drops when you mark a Hit Point or deal damage." } ], specialization: [ { name: "Moonbeam", text: "Once per session, you can conjure a column of moonlight that illuminates the area within Close range until the end of the scene. While bathed in this moonlight, you and your allies gain a +1 bonus to Spellcast Rolls and can see through illusions." }, { name: "Ire of Pale Light", text: "When a Hexed creature within Very Far range fails an attack, they must mark a Stress." } ], mastery: [ { name: "Lunar Phases", text: "At the beginning of each session, roll a d6 and place it on this card. You gain the matching effect until the end of the session. Once per rest, you can spend a Hope to increase the value of this die by one. If you increase the value of a 6, it becomes a 1.", items: ["1 New: Spend a Hope to negate Minor damage.", "2–3 Waxing: +2 to your damage rolls.", "4 Full: +3 to your damage thresholds.", "5–6 Waning: +1 to your Evasion."] } ] }, "school-of-knowledge": { spellcast: "Knowledge", extras: [], foundation: [ { name: "Prepared", text: "Take an additional domain card of your level or lower from a domain you have access to." }, { name: "Adept", text: "When you Utilize an Experience, you can mark a Stress instead of spending a Hope. If you do, double your Experience modifier for that roll." } ], specialization: [ { name: "Accomplished", text: "Take an additional domain card of your level or lower from a domain you have access to." }, { name: "Perfect Recall", text: "Once per rest, when you recall a domain card in your vault, you can reduce its Recall Cost by 1." } ], mastery: [ { name: "Brilliant", text: "Take an additional domain card of your level or lower from a domain you have access to." }, { name: "Honed Expertise", text: "When you use an Experience, roll a d6. On a result of 5 or higher, you can use it without spending Hope." } ] }, "school-of-war": { spellcast: "Knowledge", extras: [], foundation: [ { name: "Battlemage", text: "You've focused your studies on becoming an unconquerable force on the battlefield. Gain an additional Hit Point slot." }, { name: "Face Your Fear", text: "When you succeed with Fear on an attack roll, you deal an extra 1d10 magic damage." } ], specialization: [ { name: "Conjure Shield", text: "While you have at least 2 Hope, you add your Proficiency to your Evasion." }, { name: "Fueled by Fear", text: "The extra magic damage from Face Your Fear increases to 2d10." } ], mastery: [ { name: "Thrive in Chaos", text: "When you succeed on an attack, you can mark a Stress after rolling damage to force the target to mark an additional Hit Point." }, { name: "Have No Fear", text: "The extra magic damage from Face Your Fear increases to 3d10." } ] } }; var HERITAGE_FEATURES = { aetheris: [ { name: "Hallowed Aura", text: "Once per long rest, when an ally within Close range rolls with Fear, change it into a roll with Hope instead." }, { name: "Celestial Wings", text: "You have wings that allow you to fly. Once per scene while flying, you can spend a Hope instead of marking an Armor Slot." } ], clank: [ { name: "Purposeful Design", text: "Decide who made you and for what purpose. At character creation, choose one Experience that best aligns with this purpose and gain a permanent +1 bonus to it." }, { name: "Efficient", text: "When you take a short rest, you can choose a long rest move instead of a short rest move." } ], drakona: [ { name: "Scales", text: "When you would take Severe damage, you can mark a Stress to mark 1 fewer Hit Point." }, { name: "Elemental Breath", text: "Choose an element for your breath. Use it against a target or group within Very Close range as an Instinct weapon dealing d8 magic damage using your Proficiency." } ], dwarf: [ { name: "Thick Skin", text: "When you take Minor damage, you can mark 2 Stress instead of marking a Hit Point." }, { name: "Increased Fortitude", text: "Spend 3 Hope to halve incoming physical damage." } ], earthkin: [ { name: "Stoneskin", text: "Gain a permanent +1 bonus to your Armor Score and damage thresholds at character creation." }, { name: "Immovable", text: "While you are touching the ground, you can't be lifted or moved against your will." } ], elf: [ { name: "Quick Reactions", text: "Mark a Stress to gain advantage on a reaction roll." }, { name: "Celestial Trance", text: "During a rest, you can drop into a trance to choose an additional downtime move." } ], emberkin: [ { name: "Fireproof", text: "You are immune to damage from magical or mundane flame." }, { name: "Ignition", text: "Mark a Stress to wreathe your primary weapon in flame until the end of the scene. It gives off bright light, and you gain a 1d6 bonus to damage rolls with that weapon." } ], faerie: [ { name: "Luckbender", text: "Once per session, after you or a willing ally within Close range makes an action roll, spend 3 Hope to reroll the Duality Dice." }, { name: "Wings", text: "You can fly. While flying, mark a Stress after an adversary attacks you to gain a +2 bonus to your Evasion against that attack." } ], faun: [ { name: "Caprine Leap", text: "You can leap anywhere within Close range as though using normal movement." }, { name: "Kick", text: "On a successful Melee attack, mark a Stress to kick off the target, dealing an extra 2d6 damage and knocking back either yourself or the target to Very Close range." } ], firbolg: [ { name: "Charge", text: "When you succeed on an Agility Roll to move from Far or Very Far into Melee with one or more targets, mark a Stress to deal 1d12 physical damage to all targets within Melee range." }, { name: "Unshakable", text: "When you would mark a Stress, roll a d6. On a 6, don't mark it." } ], fungril: [ { name: "Fungril Network", text: "Make an Instinct Roll (12) to speak with others of your ancestry across any distance." }, { name: "Death Connection", text: "While touching a corpse that died recently, mark a Stress to extract one memory related to a specific emotion or sensation." } ], galapa: [ { name: "Shell", text: "Gain a bonus to your damage thresholds equal to your Proficiency." }, { name: "Retract", text: "Mark a Stress to retract into your shell. While in your shell, you have resistance to physical damage, disadvantage on action rolls, and you can't move." } ], giant: [ { name: "Endurance", text: "Gain an additional Hit Point slot at character creation." }, { name: "Reach", text: "Treat any weapon, ability, spell, or feature with Melee range as though it has Very Close range instead." } ], gnome: [ { name: "Nimble Fingers", text: "When you make a Finesse Roll, spend 2 Hope to reroll your Hope Die." }, { name: "Flicker Step", text: "Once per scene, teleport to another point you can see within Far range." } ], goblin: [ { name: "Surefooted", text: "You ignore disadvantage on Agility Rolls." }, { name: "Danger Sense", text: "Once per rest, mark a Stress to force an adversary to reroll an attack against you or an ally within Very Close range." } ], halfling: [ { name: "Luckbringer", text: "At the start of each session, everyone in your party gains a Hope." }, { name: "Internal Compass", text: "When you roll a 1 on your Hope Die, you can reroll it." } ], human: [ { name: "High Stamina", text: "Gain an additional Stress slot at character creation." }, { name: "Adaptability", text: "When you fail a roll that utilized one of your Experiences, mark a Stress to reroll." } ], infernis: [ { name: "Fearless", text: "When you roll with Fear, mark 2 Stress to change it into a roll with Hope instead." }, { name: "Dread Visage", text: "You have advantage on rolls to intimidate hostile creatures." } ], katari: [ { name: "Feline Instincts", text: "When you make an Agility Roll, spend 2 Hope to reroll your Hope Die." }, { name: "Retracting Claws", text: "Make an Agility Roll to scratch a target within Melee range. On a success, they become temporarily Vulnerable." } ], orc: [ { name: "Sturdy", text: "When you have 1 Hit Point remaining, attacks against you have disadvantage." }, { name: "Tusks", text: "On a successful Melee attack, spend a Hope to gore the target, dealing an extra 1d6 damage." } ], ribbet: [ { name: "Amphibious", text: "You can breathe and move naturally underwater." }, { name: "Long Tongue", text: "Grab onto things within Close range. Mark a Stress to use your tongue as a Finesse Close weapon that deals d12 physical damage using your Proficiency." } ], simiah: [ { name: "Natural Climber", text: "You have advantage on Agility Rolls that involve balancing and climbing." }, { name: "Nimble", text: "Gain a permanent +1 bonus to your Evasion at character creation." } ], skykin: [ { name: "Gale Force", text: "Mark a Stress to conjure a gust of wind that carries you or a Very Close ally up to Very Far range. You can always control the speed at which you fall." }, { name: "Eye of the Storm", text: "Spend 2 Hope to grant you or an ally within Melee range a +1 bonus to Evasion until you take Severe damage or you use this feature again." } ], tidekin: [ { name: "Amphibious", text: "You can breathe and move naturally underwater." }, { name: "Lifespring", text: "Once per rest, when you have access to a small amount of water, mark a Stress to clear a Hit Point on yourself or an ally within Very Close range." } ] }; var HERITAGE_LABELS = { aetheris: "Aetheris", clank: "Clank", drakona: "Drakona", dwarf: "Dwarf", earthkin: "Earthkin", elf: "Elf", emberkin: "Emberkin", faerie: "Faerie", faun: "Faun", firbolg: "Firbolg", fungril: "Fungril", galapa: "Galapa", giant: "Giant", gnome: "Gnome", goblin: "Goblin", halfling: "Halfling", human: "Human", infernis: "Infernis", katari: "Katari", orc: "Orc", ribbet: "Ribbet", simiah: "Simiah", skykin: "Skykin", tidekin: "Tidekin" }; var COMMUNITY_FEATURES = { duneborne: { name: "Oasis", text: "During a short rest, you or an ally can reroll a die used for a downtime move and take the higher result." }, freeborne: { name: "Unbound", text: "Once per session, when you make an action roll with Fear, you can change it to a roll with Hope instead." }, frostborne: { name: "Hardy", text: "When you take a rest, you clear a Hit Point." }, hearthborne: { name: "Close-Knit", text: "Once per long rest, you can spend any number of Hope to grant an ally within Far range an equal number of Hope." }, highborne: { name: "Privilege", text: "You have advantage on rolls to consort with nobles, negotiate prices, or leverage your reputation to get what you want." }, loreborne: { name: "Well-Read", text: "You have advantage on rolls that involve the history, culture, or politics of a prominent person or place." }, orderborne: { name: "Dedicated", text: "Record three sayings or values your upbringing instilled in you. Once per rest, when you describe how you're embodying one of these principles through your current action, you can roll a d20 as your Hope Die." }, reborne: { name: "Found Family", text: "Once per rest, you can spend a Hope to use an ally's Experience as if it were your own. When you do so, describe how your time with that ally prepared you for this moment. When you join a new community or rediscover your old one, you can permanently trade this card for that one instead." }, ridgeborne: { name: "Steady", text: "You have advantage on rolls to traverse dangerous cliffs and ledges, navigate harsh environments, and use your survival knowledge." }, seaborne: { name: "Know the Tide", text: "You can sense the ebb and flow of life. When you roll with Fear, place a token on this card. You can hold a number of tokens equal to your level. Before you make an action roll, you can spend any number of tokens to gain a +1 bonus to the roll for each token spent. At the end of each session, clear all unspent tokens." }, slyborne: { name: "Scoundrel", text: "You have advantage on rolls to negotiate with criminals, detect lies, or find a safe place to hide." }, underborne: { name: "Low-Light Living", text: "When you're in an area with low light or heavy shadow, you have advantage on rolls to hide, investigate, or perceive details within that area." }, wanderborne: { name: "Nomadic Pack", text: "Add a Nomadic Pack to your inventory. Once per session, you can spend a Hope to reach into this pack and pull out a mundane item that's useful to your situation. Work with the GM to figure out what item you take out." }, warborne: { name: "Brave Face", text: "Once per session, when any source would cause you to mark a Stress, you can spend a Hope instead." }, wildborne: { name: "Lightfoot", text: "Your movement is naturally silent. You have advantage on rolls to move without being heard." } }; var daggerheart_hope_fear_bound = false; function daggerheart_hope_fear_root() { return document.querySelector("div.ds_daggerheart_hope_fear"); } function daggerheart_hope_fear_root_from(el) { if (!el) return daggerheart_hope_fear_root(); if (el.closest) return el.closest("div.ds_daggerheart_hope_fear") || daggerheart_hope_fear_root(); while (el && el !== document) { if (el.classList && el.classList.contains("ds_daggerheart_hope_fear")) return el; el = el.parentNode; } return daggerheart_hope_fear_root(); } function daggerheart_hope_fear_each_root(fn) { daggerheart_hope_fear_each(document.querySelectorAll("div.ds_daggerheart_hope_fear"), fn); } function daggerheart_hope_fear_each(list, fn) { var i; for (i = 0; i < list.length; i++) { fn(list[i], i); } } function daggerheart_hope_fear_set_hidden(el, hide) { if (!el) return; if (hide) { el.classList.add("dh-is-hidden"); } else { el.classList.remove("dh-is-hidden"); } } function daggerheart_hope_fear_dsf_el(root, name) { return root.querySelector(".dsf." + name); } function daggerheart_hope_fear_dsf_value(root, name) { var el = daggerheart_hope_fear_dsf_el(root, name); if (!el) return ""; var nested = el.querySelector("input, textarea, select"); if (nested) return (nested.value || "").trim(); return (el.textContent || "").trim(); } function daggerheart_hope_fear_set_dsf(root, name, value) { var el = daggerheart_hope_fear_dsf_el(root, name); if (!el) return; var nested = el.querySelector("input, textarea, select"); if (nested) { nested.value = value || ""; } else { el.textContent = value || ""; } } function daggerheart_hope_fear_is_junk_value(text) { var t = String(text || "").replace(/^\s+|\s+$/g, ""); if (!t) return false; if (t.charAt(0) === "<") return true; if (t.indexOf("<input") !== -1 || t.indexOf("<form") !== -1 || t.indexOf("<button") !== -1) return true; if (t.indexOf("</button>") !== -1 || t.indexOf("type=\"submit\"") !== -1) return true; if (t.indexOf("style=") !== -1 && t.indexOf("<") !== -1) return true; if (t.indexOf(">mit") !== -1) return true; return false; } var daggerheart_hope_fear_sanitizing = false; function daggerheart_hope_fear_sanitize_fields(root) { if (!root || daggerheart_hope_fear_sanitizing) return; daggerheart_hope_fear_sanitizing = true; daggerheart_hope_fear_each(root.querySelectorAll("span.dsf"), function (span) { var live; var text; if (span.classList.contains("checkbox")) return; if (span.classList.contains("dsf_avatar_image")) return; live = span.querySelector("input:not([type=submit]), textarea"); if (live) { if (daggerheart_hope_fear_is_junk_value(live.value)) live.value = ""; return; } text = (span.textContent || "").replace(/^\s+|\s+$/g, ""); if (daggerheart_hope_fear_is_junk_value(text)) span.textContent = ""; }); daggerheart_hope_fear_sanitizing = false; } function daggerheart_hope_fear_watch_junk(root) { if (!root || root.daggerheart_hope_fear_junk_watch) return; if (typeof MutationObserver === "undefined") return; root.daggerheart_hope_fear_junk_watch = new MutationObserver(function () { daggerheart_hope_fear_sanitize_fields(root); }); root.daggerheart_hope_fear_junk_watch.observe(root, { childList: true, subtree: true, characterData: true }); } function daggerheart_hope_fear_schedule_sanitize(root) { var delays = [0, 150, 400, 900, 1800]; daggerheart_hope_fear_each(delays, function (ms) { setTimeout(function () { daggerheart_hope_fear_sanitize_fields(root); }, ms); }); } function daggerheart_hope_fear_commit_open_editors(root) { daggerheart_hope_fear_each(root.querySelectorAll("span.dsf"), function (span) { var nested; if (span.classList.contains("checkbox")) return; nested = span.querySelector("input, textarea"); if (!nested) return; if (daggerheart_hope_fear_is_junk_value(nested.value)) { span.textContent = ""; } else { span.textContent = nested.value || ""; } }); } function daggerheart_hope_fear_select_field(select) { return select ? select.getAttribute("data-dsf") : ""; } function daggerheart_hope_fear_sync_select(root, select) { var name = daggerheart_hope_fear_select_field(select); if (!name) return; daggerheart_hope_fear_set_dsf(root, name, select.value); } function daggerheart_hope_fear_sync_all_selects(root) { daggerheart_hope_fear_each(root.querySelectorAll("select[data-dsf]"), function (select) { daggerheart_hope_fear_sync_select(root, select); }); } function daggerheart_hope_fear_restore_select(root, select) { var name = daggerheart_hope_fear_select_field(select); if (!name) return; var saved = daggerheart_hope_fear_dsf_value(root, name); if (saved) select.value = saved; } function daggerheart_hope_fear_fill_subclasses(select, classKey, preferred) { var opts = SUBCLASSES[classKey] || []; var i; var option; var found = false; select.innerHTML = ""; option = document.createElement("option"); option.value = ""; option.textContent = "-- Select Subclass --"; select.appendChild(option); for (i = 0; i < opts.length; i++) { option = document.createElement("option"); option.value = opts[i].value; option.textContent = opts[i].label; select.appendChild(option); if (preferred && opts[i].value === preferred) found = true; } select.value = found ? preferred : ""; } function daggerheart_hope_fear_populate_subclasses(root, writeBack, classKey) { var classSelect = root.querySelector(".dh-class-select-input"); var subclassSelect = root.querySelector(".dh-subclass-select-input"); var preferred; if (!classSelect || !subclassSelect) return; classKey = classKey || classSelect.value || daggerheart_hope_fear_dsf_value(root, "dsf_class"); preferred = daggerheart_hope_fear_dsf_value(root, "dsf_subclass") || subclassSelect.value; daggerheart_hope_fear_fill_subclasses(subclassSelect, classKey, preferred); if (writeBack) daggerheart_hope_fear_sync_select(root, subclassSelect); } function daggerheart_hope_fear_apply_class_evasion(root) { var classSelect = root.querySelector(".dh-class-select-input"); var start; if (!classSelect) return; start = CLASS_EVASION[classSelect.value]; if (start) daggerheart_hope_fear_set_dsf(root, "dsf_evasion", start); } function daggerheart_hope_fear_hybrid_trait(value) { var parts = String(value || "").split(":"); var key = parts[0]; var idx = parseInt(parts[1], 10); var features = HERITAGE_FEATURES[key]; if (!features || isNaN(idx) || !features[idx]) return null; return features[idx]; } function daggerheart_hope_fear_fill_hybrid_trait_select(select, preferred) { var key; var features; var i; var option; var value; var found = false; if (!select) return; select.innerHTML = ""; option = document.createElement("option"); option.value = ""; option.textContent = "-- Select Trait --"; select.appendChild(option); for (key in HERITAGE_FEATURES) { if (!HERITAGE_FEATURES.hasOwnProperty(key)) continue; features = HERITAGE_FEATURES[key]; for (i = 0; i < features.length; i++) { value = key + ":" + i; option = document.createElement("option"); option.value = value; option.textContent = (HERITAGE_LABELS[key] || key) + " — " + features[i].name; select.appendChild(option); if (preferred && preferred === value) found = true; } } select.value = found ? preferred : ""; } function daggerheart_hope_fear_update_heritage(root) { var wrap = root.querySelector(".dh-heritage-features"); var body = root.querySelector(".dh-heritage-feature-body"); var select = root.querySelector(".dh-heritage-select-input"); var hybridPicks = root.querySelector(".dh-hybrid-trait-picks"); var trait1 = root.querySelector(".dh-hybrid-trait-1-input"); var trait2 = root.querySelector(".dh-hybrid-trait-2-input"); var features; var html = ""; var i; var first; var second; if (!wrap || !body || !select) return; if (select.value === "hybrid") { daggerheart_hope_fear_set_hidden(wrap, false); if (hybridPicks) daggerheart_hope_fear_set_hidden(hybridPicks, false); daggerheart_hope_fear_fill_hybrid_trait_select(trait1, daggerheart_hope_fear_dsf_value(root, "dsf_hybrid_trait_1") || (trait1 && trait1.value)); daggerheart_hope_fear_fill_hybrid_trait_select(trait2, daggerheart_hope_fear_dsf_value(root, "dsf_hybrid_trait_2") || (trait2 && trait2.value)); first = daggerheart_hope_fear_hybrid_trait(trait1 ? trait1.value : ""); second = daggerheart_hope_fear_hybrid_trait(trait2 ? trait2.value : ""); if (first) html += '<div class="dh-feature"><div class="dh-feature-name">' + daggerheart_hope_fear_escape(first.name) + '</div><p class="dh-feature-text">' + daggerheart_hope_fear_escape(first.text) + "</p></div>"; if (second) html += '<div class="dh-feature"><div class="dh-feature-name">' + daggerheart_hope_fear_escape(second.name) + '</div><p class="dh-feature-text">' + daggerheart_hope_fear_escape(second.text) + "</p></div>"; body.innerHTML = html; daggerheart_hope_fear_update_origin_split(root); return; } if (hybridPicks) daggerheart_hope_fear_set_hidden(hybridPicks, true); features = HERITAGE_FEATURES[select.value]; if (!features) { daggerheart_hope_fear_set_hidden(wrap, true); body.innerHTML = ""; daggerheart_hope_fear_update_origin_split(root); return; } daggerheart_hope_fear_set_hidden(wrap, false); for (i = 0; i < features.length; i++) { html += '<div class="dh-feature"><div class="dh-feature-name">' + daggerheart_hope_fear_escape(features[i].name) + '</div><p class="dh-feature-text">' + daggerheart_hope_fear_escape(features[i].text) + "</p></div>"; } body.innerHTML = html; daggerheart_hope_fear_update_origin_split(root); } function daggerheart_hope_fear_update_community(root) { var wrap = root.querySelector(".dh-community-features"); var body = root.querySelector(".dh-community-feature-body"); var select = root.querySelector(".dh-community-select-input"); var feature; if (!wrap || !body || !select) return; feature = COMMUNITY_FEATURES[select.value]; if (!feature) { daggerheart_hope_fear_set_hidden(wrap, true); body.innerHTML = ""; daggerheart_hope_fear_update_origin_split(root); return; } daggerheart_hope_fear_set_hidden(wrap, false); body.innerHTML = '<div class="dh-feature"><div class="dh-feature-name">' + daggerheart_hope_fear_escape(feature.name) + '</div><p class="dh-feature-text">' + daggerheart_hope_fear_escape(feature.text) + "</p></div>"; daggerheart_hope_fear_update_origin_split(root); } function daggerheart_hope_fear_update_origin_split(root) { var origin = root.querySelector(".dh-origin-features"); var heritage = root.querySelector(".dh-heritage-features"); var community = root.querySelector(".dh-community-features"); var both; if (!origin) return; both = heritage && community && !heritage.classList.contains("dh-is-hidden") && !community.classList.contains("dh-is-hidden"); if (both) { origin.classList.add("dh-origin-split"); } else { origin.classList.remove("dh-origin-split"); } } function daggerheart_hope_fear_escape(text) { return String(text) .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """); } function daggerheart_hope_fear_render_feature(feature) { var html = '<div class="dh-feature"><div class="dh-feature-name">' + daggerheart_hope_fear_escape(feature.name) + "</div>"; var i; if (feature.text) html += '<p class="dh-feature-text">' + daggerheart_hope_fear_escape(feature.text) + "</p>"; if (feature.items && feature.items.length) { html += '<ul class="dh-feature-list">'; for (i = 0; i < feature.items.length; i++) { html += "<li>" + daggerheart_hope_fear_escape(feature.items[i]) + "</li>"; } html += "</ul>"; } html += "</div>"; return html; } function daggerheart_hope_fear_render_tier(title, features) { var html; var i; if (!features || !features.length) return ""; html = '<div class="dh-subclass-tier"><div class="dh-tier-header">' + title + "</div>"; for (i = 0; i < features.length; i++) { html += daggerheart_hope_fear_render_feature(features[i]); } html += "</div>"; return html; } function daggerheart_hope_fear_update_subclass_features(root) { var subclassSelect = root.querySelector(".dh-subclass-select-input"); var empty = root.querySelector(".dh-subclass-features-empty"); var panel = root.querySelector(".dh-subclass-feature-panel"); var body = root.querySelector(".dh-subclass-feature-body"); var spellLine = root.querySelector(".dh-spellcast-line"); var key = subclassSelect ? subclassSelect.value : ""; var data = SUBCLASS_FEATURES[key]; var i; var extra; var el; if (!empty || !panel || !body) return; daggerheart_hope_fear_each(root.querySelectorAll(".dh-subclass-extra"), function (node) { daggerheart_hope_fear_set_hidden(node, true); }); if (!data) { daggerheart_hope_fear_set_hidden(empty, false); daggerheart_hope_fear_set_hidden(panel, true); body.innerHTML = ""; if (spellLine) { daggerheart_hope_fear_set_hidden(spellLine, true); spellLine.textContent = ""; } return; } daggerheart_hope_fear_set_hidden(empty, true); daggerheart_hope_fear_set_hidden(panel, false); if (spellLine) { if (data.spellcast) { daggerheart_hope_fear_set_hidden(spellLine, false); spellLine.textContent = "SPELLCAST: " + data.spellcast; } else { daggerheart_hope_fear_set_hidden(spellLine, true); spellLine.textContent = ""; } } body.innerHTML = daggerheart_hope_fear_render_tier("FOUNDATION", data.foundation) + daggerheart_hope_fear_render_tier("SPECIALIZATION", data.specialization) + daggerheart_hope_fear_render_tier("MASTERY", data.mastery); extra = data.extras || []; for (i = 0; i < extra.length; i++) { el = root.querySelector(".dh-extra-" + extra[i]); if (el) daggerheart_hope_fear_set_hidden(el, false); } } function daggerheart_hope_fear_checkbox_on(span) { var val = (span.textContent || "").trim(); return span.classList.contains("is-checked") || val === "1" || val === "true" || val === "checked"; } function daggerheart_hope_fear_checkbox_stored(span) { var val = (span.textContent || "").trim(); return val === "0" || val === "1" || val === "true" || val === "checked"; } function daggerheart_hope_fear_paint_checkbox(span) { var on; var input = span.querySelector("input[type=checkbox]"); if (input) { span.classList.add("dh-op-checkbox"); return; } on = daggerheart_hope_fear_checkbox_on(span); if (on) { span.classList.add("is-checked"); } else { span.classList.remove("is-checked"); } if (!daggerheart_hope_fear_checkbox_stored(span)) span.textContent = on ? "1" : "0"; } function daggerheart_hope_fear_toggle_checkbox(span) { var on; if (span.querySelector("input[type=checkbox]")) return; on = !span.classList.contains("is-checked"); if (on) { span.classList.add("is-checked"); } else { span.classList.remove("is-checked"); } span.textContent = on ? "1" : "0"; } function daggerheart_hope_fear_init_checkboxes(root) { daggerheart_hope_fear_each(root.querySelectorAll("span.dsf.checkbox"), daggerheart_hope_fear_paint_checkbox); } function daggerheart_hope_fear_checkbox_from_event(event) { var span = event.target.closest ? event.target.closest("span.dsf.checkbox") : null; var label; if (span) return span; label = event.target.closest ? event.target.closest("label") : null; return label ? label.querySelector("span.dsf.checkbox") : null; } function daggerheart_hope_fear_update_visibility(root) { var classSelect = root.querySelector(".dh-class-select-input"); var subclassSelect = root.querySelector(".dh-subclass-select-input"); var classKey = classSelect ? classSelect.value : ""; var subclassKey = subclassSelect ? subclassSelect.value : ""; var empty = root.querySelector(".dh-class-features-empty"); var any = false; var beast; var martial; daggerheart_hope_fear_each(root.querySelectorAll(".dh-class-feature-panel"), function (panel) { var show = panel.getAttribute("data-class") === classKey; if (show) { panel.classList.add("is-visible"); any = true; } else { panel.classList.remove("is-visible"); } }); daggerheart_hope_fear_set_hidden(empty, any); daggerheart_hope_fear_each(root.querySelectorAll(".dh-subclass-panel"), function (panel) { panel.classList.remove("is-visible"); }); if (subclassKey === "beastbound") { beast = root.querySelector(".dh-panel-beastbound"); if (beast) beast.classList.add("is-visible"); } if (subclassKey === "martial-artist") { martial = root.querySelector(".dh-panel-martial-artist"); if (martial) martial.classList.add("is-visible"); } daggerheart_hope_fear_update_subclass_features(root); } function daggerheart_hope_fear_apply_identity(root) { daggerheart_hope_fear_update_visibility(root); daggerheart_hope_fear_update_heritage(root); daggerheart_hope_fear_update_community(root); } function daggerheart_hope_fear_on_change(event) { var target = event && event.target; var select; var root; if (!target) return; select = target.tagName === "SELECT" ? target : (target.closest ? target.closest("select") : null); if (!select) return; root = daggerheart_hope_fear_root_from(select); if (!root) return; select.disabled = false; if (select.classList.contains("dh-class-select-input")) { daggerheart_hope_fear_sync_select(root, select); daggerheart_hope_fear_apply_class_evasion(root); daggerheart_hope_fear_populate_subclasses(root, true, select.value); daggerheart_hope_fear_apply_identity(root); return; } if (select.classList.contains("dh-subclass-select-input")) { daggerheart_hope_fear_sync_select(root, select); daggerheart_hope_fear_apply_identity(root); return; } if (select.classList.contains("dh-heritage-select-input")) { daggerheart_hope_fear_sync_select(root, select); daggerheart_hope_fear_update_heritage(root); return; } if (select.classList.contains("dh-hybrid-trait-1-input") || select.classList.contains("dh-hybrid-trait-2-input")) { daggerheart_hope_fear_sync_select(root, select); daggerheart_hope_fear_update_heritage(root); return; } if (select.classList.contains("dh-community-select-input")) { daggerheart_hope_fear_sync_select(root, select); daggerheart_hope_fear_update_community(root); return; } if (select.getAttribute("data-dsf")) { daggerheart_hope_fear_sync_select(root, select); } } function daggerheart_hope_fear_restore_selects(root) { daggerheart_hope_fear_each(root.querySelectorAll("select[data-dsf]"), function (select) { if (select.classList.contains("dh-subclass-select-input")) return; if (select.classList.contains("dh-hybrid-trait-1-input")) return; if (select.classList.contains("dh-hybrid-trait-2-input")) return; daggerheart_hope_fear_restore_select(root, select); }); } function daggerheart_hope_fear_refresh(root) { daggerheart_hope_fear_restore_selects(root); daggerheart_hope_fear_populate_subclasses(root, false); daggerheart_hope_fear_apply_identity(root); daggerheart_hope_fear_init_checkboxes(root); } function daggerheart_hope_fear_is_local_preview() { var href = ""; try { href = String(window.location.href || ""); } catch (err) { return false; } return href.indexOf("preview.html") !== -1 || href.indexOf("127.0.0.1") !== -1 || href.indexOf("localhost") !== -1; } function daggerheart_hope_fear_enable_preview_edit(root) { if (!daggerheart_hope_fear_is_local_preview()) return; daggerheart_hope_fear_each(root.querySelectorAll("span.dsf"), function (span) { if (span.classList.contains("checkbox")) return; if (span.classList.contains("dh-hidden-dsf")) return; if (span.classList.contains("dsf_avatar_image")) return; span.setAttribute("contenteditable", "true"); }); } function daggerheart_hope_fear_on_click(event) { var root = daggerheart_hope_fear_root(); var span = daggerheart_hope_fear_checkbox_from_event(event); if (!root || !span || !root.contains(span) || span.querySelector("input[type=checkbox]")) return; if (event.target && event.target.tagName === "INPUT") return; event.preventDefault(); daggerheart_hope_fear_toggle_checkbox(span); } function daggerheart_hope_fear_on_keydown(event) { var target = event.target; var span; var isEnter = event.key === "Enter" || event.keyCode === 13 || event.which === 13; var isSpace = event.key === " " || event.keyCode === 32; if (!target) return; if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT") return; if (isSpace || isEnter) { span = target.closest ? target.closest("span.dsf.checkbox") : null; if (span && !span.querySelector("input[type=checkbox]") && target === span) { event.preventDefault(); daggerheart_hope_fear_toggle_checkbox(span); } } if (isEnter && target.isContentEditable && target.classList && target.classList.contains("dsf") && !target.classList.contains("checkbox")) { event.preventDefault(); target.blur(); } } function daggerheart_hope_fear_wire_selects(root) { daggerheart_hope_fear_each(root.querySelectorAll("select[data-dsf]"), function (select) { select.disabled = false; if (select.daggerheart_hope_fear_wired) return; select.daggerheart_hope_fear_wired = true; select.addEventListener("change", daggerheart_hope_fear_on_change); select.addEventListener("input", daggerheart_hope_fear_on_change); }); } function daggerheart_hope_fear_bind(root) { if (!daggerheart_hope_fear_bound) { daggerheart_hope_fear_bound = true; document.addEventListener("change", daggerheart_hope_fear_on_change, true); document.addEventListener("input", daggerheart_hope_fear_on_change, true); } if (!root) return; if (!root.daggerheart_hope_fear_ui_bound) { root.daggerheart_hope_fear_ui_bound = true; root.addEventListener("click", daggerheart_hope_fear_on_click); root.addEventListener("keydown", daggerheart_hope_fear_on_keydown); } daggerheart_hope_fear_wire_selects(root); daggerheart_hope_fear_set_identity_locked(root, false); } function daggerheart_hope_fear_field_name(name) { name = String(name || ""); if (name.indexOf("dsf_") === 0) return name; return "dsf_" + name; } function daggerheart_hope_fear_set_identity_locked(root, locked) { var list = root.querySelectorAll(".dh-class-select-input, .dh-subclass-select-input, .dh-heritage-select-input, .dh-community-select-input, .dh-hybrid-trait-1-input, .dh-hybrid-trait-2-input"); daggerheart_hope_fear_each(list, function (select) { select.disabled = !!locked; }); } function daggerheart_hope_fear_dataPreLoad(opts) { daggerheart_hope_fear_patch_jeditable(); } function daggerheart_hope_fear_dataPostLoad(opts) { daggerheart_hope_fear_patch_jeditable(); daggerheart_hope_fear_each_root(function (root) { daggerheart_hope_fear_bind(root); daggerheart_hope_fear_watch_junk(root); daggerheart_hope_fear_sanitize_fields(root); daggerheart_hope_fear_refresh(root); daggerheart_hope_fear_schedule_sanitize(root); }); } function daggerheart_hope_fear_dataChange(opts) { var name = daggerheart_hope_fear_field_name(opts && opts.fieldName); daggerheart_hope_fear_each_root(function (root) { daggerheart_hope_fear_sanitize_fields(root); if (name === "dsf_class" || name === "dsf_subclass" || name === "dsf_heritage" || name === "dsf_community") { daggerheart_hope_fear_refresh(root); } }); } function daggerheart_hope_fear_dataPreSave(opts) { daggerheart_hope_fear_each_root(function (root) { daggerheart_hope_fear_commit_open_editors(root); daggerheart_hope_fear_sanitize_fields(root); daggerheart_hope_fear_sync_all_selects(root); }); } function daggerheart_hope_fear_init() { var root = daggerheart_hope_fear_root(); if (!root) return; daggerheart_hope_fear_bind(root); daggerheart_hope_fear_watch_junk(root); daggerheart_hope_fear_refresh(root); daggerheart_hope_fear_enable_preview_edit(root); } window.daggerheart_hope_fear_dataPreLoad = daggerheart_hope_fear_dataPreLoad; window.daggerheart_hope_fear_dataPostLoad = daggerheart_hope_fear_dataPostLoad; window.daggerheart_hope_fear_dataChange = daggerheart_hope_fear_dataChange; window.daggerheart_hope_fear_dataPreSave = daggerheart_hope_fear_dataPreSave; if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", daggerheart_hope_fear_init); } else { daggerheart_hope_fear_init(); } })();
Submit Notes
interactive character sheet for my daggerheart campaign specifically hope and fear version, i've added more features concerning hybrid heritages, fixed the character sheet not actually saving and added armor used in combat
Back