diff --git a/.beans/nuzlocke-tracker-66hg--auto-select-boss-team-variant-based-on-starter-cho.md b/.beans/nuzlocke-tracker-66hg--auto-select-boss-team-variant-based-on-starter-cho.md index 474b122..ef6f2c0 100644 --- a/.beans/nuzlocke-tracker-66hg--auto-select-boss-team-variant-based-on-starter-cho.md +++ b/.beans/nuzlocke-tracker-66hg--auto-select-boss-team-variant-based-on-starter-cho.md @@ -1,10 +1,11 @@ --- # nuzlocke-tracker-66hg title: Auto-select boss team variant based on starter choice -status: draft +status: in-progress type: feature +priority: normal created_at: 2026-02-08T20:21:40Z -updated_at: 2026-02-08T20:21:40Z +updated_at: 2026-02-08T20:22:47Z --- When a run's starter Pokemon is known, automatically match it against boss battle condition labels (e.g., "Chose Bulbasaur") and pre-select the matching variant instead of showing the pill selector. @@ -28,9 +29,9 @@ Currently, bosses with variant teams (condition_label) display a pill selector o ## Checklist -- [ ] Determine how the starter Pokemon is stored/accessible from the run data -- [ ] Add matching logic to find the right variant from condition labels -- [ ] Update BossDefeatModal to auto-select and hide pills when starter matches -- [ ] Update BossTeamPreview in RunEncounters with same logic +- [x] Determine how the starter Pokemon is stored/accessible from the run data +- [x] Add matching logic to find the right variant from condition labels +- [x] Update BossDefeatModal to auto-select and hide pills when starter matches +- [x] Update BossTeamPreview in RunEncounters with same logic - [ ] Test with variant bosses where starter matches a condition - [ ] Test fallback behavior when no starter is set or no match found \ No newline at end of file diff --git a/frontend/src/components/BossDefeatModal.tsx b/frontend/src/components/BossDefeatModal.tsx index 1231ab3..66856b3 100644 --- a/frontend/src/components/BossDefeatModal.tsx +++ b/frontend/src/components/BossDefeatModal.tsx @@ -7,9 +7,17 @@ interface BossDefeatModalProps { onClose: () => void isPending?: boolean hardcoreMode?: boolean + starterName?: string | null } -export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMode }: BossDefeatModalProps) { +function matchVariant(labels: string[], starterName?: string | null): string | null { + if (!starterName || labels.length === 0) return null + const lower = starterName.toLowerCase() + const matches = labels.filter((l) => l.toLowerCase().includes(lower)) + return matches.length === 1 ? matches[0] : null +} + +export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMode, starterName }: BossDefeatModalProps) { const [result, setResult] = useState<'won' | 'lost'>('won') const [attempts, setAttempts] = useState('1') @@ -22,8 +30,10 @@ export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMo }, [boss.pokemon]) const hasVariants = variantLabels.length > 0 + const autoMatch = useMemo(() => matchVariant(variantLabels, starterName), [variantLabels, starterName]) + const showPills = hasVariants && autoMatch === null const [selectedVariant, setSelectedVariant] = useState( - hasVariants ? variantLabels[0] : null, + autoMatch ?? (hasVariants ? variantLabels[0] : null), ) const displayedPokemon = useMemo(() => { @@ -54,7 +64,7 @@ export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMo {/* Boss team preview */} {boss.pokemon.length > 0 && (
- {hasVariants && ( + {showPills && (
{variantLabels.map((label) => (
{/* Boss pokemon team */} {isBossExpanded && boss.pokemon.length > 0 && ( - + )}
{sectionAfter && ( @@ -1259,6 +1284,7 @@ export function RunEncounters() { onClose={() => setSelectedBoss(null)} isPending={createBossResult.isPending} hardcoreMode={run?.rules?.hardcoreMode} + starterName={starterName} /> )}