Files
Vanity/templates/character-sheet.hbs
T
slaguru666andClaude Opus 4.8 3b7d6e778d Straining the Weave (§17) — v0.9.8
Repeated castings of the same spell in one scene now raise its Threshold
by +1 per prior cast, as the rules have always said. The sheet shows the
current Threshold with a +N badge, "Settle the Weave" clears the scene's
strain, and both rests settle it automatically.

Implemented in the VRPG source; this repo carries the published system.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 14:58:50 +01:00

363 lines
19 KiB
Handlebars
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<form class="{{cssClass}} vanity-sheet" autocomplete="off">
{{!-- Header --}}
<header class="v-head">
<img class="v-portrait" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<div class="v-title">
<input class="v-name" name="name" type="text" value="{{actor.name}}" placeholder="Name" />
<div class="v-sub">
<input name="system.details.class" type="text" value="{{sys.details.class}}" placeholder="Class" />
<span>·</span>
<input name="system.details.concept" type="text" value="{{sys.details.concept}}" placeholder="Concept" />
</div>
</div>
<div class="v-motto">“Be vain and you shine —<br>but the brighter you burn, the bigger the bill.”</div>
</header>
{{#if sys.takenOut}}<div class="v-banner out">TAKEN OUT — the fiction decides how badly</div>
{{else if sys.rattled}}<div class="v-banner rattled">RATTLED — −1 die on everything until you recover</div>{{/if}}
{{#if sys.reckoning}}<div class="v-banner reckoning">SIX BANES — THE RECKONING IS DUE</div>{{/if}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="main">Character</a>
<a class="item" data-tab="combat">Combat &amp; Gear</a>
{{#if hasSpells}}<a class="item" data-tab="magic">Magic</a>{{/if}}
<a class="item" data-tab="story">Story</a>
</nav>
<section class="sheet-body">
{{!-- ============ TAB: CHARACTER ============ --}}
<div class="tab" data-tab="main" data-group="primary">
<div class="v-cols">
<div>
<div class="sect">
<div class="bar">Attributes · click to roll · right-click to save</div>
<div class="body">
{{#each attributes}}
<div class="attr" data-attr="{{key}}">
<div class="num" title="Roll {{label}}">{{value}}</div>
<div class="meta">
<div class="nm">{{label}}</div>
<div class="ds">{{desc}}</div>
</div>
<input class="attr-input" type="number" name="system.attributes.{{key}}.value" value="{{value}}" min="1" max="5" />
</div>
{{/each}}
<div class="hint">Pool = Attribute + Knack + situation. 5–6 = a Success. Fail with two 1s = a Stumble (1 Bane).</div>
</div>
</div>
<div class="sect">
<div class="bar">Grit · staying power</div>
<div class="body">
<div class="grit-row">
<label class="mini">Current <input type="number" name="system.grit.value" value="{{sys.grit.value}}" min="0" /></label>
<label class="mini">Max <input type="number" name="system.grit.max" value="{{sys.grit.max}}" min="1" max="14" /></label>
</div>
<div class="track">
{{#each gritCells}}
<div class="grit-cell cell {{#if filled}}filled{{/if}} {{#if half}}half{{/if}}" data-i="{{i}}"><span>{{i}}</span></div>
{{/each}}
</div>
<div class="hint">Half lost = Rattled (−1 die). Emptied = Taken Out. Refuse to Fall: 1 Vanity → stop at 1 Grit (+2 Banes).</div>
</div>
</div>
<div class="sect">
<div class="bar">Vanity · Karma · Glory</div>
<div class="body">
<div class="resrow">
<span class="rl v">Vanity</span>
<div class="pips">
{{#each vanityPips}}<i class="pip pip-btn {{#if filled}}filled{{/if}}" data-res="vanity" data-i="{{i}}"></i>{{/each}}
</div>
</div>
<div class="resnote">Start 3. Spend: +1 die · go first · Refuse to Fall.</div>
<div class="resrow">
<span class="rl k">Banes</span>
<div class="pips">
{{#each karmaPips}}<i class="pip hex pip-btn {{#if filled}}filled{{/if}}" data-res="karma" data-i="{{i}}"></i>{{/each}}
</div>
</div>
<div class="resnote">Gain: Stumble · Push · Refuse to Fall · your Vice. 6 → THE RECKONING (2d6, §21b). Clear by humility &amp; rest.</div>
<div class="resrow glory">
<span class="rl">Glory</span>
<input type="number" name="system.glory" value="{{sys.glory}}" min="0" />
<span class="resnote">1–3 per session · spend between sessions to advance</span>
</div>
</div>
</div>
</div>
<div>
<div class="sect">
<div class="bar">Knacks · click name to roll · click rank to train</div>
<div class="body">
{{#each knacks}}
<div class="knack-row" data-knack="{{key}}">
<span class="kn" title="Roll {{attrLabel}} + {{label}}">{{label}} <em>{{attrLabel}}</em></span>
<span class="pool">{{pool}}d</span>
<span class="rank r{{rank}}" title="{{rankLabel}}">
<i class="ck {{#if (gt rank 0)}}on{{/if}}"></i><i class="ck {{#if (gt rank 1)}}on{{/if}}"></i>
</span>
</div>
{{/each}}
<div class="locked">
<div class="t">Locked Knack — your class key</div>
<div class="locked-row">
<select name="system.locked.name">
<option value=""></option>
{{#each lockedNames}}<option value="{{this}}" {{#if (eq this ../sys.locked.name)}}selected{{/if}}>{{this}}</option>{{/each}}
</select>
<select name="system.locked.attribute">
{{#each lockedAttrs}}<option value="{{this}}" {{#if (eq this ../sys.locked.attribute)}}selected{{/if}}>{{this}}</option>{{/each}}
</select>
<select name="system.locked.rank" data-dtype="Number">
{{#each rankOptions}}{{#if @index}}<option value="{{@index}}" {{#if (eq @index ../sys.locked.rank)}}selected{{/if}}>{{this}}</option>{{/if}}{{/each}}
</select>
<button type="button" class="locked-roll" title="Roll the Locked Knack"><i class="fa-solid fa-dice-d6"></i> {{lockedPool}}d</button>
</div>
</div>
</div>
</div>
<div class="sect">
<div class="bar">Vice — your vanity flaw</div>
<div class="body">
{{#each vices}}
<div class="item-row" data-item-id="{{id}}">
<span class="item-name">{{name}}</span>
<span class="item-note">{{system.trigger}}</span>
<button type="button" class="vice-play" title="Play your Vice: +1 Vanity now, the GM banks a Bane for later">Play it</button>
<a class="item-edit" title="Edit"><i class="fa-solid fa-pen"></i></a>
<a class="item-delete" title="Delete"><i class="fa-solid fa-trash"></i></a>
</div>
{{/each}}
{{#unless vices.length}}<div class="hint">Drag a Vice from the compendium, or <a class="item-create" data-type="vice">create one</a>. Playing it earns +1 Vanity now — and the GM a Bane for later.</div>{{/unless}}
</div>
</div>
<div class="sect">
<div class="bar">Class Edges</div>
<div class="body">
{{#each edges}}
<div class="item-row" data-item-id="{{id}}">
<span class="item-name">{{name}}</span>
<a class="item-edit" title="Edit"><i class="fa-solid fa-pen"></i></a>
<a class="item-delete" title="Delete"><i class="fa-solid fa-trash"></i></a>
</div>
{{/each}}
<div class="hint"><a class="item-create" data-type="edge">Add an edge</a></div>
</div>
</div>
</div>
</div>
</div>
{{!-- ============ TAB: COMBAT & GEAR ============ --}}
<div class="tab" data-tab="combat" data-group="primary">
<div class="v-quickbar">
<button type="button" class="roll-draw"><i class="fa-solid fa-bolt"></i> The Draw (1d6)</button>
<button type="button" class="roll-dodge"><i class="fa-solid fa-person-running"></i> Dodge {{sys.dodgePool}}d</button>
<button type="button" class="roll-block"><i class="fa-solid fa-shield-halved"></i> Block {{sys.blockPool}}d</button>
<button type="button" class="refuse-fall" title="A blow would empty your Grit: spend 1 Vanity to stop at 1 Grit (+2 Banes)"><i class="fa-solid fa-hand"></i> Refuse to Fall</button>
</div>
<div class="v-quickbar">
<button type="button" class="rest-breather" title="A quiet scene: recover 2 Grit"><i class="fa-solid fa-lungs"></i> Breather (+2 Grit)</button>
<button type="button" class="rest-full" title="A proper rest: all Grit, clear 1 Bane, recover spent spells"><i class="fa-solid fa-bed"></i> Proper Rest</button>
</div>
<div class="sect">
<div class="bar">Weapons · click ⚔ to attack</div>
<div class="body">
<table class="v-table">
<thead><tr><th></th><th>Weapon</th><th>Dice</th><th>Properties</th><th class="ctrl"></th></tr></thead>
<tbody>
{{#each weapons}}
<tr data-item-id="{{id}}">
<td class="ctrl"><a class="item-attack" title="Attack"><i class="fa-solid fa-hand-fist"></i></a></td>
<td class="item-name">{{name}}</td>
<td>+{{system.dice}}</td>
<td class="props">{{system.properties}}</td>
<td class="ctrl"><a class="item-edit"><i class="fa-solid fa-pen"></i></a> <a class="item-delete"><i class="fa-solid fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
<div class="hint"><a class="item-create" data-type="weapon">Add a weapon</a> · net 1 = 1 Grit; each extra Success = +1 damage or a Special Attack.</div>
<label class="f"><span class="cap">Fighting style</span>
<input type="text" name="system.details.fightingStyle" value="{{sys.details.fightingStyle}}" placeholder="Sword &amp; Shield · Two-Weapon · Two-Handed · Ranged" /></label>
</div>
</div>
<div class="v-cols">
<div class="sect">
<div class="bar">Armour &amp; Defence</div>
<div class="body">
{{#each armour}}
<div class="item-row" data-item-id="{{id}}">
<a class="item-equip" title="Toggle equipped"><i class="fa-solid {{#if system.equipped}}fa-circle-check{{else}}fa-circle{{/if}}"></i></a>
<span class="item-name {{#unless system.equipped}}unequipped{{/unless}}">{{name}}</span>
<span class="item-note">+{{system.defence}} {{system.kind}}{{#if system.perk}} · {{system.perk}}{{/if}}</span>
<a class="item-edit"><i class="fa-solid fa-pen"></i></a>
<a class="item-delete"><i class="fa-solid fa-trash"></i></a>
</div>
{{/each}}
<div class="hint"><a class="item-create" data-type="armour">Add armour</a> · Defend with Flair (dodge) or Brawn (block) + armour + shield. Armour never stops spells.</div>
</div>
</div>
<div class="sect">
<div class="bar">Gear · Load {{slotsUsed}} / {{sys.load}}</div>
<div class="body">
{{#each gear}}
<div class="item-row" data-item-id="{{id}}">
<span class="item-name">{{name}}</span>
<span class="item-note">{{#if (gt system.quantity 1)}}×{{system.quantity}}{{/if}}</span>
<a class="item-edit"><i class="fa-solid fa-pen"></i></a>
<a class="item-delete"><i class="fa-solid fa-trash"></i></a>
</div>
{{/each}}
<div class="hint"><a class="item-create" data-type="gear">Add gear</a></div>
<div class="coin-row">
<span class="cap">Coin</span>
<label>gp <input type="number" name="system.details.coin.gp" value="{{sys.details.coin.gp}}" /></label>
<label>sp <input type="number" name="system.details.coin.sp" value="{{sys.details.coin.sp}}" /></label>
<label>cp <input type="number" name="system.details.coin.cp" value="{{sys.details.coin.cp}}" /></label>
</div>
</div>
</div>
</div>
<div class="ref">
<h3>Special Attacks — spend net Successes</h3>
<div class="two">
<div><b>1</b>&nbsp; Disarm · Knock Down · Drive Back · Wound · Feint · Grapple · Find the Gap · Called Shot</div>
<div><b>2</b>&nbsp; Sunder · Cleave · Off-Balance (−2 dice) · Press (extra attack) · Environment</div>
</div>
</div>
</div>
{{!-- ============ TAB: MAGIC ============ --}}
{{#if hasSpells}}
<div class="tab" data-tab="magic" data-group="primary">
<div class="sect">
<div class="bar">Spells &amp; Nature Tricks · Threshold 1·2·3
{{#if strained}}<a class="strain-reset" title="The Weave is strained — clear this scene's repeats"><i class="fa-solid fa-rotate-left"></i> Settle the Weave</a>{{/if}}
</div>
<div class="body">
<table class="v-table">
<thead><tr><th></th><th>Spell</th><th>Thr</th><th>Effect · scaling</th><th class="ctrl"></th></tr></thead>
<tbody>
{{#each spells}}
<tr data-item-id="{{item.id}}" class="{{#if item.system.spent}}spent{{/if}}">
<td class="ctrl"><a class="item-cast" title="Cast"><i class="fa-solid fa-wand-sparkles"></i></a></td>
<td class="item-name">{{item.name}} <em class="listtag">{{listLabel}}</em></td>
<td>{{threshold}}{{#if strain}} <span class="strain-badge" title="Cast {{strain}}× this scene — Threshold {{item.system.threshold}} +{{strain}}">+{{strain}}</span>{{/if}}</td>
<td class="props">{{item.system.effect}}{{#if item.system.scaling}} · <em>{{item.system.scaling}}</em>{{/if}}</td>
<td class="ctrl">
<a class="item-spent" title="Toggle spent"><i class="fa-solid {{#if item.system.spent}}fa-battery-empty{{else}}fa-battery-full{{/if}}"></i></a>
<a class="item-edit"><i class="fa-solid fa-pen"></i></a>
<a class="item-delete"><i class="fa-solid fa-trash"></i></a>
</td>
</tr>
{{/each}}
</tbody>
</table>
<div class="hint"><a class="item-create" data-type="spell">Add a spell</a> · Meet the Threshold → works &amp; stays. Short → Fizzle (spent) or Push (+1 Bane); a failed Push = Catastrophe. Repeats in a scene raise the Threshold.</div>
</div>
</div>
</div>
{{/if}}
{{!-- ============ TAB: STORY ============ --}}
<div class="tab" data-tab="story" data-group="primary">
<div class="sect">
<div class="bar">Companion — the Bond
<button type="button" class="cmp-bond" title="Roll d10 on The Bond, or pick from the Animal Companions compendium"><i class="fa-solid fa-dice-d20"></i> Roll the Bond</button>
</div>
<div class="body companion-card">
<div class="cmp-art">
{{#if sys.companion.img}}<img src="{{sys.companion.img}}" alt="{{sys.companion.name}}" />
{{else}}<div class="cmp-art-empty"><i class="fa-solid fa-paw"></i></div>{{/if}}
</div>
<div class="cmp-body">
<div class="cmp-line">
<label class="f grow"><span class="cap">Name</span>
<input type="text" name="system.companion.name" value="{{sys.companion.name}}" placeholder="Ash…" /></label>
<label class="f grow"><span class="cap">Kind</span>
<input type="text" name="system.companion.kind" value="{{sys.companion.kind}}" placeholder="hawk" /></label>
</div>
<div class="cmp-line">
<label class="f"><span class="cap">Attack</span>
<input type="number" name="system.companion.pool" value="{{sys.companion.pool}}" /></label>
<label class="f"><span class="cap">Dodge</span>
<input type="number" name="system.companion.dodge" value="{{sys.companion.dodge}}" /></label>
<label class="f"><span class="cap">Grit</span>
<input type="number" name="system.companion.grit.value" value="{{sys.companion.grit.value}}" />
<span class="sl">/</span>
<input type="number" name="system.companion.grit.max" value="{{sys.companion.grit.max}}" /></label>
{{#if companionDowned}}<span class="cmp-downed">DOWNED — not dead</span>{{/if}}
</div>
<label class="f wide"><span class="cap">Trick</span>
<input type="text" name="system.companion.trick" value="{{sys.companion.trick}}" placeholder="its one distinctive knack…" /></label>
<div class="cmp-actions">
<span class="cap">Each round, one action</span>
<button type="button" class="cmp-act" data-act="help" title="It flanks, flushes or calls the shot: you gain +1 die">Help <b>+1 die</b></button>
<button type="button" class="cmp-act" data-act="harry" title="It worries a foe: −1 die, and you may treat it as flanked">Harry <b>−1 die</b></button>
<button type="button" class="cmp-act" data-act="guard" title="Reaction: it intercepts one hit meant for you">Guard <b>reaction</b></button>
<button type="button" class="cmp-roll" data-roll="attack" title="Roll the companion's attack pool"><i class="fa-solid fa-paw"></i> Attack</button>
<button type="button" class="cmp-roll" data-roll="dodge" title="Roll the companion's dodge"><i class="fa-solid fa-feather"></i> Dodge</button>
</div>
</div>
</div>
</div>
<div class="sect">
<div class="bar">Notes</div>
<div class="body">{{editor notesHTML target="system.notes" button=true editable=editable engine="prosemirror" collaborate=false}}</div>
</div>
<div class="sect">
<div class="bar">Biography</div>
<div class="body">{{editor bioHTML target="system.biography" button=true editable=editable engine="prosemirror" collaborate=false}}</div>
</div>
</div>
</section>
{{!-- Conditions — an even grid at the foot, across every tab; click to toggle & read below --}}
<div class="v-cond-foot">
<div class="v-cond-title">Conditions · click to set &amp; read</div>
<div class="v-conditions">
{{#each conditionGroups}}
{{#each items}}
<span class="cond-badge {{../group}} {{#if active}}on{{/if}}" data-cond="{{id}}" title="{{name}} — {{short}} · ends: {{ends}}">
<img src="{{img}}" alt=""><span class="cond-name">{{name}}</span>
</span>
{{/each}}
{{/each}}
</div>
</div>
{{#if focusCond}}
<div class="v-cond-detail {{focusCond.group}}">
<img src="{{focusCond.img}}" alt="">
<div class="cd-body">
<div class="cd-head"><span class="cd-name">{{focusCond.name}}</span>
<span class="cd-state {{#if focusCond.active}}on{{/if}}">{{#if focusCond.active}}active{{else}}not active{{/if}}</span></div>
<div class="cd-rules">{{{focusCond.rules}}}</div>
<div class="cd-ends"><b>Ends:</b> {{focusCond.ends}}</div>
</div>
</div>
{{/if}}
{{#if activeConditions.length}}
<div class="v-cond-active">
<span class="ca-title">In play:</span>
{{#each activeConditions}}
<a class="cond-read {{group}}" data-cond="{{id}}">{{name}}</a>
{{/each}}
</div>
{{/if}}
</form>