Merge pull request #15226 from aikepah/feature/curseborne-roll-mechanics

[Curseborne] Bugfix: Support rolled 10s counting as 2 hits and broken injuries
This commit is contained in:
Oliver
2026-06-30 12:34:26 -06:00
committed by GitHub
3 changed files with 381 additions and 164 deletions
+135 -3
View File
@@ -75,8 +75,11 @@ input[type="checkbox"].readonly {
}
.charsheet button[type="roll"].label,
.charsheet button[type="action"].label,
.charsheet button[type="roll"].label:focus,
.charsheet button[type="roll"].label:hover {
.charsheet button[type="action"].label:focus,
.charsheet button[type="roll"].label:hover,
.charsheet button[type="action"].label:hover {
font-family: 'Montserrat', sans-serif;
text-transform: uppercase;
color: #333;
@@ -93,12 +96,14 @@ input[type="checkbox"].readonly {
background-color: transparent;
}
.charsheet button[type="roll"].label::before {
.charsheet button[type="roll"].label::before,
.charsheet button[type="action"].label::before {
content: " ";
}
.charsheet button[type="roll"].dice-roll {
.charsheet button[type="roll"].dice-roll,
.charsheet button[type="action"].dice-roll {
border-style: none;
border-radius: 10px;
text-shadow: none !important;
@@ -963,6 +968,7 @@ input.toggle-more[value="0"] + button > span.less {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.sheet-rolltemplate-skillroll .sheet-inner p:last-child,
@@ -1240,3 +1246,129 @@ input.neardeath-toggle[value="0"] + div.neardeath-hide {
.charsheet .sheet-tabstoggle[value="configuration"] ~ div.sheet-configuration {
display: block;
}
/* --- Roll options modal --- */
.charsheet input.sheet-roll-dialog-toggle {
display: none;
}
.charsheet .sheet-roll-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
align-items: center;
justify-content: center;
}
.charsheet input.sheet-roll-dialog-toggle:checked ~ .sheet-roll-modal {
display: flex;
}
.charsheet .sheet-roll-modal-backdrop {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.55);
}
.charsheet .sheet-roll-modal-content {
position: relative;
background: #f5f0ea;
border: 2px solid #333;
border-radius: 4px;
padding: 24px 28px;
min-width: 280px;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
z-index: 1;
}
.charsheet .sheet-roll-modal-title {
margin: 0 0 16px;
font-size: 1.4rem;
letter-spacing: 1px;
}
.charsheet .sheet-roll-modal-field {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
gap: 12px;
}
.charsheet .sheet-roll-modal-field label {
font-family: 'Montserrat', sans-serif;
font-weight: 700;
font-size: 13px;
text-transform: uppercase;
color: #333;
white-space: nowrap;
}
.charsheet .sheet-roll-modal-field select,
.charsheet .sheet-roll-modal-field input[type="number"] {
flex: 1;
}
.charsheet .sheet-roll-modal-buttons {
display: flex;
gap: 10px;
margin-top: 20px;
justify-content: flex-end;
}
.charsheet .sheet-roll-modal-buttons button[type="action"] {
font-family: 'Montserrat', sans-serif;
font-weight: 700;
font-size: 13px;
text-transform: uppercase;
padding: 6px 16px;
border: 2px solid #333;
border-radius: 3px;
cursor: pointer;
background: #333;
color: #fff;
}
.charsheet .sheet-roll-modal-buttons button[type="action"]:last-child {
background: transparent;
color: #333;
}
/* --- Roll template result rows --- */
.sheet-rolltemplate-skillroll .sheet-roll-label {
font-family: 'Montserrat', sans-serif;
font-weight: 700;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: #555;
align-self: center;
}
.sheet-rolltemplate-skillroll .sheet-curse-label {
color: #8b0000;
}
.sheet-rolltemplate-skillroll .sheet-total-label {
color: #fff;
font-size: 12px;
border-top: 1px solid #ccc;
padding-top: 6px;
margin-top: 2px;
}
.sheet-rolltemplate-skillroll em.sheet-bonus-label {
font-size: 11px;
color: #666;
font-style: italic;
}
+245 -160
View File
@@ -19,6 +19,40 @@
-->
<!-- Hidden fields -->
<input type="hidden" name="attr_sheet-version">
<input type="hidden" name="attr_pending_skill_attr">
<input type="hidden" name="attr_pending_skill_label">
<input type="hidden" name="attr_pending_roll_name">
<input type="checkbox" name="attr_roll_dialog" value="1" class="sheet-roll-dialog-toggle">
<div class="sheet-roll-modal">
<div class="sheet-roll-modal-backdrop"></div>
<div class="sheet-roll-modal-content">
<h3 class="sheet-roll-modal-title">Roll: <span name="attr_pending_skill_label"></span></h3>
<div class="sheet-roll-modal-field">
<label>Active Attribute</label>
<select name="attr_active_attribute">
<option value="intellect">Intellect</option>
<option value="might">Might</option>
<option value="presence">Presence</option>
<option value="cunning">Cunning</option>
<option value="dexterity">Dexterity</option>
<option value="manipulation">Manipulation</option>
<option value="resolve">Resolve</option>
<option value="stamina">Stamina</option>
<option value="composure">Composure</option>
<option value="entanglement">Entanglement</option>
</select>
</div>
<div class="sheet-roll-modal-field">
<label>Bonus Dice</label>
<input type="number" name="attr_extra_dice" value="0" min="0">
</div>
<div class="sheet-roll-modal-buttons">
<button type="action" name="act_confirm_roll">Roll</button>
<button type="action" name="act_cancel_roll">Cancel</button>
</div>
</div>
</div>
<input type="hidden" class="sheet-tabstoggle" name="attr_sheetTab" value="character" />
<div>
@@ -115,7 +149,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<!-- Artistry -->
<div>
<input class="check" type="checkbox" name="attr_artistry_path">
<button type="roll" name="roll_artistryroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=artistry}} {{successes=[[@{rollqueryartistry}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="artistry">Artistry</span>:</button>
<button type="action" name="act_artistryroll" class="label"><span data-i18n="artistry">Artistry</span>:</button>
<input class="value" type="text" name="attr_artistry_field">
<div class="dots">
<input type="hidden" name="attr_artistry" class="dot" value="0" />
@@ -137,14 +171,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_artistry_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_artistryroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=artistry}} {{successes=[[@{rollqueryartistry}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_artistryroll" class="dice-roll"></button>
</div>
</div>
<!-- Athletics -->
<div>
<input class="check" type="checkbox" name="attr_athletics_path">
<button type="roll" name="roll_athleticsroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=athletics}} {{successes=[[@{rollqueryathletics}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="athletics">Athletics</span>:</button>
<button type="action" name="act_athleticsroll" class="label"><span data-i18n="athletics">Athletics</span>:</button>
<input class="value" type="text" name="attr_athletics_field">
<div class="dots">
<input type="hidden" name="attr_athletics" class="dot" value="0" />
@@ -166,14 +200,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_athletics_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_athleticsroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=athletics}} {{successes=[[@{rollqueryathletics}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_athleticsroll" class="dice-roll"></button>
</div>
</div>
<!-- Close Combat -->
<div>
<input class="check" type="checkbox" name="attr_close-combat_path">
<button type="roll" name="roll_close-combatroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=closecombat}} {{successes=[[@{rollqueryclosecombat}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="closecombat">Close Combat</span>:</button>
<button type="action" name="act_close-combatroll" class="label"><span data-i18n="closecombat">Close Combat</span>:</button>
<input class="value" type="text" name="attr_close-combat_field">
<div class="dots">
<input type="hidden" name="attr_close-combat" class="dot" value="0" />
@@ -195,7 +229,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_close-combat_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_close-combatroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=closecombat}} {{successes=[[@{rollqueryclosecombat}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_close-combatroll" class="dice-roll"></button>
</div>
</div>
@@ -203,7 +237,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<!-- Culture -->
<div>
<input class="check" type="checkbox" name="attr_culture_path">
<button type="roll" name="roll_cultureroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=culture}} {{successes=[[@{rollqueryculture}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="culture">Culture</span>:</button>
<button type="action" name="act_cultureroll" class="label"><span data-i18n="culture">Culture</span>:</button>
<input class="value" type="text" name="attr_culture_field">
<div class="dots">
<input type="hidden" name="attr_culture" class="dot" value="0" />
@@ -225,14 +259,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_culture_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_cultureroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=culture}} {{successes=[[@{rollqueryculture}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_cultureroll" class="dice-roll"></button>
</div>
</div>
<!-- Empathy -->
<div>
<input class="check" type="checkbox" name="attr_empathy_path">
<button type="roll" name="roll_empathyroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=empathy}} {{successes=[[@{rollqueryempathy}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="empathy">Empathy</span>:</button>
<button type="action" name="act_empathyroll" class="label"><span data-i18n="empathy">Empathy</span>:</button>
<input class="value" type="text" name="attr_empathy_field">
<div class="dots">
<input type="hidden" name="attr_empathy" class="dot" value="0" />
@@ -254,14 +288,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_empathy_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_empathyroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=empathy}} {{successes=[[@{rollqueryempathy}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_empathyroll" class="dice-roll"></button>
</div>
</div>
<!-- Enigmas -->
<div>
<input class="check" type="checkbox" name="attr_enigmas_path">
<button type="roll" name="roll_enigmasroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=enigmas}} {{successes=[[@{rollqueryenigmas}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="enigmas">Enigmas</span>:</button>
<button type="action" name="act_enigmasroll" class="label"><span data-i18n="enigmas">Enigmas</span>:</button>
<input class="value" type="text" name="attr_enigmas_field">
<div class="dots">
<input type="hidden" name="attr_enigmas" class="dot" value="0" />
@@ -283,14 +317,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_enigmas_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_enigmasroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=enigmas}} {{successes=[[@{rollqueryenigmas}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_enigmasroll" class="dice-roll"></button>
</div>
</div>
<!-- Esoterica -->
<div>
<input class="check" type="checkbox" name="attr_esoterica_path">
<button type="roll" name="roll_esotericaroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=esoterica}} {{successes=[[@{rollqueryesoterica}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="esoterica">Esoterica</span>:</button>
<button type="action" name="act_esotericaroll" class="label"><span data-i18n="esoterica">Esoterica</span>:</button>
<input class="value" type="text" name="attr_esoterica_field">
<div class="dots">
<input type="hidden" name="attr_esoterica" class="dot" value="0" />
@@ -312,14 +346,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_esoterica_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_esotericaroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=esoterica}} {{successes=[[@{rollqueryesoterica}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_esotericaroll" class="dice-roll"></button>
</div>
</div>
<!-- Larceny -->
<div>
<input class="check" type="checkbox" name="attr_larceny_path">
<button type="roll" name="roll_larcenyroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=larceny}} {{successes=[[@{rollquerylarceny}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="larceny">larceny</span>:</button>
<button type="action" name="act_larcenyroll" class="label"><span data-i18n="larceny">larceny</span>:</button>
<input class="value" type="text" name="attr_larceny_field">
<div class="dots">
<input type="hidden" name="attr_larceny" class="dot" value="0" />
@@ -341,7 +375,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_larceny_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_larcenyroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=larceny}} {{successes=[[@{rollquerylarceny}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_larcenyroll" class="dice-roll"></button>
</div>
</div>
@@ -351,7 +385,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<!-- Leadership -->
<div>
<input class="check" type="checkbox" name="attr_leadership_path">
<button type="roll" name="roll_leadershiproll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=leadership}} {{successes=[[@{rollqueryleadership}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="leadership">Leadership</span>:</button>
<button type="action" name="act_leadershiproll" class="label"><span data-i18n="leadership">Leadership</span>:</button>
<input class="value" type="text" name="attr_leadership_field">
<div class="dots">
<input type="hidden" name="attr_leadership" class="dot" value="0" />
@@ -373,14 +407,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_leadership_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_leadershiproll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=leadership}} {{successes=[[@{rollqueryleadership}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_leadershiproll" class="dice-roll"></button>
</div>
</div>
<!-- Medicine -->
<div>
<input class="check" type="checkbox" name="attr_medicine_path">
<button type="roll" name="roll_medicineroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=medicine}} {{successes=[[@{rollquerymedicine}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="medicine">Medicine</span>:</button>
<button type="action" name="act_medicineroll" class="label"><span data-i18n="medicine">Medicine</span>:</button>
<input class="value" type="text" name="attr_medicine_field">
<div class="dots">
<input type="hidden" name="attr_medicine" class="dot" value="0" />
@@ -402,14 +436,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_medicine_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_medicineroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=medicine}} {{successes=[[@{rollquerymedicine}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_medicineroll" class="dice-roll"></button>
</div>
</div>
<!-- Persuasion -->
<div>
<input class="check" type="checkbox" name="attr_persuasion_path">
<button type="roll" name="roll_persuasionroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=persuasion}} {{successes=[[@{rollquerypersuasion}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="persuasion">Persuasion</span>:</button>
<button type="action" name="act_persuasionroll" class="label"><span data-i18n="persuasion">Persuasion</span>:</button>
<input class="value" type="text" name="attr_persuasion_field">
<div class="dots">
<input type="hidden" name="attr_persuasion" class="dot" value="0" />
@@ -431,14 +465,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_persuasion_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_persuasionroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=persuasion}} {{successes=[[@{rollquerypersuasion}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_persuasionroll" class="dice-roll"></button>
</div>
</div>
<!-- Pilot -->
<div>
<input class="check" type="checkbox" name="attr_pilot_path">
<button type="roll" name="roll_pilotroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=pilot}} {{successes=[[@{rollquerypilot}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="pilot">Pilot</span>:</button>
<button type="action" name="act_pilotroll" class="label"><span data-i18n="pilot">Pilot</span>:</button>
<input class="value" type="text" name="attr_pilot_field">
<div class="dots">
<input type="hidden" name="attr_pilot" class="dot" value="0" />
@@ -460,14 +494,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_pilot_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_pilotroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=pilot}} {{successes=[[@{rollquerypilot}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_pilotroll" class="dice-roll"></button>
</div>
</div>
<!-- Ranged Combat -->
<div>
<input class="check" type="checkbox" name="attr_rangedcombat_path">
<button type="roll" name="roll_rangedcombatroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=rangedcombat}} {{successes=[[@{rollqueryrangedcombat}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="rangedcombat">Ranged Combat</span>:</button>
<button type="action" name="act_rangedcombatroll" class="label"><span data-i18n="rangedcombat">Ranged Combat</span>:</button>
<input class="value" type="text" name="attr_rangedcombat_field">
<div class="dots">
<input type="hidden" name="attr_rangedcombat" class="dot" value="0" />
@@ -489,14 +523,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_rangedcombat_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_rangedcombatroll" class="dice-roll" value="&{template:skillroll} {{character=@{character_name}}} {{name=rangedcombat}} {{successes=[[@{rollqueryrangedcombat}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_rangedcombatroll" class="dice-roll"></button>
</div>
</div>
<!-- Science -->
<div>
<input class="check" type="checkbox" name="attr_science_path">
<button type="roll" name="roll_scienceroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=science}} {{successes=[[@{rollqueryscience}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="science">Science</span>:</button>
<button type="action" name="act_scienceroll" class="label"><span data-i18n="science">Science</span>:</button>
<input class="value" type="text" name="attr_science_field">
<div class="dots">
<input type="hidden" name="attr_science" class="dot" value="0" />
@@ -518,14 +552,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_science_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_scienceroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=science}} {{successes=[[@{rollqueryscience}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_scienceroll" class="dice-roll"></button>
</div>
</div>
<!-- Survival -->
<div>
<input class="check" type="checkbox" name="attr_survival_path">
<button type="roll" name="roll_survivalroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=survival}} {{successes=[[@{rollquerysurvival}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="survival">Survival</span>:</button>
<button type="action" name="act_survivalroll" class="label"><span data-i18n="survival">Survival</span>:</button>
<input class="value" type="text" name="attr_survival_field">
<div class="dots">
<input type="hidden" name="attr_survival" class="dot" value="0" />
@@ -547,14 +581,14 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_survival_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_survivalroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=survival}} {{successes=[[@{rollquerysurvival}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_survivalroll" class="dice-roll"></button>
</div>
</div>
<!-- Technology -->
<div>
<input class="check" type="checkbox" name="attr_technology_path">
<button type="roll" name="roll_technologyroll" class="label" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=technology}} {{successes=[[@{rollquerytechnology}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"><span data-i18n="technology">Technology</span>:</button>
<button type="action" name="act_technologyroll" class="label"><span data-i18n="technology">Technology</span>:</button>
<input class="value" type="text" name="attr_technology_field">
<div class="dots">
<input type="hidden" name="attr_technology" class="dot" value="0" />
@@ -576,7 +610,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_technology_5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_technologyroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=technology}} {{successes=[[@{rollquerytechnology}]]}} {{cursedsuccesses=[[@{curse}d10>8]]}}"></button>
<button type="action" name="act_technologyroll" class="dice-roll"></button>
</div>
</div>
@@ -669,7 +703,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_cunning_5" class="dot gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_cunningroll" class="dice-roll" title="Initiative" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=initiative}} {{successes=[[@{rollquerycunning}]]}}"></button>
<button type="action" name="act_cunningroll" class="dice-roll" title="Initiative"></button>
</div>
<!-- Dexterity -->
@@ -691,7 +725,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_dexterity_5" class="dot gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_dexterityroll" class="dice-roll" title="Initiative" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=initiative}} {{successes=[[@{rollquerydexterity}]]}}"></button>
<button type="action" name="act_dexterityroll" class="dice-roll" title="Initiative"></button>
</div>
<!-- Manipulation -->
@@ -734,7 +768,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_resolve_5" class="dot gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_resolveroll" class="dice-roll" title="Integrity" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=integrity}} {{successes=[[@{rollqueryresolve}]]}}"></button>
<button type="action" name="act_resolveroll" class="dice-roll" title="Integrity"></button>
</div>
<!-- Stamina -->
@@ -756,7 +790,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_stamina_5" class="dot gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_staminaroll" class="dice-roll" title="Defense" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=defense}} {{successes=[[@{rollquerystamina}]]}}"></button>
<button type="action" name="act_staminaroll" class="dice-roll" title="Defense"></button>
</div>
<!-- Composure -->
@@ -778,7 +812,7 @@ Resolution: The Primal must express her elemental nature and satisfy the Creatur
<button type="action" name="act_composure_5" class="dot gt-1 gt-2 gt-3 gt-4">
<span class="checked"></span>
</button>
<button type="roll" name="roll_composureroll" class="dice-roll" title="Integrity" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=integrity}} {{successes=[[@{rollquerycomposure}]]}}"></button>
<button type="action" name="act_composureroll" class="dice-roll" title="Integrity"></button>
</div>
</div>
@@ -936,22 +970,22 @@ Enjoy your Armor!
<input type="hidden" class="armor-toggle" name="attr_toggle_armor1" value="0" />
<div align="center" style="margin-left: 48px" class="char-health armor-hide">
<input type="checkbox" name="attr_armor1" value="0" >
<input type="checkbox" name="attr_armor1" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor2" value="0" />
<div align="center" class="char-health armor-hide">
<input type="checkbox" name="attr_armor2" value="0" >
<input type="checkbox" name="attr_armor2" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor3" value="0" />
<div align="center" class="char-health armor-hide">
<input type="checkbox" name="attr_armor3" value="0" >
<input type="checkbox" name="attr_armor3" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor4" value="0" />
<div align="center" class="char-health armor-hide">
<input type="checkbox" name="attr_armor4" value="0" >
<input type="checkbox" name="attr_armor4" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor5" value="0" />
@@ -970,22 +1004,22 @@ Bloodied: +1 Path Skill Die.
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied1" value="0" />
<div align="center" style="margin-left: 33px" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied1" value="0" >
<input type="checkbox" name="attr_bloodied1" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied2" value="0" />
<div align="center" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied2" value="0" >
<input type="checkbox" name="attr_bloodied2" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied3" value="0" />
<div align="center" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied3" value="0" >
<input type="checkbox" name="attr_bloodied3" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied4" value="0" />
<div align="center" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied4" value="0" >
<input type="checkbox" name="attr_bloodied4" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied5" value="0" />
@@ -1004,22 +1038,22 @@ Wounded: +2 Path Skill Dice.
<input type="hidden" class="wounded-toggle" name="attr_toggle_wounded1" value="0" />
<div align="center" style="margin-left: 29px" class="char-health wounded-hide">
<input type="checkbox" name="attr_wounded1" value="0" >
<input type="checkbox" name="attr_wounded1" value="1" >
</div>
<input type="hidden" class="wounded-toggle" name="attr_toggle_wounded2" value="0" />
<div align="center" class="char-health wounded-hide">
<input type="checkbox" name="attr_wounded2" value="0" >
<input type="checkbox" name="attr_wounded2" value="1" >
</div>
<input type="hidden" class="wounded-toggle" name="attr_toggle_wounded3" value="0" />
<div align="center" class="char-health wounded-hide">
<input type="checkbox" name="attr_wounded3" value="0" >
<input type="checkbox" name="attr_wounded3" value="1" >
</div>
<input type="hidden" class="wounded-toggle" name="attr_toggle_wounded4" value="0" />
<div align="center" class="char-health wounded-hide">
<input type="checkbox" name="attr_wounded4" value="0" >
<input type="checkbox" name="attr_wounded4" value="1" >
</div>
<input type="hidden" class="wounded-toggle" name="attr_toggle_wounded5" value="0" />
@@ -1038,22 +1072,22 @@ Maimed: +2 Path Skill Dice, +2 Enhancement if Aggravated Wound Status Effect tak
<input type="hidden" class="maimed-toggle" name="attr_toggle_maimed1" value="0" />
<div align="center" style="margin-left: 38px" class="char-health maimed-hide">
<input type="checkbox" name="attr_maimed1" value="0" >
<input type="checkbox" name="attr_maimed1" value="1" >
</div>
<input type="hidden" class="maimed-toggle" name="attr_toggle_maimed2" value="0" />
<div align="center" class="char-health maimed-hide">
<input type="checkbox" name="attr_maimed2" value="0" >
<input type="checkbox" name="attr_maimed2" value="1" >
</div>
<input type="hidden" class="maimed-toggle" name="attr_toggle_maimed3" value="0" />
<div align="center" class="char-health maimed-hide">
<input type="checkbox" name="attr_maimed3" value="0" >
<input type="checkbox" name="attr_maimed3" value="1" >
</div>
<input type="hidden" class="maimed-toggle" name="attr_toggle_maimed4" value="0" />
<div align="center" class="char-health maimed-hide">
<input type="checkbox" name="attr_maimed4" value="0" >
<input type="checkbox" name="attr_maimed4" value="1" >
</div>
<input type="hidden" class="maimed-toggle" name="attr_toggle_maimed5" value="0" />
@@ -1072,22 +1106,22 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<input type="hidden" class="neardeath-toggle" name="attr_toggle_neardeath1" value="0" />
<div align="center" style="margin-left: 20px" class="char-health neardeath-hide">
<input type="checkbox" name="attr_neardeath1" value="0" >
<input type="checkbox" name="attr_neardeath1" value="1" >
</div>
<input type="hidden" class="neardeath-toggle" name="attr_toggle_neardeath2" value="0" />
<div align="center" class="char-health neardeath-hide">
<input type="checkbox" name="attr_neardeath2" value="0" >
<input type="checkbox" name="attr_neardeath2" value="1" >
</div>
<input type="hidden" class="neardeath-toggle" name="attr_toggle_neardeath3" value="0" />
<div align="center" class="char-health neardeath-hide">
<input type="checkbox" name="attr_neardeath3" value="0" >
<input type="checkbox" name="attr_neardeath3" value="1" >
</div>
<input type="hidden" class="neardeath-toggle" name="attr_toggle_neardeath4" value="0" />
<div align="center" class="char-health neardeath-hide">
<input type="checkbox" name="attr_neardeath4" value="0" >
<input type="checkbox" name="attr_neardeath4" value="1" >
</div>
<input type="hidden" class="neardeath-toggle" name="attr_toggle_neardeath5" value="0" />
@@ -1460,7 +1494,7 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<button type="action" name="act_primary_12" class="dot gt-0 gt-1 gt-2 gt-3 gt-4 gt-5 gt-6 gt-7 gt-8 gt-9 gt-10 gt-11">
<span class="checked"></span>
</button>
<button type="roll" name="roll_primaryroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=primary}} {{successes=[[@{rollqueryprimary}]]}}"></button>
<button type="action" name="act_primaryroll" class="dice-roll"></button>
</div>
</div>
@@ -1504,7 +1538,7 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<button type="action" name="act_secondary_10" class="dot gt-0 gt-1 gt-2 gt-3 gt-4 gt-5 gt-6 gt-7 gt-8 gt-9">
<span class="checked"></span>
</button>
<button type="roll" name="roll_secondaryroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=secondary}} {{successes=[[@{rollquerysecondary}]]}}"></button>
<button type="action" name="act_secondaryroll" class="dice-roll"></button>
</div>
</div>
@@ -1536,7 +1570,7 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<button type="action" name="act_desperation_6" class="dot gt-0 gt-1 gt-2 gt-3 gt-4 gt-5">
<span class="checked"></span>
</button>
<button type="roll" name="roll_desperationroll" class="dice-roll" value="@{whisper} &{template:skillroll} {{character=@{character_name}}} {{name=desperation}} {{successes=[[@{rollquerydesperation}]]}}"></button>
<button type="action" name="act_desperationroll" class="dice-roll"></button>
</div>
</div>
@@ -1610,22 +1644,22 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<input type="hidden" class="armor-toggle" name="attr_toggle_armor1" value="0" />
<div align="center" style="margin-left: 39px" class="char-health armor-hide">
<input type="checkbox" name="attr_armor1" value="0" >
<input type="checkbox" name="attr_armor1" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor2" value="0" />
<div align="center" class="char-health armor-hide">
<input type="checkbox" name="attr_armor2" value="0" >
<input type="checkbox" name="attr_armor2" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor3" value="0" />
<div align="center" class="char-health armor-hide">
<input type="checkbox" name="attr_armor3" value="0" >
<input type="checkbox" name="attr_armor3" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor4" value="0" />
<div align="center" class="char-health armor-hide">
<input type="checkbox" name="attr_armor4" value="0" >
<input type="checkbox" name="attr_armor4" value="1" >
</div>
<input type="hidden" class="armor-toggle" name="attr_toggle_armor5" value="0" />
@@ -1641,22 +1675,22 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied1" value="0" />
<div align="center" style="margin-left: 33px" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied1" value="0" >
<input type="checkbox" name="attr_bloodied1" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied2" value="0" />
<div align="center" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied2" value="0" >
<input type="checkbox" name="attr_bloodied2" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied3" value="0" />
<div align="center" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied3" value="0" >
<input type="checkbox" name="attr_bloodied3" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied4" value="0" />
<div align="center" class="char-health bloodied-hide">
<input type="checkbox" name="attr_bloodied4" value="0" >
<input type="checkbox" name="attr_bloodied4" value="1" >
</div>
<input type="hidden" class="bloodied-toggle" name="attr_toggle_bloodied5" value="0" />
@@ -1742,16 +1776,21 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<h4>{{character}}<br><span data-i18n="rolled">Rolled</span> <span data-i18n="{{name}}">{{name}}</span></h4>
</div>
<div class="sheet-inner">
<div class="results">
<h4><span data-i18n="successes">Normal Dice</span>:</h4>
<p>{{successes}}</p>
<h4><span data-i18n="cursedsuccesses">Curse Dice</span>:</h4>
<p>{{cursedsuccesses}}</p>
<div class="sheet-roll-label">Dice</div>
<div>{{mainroll}}{{#computed::bonusdice}} <em class="sheet-bonus-label">(+{{computed::bonusdice}} bonus)</em>{{/computed::bonusdice}}</div>
<div class="sheet-roll-label">Hits</div>
<div><strong>{{computed::successes}}</strong></div>
{{#curseroll}}
<div class="sheet-roll-label sheet-curse-label">Curse Dice</div>
<div>{{curseroll}}</div>
<div class="sheet-roll-label sheet-curse-label">Curse Hits</div>
<div><strong>{{computed::cursedsuccesses}}</strong></div>
<div class="sheet-roll-label sheet-total-label">Total Hits</div>
<div class="sheet-total-label"><strong>{{computed::total}}</strong></div>
{{/curseroll}}
</div>
{{#rollWasCrit() successes}}
<p>Yay! You rolled one or more 10s!</p>
{{/rollWasCrit() successes}}
</div>
</div>
</rolltemplate>
@@ -1790,105 +1829,151 @@ Near Death: +3 Dice and +2 Enhancement. Gain Taken Out Status Effect.
<script type="text/worker">
on("sheet:opened", function(eventInfo){
const selectAttribute = "?{" +
getTranslationByKey("selectattribute") + "|" +
getTranslationByKey("intellect") + ",@{intellect}|" +
getTranslationByKey("might") + ",@{might}|" +
getTranslationByKey("presence") + ",@{presence}|" +
getTranslationByKey("cunning") + ",@{cunning}|" +
getTranslationByKey("dexterity") + ",@{dexterity}|" +
getTranslationByKey("manipulation") + ",@{manipulation}|" +
getTranslationByKey("resolve") + ",@{resolve}|" +
getTranslationByKey("stamina") + ",@{stamina}|" +
getTranslationByKey("composure") + ",@{composure}|" +
getTranslationByKey("entanglement") + ",@{entanglement}}"
// --- Dice Rolling Utilities ---
const extraDice = `?{${getTranslationByKey("extradice")}|0}`
const curseDice = "@{curse}"
const cunning = "@{cunning}"
const dexterity = "@{dexterity}"
function getDiceValues(rollField) {
if (!rollField) return [];
if (rollField.rolls && rollField.rolls[0] && Array.isArray(rollField.rolls[0].results)) {
return rollField.rolls[0].results;
}
if (Array.isArray(rollField.dice)) return rollField.dice.map(function(v) { return { v: v }; });
return [];
}
setAttrs({
rollqueryrangedcombat:
`(@{rangedcombat}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
function countDice(diceResults) {
let successes = 0;
diceResults.forEach(function(die) {
const v = (die && typeof die === 'object' && 'v' in die) ? die.v : +die;
if (v >= 10) { successes += 2; }
else if (v >= 8) { successes++; }
});
return { successes: successes };
}
rollqueryathletics:
`(@{athletics}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryclosecombat:
`(@{close-combat}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryleadership:
`(@{leadership}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryculture:
`(@{culture}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryempathy:
`(@{empathy}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryenigmas:
`(@{enigmas}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryartistry:
`(@{artistry}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryesoterica:
`(@{esoterica}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollquerylarceny:
`(@{larceny}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollquerymedicine:
`(@{medicine}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollquerypersuasion:
`(@{persuasion}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollquerypilot:
`(@{pilot}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollqueryscience:
`(@{science}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollquerysurvival:
`(@{survival}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
rollquerytechnology:
`(@{technology}+${selectAttribute}+${extraDice}-${curseDice})d10>8`,
const COMPUTED_PLACEHOLDERS = ' {{successes=[[0]]}} {{cursedsuccesses=[[0]]}} {{total=[[0]]}} {{bonusdice=[[0]]}}';
rollqueryspell:
`(@{spell_skill}+@{spell_attribute}+${extraDice}-${curseDice})d10>8`,
async function performRoll(mainPool, cursePool, rollName, charName, whisper, bonusDice) {
mainPool = Math.max(0, mainPool);
cursePool = Math.max(0, cursePool);
rollquerystamina:
`(@{stamina}+${extraDice})d10>8`,
const mainExpr = mainPool > 0 ? mainPool + 'd10' : '0';
const curseExpr = cursePool > 0 ? cursePool + 'd10' : null;
rollquerycomposure:
`(@{composure}+${extraDice})d10>8`,
let templateExpr = whisper + ' &{template:skillroll} {{character=' + charName + '}} {{name=' + rollName + '}} {{mainroll=[[' + mainExpr + ']]}}';
if (curseExpr) templateExpr += ' {{curseroll=[[' + curseExpr + ']]}}';
templateExpr += COMPUTED_PLACEHOLDERS;
rollqueryresolve:
`(@{resolve}+${extraDice})d10>8`,
const result = await startRoll(templateExpr);
const mainCount = countDice(getDiceValues(result.results.mainroll));
const curseCount = countDice(getDiceValues(result.results.curseroll));
finishRoll(result.rollId, {
successes: mainCount.successes,
cursedsuccesses: curseCount.successes,
total: mainCount.successes + curseCount.successes,
bonusdice: bonusDice || 0
});
}
rollquerydexterity:
`(@{empathy}+${dexterity}+${extraDice})d10>8`,
// --- Skill Roll Handlers (open modal) ---
rollquerycunning:
`(@{athletics}+${cunning}+${extraDice})d10>8`,
const ALL_ATTR_NAMES = ['intellect', 'might', 'presence', 'cunning', 'dexterity',
'manipulation', 'resolve', 'stamina', 'composure', 'entanglement'];
rollqueryprimary:
`(@{primary}+${extraDice})d10>8`,
const ALL_SKILL_NAMES = ['artistry', 'athletics', 'close-combat', 'culture', 'empathy',
'enigmas', 'esoterica', 'larceny', 'leadership', 'medicine',
'persuasion', 'pilot', 'rangedcombat', 'science', 'survival', 'technology'];
rollquerysecondary:
`(@{secondary}+${extraDice})d10>8`,
function makeSkillRollHandler(skillAttr, rollName, displayName) {
return function() {
setAttrs({
roll_dialog: '1',
pending_skill_attr: skillAttr,
pending_skill_label: displayName,
pending_roll_name: rollName,
active_attribute: 'intellect',
extra_dice: '0'
});
};
}
rollquerydesperation:
`(@{desperation}+${extraDice})d10>8`,
on('clicked:artistryroll', makeSkillRollHandler('artistry', 'artistry', 'Artistry'));
on('clicked:athleticsroll', makeSkillRollHandler('athletics', 'athletics', 'Athletics'));
on('clicked:close-combatroll',makeSkillRollHandler('close-combat', 'closecombat', 'Close Combat'));
on('clicked:cultureroll', makeSkillRollHandler('culture', 'culture', 'Culture'));
on('clicked:empathyroll', makeSkillRollHandler('empathy', 'empathy', 'Empathy'));
on('clicked:enigmasroll', makeSkillRollHandler('enigmas', 'enigmas', 'Enigmas'));
on('clicked:esotericaroll', makeSkillRollHandler('esoterica', 'esoterica', 'Esoterica'));
on('clicked:larcenyroll', makeSkillRollHandler('larceny', 'larceny', 'Larceny'));
on('clicked:leadershiproll', makeSkillRollHandler('leadership', 'leadership', 'Leadership'));
on('clicked:medicineroll', makeSkillRollHandler('medicine', 'medicine', 'Medicine'));
on('clicked:persuasionroll', makeSkillRollHandler('persuasion', 'persuasion', 'Persuasion'));
on('clicked:pilotroll', makeSkillRollHandler('pilot', 'pilot', 'Pilot'));
on('clicked:rangedcombatroll',makeSkillRollHandler('rangedcombat', 'rangedcombat', 'Ranged Combat'));
on('clicked:scienceroll', makeSkillRollHandler('science', 'science', 'Science'));
on('clicked:survivalroll', makeSkillRollHandler('survival', 'survival', 'Survival'));
on('clicked:technologyroll', makeSkillRollHandler('technology', 'technology', 'Technology'));
// --- Modal confirm / cancel ---
on('clicked:confirm_roll', function() {
const attrList = ['pending_skill_attr', 'pending_roll_name', 'active_attribute',
'extra_dice', 'curse', 'character_name', 'whisper']
.concat(ALL_ATTR_NAMES)
.concat(ALL_SKILL_NAMES);
getAttrs(attrList, async function(attrs) {
setAttrs({ roll_dialog: '0' });
const skillAttr = attrs.pending_skill_attr;
const rollName = attrs.pending_roll_name;
const skill = parseInt(attrs[skillAttr]) || 0;
const activeAttr = attrs.active_attribute || 'intellect';
const attrValue = parseInt(attrs[activeAttr]) || 0;
const extra = parseInt(attrs.extra_dice) || 0;
const curse = parseInt(attrs.curse) || 0;
const mainPool = skill + attrValue + extra - curse;
const whisper = attrs.whisper === '/w gm' ? '/w gm ' : '';
await performRoll(mainPool, curse, rollName, attrs.character_name || '', whisper, extra);
});
});
on('clicked:cancel_roll', function() {
setAttrs({ roll_dialog: '0' });
});
// --- Fixed-Formula Roll Handlers ---
function makeFixedRollHandler(attr1, attr2, rollName) {
const attrList = attr2 ? [attr1, attr2, 'character_name', 'whisper']
: [attr1, 'character_name', 'whisper'];
return function() {
getAttrs(attrList, async function(attrs) {
const pool = (parseInt(attrs[attr1]) || 0)
+ (attr2 ? (parseInt(attrs[attr2]) || 0) : 0);
const whisper = attrs.whisper === '/w gm' ? '/w gm ' : '';
await performRoll(pool, 0, rollName, attrs.character_name || '', whisper);
});
};
}
on('clicked:cunningroll', makeFixedRollHandler('athletics', 'cunning', 'initiative'));
on('clicked:dexterityroll', makeFixedRollHandler('empathy', 'dexterity', 'initiative'));
on('clicked:resolveroll', makeFixedRollHandler('resolve', null, 'integrity'));
on('clicked:staminaroll', makeFixedRollHandler('stamina', null, 'defense'));
on('clicked:composureroll', makeFixedRollHandler('composure', null, 'integrity'));
function makePoolRollHandler(poolAttr, rollName) {
return function() {
getAttrs([poolAttr, 'character_name', 'whisper'], async function(attrs) {
const pool = parseInt(attrs[poolAttr]) || 0;
const whisper = attrs.whisper === '/w gm' ? '/w gm ' : '';
await performRoll(pool, 0, rollName, attrs.character_name || '', whisper);
});
};
}
on('clicked:primaryroll', makePoolRollHandler('primary', 'primary'));
on('clicked:secondaryroll', makePoolRollHandler('secondary', 'secondary'));
on('clicked:desperationroll', makePoolRollHandler('desperation', 'desperation'));
const characteristicValues = ["0","1","2","3","4","5","6","7","8","9","10","11","12"];
+1 -1
View File
@@ -1,7 +1,7 @@
{
"html": "Cursed_HTML.html",
"css": "Cursed.css",
"authors": "Chris Jones (chipotlechris)",
"authors": "Chris Jones (chipotlechris), Austin Welch (aikepah)",
"roll20userid": "3717626",
"preview": "preview.png",
"instructions": "Enjoy the sheet!.",