dex/src/store/shinyHunts.js
chris b15ee3dd7f Shiny hunt tracker (#/shiny)
New store + view (linked from Settings > Your data): one card per active
hunt with a big +1 counter, the method's odds, and the running cumulative
chance (1 - (1-p)^count). Nine methods with shiny-charm variants
(Full odds, Masuda, SOS, Radar, DexNav, Catch Combo, Dynamax Adventure,
Mass/Massive Outbreak). "Found it" marks the Pokémon caught and clears
the hunt; per-hunt notes field.

Also: JSON export/import now covers team, formTracking and shinyHunts
alongside settings/selection; openPokemonPicker gains a `closeAfterPick`
option (used by the shiny + breeding single-pick flows).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
2026-09-09 19:06:46 -04:00

40 lines
1.1 KiB
JavaScript

import { createStore } from './createStore.js';
/**
* Shiny hunts: one entry per Pokémon you're actively hunting, with an
* encounter counter and the method's odds. Lives in localStorage next to
* the other tracking data; rides along in the JSON export.
*/
export const shinyHunts = createStore('pdx.shinyHunts', { hunts: [] });
let seq = Date.now();
const uid = () => `h${(seq++).toString(36)}`;
export function addHunt({ speciesId, method, charm }) {
shinyHunts.set((s) => ({
...s,
hunts: [
{ id: uid(), speciesId, method, charm: !!charm, count: 0, notes: '', startedAt: new Date().toISOString() },
...s.hunts,
],
}));
}
export function updateHunt(id, patch) {
shinyHunts.set((s) => ({
...s,
hunts: s.hunts.map((h) => (h.id === id ? { ...h, ...patch } : h)),
}));
}
export function bumpHunt(id, delta) {
shinyHunts.set((s) => ({
...s,
hunts: s.hunts.map((h) => (h.id === id ? { ...h, count: Math.max(0, h.count + delta) } : h)),
}));
}
export function removeHunt(id) {
shinyHunts.set((s) => ({ ...s, hunts: s.hunts.filter((h) => h.id !== id) }));
}