From 2a1e0c4373b8e14f98badb297a67ccd4cebab133 Mon Sep 17 00:00:00 2001 From: fabske0 <192151969+fabske0@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:12:51 +0100 Subject: [PATCH 1/7] - Add option for shiny starter - change how the starter part of the seed is parsed --- src/data/daily-run.ts | 70 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index ea2852976e8..c3aec54c4e4 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -58,11 +58,19 @@ export function getDailyRunStarters(seed: string): StarterTuple { } // TODO: Refactor this unmaintainable mess -function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLevel: number): Starter { +function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLevel: number, variant?: Variant): Starter { const starterSpecies = starterSpeciesForm instanceof PokemonSpecies ? starterSpeciesForm : getPokemonSpecies(starterSpeciesForm.speciesId); const formIndex = starterSpeciesForm instanceof PokemonSpecies ? undefined : starterSpeciesForm.formIndex; - const pokemon = globalScene.addPlayerPokemon(starterSpecies, startingLevel, undefined, formIndex); + const pokemon = globalScene.addPlayerPokemon( + starterSpecies, + startingLevel, + undefined, + formIndex, + undefined, + variant !== undefined ? true : undefined, + variant, + ); const starter: Starter = { speciesId: starterSpecies.speciesId, shiny: pokemon.shiny, @@ -215,14 +223,68 @@ function setDailyRunEventStarterMovesets(seed: string, starters: StarterTuple): } } +/** + * Expects the seed to contain `starters` followed by 3 `s{\d{4}}` for the starters. The 4 digits are the species ID. \ + * Each starter can optionally be followed by `f{\d{2}}` for the form index and `v{\d{2}}` for the variant. \ + * The order of `f` and `v` does not matter. + * @example `/starterss0003f01s0025v01s0150f02v02` + * @param seed - The daily run seed + * @returns An array of {@linkcode Starter}s, or `null` if no valid match. + */ +// TODO: Rework this setup into JSON or similar - this is quite hard to maintain +function getDailyEventSeedStarters(seed: string): StarterTuple | null { + const speciesCongigurations = + /starters(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?/.exec( + seed, + )?.groups; + + if (!speciesCongigurations) { + const legacyStarters = getDailyEventSeedStartersLegay(seed); + if (legacyStarters != null) { + console.log("Using lecacy starter parsing for daily run seed."); + return legacyStarters; + } + console.error("Invalid starters used for custom daily run seed!"); + return null; + } + console.log(speciesCongigurations); + + const speciesIds = getEnumValues(SpeciesId); + + const starters: Starter[] = []; + for (let i = 0; i < 3; i++) { + const speciesId = Number.parseInt(speciesCongigurations[`species${i + 1}`].slice(1)) as SpeciesId; + const formIndex = Number.parseInt(speciesCongigurations[`form${i + 1}`]?.slice(1) ?? "00"); + let variant: Variant | undefined = Number.parseInt(speciesCongigurations[`variant${i + 1}`]?.slice(1)) as Variant; + + if (!speciesIds.includes(speciesId)) { + console.error("Invalid species ID used for custom daily run seed starter:", speciesId); + return null; + } + + const starterSpecies = getPokemonSpecies(speciesId); + if (Number.isNaN(variant) || variant > 2 || (!starterSpecies.hasVariants() && variant !== 0)) { + console.error("Invalid variant used for custom daily run seed starter:", variant); + variant = undefined; + } + + const starterForm = getPokemonSpeciesForm(speciesId, formIndex); + const startingLevel = globalScene.gameMode.getStartingLevel(); + const starter = getDailyRunStarter(starterForm, startingLevel, variant); + starters.push(starter); + } + + return starters as StarterTuple; +} + /** * Expects the seed to contain `/starters\d{18}/` * where the digits alternate between 4 digits for the species ID and 2 digits for the form index * (left padded with `0`s as necessary). * @returns An array of {@linkcode Starter}s, or `null` if no valid match. */ -// TODO: Rework this setup into JSON or similar - this is quite hard to maintain -export function getDailyEventSeedStarters(seed: string): StarterTuple | null { +// TODO: Can be removed after october 31st 2025 +function getDailyEventSeedStartersLegay(seed: string): StarterTuple | null { if (!isDailyEventSeed(seed)) { return null; } From 8e01876bd0ddf19e3ec3103553b991953a3ee6d7 Mon Sep 17 00:00:00 2001 From: fabske0 <192151969+fabske0@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:16:33 +0100 Subject: [PATCH 2/7] fix typo --- src/data/daily-run.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index c3aec54c4e4..c79bc9a3efd 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -233,12 +233,12 @@ function setDailyRunEventStarterMovesets(seed: string, starters: StarterTuple): */ // TODO: Rework this setup into JSON or similar - this is quite hard to maintain function getDailyEventSeedStarters(seed: string): StarterTuple | null { - const speciesCongigurations = + const speciesConfigurations = /starters(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?/.exec( seed, )?.groups; - if (!speciesCongigurations) { + if (!speciesConfigurations) { const legacyStarters = getDailyEventSeedStartersLegay(seed); if (legacyStarters != null) { console.log("Using lecacy starter parsing for daily run seed."); @@ -247,15 +247,15 @@ function getDailyEventSeedStarters(seed: string): StarterTuple | null { console.error("Invalid starters used for custom daily run seed!"); return null; } - console.log(speciesCongigurations); + console.log(speciesConfigurations); const speciesIds = getEnumValues(SpeciesId); const starters: Starter[] = []; for (let i = 0; i < 3; i++) { - const speciesId = Number.parseInt(speciesCongigurations[`species${i + 1}`].slice(1)) as SpeciesId; - const formIndex = Number.parseInt(speciesCongigurations[`form${i + 1}`]?.slice(1) ?? "00"); - let variant: Variant | undefined = Number.parseInt(speciesCongigurations[`variant${i + 1}`]?.slice(1)) as Variant; + const speciesId = Number.parseInt(speciesConfigurations[`species${i + 1}`].slice(1)) as SpeciesId; + const formIndex = Number.parseInt(speciesConfigurations[`form${i + 1}`]?.slice(1) ?? "00"); + let variant: Variant | undefined = Number.parseInt(speciesConfigurations[`variant${i + 1}`]?.slice(1)) as Variant; if (!speciesIds.includes(speciesId)) { console.error("Invalid species ID used for custom daily run seed starter:", speciesId); From 6049038537de3350448090e84e4934ad15291baa Mon Sep 17 00:00:00 2001 From: fabske0 <192151969+fabske0@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:17:14 +0100 Subject: [PATCH 3/7] remove console.log and another typo --- src/data/daily-run.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index c79bc9a3efd..8cd9ff8a115 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -241,13 +241,12 @@ function getDailyEventSeedStarters(seed: string): StarterTuple | null { if (!speciesConfigurations) { const legacyStarters = getDailyEventSeedStartersLegay(seed); if (legacyStarters != null) { - console.log("Using lecacy starter parsing for daily run seed."); + console.log("Using legacy starter parsing for daily run seed."); return legacyStarters; } console.error("Invalid starters used for custom daily run seed!"); return null; } - console.log(speciesConfigurations); const speciesIds = getEnumValues(SpeciesId); From b150b5208c1544beb343a51f7c59b8736a1050c2 Mon Sep 17 00:00:00 2001 From: fabske0 <192151969+fabske0@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:48:01 +0100 Subject: [PATCH 4/7] split up regex --- src/data/daily-run.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index 8cd9ff8a115..a5635bf464e 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -233,10 +233,12 @@ function setDailyRunEventStarterMovesets(seed: string, starters: StarterTuple): */ // TODO: Rework this setup into JSON or similar - this is quite hard to maintain function getDailyEventSeedStarters(seed: string): StarterTuple | null { - const speciesConfigurations = - /starters(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?(?s\d{4})(?:(?f\d{2})(?v\d{2})?|(?v\d{2})(?f\d{2})?)?/.exec( - seed, - )?.groups; + const speciesRegex = i => + `(?s\\d{4})(?:(?f\\d{2})(?v\\d{2})?|(?v\\d{2})(?f\\d{2})?)?`; + + const matcher = new RegExp(`starters${speciesRegex(1)}${speciesRegex(2)}${speciesRegex(3)}`); + + const speciesConfigurations = matcher.exec(seed)?.groups; if (!speciesConfigurations) { const legacyStarters = getDailyEventSeedStartersLegay(seed); From ac79e82013160f00c9045f06ae5357a96c35ebf3 Mon Sep 17 00:00:00 2001 From: fabske0 <192151969+fabske0@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:11:10 +0100 Subject: [PATCH 5/7] another typo --- src/data/daily-run.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index a5635bf464e..c52bb164f4b 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -241,7 +241,7 @@ function getDailyEventSeedStarters(seed: string): StarterTuple | null { const speciesConfigurations = matcher.exec(seed)?.groups; if (!speciesConfigurations) { - const legacyStarters = getDailyEventSeedStartersLegay(seed); + const legacyStarters = getDailyEventSeedStartersLegacy(seed); if (legacyStarters != null) { console.log("Using legacy starter parsing for daily run seed."); return legacyStarters; @@ -285,7 +285,7 @@ function getDailyEventSeedStarters(seed: string): StarterTuple | null { * @returns An array of {@linkcode Starter}s, or `null` if no valid match. */ // TODO: Can be removed after october 31st 2025 -function getDailyEventSeedStartersLegay(seed: string): StarterTuple | null { +function getDailyEventSeedStartersLegacy(seed: string): StarterTuple | null { if (!isDailyEventSeed(seed)) { return null; } From fb274077c233a30a3d24679684cb6e04fe319e45 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Fri, 31 Oct 2025 19:01:33 -0400 Subject: [PATCH 6/7] Reworked regex to use `matchAll`, added error handling + tests --- src/data/daily-run.ts | 92 +++++++++++++++++++++-------- src/utils/pokemon-utils.ts | 8 +-- test/daily-mode.test.ts | 115 ++++++++++++++++++++++++------------- 3 files changed, 145 insertions(+), 70 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index c52bb164f4b..9daabc01529 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -68,9 +68,10 @@ function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLeve undefined, formIndex, undefined, - variant !== undefined ? true : undefined, + variant != null, variant, ); + console.log(`%c${pokemon.shiny} ${variant} ${variant != null}`, "color:blue"); const starter: Starter = { speciesId: starterSpecies.speciesId, shiny: pokemon.shiny, @@ -180,7 +181,11 @@ export function isDailyEventSeed(seed: string): boolean { * Must be updated whenever the `MoveId` enum gets a new digit! */ const MOVE_ID_STRING_LENGTH = 4; - +/** + * The regex literal used to parse daily run custom movesets. + * @privateRemarks + * Intentionally does not use the `g` flag to avoid altering `lastIndex` after each match. + */ const MOVE_ID_SEED_REGEX = /(?<=\/moves)((?:\d{4}){0,4})(?:,((?:\d{4}){0,4}))?(?:,((?:\d{4}){0,4}))?/; /** @@ -223,53 +228,90 @@ function setDailyRunEventStarterMovesets(seed: string, starters: StarterTuple): } } +/** The regex literal string used to extract the content of the "starters" block of Daily Run custom seeds. */ +const STARTER_SEED_PREFIX_REGEX = /\/starters(.*?)(?:\/|$)/; /** - * Expects the seed to contain `starters` followed by 3 `s{\d{4}}` for the starters. The 4 digits are the species ID. \ - * Each starter can optionally be followed by `f{\d{2}}` for the form index and `v{\d{2}}` for the variant. \ - * The order of `f` and `v` does not matter. - * @example `/starterss0003f01s0025v01s0150f02v02` + * The regex literal used to parse daily run custom starter information for a single starter. \ + * Contains a 4-digit species ID, as well as an optional 2-digit form index and 1-digit variant. + * + * If either of form index or variant are omitted, the starter will default to its species' base form/ + * not be shiny, respectively. + */ +const STARTER_SEED_MATCH_REGEX = /(?:s(?\d{4}))(?:f(?
\d{2}))?(?:v(?\d))?/g; + +/** + * Parse a custom daily run seed into a set of pre-defined starters. + * @see {@linkcode STARTER_SEED_MATCH_REGEX} * @param seed - The daily run seed - * @returns An array of {@linkcode Starter}s, or `null` if no valid match. + * @returns An array of {@linkcode Starter}s, or `null` if it did not match. */ // TODO: Rework this setup into JSON or similar - this is quite hard to maintain function getDailyEventSeedStarters(seed: string): StarterTuple | null { - const speciesRegex = i => - `(?s\\d{4})(?:(?f\\d{2})(?v\\d{2})?|(?v\\d{2})(?f\\d{2})?)?`; + if (!isDailyEventSeed(seed)) { + return null; + } - const matcher = new RegExp(`starters${speciesRegex(1)}${speciesRegex(2)}${speciesRegex(3)}`); + const seedAfterPrefix = seed.split(STARTER_SEED_PREFIX_REGEX)[1] as string | undefined; + if (!seedAfterPrefix) { + return null; + } - const speciesConfigurations = matcher.exec(seed)?.groups; + const speciesConfigurations = [...seedAfterPrefix.matchAll(STARTER_SEED_MATCH_REGEX)]; - if (!speciesConfigurations) { + if (speciesConfigurations.length !== 3) { + // TODO: Remove legacy fallback code after next hotfix version - this is needed for Oct 31's daily to function const legacyStarters = getDailyEventSeedStartersLegacy(seed); - if (legacyStarters != null) { - console.log("Using legacy starter parsing for daily run seed."); + if (legacyStarters == null) { return legacyStarters; } - console.error("Invalid starters used for custom daily run seed!"); + console.error("Invalid starters used for custom daily run seed!", seed); return null; } const speciesIds = getEnumValues(SpeciesId); - const starters: Starter[] = []; - for (let i = 0; i < 3; i++) { - const speciesId = Number.parseInt(speciesConfigurations[`species${i + 1}`].slice(1)) as SpeciesId; - const formIndex = Number.parseInt(speciesConfigurations[`form${i + 1}`]?.slice(1) ?? "00"); - let variant: Variant | undefined = Number.parseInt(speciesConfigurations[`variant${i + 1}`]?.slice(1)) as Variant; - if (!speciesIds.includes(speciesId)) { - console.error("Invalid species ID used for custom daily run seed starter:", speciesId); + for (const [i, match] of speciesConfigurations.entries()) { + const { groups } = match; + if (!groups) { + console.error("Invalid seed used for custom daily run starter:", match); + return null; + } + + const { species: speciesStr, form: formStr, variant: variantStr } = groups; + + const speciesId = Number.parseInt(speciesStr) as SpeciesId; + + // NB: We check the parsed integer here to exclude SpeciesID.NONE as well as invalid values; + // other fields only check the string to permit 0 as valid inputs + if (!speciesId || !speciesIds.includes(speciesId)) { + console.error("Invalid species ID used for custom daily run starter:", speciesStr); return null; } const starterSpecies = getPokemonSpecies(speciesId); - if (Number.isNaN(variant) || variant > 2 || (!starterSpecies.hasVariants() && variant !== 0)) { - console.error("Invalid variant used for custom daily run seed starter:", variant); + // Omitted form index = use base form + const starterForm = formStr ? starterSpecies.forms[Number.parseInt(formStr)] : starterSpecies; + + if (!starterForm) { + console.log(starterSpecies.name); + console.error("Invalid form index used for custom daily run starter:", formStr); + return null; + } + + // Get and validate variant + let variant = (variantStr ? Number.parseInt(variantStr) : undefined) as Variant | undefined; + if (!isBetween(variant ?? 0, 0, 2)) { + console.error("Variant used for custom daily run seed starter out of bounds:", variantStr); + return null; + } + + // Fall back to default variant if none exists + if (!starterSpecies.hasVariants() && !!variant) { + console.warn("Variant for custom daily run seed starter does not exist, using base variant...", variant); variant = undefined; } - const starterForm = getPokemonSpeciesForm(speciesId, formIndex); const startingLevel = globalScene.gameMode.getStartingLevel(); const starter = getDailyRunStarter(starterForm, startingLevel, variant); starters.push(starter); diff --git a/src/utils/pokemon-utils.ts b/src/utils/pokemon-utils.ts index e3c8d8eab68..f1716487b34 100644 --- a/src/utils/pokemon-utils.ts +++ b/src/utils/pokemon-utils.ts @@ -118,11 +118,9 @@ export function getFusedSpeciesName(speciesAName: string, speciesBName: string): } export function getPokemonSpeciesForm(species: SpeciesId, formIndex: number): PokemonSpeciesForm { - const retSpecies: PokemonSpecies = - species >= 2000 - ? allSpecies.find(s => s.speciesId === species)! // TODO: is the bang correct? - : allSpecies[species - 1]; - if (formIndex < retSpecies.forms?.length) { + const retSpecies: PokemonSpecies = getPokemonSpecies(species); + + if (formIndex < retSpecies.forms.length) { return retSpecies.forms[formIndex]; } return retSpecies; diff --git a/test/daily-mode.test.ts b/test/daily-mode.test.ts index e5284906318..6ab61cc0ed0 100644 --- a/test/daily-mode.test.ts +++ b/test/daily-mode.test.ts @@ -21,6 +21,8 @@ describe("Daily Mode", () => { beforeEach(() => { game = new GameManager(phaserGame); + + game.override.disableShinies = false; }); afterEach(() => { @@ -41,52 +43,85 @@ describe("Daily Mode", () => { }); describe("Custom Seeds", () => { - it("should support custom moves", async () => { - vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves0001000200030004,03320006,01300919"); - await game.dailyMode.startBattle(); + describe("Moves", () => { + it("should support custom moves", async () => { + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves0001000200030004,03320006,01300919"); + await game.dailyMode.startBattle(); - const [moves1, moves2, moves3] = game.scene.getPlayerParty().map(p => p.moveset.map(pm => pm.moveId)); - expect(moves1, stringifyEnumArray(MoveId, moves1)).toEqual([ - MoveId.POUND, - MoveId.KARATE_CHOP, - MoveId.DOUBLE_SLAP, - MoveId.COMET_PUNCH, - ]); - expect(moves2, stringifyEnumArray(MoveId, moves2)).toEqual([ - MoveId.AERIAL_ACE, - MoveId.PAY_DAY, - expect.anything(), // make sure it doesn't replace normal moveset gen - expect.anything(), - ]); - expect(moves3, stringifyEnumArray(MoveId, moves3)).toEqual([ - MoveId.SKULL_BASH, - MoveId.MALIGNANT_CHAIN, - expect.anything(), - expect.anything(), - ]); + const [moves1, moves2, moves3] = game.scene.getPlayerParty().map(p => p.moveset.map(pm => pm.moveId)); + expect(moves1, stringifyEnumArray(MoveId, moves1)).toEqual([ + MoveId.POUND, + MoveId.KARATE_CHOP, + MoveId.DOUBLE_SLAP, + MoveId.COMET_PUNCH, + ]); + expect(moves2, stringifyEnumArray(MoveId, moves2)).toEqual([ + MoveId.AERIAL_ACE, + MoveId.PAY_DAY, + expect.anything(), // make sure it doesn't replace normal moveset gen + expect.anything(), + ]); + expect(moves3, stringifyEnumArray(MoveId, moves3)).toEqual([ + MoveId.SKULL_BASH, + MoveId.MALIGNANT_CHAIN, + expect.anything(), + expect.anything(), + ]); + }); + + it("should allow omitting movesets for some starters", async () => { + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves0001000200030004"); + await game.dailyMode.startBattle(); + + const [moves1, moves2, moves3] = game.scene.getPlayerParty().map(p => p.moveset.map(pm => pm.moveId)); + expect(moves1, stringifyEnumArray(MoveId, moves1)).toEqual([ + MoveId.POUND, + MoveId.KARATE_CHOP, + MoveId.DOUBLE_SLAP, + MoveId.COMET_PUNCH, + ]); + expect(moves2, "was not a random moveset").toHaveLength(4); + expect(moves3, "was not a random moveset").toHaveLength(4); + }); + + it("should skip invalid move IDs", async () => { + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves9999,,0919"); + await game.dailyMode.startBattle(); + + const moves = game.field.getPlayerPokemon().moveset.map(pm => pm.moveId); + expect(moves, "invalid move was in moveset").not.toContain(MoveId[9999]); + }); }); - it("should allow omitting movesets for some starters", async () => { - vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves0001000200030004"); - await game.dailyMode.startBattle(); + describe("Starters", () => { + it("should support custom species IDs", async () => { + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("foo/starterss0001s0113s1024"); + await game.dailyMode.startBattle(); - const [moves1, moves2, moves3] = game.scene.getPlayerParty().map(p => p.moveset.map(pm => pm.moveId)); - expect(moves1, stringifyEnumArray(MoveId, moves1)).toEqual([ - MoveId.POUND, - MoveId.KARATE_CHOP, - MoveId.DOUBLE_SLAP, - MoveId.COMET_PUNCH, - ]); - expect(moves2, "was not a random moveset").toHaveLength(4); - expect(moves3, "was not a random moveset").toHaveLength(4); - }); + const party = game.scene.getPlayerParty().map(p => p.species.speciesId); + expect(party, stringifyEnumArray(SpeciesId, party)).toEqual([ + SpeciesId.BULBASAUR, + SpeciesId.CHANSEY, + SpeciesId.TERAPAGOS, + ]); + }); - it("should skip invalid move IDs", async () => { - vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves9999,,0919"); - await game.dailyMode.startBattle(); + it("should support custom forms and variants", async () => { + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/starterss0006f01v2s0113v0s1024f02"); + await game.dailyMode.startBattle(); - const moves = game.field.getPlayerPokemon().moveset.map(pm => pm.moveId); - expect(moves, "invalid move was in moveset").not.toContain(MoveId[9999]); + const party = game.scene.getPlayerParty().map(p => ({ + speciesId: p.species.speciesId, + variant: p.getVariant(), + form: p.formIndex, + shiny: p.isShiny(), + })); + expect(party).toEqual([ + { speciesId: SpeciesId.CHARIZARD, variant: 2, form: 1, shiny: true }, + { speciesId: SpeciesId.CHANSEY, variant: 0, form: 0, shiny: true }, + { speciesId: SpeciesId.TERAPAGOS, variant: expect.anything(), form: 2, shiny: false }, + ]); + }); }); }); }); From 617e12f6342e650355cbdb01b04abaf502b0f2c6 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Fri, 31 Oct 2025 19:14:19 -0400 Subject: [PATCH 7/7] Removed console log --- src/data/daily-run.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index 9daabc01529..215e23be3b9 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -71,7 +71,6 @@ function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLeve variant != null, variant, ); - console.log(`%c${pokemon.shiny} ${variant} ${variant != null}`, "color:blue"); const starter: Starter = { speciesId: starterSpecies.speciesId, shiny: pokemon.shiny, @@ -271,7 +270,7 @@ function getDailyEventSeedStarters(seed: string): StarterTuple | null { const speciesIds = getEnumValues(SpeciesId); const starters: Starter[] = []; - for (const [i, match] of speciesConfigurations.entries()) { + for (const match of speciesConfigurations) { const { groups } = match; if (!groups) { console.error("Invalid seed used for custom daily run starter:", match);