diff --git a/src/@types/turn-move.ts b/src/@types/turn-move.ts index f26e3b9e640..a5a69eb3749 100644 --- a/src/@types/turn-move.ts +++ b/src/@types/turn-move.ts @@ -10,4 +10,4 @@ export interface TurnMove { useMode: MoveUseMode; result?: MoveResult; turn?: number; -} \ No newline at end of file +} diff --git a/src/system/schema-migrators/custom-pokemon-data.ts b/src/system/schema-migrators/custom-pokemon-data.ts index b979e3d1b8e..fc009d3c34b 100644 --- a/src/system/schema-migrators/custom-pokemon-data.ts +++ b/src/system/schema-migrators/custom-pokemon-data.ts @@ -1,5 +1,5 @@ -import type { Z$PokemonData } from "#system/schemas/v1.10/pokemon-data"; -import { NatureSchema } from "#system/schemas/v1.10/pokemon-nature"; +import type { Z$PokemonData } from "#system/schemas/pokemon/pokemon-data"; +import { NatureSchema } from "#system/schemas/pokemon/pokemon-nature"; import type z from "zod"; /** diff --git a/src/system/schema-migrators/summon-data.ts b/src/system/schema-migrators/summon-data.ts index 6268185a8a3..d836619fcec 100644 --- a/src/system/schema-migrators/summon-data.ts +++ b/src/system/schema-migrators/summon-data.ts @@ -1,5 +1,6 @@ import { Z$PositiveInt } from "#system/schemas/common"; -import type { Z$IllusionData } from "#system/schemas/v1.10/illusion-data"; +import type { Z$IllusionData } from "#system/schemas/pokemon/illusion-data"; +import { isNullOrUndefined } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; import { z } from "zod"; @@ -29,6 +30,7 @@ import { z } from "zod"; * ``` * * As this version of the data is compatible with version 1.10, we only need to specify the new properties. + * In addition, the value type of `fusionSpecies` changed from `PokemonSpecies` to simply the species ID. */ export const Z$V1_9_IllusionData = z.looseObject({ species: Z$PositiveInt, @@ -45,25 +47,27 @@ type V1_9_IllusionData = z.input; * Migrate illusion data from version 1.9 to 1.10 * * @remarks - * Extract `speciesId` from `fusionSpecies`, and use defaults for all fields from the illusioned pokemon. + * Extracts `speciesId` from `fusionSpecies`, and use defaults for all fields from the illusioned pokemon. * + * In version 1.9, the illusion's name and shiny state were not serialized. + * The name is recoverable from the species ID, but shiny state is not recoverable. */ export function V1_10_IllusionDataMigrator(arg: V1_9_IllusionData): Partial> { return Z$V1_9_IllusionData.transform(data => { // Needed to fetch a default name. const pokemon = getPokemonSpecies(data.species); - return { + const result = { ...(data as Omit), - // unwrap fusion species - fusionSpecies: data.fusionSpecies?.speciesId, - // and use defaults for all fields from the illusioned pokemon name: pokemon.name, - nickname: pokemon.name, shiny: false, - fusionShiny: false, - variant: 0, - fusionVariant: 0, - fusionFormIndex: 0, - }; + } as Partial>; + + // With no fusion species, these fields should be left undefined. + if (!isNullOrUndefined(data.fusionSpecies)) { + result.fusionSpecies = data.fusionSpecies.speciesId; + result.fusionShiny = false; // default shiny state + result.fusionVariant = 0; // default variant + } + return result; }).parse(arg); } diff --git a/src/system/schemas/arena/arena-data.ts b/src/system/schemas/arena/arena-data.ts new file mode 100644 index 00000000000..cd503ff04e2 --- /dev/null +++ b/src/system/schemas/arena/arena-data.ts @@ -0,0 +1,22 @@ +// biome-ignore-start lint/correctness/noUnusedImports: used in a tsdoc comment +import type { SerializedArenaData } from "#system/arena-data"; +import { Z$Terrain } from "#system/schemas/arena/terrain"; +import { Z$Weather } from "#system/schemas/arena/weather"; +// biome-ignore-end lint/correctness/noUnusedImports: end +import { Z$BiomeID } from "#system/schemas/biome-id"; +import { Z$NonNegativeInt } from "#system/schemas/common"; +import { z } from "zod"; + +/** + * Zod schema for {@linkcode SerializedArenaData} as of version 1.10 + */ +export const Z$ArenaData = z.object({ + biome: Z$BiomeID, + weather: Z$Weather.optional().catch(undefined), + terrain: Z$Terrain.optional().catch(undefined), + tags: z + .array(0 as unknown as any) + .optional() + .catch(undefined), + playerTerasUsed: Z$NonNegativeInt.optional().catch(undefined), +}); diff --git a/src/system/schemas/v1.10/session-save-data.ts b/src/system/schemas/arena/arena-tag.ts similarity index 100% rename from src/system/schemas/v1.10/session-save-data.ts rename to src/system/schemas/arena/arena-tag.ts diff --git a/src/system/schemas/arena/terrain.ts b/src/system/schemas/arena/terrain.ts new file mode 100644 index 00000000000..8b574393934 --- /dev/null +++ b/src/system/schemas/arena/terrain.ts @@ -0,0 +1,24 @@ +// biome-ignore-start lint/correctness/noUnusedImports: used in a tsdoc commentD +import type { SerializedTerrain, TerrainType } from "#data/terrain"; +// biome-ignore-end lint/correctness/noUnusedImports: end +import { z } from "zod"; + +/** + * Zod schema for {@linkcode TerrainType} as of version 1.10. + * + * @remarks + * - `0`: NONE, + * - `1`: MISTY, + * - `2`: ELECTRIC, + * - `3`: GRASSY, + * - `4`: PSYCHIC + */ +export const Z$TerrainType = z.literal([0, 1, 2, 3, 4]); + +/** + * Zod schema for {@linkcode SerializedTerrain} as of version 1.10. + */ +export const Z$Terrain = z.object({ + terrainType: Z$TerrainType, + turnsLeft: z.int(), +}); diff --git a/src/system/schemas/arena/weather.ts b/src/system/schemas/arena/weather.ts new file mode 100644 index 00000000000..84eaeb1ba18 --- /dev/null +++ b/src/system/schemas/arena/weather.ts @@ -0,0 +1,30 @@ +// biome-ignore-start lint/correctness/noUnusedImports: used in a tsdoc comment +import type { Weather } from "#data/weather"; +import type { WeatherType } from "#enums/weather-type"; +// biome-ignore-end lint/correctness/noUnusedImports: used in a tsdoc comment +import { z } from "zod"; + +/** + * Zod schema for {@linkcode WeatherType} as of version 1.10. + * + * @remarks + * - `0`: NONE, + * - `1`: SUNNY, + * - `2`: RAIN, + * - `3`: SANDSTORM, + * - `4`: HAIL, + * - `5`: SNOW, + * - `6`: FOG, + * - `7`: HEAVY_RAIN, + * - `8`: HARSH_SUN, + * - `9`: STRONG_WINDS + */ +export const Z$WeatherType = z.literal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + +/** + * Zod schema for {@linkcode SerializedWeather} as of version 1.10. + */ +export const Z$Weather = z.object({ + type: Z$WeatherType, + turnsLeft: z.int(), +}); diff --git a/src/system/schemas/v1.10/berry-type.ts b/src/system/schemas/berry-type.ts similarity index 100% rename from src/system/schemas/v1.10/berry-type.ts rename to src/system/schemas/berry-type.ts diff --git a/src/system/schemas/v1.10/biome-id.ts b/src/system/schemas/biome-id.ts similarity index 100% rename from src/system/schemas/v1.10/biome-id.ts rename to src/system/schemas/biome-id.ts diff --git a/src/system/schemas/v1.10/move-result.ts b/src/system/schemas/moves/move-result.ts similarity index 100% rename from src/system/schemas/v1.10/move-result.ts rename to src/system/schemas/moves/move-result.ts diff --git a/src/system/schemas/v1.10/pokemon-move.ts b/src/system/schemas/moves/pokemon-move.ts similarity index 99% rename from src/system/schemas/v1.10/pokemon-move.ts rename to src/system/schemas/moves/pokemon-move.ts index 9eabecfa152..817ef35f8c9 100644 --- a/src/system/schemas/v1.10/pokemon-move.ts +++ b/src/system/schemas/moves/pokemon-move.ts @@ -1,6 +1,5 @@ import { z } from "zod"; - /** * Zod schema for a Pokémon move, as of version 1.10. */ @@ -14,4 +13,3 @@ export const Z$PokemonMove = z.object({ // If necessary, we can define `transforms` which implicitly create an instance of the class. export type ParsedPokemonMove = z.output; - diff --git a/src/system/schemas/v1.10/turn-move.ts b/src/system/schemas/moves/turn-move.ts similarity index 70% rename from src/system/schemas/v1.10/turn-move.ts rename to src/system/schemas/moves/turn-move.ts index da64c695936..2f08f63fb75 100644 --- a/src/system/schemas/v1.10/turn-move.ts +++ b/src/system/schemas/moves/turn-move.ts @@ -4,7 +4,7 @@ import type { TurnMove } from "#types/turn-move"; // biome-ignore-end lint/correctness/noUnusedImports: used in tsdoc comment import { Z$NonNegativeInt, Z$PositiveInt } from "#system/schemas/common"; -import { Z$BattlerIndex } from "#system/schemas/v1.10/battler-index"; +import { Z$BattlerIndex } from "#system/schemas/pokemon/battler-index"; import { Z$MoveResult } from "#system/schemas/v1.10/move-result"; import { z } from "zod"; @@ -17,9 +17,9 @@ export const Z$MoveUseMode = z.literal([1, 2, 3, 4, 5]); * Zod schema for `{@linkcode TurnMove} as of version 1.10. */ export const Z$TurnMove = z.object({ - move: Z$PositiveInt, - targets: z.array(Z$BattlerIndex), - useMode: Z$MoveUseMode, - result: Z$MoveResult.optional().catch(undefined), - turn: Z$NonNegativeInt.optional().catch(undefined) + move: Z$PositiveInt, + targets: z.array(Z$BattlerIndex), + useMode: Z$MoveUseMode, + result: Z$MoveResult.optional().catch(undefined), + turn: Z$NonNegativeInt.optional().catch(undefined), }); diff --git a/src/system/schemas/v1.10/pokeball-type.ts b/src/system/schemas/pokeball-type.ts similarity index 100% rename from src/system/schemas/v1.10/pokeball-type.ts rename to src/system/schemas/pokeball-type.ts diff --git a/src/system/schemas/v1.10/battler-index.ts b/src/system/schemas/pokemon/battler-index.ts similarity index 100% rename from src/system/schemas/v1.10/battler-index.ts rename to src/system/schemas/pokemon/battler-index.ts diff --git a/src/system/schemas/v1.10/battler-tag.ts b/src/system/schemas/pokemon/battler-tag.ts similarity index 83% rename from src/system/schemas/v1.10/battler-tag.ts rename to src/system/schemas/pokemon/battler-tag.ts index 915ba29e6e1..4a43f0038ee 100644 --- a/src/system/schemas/v1.10/battler-tag.ts +++ b/src/system/schemas/pokemon/battler-tag.ts @@ -1,5 +1,5 @@ import { Z$NonNegativeInt, Z$PositiveInt } from "#system/schemas/common"; -import { Z$BattlerIndex } from "#system/schemas/v1.10/battler-index"; +import { Z$BattlerIndex } from "#system/schemas/pokemon/battler-index"; import { z } from "zod"; /* @@ -126,17 +126,17 @@ const Z$BattlerTagLapseType = z.literal([0, 1, 2, 3, 4, 5, 6, 7, 8]); // DamagingTrapTag may have a `commonAnim` field, though it's always instantiated. const Z$BattlerTag = z.object({ - tagType: Z$BattlerTagType, - lapseTypes: z.array(Z$BattlerTagLapseType), - turnCount: Z$PositiveInt, - // Source move can be `none` for tags not applied by move, so allow `0` here. - sourceMove: Z$NonNegativeInt, - sourceId: z.int().optional().catch(undefined), - isBatonPassable: z.boolean(), + tagType: Z$BattlerTagType, + lapseTypes: z.array(Z$BattlerTagLapseType), + turnCount: Z$PositiveInt, + // Source move can be `none` for tags not applied by move, so allow `0` here. + sourceMove: Z$NonNegativeInt, + sourceId: z.int().optional().catch(undefined), + isBatonPassable: z.boolean(), }); export const Z$SeedTag = z.object({ - ...Z$BattlerTag.shape, - seedType: z.literal("SEEDED"), - sourceIndex: Z$BattlerIndex, -}) + ...Z$BattlerTag.shape, + seedType: z.literal("SEEDED"), + sourceIndex: Z$BattlerIndex, +}); diff --git a/src/system/schemas/v1.10/custom-pokemon-data.ts b/src/system/schemas/pokemon/custom-pokemon-data.ts similarity index 92% rename from src/system/schemas/v1.10/custom-pokemon-data.ts rename to src/system/schemas/pokemon/custom-pokemon-data.ts index 3fb65753c94..eb1143f6f80 100644 --- a/src/system/schemas/v1.10/custom-pokemon-data.ts +++ b/src/system/schemas/pokemon/custom-pokemon-data.ts @@ -1,5 +1,5 @@ import { Z$OptionalNonNegativeIntCatchToUndef, Z$PositiveInt } from "#schemas/common"; -import { Z$PokemonType } from "#system/schemas/v1.10/pokemon-type"; +import { Z$PokemonType } from "#system/schemas/pokemon/pokemon-type"; import { z } from "zod"; /** diff --git a/src/system/schemas/v1.10/illusion-data.ts b/src/system/schemas/pokemon/illusion-data.ts similarity index 87% rename from src/system/schemas/v1.10/illusion-data.ts rename to src/system/schemas/pokemon/illusion-data.ts index 073db626dd9..abb955d2e3f 100644 --- a/src/system/schemas/v1.10/illusion-data.ts +++ b/src/system/schemas/pokemon/illusion-data.ts @@ -1,15 +1,14 @@ import { Z$NonNegativeInt, Z$PositiveInt } from "#system/schemas/common"; +import { Z$Gender } from "#system/schemas/pokemon/pokemon-gender"; import { Z$PokeballType } from "#system/schemas/v1.10/pokeball-type"; -import { Z$Gender } from "#system/schemas/v1.10/pokemon-gender"; import { z } from "zod"; - // TODO: Write migrator for illusion data's fusionSpecies field // that transforms incoming fusion species export const Z$IllusionData = z.object({ name: z.string(), - nickname: z.string(), + nickname: z.string().optional().catch(undefined), shiny: z.boolean(), variant: z.literal([0, 1, 2]).catch(0), species: Z$PositiveInt, diff --git a/src/system/schemas/v1.10/pokemon-battle-data.ts b/src/system/schemas/pokemon/pokemon-battle-data.ts similarity index 100% rename from src/system/schemas/v1.10/pokemon-battle-data.ts rename to src/system/schemas/pokemon/pokemon-battle-data.ts diff --git a/src/system/schemas/v1.10/pokemon-data.ts b/src/system/schemas/pokemon/pokemon-data.ts similarity index 89% rename from src/system/schemas/v1.10/pokemon-data.ts rename to src/system/schemas/pokemon/pokemon-data.ts index b9476711c13..697add7ca8d 100644 --- a/src/system/schemas/v1.10/pokemon-data.ts +++ b/src/system/schemas/pokemon/pokemon-data.ts @@ -1,13 +1,13 @@ import { Z$BoolCatchToFalse, Z$NonNegativeInt, Z$PositiveInt } from "#schemas/common"; import { Z$PokeballType } from "#schemas/pokeball-type"; -import { Z$PokemonMove } from "#schemas/pokemon-move"; -import { Z$PokemonBattleData } from "#system/schemas/v1.10/pokemon-battle-data"; -import { Z$Gender } from "#system/schemas/v1.10/pokemon-gender"; +import { NatureSchema } from "#schemas/pokemon/pokemon-nature"; +import { Z$IVSet, Z$StatSet } from "#schemas/pokemon/pokemon-stats"; +import { StatusSchema } from "#schemas/status-effect"; +import { Z$PokemonMove } from "#system/schemas/moves/pokemon-move"; +import { Z$PokemonBattleData } from "#system/schemas/pokemon/pokemon-battle-data"; +import { Z$Gender } from "#system/schemas/pokemon/pokemon-gender"; import z from "zod"; -import { NatureSchema } from "./pokemon-nature"; -import { Z$IVSet, Z$StatSet } from "./pokemon-stats"; import { Z$PokemonType } from "./pokemon-type"; -import { StatusSchema } from "./status-effect"; /** * Not meant to actually be used itself. diff --git a/src/system/schemas/v1.10/pokemon-gender.ts b/src/system/schemas/pokemon/pokemon-gender.ts similarity index 100% rename from src/system/schemas/v1.10/pokemon-gender.ts rename to src/system/schemas/pokemon/pokemon-gender.ts diff --git a/src/system/schemas/v1.10/pokemon-nature.ts b/src/system/schemas/pokemon/pokemon-nature.ts similarity index 100% rename from src/system/schemas/v1.10/pokemon-nature.ts rename to src/system/schemas/pokemon/pokemon-nature.ts diff --git a/src/system/schemas/v1.10/pokemon-species-form.ts b/src/system/schemas/pokemon/pokemon-species-form.ts similarity index 92% rename from src/system/schemas/v1.10/pokemon-species-form.ts rename to src/system/schemas/pokemon/pokemon-species-form.ts index aed8bbea42e..40b84af9e21 100644 --- a/src/system/schemas/v1.10/pokemon-species-form.ts +++ b/src/system/schemas/pokemon/pokemon-species-form.ts @@ -1,5 +1,5 @@ import { Z$NonNegativeInt, Z$PositiveInt, Z$PositiveNumber } from "#system/schemas/common"; -import { Z$PokemonType } from "#system/schemas/v1.10/pokemon-type"; +import { Z$PokemonType } from "#system/schemas/pokemon/pokemon-type"; import { z } from "zod"; export const Z$PokemonSpeciesForm = z.object({ diff --git a/src/system/schemas/v1.10/pokemon-stats.ts b/src/system/schemas/pokemon/pokemon-stats.ts similarity index 100% rename from src/system/schemas/v1.10/pokemon-stats.ts rename to src/system/schemas/pokemon/pokemon-stats.ts diff --git a/src/system/schemas/v1.10/pokemon-summon-data.ts b/src/system/schemas/pokemon/pokemon-summon-data.ts similarity index 77% rename from src/system/schemas/v1.10/pokemon-summon-data.ts rename to src/system/schemas/pokemon/pokemon-summon-data.ts index b03a93ae2a2..161d5cd3229 100644 --- a/src/system/schemas/v1.10/pokemon-summon-data.ts +++ b/src/system/schemas/pokemon/pokemon-summon-data.ts @@ -1,9 +1,9 @@ import { Z$NonNegativeInt } from "#system/schemas/common"; -import { Z$Gender } from "#system/schemas/v1.10/pokemon-gender"; -import { Z$PokemonMove } from "#system/schemas/v1.10/pokemon-move"; -import { Z$StatSet } from "#system/schemas/v1.10/pokemon-stats"; -import { Z$PokemonType } from "#system/schemas/v1.10/pokemon-type"; -import { Z$TurnMove } from "#system/schemas/v1.10/turn-move"; +import { Z$PokemonMove } from "#system/schemas/moves/pokemon-move"; +import { Z$TurnMove } from "#system/schemas/moves/turn-move"; +import { Z$Gender } from "#system/schemas/pokemon/pokemon-gender"; +import { Z$StatSet } from "#system/schemas/pokemon/pokemon-stats"; +import { Z$PokemonType } from "#system/schemas/pokemon/pokemon-type"; import { z } from "zod"; export const Z$SerializedSpeciesForm = z.object({ @@ -17,7 +17,7 @@ export const Z$SerializedSpeciesForm = z.object({ * @remarks * All fields other than `stats` are optional, and catch to `undefined` on parse error, * allowing {@linkcode PokemonSummonData} to fill in defaults. - * + * */ export const Z$PokemonSummonData = z.object({ statSages: z.array(z.int().min(-6).max(6).catch(0)).optional().catch(undefined), @@ -32,5 +32,5 @@ export const Z$PokemonSummonData = z.object({ moveset: z.array(Z$PokemonMove).optional().catch(undefined), types: z.array(Z$PokemonType).optional().catch(undefined), addedType: Z$PokemonType.optional().catch(undefined), - illusion + illusion, }); diff --git a/src/system/schemas/v1.10/pokemon-type.ts b/src/system/schemas/pokemon/pokemon-type.ts similarity index 100% rename from src/system/schemas/v1.10/pokemon-type.ts rename to src/system/schemas/pokemon/pokemon-type.ts diff --git a/src/system/schemas/session-save-data.ts b/src/system/schemas/session-save-data.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/system/schemas/v1.10/status-effect.ts b/src/system/schemas/status-effect.ts similarity index 100% rename from src/system/schemas/v1.10/status-effect.ts rename to src/system/schemas/status-effect.ts diff --git a/tsconfig.json b/tsconfig.json index 780f33598c8..9c943473884 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -48,7 +48,12 @@ "./system/version-migration/*.ts", "./system/*.ts" ], - "#schemas/*": ["./system/schemas/*.ts", "./system/schemas/v1.10/*.ts"], + "#schemas/*": [ + "./system/schemas/*.ts", + "./system/schemas/arena/*.ts", + "./system/schemas/moves/*.ts", + "./system/schemas/pokemon/*.ts" + ], "#trainers/*": ["./data/trainers/*.ts"], "#types/*": ["./@types/helpers/*.ts", "./@types/*.ts", "./typings/phaser/*.ts"], "#ui/*": ["./ui/battle-info/*.ts", "./ui/settings/*.ts", "./ui/*.ts"],