feat: dying label and Roll Recovery button in InitiativeTracker active phase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
52f792d63b
commit
bf7db6bd4c
2 changed files with 55 additions and 8 deletions
|
|
@ -302,3 +302,27 @@
|
||||||
border-color: rgba(var(--gold-rgb), 0.5);
|
border-color: rgba(var(--gold-rgb), 0.5);
|
||||||
color: var(--gold);
|
color: var(--gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dyingTag {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: var(--danger);
|
||||||
|
font-weight: 600;
|
||||||
|
margin-left: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recoveryBtn {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
padding: 0.15rem 0.4rem;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--danger);
|
||||||
|
color: var(--danger);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recoveryBtn:hover {
|
||||||
|
background: rgba(var(--danger-rgb), 0.12);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@ export default function InitiativeTracker({
|
||||||
socket.emit("initiative:end", { campaignId, combatId: combat.id });
|
socket.emit("initiative:end", { campaignId, combatId: combat.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emitRecoveryRoll(characterId: number) {
|
||||||
|
socket.emit("death:recovery-roll", { campaignId, characterId });
|
||||||
|
}
|
||||||
|
|
||||||
function emitUpdateEnemyHp(enemyId: string, hp_current: number) {
|
function emitUpdateEnemyHp(enemyId: string, hp_current: number) {
|
||||||
socket.emit("initiative:update-enemy", {
|
socket.emit("initiative:update-enemy", {
|
||||||
campaignId,
|
campaignId,
|
||||||
|
|
@ -119,6 +123,7 @@ export default function InitiativeTracker({
|
||||||
onAddEnemy={emitAddEnemy}
|
onAddEnemy={emitAddEnemy}
|
||||||
onNext={emitNext}
|
onNext={emitNext}
|
||||||
onEnd={emitEnd}
|
onEnd={emitEnd}
|
||||||
|
onRecoveryRoll={emitRecoveryRoll}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -232,6 +237,7 @@ interface ActivePhaseProps {
|
||||||
onAddEnemy: () => void;
|
onAddEnemy: () => void;
|
||||||
onNext: () => void;
|
onNext: () => void;
|
||||||
onEnd: () => void;
|
onEnd: () => void;
|
||||||
|
onRecoveryRoll: (characterId: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ActivePhase({
|
function ActivePhase({
|
||||||
|
|
@ -249,6 +255,7 @@ function ActivePhase({
|
||||||
onAddEnemy,
|
onAddEnemy,
|
||||||
onNext,
|
onNext,
|
||||||
onEnd,
|
onEnd,
|
||||||
|
onRecoveryRoll,
|
||||||
}: ActivePhaseProps) {
|
}: ActivePhaseProps) {
|
||||||
const partyActive = combat.current_side === "party";
|
const partyActive = combat.current_side === "party";
|
||||||
|
|
||||||
|
|
@ -263,14 +270,30 @@ function ActivePhase({
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{partyChars.map((c) => (
|
{partyChars.map((c) => {
|
||||||
|
const dyingCondition = c.conditions?.find((cond) => cond.name === "Dying");
|
||||||
|
return (
|
||||||
<div key={c.id} className={styles.combatantRow}>
|
<div key={c.id} className={styles.combatantRow}>
|
||||||
<span className={styles.dot} style={{ background: c.color }} />
|
<span className={styles.dot} style={{ background: c.color }} />
|
||||||
<span className={partyActive ? styles.activeName : styles.rollName}>
|
<span className={partyActive ? styles.activeName : styles.rollName}>
|
||||||
{c.name}
|
{c.is_dead ? "\u{1F480} " : ""}{c.name}
|
||||||
</span>
|
</span>
|
||||||
|
{dyingCondition && (
|
||||||
|
<span className={styles.dyingTag}>
|
||||||
|
{"\u{1F480}"} Dying ({dyingCondition.rounds_remaining}r)
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{isDM && dyingCondition && !c.is_dead && (
|
||||||
|
<button
|
||||||
|
className={styles.recoveryBtn}
|
||||||
|
onClick={() => onRecoveryRoll(c.id)}
|
||||||
|
>
|
||||||
|
Roll Recovery
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${styles.section} ${!partyActive ? styles.activeSection : ""}`}>
|
<div className={`${styles.section} ${!partyActive ? styles.activeSection : ""}`}>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue