vagabond-rpg-foundryvtt/templates/chat/save-roll.hbs
Cal Corum 27a5f481aa Implement attack and save roll systems with difficulty fix
Phase 2 Tasks 2.6 & 2.7: Complete roll dialog system
- Add AttackRollDialog with weapon selection, grip toggle, attack type display
- Add SaveRollDialog with save type selection, defense options (block/dodge)
- Fix Handlebars template context resolution bug ({{this.difficulty}} pattern)
- Calculate difficulty once in dialog, pass to roll function via options
- Add difficulty/critThreshold pass-through tests for skill checks
- Fix attack check tests: use embedded items, correct damageType to "slashing"
- Add i18n strings for saves, attacks, defense types
- Add chat card and dialog styles for all roll types
- Export all roll dialogs and create system macros

Key technical fix: Handlebars was resolving {{difficulty}} through context
chain to actor.system.skills.X.difficulty (schema default 20) instead of
root template data. Using {{this.difficulty}} explicitly references root.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 19:52:28 -06:00

98 lines
3.1 KiB
Handlebars

{{!-- Save Roll Chat Card Template --}}
{{!-- Displays save results with stats used and success/fail --}}
<div class="vagabond chat-card save-roll">
{{!-- Header --}}
<header class="card-header">
<h3 class="save-name">
<i class="fa-solid fa-shield-halved"></i>
{{saveLabel}} {{localize "VAGABOND.Save"}}
</h3>
{{#if isDefense}}
<span class="defense-badge {{defenseType}}">{{defenseLabel}}</span>
{{/if}}
</header>
{{!-- Roll Result --}}
<div class="roll-result {{#if isCrit}}critical{{else if isFumble}}fumble{{else if success}}success{{else}}failure{{/if}}">
<div class="roll-total">{{total}}</div>
<div class="roll-status">
{{#if isCrit}}
<span class="status critical">{{localize "VAGABOND.CriticalSuccess"}}</span>
{{else if isFumble}}
<span class="status fumble">{{localize "VAGABOND.Fumble"}}</span>
{{else if success}}
<span class="status success">{{localize "VAGABOND.Success"}}</span>
{{else}}
<span class="status failure">{{localize "VAGABOND.Failure"}}</span>
{{/if}}
</div>
</div>
{{!-- Roll Details --}}
<div class="roll-details">
<div class="roll-formula">
<span class="label">{{localize "VAGABOND.Formula"}}:</span>
<span class="value">{{formula}}</span>
</div>
<div class="roll-breakdown">
<span class="d20-result">
<i class="fa-solid fa-dice-d20"></i> {{d20Result}}
</span>
{{#if favorDie}}
<span class="favor-die {{#if (gt netFavorHinder 0)}}favor{{else}}hinder{{/if}}">
<i class="fa-solid fa-dice-d6"></i> {{favorDie}}
</span>
{{/if}}
{{#if modifier}}
<span class="modifier">
{{#if (gt modifier 0)}}+{{/if}}{{modifier}}
</span>
{{/if}}
</div>
</div>
{{!-- Save Info --}}
<div class="save-info">
<div class="stats-used">
<span class="label">{{localize "VAGABOND.Stats"}}:</span>
<span class="value">
{{#each stats}}
<span class="stat-abbr">{{this}}</span>{{#unless @last}} + {{/unless}}
{{/each}}
</span>
</div>
<div class="difficulty">
<span class="label">{{localize "VAGABOND.Difficulty"}}:</span>
<span class="value">{{this.difficulty}}</span>
</div>
</div>
{{!-- Defense Info --}}
{{#if isDefense}}
<div class="defense-info-display">
{{#if (eq defenseType 'block')}}
<i class="fa-solid fa-shield"></i>
<span>{{localize "VAGABOND.BlockedWith"}}</span>
{{else if (eq defenseType 'dodge')}}
<i class="fa-solid fa-person-running"></i>
<span>{{localize "VAGABOND.DodgedAttack"}}</span>
{{/if}}
</div>
{{/if}}
{{!-- Favor/Hinder Sources --}}
{{#if favorSources.length}}
<div class="favor-sources">
<i class="fa-solid fa-arrow-up"></i>
<span>{{localize "VAGABOND.Favor"}}: {{#each favorSources}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}</span>
</div>
{{/if}}
{{#if hinderSources.length}}
<div class="hinder-sources">
<i class="fa-solid fa-arrow-down"></i>
<span>{{localize "VAGABOND.Hinder"}}: {{#each hinderSources}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}</span>
</div>
{{/if}}
</div>