Add Crit Damage button for dying/stable participants
5e crit-at-0-HP rule: any crit damage while downed = +2 death-save failures.
Shared logic supported via applyHpChange(..., { isCriticalHit: true }) but UI
had no trigger. Normal Damage at 0 only added 1 fail.
handleCritDamage handler calls applyHpChange with isCriticalHit: true.
Button renders in HP block (right-aligned) for character/NPC participants
when dying or stable and combat started. Dead excluded (no-op).
This commit is contained in:
@@ -6,13 +6,6 @@ Backlog of bugs + long-term items. Milestones live in REWORK_PLAN.md.
|
||||
|
||||
|
||||
|
||||
### FEAT: critical damage button for dying/stable participants
|
||||
- Shared logic already supports `applyHpChange(..., { isCriticalHit:true })`.
|
||||
- UI only has normal Damage, which adds 1 failure at 0 HP.
|
||||
- Add button near Revive/Stabilize: **Crit Damage** / **Critical Hit**.
|
||||
- Use only for dying/stable character/NPC at 0 HP; adds 2 death-save failures.
|
||||
- Dead target remains dead; no action.
|
||||
|
||||
### dm list - keep active particpant in view (scroll)
|
||||
|
||||
### combat.js doesnt seem to actually exercise the add characters. there are no characters in the campaign. only in the encounter..
|
||||
|
||||
+16
-1
@@ -7,7 +7,7 @@ import {
|
||||
Play as PlayIcon, Pause as PauseIcon, SkipForward as SkipForwardIcon,
|
||||
StopCircle as StopCircleIcon, Users2, Dices, ChevronUp, ChevronDown, ScrollText,
|
||||
Maximize2, Minimize2, Moon, Coffee, Clock, ChevronRight, X,
|
||||
Undo2, Redo2
|
||||
Undo2, Redo2, Crosshair
|
||||
} from 'lucide-react';
|
||||
|
||||
// ----- UI feedback: toast (transient) + info modal (persistent) -----
|
||||
@@ -1153,6 +1153,16 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters, camp
|
||||
}
|
||||
};
|
||||
|
||||
const handleCritDamage = async (participantId) => {
|
||||
if (!db) return;
|
||||
try {
|
||||
// Any damage at 0 HP + isCriticalHit = 2 death-save failures (5e crit-at-0).
|
||||
await combatApplyHpChange(encounter, participantId, 'damage', 1, { isCriticalHit: true }, buildCtx(encounterPath));
|
||||
} catch (err) {
|
||||
showToast(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleCondition = async (participantId, conditionId) => {
|
||||
if (!db) return;
|
||||
try {
|
||||
@@ -1464,6 +1474,11 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters, camp
|
||||
/>
|
||||
</span>
|
||||
<span>HP: {p.currentHp}/{p.maxHp}</span>
|
||||
{hasDeathSaves && (participantStatus === 'dying' || participantStatus === 'stable') && encounter.isStarted && (
|
||||
<button onClick={() => handleCritDamage(p.id)} className="ml-auto px-2 py-0.5 text-xs rounded bg-red-900 hover:bg-red-800 text-red-100 border border-red-700" title="Critical hit at 0 HP: +2 death-save failures">
|
||||
<Crosshair size={12} className="inline mr-1" />Crit
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{participantStatus === 'dead' && (
|
||||
|
||||
Reference in New Issue
Block a user