Implement Retire HoF (Gauntlet) rule enforcement for genlockes
When retireHoF is enabled, surviving HoF Pokemon and their evolutionary families are retired at leg advancement and treated as duplicates in all subsequent legs — both in the encounter modal and bulk randomize. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ interface EncounterModalProps {
|
||||
gameId: number
|
||||
existing?: EncounterDetail
|
||||
dupedPokemonIds?: Set<number>
|
||||
retiredPokemonIds?: Set<number>
|
||||
onSubmit: (data: {
|
||||
routeId: number
|
||||
pokemonId: number
|
||||
@@ -93,6 +94,7 @@ export function EncounterModal({
|
||||
gameId,
|
||||
existing,
|
||||
dupedPokemonIds,
|
||||
retiredPokemonIds,
|
||||
onSubmit,
|
||||
onUpdate,
|
||||
onClose,
|
||||
@@ -285,7 +287,7 @@ export function EncounterModal({
|
||||
</span>
|
||||
{isDuped && (
|
||||
<span className="text-[10px] text-gray-400 italic">
|
||||
already caught
|
||||
{retiredPokemonIds?.has(rp.pokemonId) ? 'retired (HoF)' : 'already caught'}
|
||||
</span>
|
||||
)}
|
||||
{!isDuped && SPECIAL_METHODS.includes(rp.encounterMethod) && (
|
||||
|
||||
@@ -469,6 +469,13 @@ export function RunEncounters() {
|
||||
return map
|
||||
}, [normalEncounters])
|
||||
|
||||
// Build set of retired Pokemon IDs from genlocke context
|
||||
const retiredPokemonIds = useMemo(() => {
|
||||
const ids = run?.genlocke?.retiredPokemonIds
|
||||
if (!ids || ids.length === 0) return undefined
|
||||
return new Set(ids)
|
||||
}, [run])
|
||||
|
||||
// Build set of duped Pokemon IDs (for duplicates clause)
|
||||
const dupedPokemonIds = useMemo(() => {
|
||||
const dupesClauseOn = run?.rules?.duplicatesClause ?? true
|
||||
@@ -483,6 +490,14 @@ export function RunEncounters() {
|
||||
}
|
||||
|
||||
const duped = new Set<number>()
|
||||
|
||||
// Seed with retired Pokemon IDs from prior genlocke legs
|
||||
if (retiredPokemonIds) {
|
||||
for (const id of retiredPokemonIds) {
|
||||
duped.add(id)
|
||||
}
|
||||
}
|
||||
|
||||
for (const enc of normalEncounters) {
|
||||
if (enc.status !== 'caught') continue
|
||||
const pokemonId = enc.currentPokemonId ?? enc.pokemonId
|
||||
@@ -504,7 +519,7 @@ export function RunEncounters() {
|
||||
}
|
||||
}
|
||||
return duped.size > 0 ? duped : undefined
|
||||
}, [run, normalEncounters, familiesData])
|
||||
}, [run, normalEncounters, familiesData, retiredPokemonIds])
|
||||
|
||||
// Find starter Pokemon name for auto-matching variant boss teams
|
||||
// Note: enc.route from the run detail doesn't include encounterMethods
|
||||
@@ -1286,6 +1301,7 @@ export function RunEncounters() {
|
||||
gameId={run!.gameId}
|
||||
existing={editingEncounter ?? undefined}
|
||||
dupedPokemonIds={dupedPokemonIds}
|
||||
retiredPokemonIds={retiredPokemonIds}
|
||||
onSubmit={handleCreate}
|
||||
onUpdate={handleUpdate}
|
||||
onClose={() => {
|
||||
|
||||
@@ -99,6 +99,7 @@ export interface RunGenlockeContext {
|
||||
legOrder: number
|
||||
totalLegs: number
|
||||
isFinalLeg: boolean
|
||||
retiredPokemonIds: number[]
|
||||
}
|
||||
|
||||
export interface RunDetail extends NuzlockeRun {
|
||||
|
||||
Reference in New Issue
Block a user