diff --git a/Demon Gate/DemonGate.css b/Demon Gate/DemonGate.css index fce59b4851..26ae308af0 100644 --- a/Demon Gate/DemonGate.css +++ b/Demon Gate/DemonGate.css @@ -68,6 +68,36 @@ --dg-mental-4: rgba(110, 20, 185, 0.62); --dg-mental-5: rgba(110, 20, 185, 0.78); --dg-mental-6: rgba(110, 20, 185, 0.94); + + /* Toggle button / pill tokens — shared by tab buttons and max-uses pills */ + --dg-toggle-bg: var(--dg-surface); /* unselected bg — header background */ + --dg-toggle-bg-dark: var(--dg-surface-dark); /* unselected bg — header background (dark) */ + + /* selected bg — h1 radial gradient (light: amber→dark-red; dark: dark-red→near-black) */ + --dg-toggle-bg-selected: radial-gradient(ellipse at center, #c85e21 0%, #a53c18 42%, #732012 72%, #4f140b 100%); + --dg-toggle-bg-selected-dark: radial-gradient(ellipse at center, #5f1d14 0%, #441711 22%, #301411 100%); + + --dg-toggle-fg: var(--dg-primary); /* general toggle fg — unselected button text */ + --dg-toggle-fg-dark: var(--dg-primary-dark); /* general toggle fg (dark) */ + + --dg-toggle-fg-selected: var(--dg-surface); /* selected toggle fg — text on gradient bg */ + --dg-toggle-fg-selected-dark: var(--dg-primary-dark); /* selected toggle fg (dark) */ + + --dg-toggle-border: var(--dg-border); /* unselected border */ + --dg-toggle-border-dark: var(--dg-border-dark); /* unselected border (dark) */ + + --dg-toggle-border-selected: var(--dg-border); /* selected border — same as unselected in light */ + --dg-toggle-border-selected-dark: #b03828; /* selected border — brighter red for dark mode */ +} + +/* Override toggle selected-state tokens in dark mode so the enable-selector matrix + (which references the plain --dg-toggle-* names) automatically resolves the dark values + without duplicating the full 15-rule selector matrix. */ +.sheet-darkmode { + --dg-toggle-bg-selected: radial-gradient(ellipse at center, #5f1d14 0%, #441711 22%, #301411 100%); + --dg-toggle-border-selected: #b03828; + --dg-toggle-fg: var(--dg-primary-dark); + --dg-toggle-fg-selected: var(--dg-primary-dark); } /* ************************************************************************************************************************************************ */ @@ -75,12 +105,12 @@ /* ************************************************************************************************************************************************ */ .charsheet { - background: url("https://raw.githubusercontent.com/phaldenby72/roll20-character-sheets/refs/heads/demon-gate-attributes-and-defences/Demon%20Gate/map_watermark.jpg"); + background: url("https://raw.githubusercontent.com/Roll20/roll20-character-sheets/refs/heads/master/Demon%20Gate/map_watermark.jpg"); font-family: "Atkinson Hyperlegible", sans-serif; } .sheet-darkmode .charsheet { - background: url("https://raw.githubusercontent.com/phaldenby72/roll20-character-sheets/refs/heads/demon-gate-attributes-and-defences/Demon%20Gate/map_watermark_dark.jpg"); + background: url("https://raw.githubusercontent.com/Roll20/roll20-character-sheets/refs/heads/master/Demon%20Gate/map_watermark_dark.jpg"); } .sheet-demon-gate-charsheet { @@ -142,10 +172,10 @@ span.sheet-tab { display: inline-block; font-size: 14px; line-height: 28px; - color: var(--dg-text-muted); - border: 1px solid var(--dg-primary); + color: var(--dg-toggle-fg); + border: 1px solid var(--dg-toggle-border); border-radius: 4px; - background: var(--dg-table-header-bg); + background: var(--dg-toggle-bg); width: 90px; height: 28px; cursor: pointer; @@ -170,9 +200,9 @@ input.sheet-tab8:checked ~ div.sheet-section-notes { } input.sheet-tab:checked + span { - background: var(--dg-surface); - color: var(--dg-primary); - border: 2px solid var(--dg-primary); + background: var(--dg-toggle-bg-selected); + border: 2px solid var(--dg-toggle-border-selected); + color: var(--dg-toggle-fg-selected); } /* ************************************************************************************************************************************************ */ @@ -180,15 +210,15 @@ input.sheet-tab:checked + span { /* ************************************************************************************************************************************************ */ .sheet-darkmode span.sheet-tab { - color: var(--dg-text-muted-dark); - border-color: var(--dg-border-dark); - background: var(--dg-table-header-bg-dark); + color: var(--dg-toggle-fg-dark); + border-color: var(--dg-toggle-border-dark); + background: var(--dg-toggle-bg-dark); } .sheet-darkmode input.sheet-tab:checked + span { - background: var(--dg-surface-dark); - color: var(--dg-primary-dark); - border-color: var(--dg-primary-dark); + background: var(--dg-toggle-bg-selected-dark); + border-color: var(--dg-toggle-border-selected-dark); + color: var(--dg-toggle-fg-selected-dark); } /* ************************************************************************************************************************************************ */ @@ -534,7 +564,7 @@ td.sheet-cell-numeric { /* Entry controls */ /* ************************************************************************************************************************************************ */ -input, +input:not([type="radio"]):not([type="checkbox"]), select, textarea, .sheet-input-like { @@ -655,7 +685,7 @@ textarea::placeholder { /* Dark mode overrides */ /* ************************************************************************************************************************************************ */ -.sheet-darkmode input, +.sheet-darkmode input:not([type="radio"]):not([type="checkbox"]), .sheet-darkmode select, .sheet-darkmode textarea, .sheet-darkmode .sheet-input-like { @@ -915,6 +945,170 @@ textarea.sheet-textarea-equipment { margin-bottom: -10px; } +/* ************************************************************************************************************************************************ */ +/* Class ability usage tracking */ +/* ************************************************************************************************************************************************ */ + +/* Row containing the pill radio group and use circles */ +.sheet-uses-row { + display: flex; + flex-wrap: nowrap; + align-items: center; + padding: 4px 8px; + border-top: 1px solid var(--dg-border); + background-color: var(--dg-surface); +} + +/* "Max" / "Used" section labels */ +.sheet-uses-label { + font-size: 0.8em; + font-weight: bold; + white-space: nowrap; + color: var(--dg-text-muted); + margin-right: 6px; + flex-shrink: 0; +} + +/* Radio pill: invisible but clickable (opacity: 0 pattern, same as .sheet-expand-collapse-checkbox). + The LABEL span is the visual element; the radio just captures clicks. + No gap on the flex container — spacing comes from .sheet-max-label margin-right. */ +input.sheet-max-radio { + opacity: 0; + display: inline-block; + width: 28px; + height: 20px; + flex-shrink: 0; + cursor: pointer; + box-sizing: border-box; +} + +/* Pill label: the visual pill. Overlays the preceding radio via negative margin. + pointer-events: none lets clicks fall through to the radio behind it. + margin-left: -28px pulls it back over the radio. + margin-right: 4px provides the gap before the next pill. + Net flex contribution = -28 + 28 + 4 = 4px (gap only). */ +.sheet-max-pill { + display: inline-block; + width: 28px; + height: 20px; + line-height: 18px; + margin-left: -28px; + margin-right: 4px; + text-align: center; + font-size: 0.7em; + font-weight: bold; + pointer-events: none; + color: var(--dg-toggle-fg); + flex-shrink: 0; + border-radius: 10px; + border: 1px solid var(--dg-toggle-border); + background: var(--dg-toggle-bg); + box-sizing: border-box; +} + +/* Selected pill — toggle gradient background; fg from toggle-fg token */ +input.sheet-max-radio:checked + .sheet-max-pill { + background: var(--dg-toggle-bg-selected); + border: 1px solid var(--dg-toggle-border-selected); + color: var(--dg-toggle-fg-selected); +} + +/* Thin vertical divider between pill group and use circles */ +.sheet-uses-sep { + width: 1px; + height: 20px; + background: var(--dg-border); + margin: 0 8px; + flex-shrink: 0; +} + +/* Use circle checkboxes — disabled by default. + appearance: none + explicit size. element.class selector (0,1,1) beats any + Roll20-injected input rules. background: transparent is required — without it + the dark-mode forms rule would fill the circle with the control background colour. */ +.sheet-demon-gate-charsheet input.sheet-use-cb { + /** Use higher specificity to override Roll20's injected rules */ + appearance: none; + -webkit-appearance: none; + width: 16px; + height: 16px; + min-width: 16px; + flex-shrink: 0; + border-radius: 50%; + border: 2px solid var(--dg-border); + background: transparent; + cursor: not-allowed; + opacity: 0.3; + pointer-events: none; + margin-left: 4px; + box-sizing: border-box; +} + +/* Checked — same look as a selected pill; the × is provided by the adjacent .sheet-use-icon span */ +.sheet-demon-gate-charsheet input.sheet-use-cb:checked { + background: var(--dg-toggle-bg-selected); + border: 2px solid var(--dg-toggle-border-selected); +} + +/* Icon span: overlays the preceding checkbox via negative margin. + The × is always in the DOM but transparent until the checkbox is checked or focused+checked. */ +.sheet-use-icon { + display: inline-block; + width: 16px; + height: 18px; + line-height: 16px; + margin-left: -16px; + text-align: center; + font-size: 16px; + font-weight: bold; + color: transparent; + pointer-events: none; + flex-shrink: 0; + box-sizing: border-box; + user-select: none; +} + +/* Show × when the checkbox is checked (covers plain :checked and :focus:checked) */ +input.sheet-use-cb:checked + .sheet-use-icon { + color: var(--dg-toggle-fg-selected); +} + +/* Hide the separator, "Used" label, circles, icons, and reset button when max is N/A (value 0). + The "Max" label precedes the radio so ~ won't reach it — only siblings after value="0" are hidden. */ +input.sheet-max-radio[value="0"]:checked ~ .sheet-uses-sep, +input.sheet-max-radio[value="0"]:checked ~ .sheet-uses-label, +input.sheet-max-radio[value="0"]:checked ~ input.sheet-use-cb, +input.sheet-max-radio[value="0"]:checked ~ .sheet-use-icon { + display: none; +} + +/* Progressively enable circles based on the selected max pill. + ~ general sibling selector skips the separator and "Used" label spans between + the radio pills and the use circles. */ +input.sheet-max-radio[value="1"]:checked ~ input.sheet-use-cb-1, +input.sheet-max-radio[value="2"]:checked ~ input.sheet-use-cb-1, +input.sheet-max-radio[value="2"]:checked ~ input.sheet-use-cb-2, +input.sheet-max-radio[value="3"]:checked ~ input.sheet-use-cb-1, +input.sheet-max-radio[value="3"]:checked ~ input.sheet-use-cb-2, +input.sheet-max-radio[value="3"]:checked ~ input.sheet-use-cb-3, +input.sheet-max-radio[value="4"]:checked ~ input.sheet-use-cb-1, +input.sheet-max-radio[value="4"]:checked ~ input.sheet-use-cb-2, +input.sheet-max-radio[value="4"]:checked ~ input.sheet-use-cb-3, +input.sheet-max-radio[value="4"]:checked ~ input.sheet-use-cb-4, +input.sheet-max-radio[value="5"]:checked ~ input.sheet-use-cb-1, +input.sheet-max-radio[value="5"]:checked ~ input.sheet-use-cb-2, +input.sheet-max-radio[value="5"]:checked ~ input.sheet-use-cb-3, +input.sheet-max-radio[value="5"]:checked ~ input.sheet-use-cb-4, +input.sheet-max-radio[value="5"]:checked ~ input.sheet-use-cb-5 { + opacity: 1; + pointer-events: auto; + cursor: pointer; + background: var(--dg-toggle-bg-selected); + border: 1px solid var(--dg-toggle-border-selected); + /* Dark mode: .sheet-darkmode overrides --dg-toggle-bg-selected and --dg-toggle-border-selected + in variables.css, so this rule resolves correctly in both modes without a separate matrix. */ +} + /* ************************************************************************************************************************************************ */ /* Dark mode overrides */ /* ************************************************************************************************************************************************ */ @@ -929,6 +1123,43 @@ textarea.sheet-textarea-equipment { border-color: var(--dg-border-dark); } +.sheet-darkmode .sheet-uses-row { + border-color: var(--dg-border-dark); + background-color: var(--dg-surface-dark); +} + +.sheet-darkmode .sheet-uses-label { + color: var(--dg-text-muted-dark); +} + +.sheet-darkmode .sheet-max-pill { + color: var(--dg-toggle-fg-dark); + border-color: var(--dg-toggle-border-dark); + background: var(--dg-toggle-bg-dark); +} + +.sheet-darkmode input.sheet-max-radio:checked + .sheet-max-pill { + background: var(--dg-toggle-bg-selected-dark); + border: 1px solid var(--dg-toggle-border-selected-dark); + color: var(--dg-toggle-fg-selected-dark); +} + +.sheet-darkmode .sheet-uses-sep { + background: var(--dg-border-dark); +} + +.sheet-darkmode input.sheet-use-cb { + background: transparent; + border-color: var(--dg-border-dark); +} + +.sheet-darkmode input.sheet-use-cb:checked + .sheet-use-icon { + color: var(--dg-toggle-fg-selected-dark); +} + +/* Checked circles and enable selectors use the same red in dark mode — + base-rule specificity (0,4,2) already beats dark mode overrides (0,2,1), so no dark overrides needed */ + /* ************************************************************************************************************************************************ */ /* Mysic tab /* ************************************************************************************************************************************************ */ @@ -946,7 +1177,7 @@ textarea.sheet-textarea-equipment { } .sheet-spiritual-influence-image { - background: url("https://raw.githubusercontent.com/phaldenby72/roll20-character-sheets/refs/heads/demon-gate-attributes-and-defences/Demon%20Gate/circle_v2.png"); + background: url("https://raw.githubusercontent.com/Roll20/roll20-character-sheets/refs/heads/master/Demon%20Gate/circle_v2.png"); background-repeat: no-repeat; background-size: contain; background-position: center; @@ -1026,6 +1257,7 @@ tr.sheet-spell-spacer-row td { /* Roll template CSS variables - Roll20 requires these to be defined separately */ .sheet-rolltemplate-text, .sheet-rolltemplate-class-ability-text, +.sheet-rolltemplate-chi-power, .sheet-rolltemplate-percentile, .sheet-rolltemplate-attack, .sheet-rolltemplate-damage, @@ -1072,6 +1304,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-text .sheet-template-box, .sheet-rolltemplate-class-ability-text .sheet-template-box, +.sheet-rolltemplate-chi-power .sheet-template-box, .sheet-rolltemplate-percentile .sheet-template-box, .sheet-rolltemplate-attack .sheet-template-box, .sheet-rolltemplate-damage .sheet-template-box, @@ -1089,6 +1322,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-text .sheet-template-text, .sheet-rolltemplate-class-ability-text .sheet-template-text, +.sheet-rolltemplate-chi-power .sheet-template-text, .sheet-rolltemplate-percentile .sheet-template-text, .sheet-rolltemplate-spell-description .sheet-template-text { font-size: 13px; @@ -1100,6 +1334,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-text .sheet-template-title, .sheet-rolltemplate-class-ability-text .sheet-template-title, +.sheet-rolltemplate-chi-power .sheet-template-title, .sheet-rolltemplate-percentile .sheet-template-title, .sheet-rolltemplate-attack .sheet-template-title, .sheet-rolltemplate-damage .sheet-template-title, @@ -1126,6 +1361,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-text .sheet-template-title::before, .sheet-rolltemplate-class-ability-text .sheet-template-title::before, +.sheet-rolltemplate-chi-power .sheet-template-title::before, .sheet-rolltemplate-percentile .sheet-template-title::before, .sheet-rolltemplate-attack .sheet-template-title::before, .sheet-rolltemplate-damage .sheet-template-title::before, @@ -1149,6 +1385,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-text .sheet-template-subtitle, .sheet-rolltemplate-class-ability-text .sheet-template-subtitle, +.sheet-rolltemplate-chi-power .sheet-template-subtitle, .sheet-rolltemplate-percentile .sheet-template-subtitle, .sheet-rolltemplate-attack .sheet-template-subtitle, .sheet-rolltemplate-damage .sheet-template-subtitle, @@ -1170,6 +1407,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-darkmode.sheet-rolltemplate-text .sheet-template-title, .sheet-rolltemplate-darkmode.sheet-rolltemplate-class-ability-text .sheet-template-title, +.sheet-rolltemplate-darkmode.sheet-rolltemplate-chi-power .sheet-template-title, .sheet-rolltemplate-darkmode.sheet-rolltemplate-percentile .sheet-template-title, .sheet-rolltemplate-darkmode.sheet-rolltemplate-attack .sheet-template-title, .sheet-rolltemplate-darkmode.sheet-rolltemplate-damage .sheet-template-title, @@ -1186,6 +1424,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-darkmode.sheet-rolltemplate-text .sheet-template-subtitle, .sheet-rolltemplate-darkmode.sheet-rolltemplate-class-ability-text .sheet-template-subtitle, +.sheet-rolltemplate-darkmode.sheet-rolltemplate-chi-power .sheet-template-subtitle, .sheet-rolltemplate-darkmode.sheet-rolltemplate-percentile .sheet-template-subtitle, .sheet-rolltemplate-darkmode.sheet-rolltemplate-attack .sheet-template-subtitle, .sheet-rolltemplate-darkmode.sheet-rolltemplate-damage .sheet-template-subtitle, @@ -1202,6 +1441,7 @@ tr.sheet-spell-spacer-row td { /* Divider styling for roll templates that use them */ .sheet-rolltemplate-class-ability-text .sheet-template-hr, +.sheet-rolltemplate-chi-power .sheet-template-hr, .sheet-rolltemplate-percentile .sheet-template-hr, .sheet-rolltemplate-attack .sheet-template-hr, .sheet-rolltemplate-spell-description .sheet-template-hr, @@ -1221,6 +1461,7 @@ tr.sheet-spell-spacer-row td { /** Table styling for roll templates that use them */ .sheet-rolltemplate-class-ability-text th, +.sheet-rolltemplate-chi-power th, .sheet-rolltemplate-percentile th, .sheet-rolltemplate-spell-description th, .sheet-rolltemplate-spell-cast th, @@ -1241,6 +1482,7 @@ tr.sheet-spell-spacer-row td { } .sheet-rolltemplate-class-ability-text th span, +.sheet-rolltemplate-chi-power th span, .sheet-rolltemplate-percentile th span, .sheet-rolltemplate-attack th span, .sheet-rolltemplate-damage th span, @@ -1252,6 +1494,7 @@ tr.sheet-spell-spacer-row td { } .sheet-rolltemplate-class-ability-text td, +.sheet-rolltemplate-chi-power td, .sheet-rolltemplate-percentile td, .sheet-rolltemplate-spell-description td, .sheet-rolltemplate-spell-cast td, @@ -1292,6 +1535,7 @@ tr.sheet-spell-spacer-row td { /* Dark mode text colour — th span overrides Roll20's html.dark th !important; td/text elements get full amber */ .sheet-rolltemplate-darkmode.sheet-rolltemplate-class-ability-text th span, +.sheet-rolltemplate-darkmode.sheet-rolltemplate-chi-power th span, .sheet-rolltemplate-darkmode.sheet-rolltemplate-percentile th span, .sheet-rolltemplate-darkmode.sheet-rolltemplate-attack th span, .sheet-rolltemplate-darkmode.sheet-rolltemplate-damage th span, @@ -1304,6 +1548,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-darkmode.sheet-rolltemplate-text td, .sheet-rolltemplate-darkmode.sheet-rolltemplate-class-ability-text td, +.sheet-rolltemplate-darkmode.sheet-rolltemplate-chi-power td, .sheet-rolltemplate-darkmode.sheet-rolltemplate-percentile td, .sheet-rolltemplate-darkmode.sheet-rolltemplate-attack td, .sheet-rolltemplate-darkmode.sheet-rolltemplate-damage td, @@ -1318,6 +1563,7 @@ tr.sheet-spell-spacer-row td { .sheet-rolltemplate-darkmode.sheet-rolltemplate-text .sheet-template-text, .sheet-rolltemplate-darkmode.sheet-rolltemplate-class-ability-text .sheet-template-text, +.sheet-rolltemplate-darkmode.sheet-rolltemplate-chi-power .sheet-template-text, .sheet-rolltemplate-darkmode.sheet-rolltemplate-percentile .sheet-template-text, .sheet-rolltemplate-darkmode.sheet-rolltemplate-spell-description .sheet-template-text, .sheet-rolltemplate-darkmode.sheet-rolltemplate-simple .sheet-template-text-prominent, @@ -1329,6 +1575,7 @@ tr.sheet-spell-spacer-row td { /* Dark mode support */ .sheet-rolltemplate-darkmode.sheet-rolltemplate-text .sheet-template-box, .sheet-rolltemplate-darkmode.sheet-rolltemplate-class-ability-text .sheet-template-box, +.sheet-rolltemplate-darkmode.sheet-rolltemplate-chi-power .sheet-template-box, .sheet-rolltemplate-darkmode.sheet-rolltemplate-percentile .sheet-template-box, .sheet-rolltemplate-darkmode.sheet-rolltemplate-attack .sheet-template-box, .sheet-rolltemplate-darkmode.sheet-rolltemplate-damage .sheet-template-box, diff --git a/Demon Gate/DemonGate.html b/Demon Gate/DemonGate.html index 3c61ce58d5..a7b1d4170c 100644 --- a/Demon Gate/DemonGate.html +++ b/Demon Gate/DemonGate.html @@ -4,6 +4,7 @@ updateAllAttributes(); updateAllSkills(); + updateUnarmed(); }); // Latest sheet version - used for migration purposes @@ -1037,6 +1038,13 @@ }); }); + on( + "change:helmetar change:amuletar change:cloakar change:pauldronsar change:clothingar change:torsoar change:bracersar change:glovesar change:beltar change:greavesar change:bootar change:ringar change:ring2ar change:otherar change:other2ar", + function () { + updateTotalArmorRating(); + } + ); + function updateBody() { getAttrs(["BdyBase", "BdyBonus", "BdyRace", "HPAdj", "MaxHP", "ToughBonus"], function (values) { let total = Number(values.BdyBase) + Number(values.BdyBonus) + Number(values.BdyRace); @@ -1993,25 +2001,55 @@ let racialUnarmedAttackName = ""; let racialUnarmedAttackDamage = getDice(rank); + let racialUnarmedAttackDesc = ""; + if (values.Race == "mungreel") { racialUnarmedAttackName = "Blade Teeth"; racialUnarmedAttackDamage = "d12!"; - } else if (values.Race == "mhentep") { + racialUnarmedAttackDesc = + "A natural bite attack using the Mungreel's razor-edged serrated teeth. Deals d12 damage independently of unarmed combat rank. Can be combined with other unarmed attacks using additional actions."; + } else if (values.Race == "mhentep" || values.Race == "sharpheen" || values.Race == "mulpheen") { racialUnarmedAttackName = "Claws"; racialUnarmedAttackDamage = unarmedDamage + "+3"; + racialUnarmedAttackDesc = + "Powerful natural claws that add +3 damage to all unarmed attacks. Stacks with unarmed combat specialization."; + } else if (values.Race == "kuthalan") { + racialUnarmedAttackName = "Chitin"; + racialUnarmedAttackDamage = unarmedDamage + "+1"; + racialUnarmedAttackDesc = + "Hardened chitin plating on the fists and forearms adds +1 damage to all unarmed attacks."; + } else if (values.Race == "tarkanys") { + racialUnarmedAttackName = "Bite"; + racialUnarmedAttackDamage = "d8!"; + racialUnarmedAttackDesc = + "A natural bite attack dealing d8 damage independently of unarmed combat rank. Can be combined with other unarmed attacks using additional actions."; + } else if (values.Race == "minotaur") { + racialUnarmedAttackName = "Therian Charge"; + racialUnarmedAttackDamage = ""; + racialUnarmedAttackDesc = "Damage bonus depends on distance charged."; + } else if (values.Race == "mutant") { + racialUnarmedAttackName = "Vatagi Natural Weapon"; + racialUnarmedAttackDamage = ""; + racialUnarmedAttackDesc = + "Varies. Use the 'alternate unarmed' field to detail this character's specific mutation."; } else { // Most races don't have special unarmed abilities - racialUnarmedAttackName = "None"; + racialUnarmedAttackName = "Racial Unarmed"; + racialUnarmedAttackDesc = + "No racial unarmed attack specified. Use the 'alternate unarmed' field if needed."; } // Update all attributes in a single call setAttrs({ UnarmedHit: Number(values.Unarmed), + AltUnarmedHit: Number(values.Unarmed), + RacialUnarmedHit: Number(values.Unarmed), UnarmedRank: baseRank, UnarmedDmg: unarmedDamage, UnarmedDisplayName: unarmedDisplayName, RacialUnarmedName: racialUnarmedAttackName, - RacialUnarmedDmg: racialUnarmedAttackDamage + RacialUnarmedDmg: racialUnarmedAttackDamage, + RacialUnarmedAccessory: racialUnarmedAttackDesc }); }); } @@ -2033,6 +2071,45 @@ return unarmedNames[unarmedValue] || "Unarmed: Basic"; } + /* CLASS ABILITY USAGE TRACKING */ + + // Reset All Uses button: clears every row's use checkboxes at once. + // Placed outside the repeating section so type="action" + clicked fires reliably. + on("clicked:ClassAbilResetAll", function () { + getSectionIDs("classabilities", function (ids) { + const updates = {}; + ids.forEach(function (id) { + const prefix = "repeating_classabilities_" + id + "_"; + for (let i = 1; i <= 5; i++) { + updates[prefix + "ClassAbilUse" + i] = "0"; + } + }); + if (Object.keys(updates).length > 0) { + setAttrs(updates); + } + }); + }); + + // When Max. Uses changes: clear any checkboxes that are now beyond the new maximum. + // The pill radio buttons are the CSS driver directly, so no hidden radio sync is needed. + on("change:repeating_classabilities:ClassAbilMaxUses", function (eventInfo) { + const src = eventInfo.sourceAttribute; + const prefix = src.substring(0, src.lastIndexOf("_") + 1); + + getAttrs([src], function (values) { + const max = Number(values[src]) || 0; + const updates = {}; + + for (let i = max + 1; i <= 5; i++) { + updates[prefix + "ClassAbilUse" + i] = "0"; + } + + if (Object.keys(updates).length > 0) { + setAttrs(updates); + } + }); + }); + on("change:honorrep change:corruptrep", function () { getAttrs(["HonorRep", "CorruptRep"], function (values) { const goodRepDetails = getReputationDetails(values.HonorRep); @@ -3366,6 +3443,8 @@ Base Bonus Total + Rank + Dice @@ -5921,7 +6000,7 @@ - + @@ -5958,7 +6037,7 @@ @@ -5975,7 +6054,7 @@ @@ -5992,7 +6071,7 @@ @@ -6009,7 +6088,7 @@ @@ -6026,7 +6105,7 @@ @@ -6043,7 +6122,7 @@ @@ -6060,7 +6139,7 @@ @@ -6077,7 +6156,7 @@ @@ -6094,7 +6173,7 @@ @@ -6111,7 +6190,7 @@ @@ -6409,846 +6488,1136 @@
-

Weapons

+

Unarmed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Unarmed

-
NameHit BonusSpecializationHit
- - - - - - - -
AccessoryBonus DmgDamageDmg
- - - - - - - - - -
NameHit BonusSpecializationHit
- - - - - - - -
AccessoryBonus DmgDamageDmg
- - - - - - - -
NameHit BonusSpecializationHit
- - - - - - - -
AccessoryBonus DmgDamageDmg
- - - - - - - -
+
+

Primary Unarmed

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + + + +
Notes
+ +
+
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Primary Weapon

-
NameHit BonusSpecializationHit
- - - - - - - -
Bonus DmgDamageDmg
Damage: - - - - - -
Accessory: - -
Type: - -
Durability: - -
Weight: - -
Ammo: - -
+
+

Alternate Unarmed

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes
+ +
+
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Secondary Weapon

-
NameHit BonusSpecializationHit
- - - - - - - -
Bonus DmgDamageDmg
Damage: - - - - - -
Accessory: - -
Type: - -
Durability: - -
Weight: - -
Ammo: - -
+
+

Racial Unarmed

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes
+ +
+
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Third Weapon

-
NameHit BonusSpecializationHit
- - - - - - - -
Bonus DmgDamageDmg
Damage: - - - - - -
Accessory: - -
Type: - -
Durability: - -
Weight: - -
Ammo: - -
+

Weapons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Fourth Weapon

-
NameHit BonusSpecializationHit
- - - - - - - -
Bonus DmgDamageDmg
Damage: - - - - - -
Accessory: - -
Type: - -
Durability: - -
Weight: - -
Ammo: - -
+
+

Primary Weapon

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes: + +
Type: + +
Durability: + +
Weight: + +
Ammo: + +
+
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Fifth Weapon

-
NameHit BonusSpecializationHit
- - - - - - - -
Bonus DmgDamageDmg
Damage: - - - - - -
Accessory: - -
Type: - -
Durability: - -
Weight: - -
Ammo: - -
+
+

Secondary Weapon

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes: + +
Type: + +
Durability: + +
Weight: + +
Ammo: + +
+
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Sixth Weapon

-
NameHit BonusSpecializationHit
- - - - - - - -
Bonus DmgDamageDmg
Damage: - - - - - -
Accessory: - -
Type: - -
Durability: - -
Weight: - -
Ammo: - -
+
+

Third Weapon

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes: + +
Type: + +
Durability: + +
Weight: + +
Ammo: + +
+
+
+
+ +
+

Fourth Weapon

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes: + +
Type: + +
Durability: + +
Weight: + +
Ammo: + +
+
+
+
+ +
+

Fifth Weapon

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes: + +
Type: + +
Durability: + +
Weight: + +
Ammo: + +
+
+
+
+ +
+

Sixth Weapon

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameHit BonusSpecializationHit
+ + + + + + + +
Bonus DmgDamageDmg
Damage: + + + + + +
Notes: + +
Type: + +
Durability: + +
Weight: + +
Ammo: + +
+
+
+
@@ -7314,250 +7683,342 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Armor

-
SlotNameWeightDurabilityArmor Rating
Helmet - - - - - - - -
Amulet - - - - - - - -
Cloak - - - - - - - -
Pauldrons - - - - - - - -
Clothing - - - - - - - -
Torso - - - - - - - -
Bracers - - - - - - - -
Gloves - - - - - - - -
Belt - - - - - - - -
Greaves - - - - - - - -
Boots - - - - - - - -
Ring - - - - - - - -
Ring - - - - - - - -
Other - - - - - - - -
Other - - - - - - - -
+
+

Armor

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SlotNameWeightDurabilityArmor Rating
Helmet + + + + + + + +
Amulet + + + + + + + +
Cloak + + + + + + + +
Pauldrons + + + + + + + +
Clothing + + + + + + + +
Torso + + + + + + + +
Bracers + + + + + + + +
Gloves + + + + + + + +
Belt + + + + + + + +
Greaves + + + + + + + +
Boots + + + + + + + +
Ring + + + + + + + +
Ring + + + + + + + +
Other + + + + + + + +
Other + + + + + + + +
Total Armor Value + +
+
+
+

Valuables

@@ -7776,7 +8237,7 @@ - Accessories + Notes @@ -7992,7 +8453,7 @@ @@ -8067,7 +8528,7 @@ @@ -8142,7 +8603,7 @@ @@ -8217,7 +8678,7 @@ @@ -8292,7 +8753,7 @@ @@ -8367,7 +8828,7 @@ @@ -8442,7 +8903,7 @@ @@ -8517,7 +8978,7 @@ @@ -8592,7 +9053,7 @@ @@ -8667,7 +9128,7 @@ @@ -8756,7 +9217,7 @@ @@ -8831,7 +9292,7 @@ @@ -8906,7 +9367,7 @@ @@ -8981,7 +9442,7 @@ @@ -9056,7 +9517,7 @@ @@ -9131,7 +9592,7 @@ @@ -9206,7 +9667,7 @@ @@ -9281,7 +9742,7 @@ @@ -9356,7 +9817,7 @@ @@ -9431,7 +9892,7 @@ @@ -9521,7 +9982,7 @@ @@ -9544,10 +10005,10 @@
-

Chi Abilities

+

Chi Powers

-

Abilities

+

Powers

- + + + + + @@ -9683,7 +10154,7 @@
-

Racial Abilities

+

Racial Powers

@@ -9803,6 +10274,9 @@

Class Abilities

+
@@ -9826,6 +10300,83 @@
+
+ Max + + N/A + + 1 + + 2 + + 3 + + 4 + + 5 + + Used + × + × + × + × + × +
+ +
+
+
{{name}}
+
{{character}}
+ + + + + + + + + + +
Rating{{rating}}
Drain{{drain}}
+ +
+ +
{{description}}
+
+
+
+