Release v0.1.5 2026-07-12

This commit is contained in:
Warren H
2026-07-12 22:10:12 -04:00
parent bef71d391a
commit 35553c18dd
41 changed files with 2005 additions and 2654 deletions
+23 -9
View File
@@ -1,14 +1,19 @@
import { RUN_BUFFS, bossHealthMultiplier, countRunBuff } from "../game/roguelike";
import { RUN_BUFFS, bossHealthMultiplier, effectiveRunBuffRank, formatRunBuffEffect } from "../game/roguelike";
import { HEALER_CLASSES } from "../game/healers";
import { useGameStore } from "../game/store";
export function BuffDraftPanel({ className = "" }: { className?: string }) {
const round = useGameStore((state) => state.round);
const runBuffs = useGameStore((state) => state.runBuffs);
const healerClassId = useGameStore((state) => state.healerClassId);
const runBuffRanks = useGameStore((state) => state.runBuffRanks);
const passiveRunBuffId = useGameStore((state) => state.passiveRunBuffId);
const choices = useGameStore((state) => state.draftBuffIds);
const selected = useGameStore((state) => state.selectedRunBuffId);
const setSelected = useGameStore((state) => state.setSelectedRunBuff);
const choose = useGameStore((state) => state.chooseRunBuff);
const continueRun = useGameStore((state) => state.continueRoguelikeRound);
const nextRound = round + 1;
const abilities = HEALER_CLASSES[healerClassId].abilities;
return (
<div className={`buff-draft ${className}`.trim()} role="dialog" aria-modal="true" aria-label={`Choose a buff for round ${nextRound}`}>
<header>
@@ -16,10 +21,12 @@ export function BuffDraftPanel({ className = "" }: { className?: string }) {
<h2>Choose one blessing</h2>
<p>Claim required. Round {nextRound} begins with two new bosses at {Math.round(bossHealthMultiplier(nextRound) * 100)}% base HP.</p>
</header>
<div className="buff-choice-grid">
{choices.map((buffId) => {
<div className={`buff-choice-grid choice-count-${choices.length}`}>
{choices.length > 0 ? choices.map((buffId) => {
const buff = RUN_BUFFS[buffId];
const stacks = countRunBuff(runBuffs, buffId);
const rank = effectiveRunBuffRank(runBuffRanks, buffId, passiveRunBuffId);
const nextRank = Math.min(buff.maxRank, rank + 1);
const ability = abilities[buff.abilityId];
return (
<button
key={buffId}
@@ -31,14 +38,21 @@ export function BuffDraftPanel({ className = "" }: { className?: string }) {
aria-pressed={selected === buffId}
>
<i>{buff.icon}</i>
<span><small>{stacks ? `${stacks} owned` : "New blessing"}</small><strong>{buff.name}</strong></span>
<b>{buff.summary}</b>
<span><small>{rank ? `Rank ${rank} ${nextRank} / ${buff.maxRank}` : `New blessing · Rank 1 / ${buff.maxRank}`}</small><strong>{ability.shortName}: {buff.name}</strong></span>
<b>{formatRunBuffEffect(buffId, nextRank)}</b>
<p>{buff.detail}</p>
</button>
);
})}
}) : (
<button className="buff-mastery-continue is-controller-focused" onClick={continueRun}>
<i></i>
<span><small>Full mastery</small><strong>Continue Without Buff</strong></span>
<b>All 18 blessings reached maximum rank.</b>
<p>Keep completed build and begin next randomized encounter.</p>
</button>
)}
</div>
<footer><b> / </b> Choose <i /> <b>A / ENTER</b> Claim</footer>
<footer>{choices.length > 0 && <><b> / </b> Choose <i /></>} <b>A / ENTER</b> {choices.length > 0 ? "Claim" : "Continue"}</footer>
</div>
);
}