diff --git a/play.pokemonshowdown.com/src/battle-team-editor.tsx b/play.pokemonshowdown.com/src/battle-team-editor.tsx index f9ba7f20c..723d0d36b 100644 --- a/play.pokemonshowdown.com/src/battle-team-editor.tsx +++ b/play.pokemonshowdown.com/src/battle-team-editor.tsx @@ -71,6 +71,7 @@ class TeamEditorState extends PSModel { defaultLevel = 100; readonly = false; fetching = false; + private userSetsCache: Record = {}; constructor(team: Team) { super(); this.team = team; @@ -766,6 +767,36 @@ class TeamEditorState extends PSModel { }; return Object.keys(all); } + /** returns null if no boxes exist, empty array if no sets for this species */ + getUserSets(set: Dex.PokemonSet): { [setName: string]: Dex.PokemonSet } | null { + if (!this.userSetsCache[this.format]) { + const userSets: { [species: string]: { [setName: string]: Dex.PokemonSet } } = {}; + + for (const team of window.PS?.teams.list || []) { + if (team.format !== this.format || !team.isBox) continue; + + const setList = Teams.unpack(team.packedTeam); + const duplicateNameIndices: Record = {}; + + for (const boxSet of setList) { + let name = boxSet.name || boxSet.species; + if (duplicateNameIndices[name]) { + name += ` ${duplicateNameIndices[name]}`; + } + duplicateNameIndices[name] = (duplicateNameIndices[name] || 0) + 1; + + userSets[boxSet.species] ??= {}; + userSets[boxSet.species][name] = boxSet; + } + } + + this.userSetsCache[this.format] = userSets; + } + + const cachedSets = this.userSetsCache[this.format]; + if (Object.keys(cachedSets).length === 0) return null; + return cachedSets[set.species] || {}; + } } export class TeamEditor extends preact.Component<{ @@ -2061,6 +2092,28 @@ class TeamWizard extends preact.Component<{ this.props.onUpdate?.(); this.forceUpdate(); }; + handleLoadUserSet = (ev: Event) => { + const setName = (ev.target as HTMLButtonElement).value; + this.loadUserSet(setName); + }; + loadUserSet = (setName: string) => { + const { editor } = this.props; + const setIndex = editor.innerFocus!.setIndex; + const set = editor.sets[setIndex]; + if (!set?.species) return; + + const userSets = editor.getUserSets(set); + const setTemplate = userSets?.[setName]; + if (!setTemplate) return; + + const applied: Partial = JSON.parse(JSON.stringify(setTemplate)); + delete applied.name; + Object.assign(set, applied); + + editor.save(); + this.props.onUpdate?.(); + this.forceUpdate(); + }; updateSearch = (ev: Event) => { const searchBox = ev.currentTarget as HTMLInputElement; this.props.editor.setSearchValue(searchBox.value); @@ -2196,6 +2249,7 @@ class TeamWizard extends preact.Component<{ const set = this.props.editor.sets[setIndex] as Dex.PokemonSet | undefined; const cur = (i: number) => setIndex === i ? ' cur' : ''; const sampleSets = type === 'ability' ? editor.getSampleSets(set!) : []; + const userSets = type === 'ability' ? editor.getUserSets(set!) : null; return
)} + {userSets !== null && ( +
+

Box sets

+ {Object.keys(userSets).length > 0 ? ( +
+ {Object.keys(userSets).map(setName => <> + {} + )} +
+ ) : ( +
No {set!.species} sets found in boxes
+ )} +
+ )} )}