From 512be228a2e2dea6f48ec5a1c93bb95179d92e2f Mon Sep 17 00:00:00 2001 From: Julian Tabel Date: Sun, 8 Feb 2026 21:33:28 +0100 Subject: [PATCH] Auto-select boss team variant based on starter choice When a run has a starter Pokemon, automatically match its species name against boss battle condition labels (e.g., "charmander" matches "Chose Charmander"). If exactly one variant matches, pre-select it and hide the pill selector. Falls back to showing pills when no match is found. Fixes starter lookup to use game routes data (which has encounterMethods populated) instead of the run detail route (which defaults to empty). Co-Authored-By: Claude Opus 4.6 --- ...-boss-team-variant-based-on-starter-cho.md | 13 +++---- frontend/src/components/BossDefeatModal.tsx | 16 +++++++-- frontend/src/pages/RunEncounters.tsx | 34 ++++++++++++++++--- 3 files changed, 50 insertions(+), 13 deletions(-) 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} /> )}