mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-08 16:39:26 +02:00
[WIP]
This commit is contained in:
parent
e50ebaa815
commit
0c42f16fdd
@ -49,6 +49,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material/material-color-utilities": "^0.2.7",
|
"@material/material-color-utilities": "^0.2.7",
|
||||||
|
"ajv": "^8.17.1",
|
||||||
"compare-versions": "^6.1.1",
|
"compare-versions": "^6.1.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"i18next": "^24.2.3",
|
"i18next": "^24.2.3",
|
||||||
@ -58,7 +59,8 @@
|
|||||||
"json-stable-stringify": "^1.3.0",
|
"json-stable-stringify": "^1.3.0",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"phaser": "^3.90.0",
|
"phaser": "^3.90.0",
|
||||||
"phaser3-rex-plugins": "^1.80.16"
|
"phaser3-rex-plugins": "^1.80.16",
|
||||||
|
"zod": "^4.0.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.0.0"
|
"node": ">=22.0.0"
|
||||||
|
@ -11,6 +11,9 @@ importers:
|
|||||||
'@material/material-color-utilities':
|
'@material/material-color-utilities':
|
||||||
specifier: ^0.2.7
|
specifier: ^0.2.7
|
||||||
version: 0.2.7
|
version: 0.2.7
|
||||||
|
ajv:
|
||||||
|
specifier: ^8.17.1
|
||||||
|
version: 8.17.1
|
||||||
compare-versions:
|
compare-versions:
|
||||||
specifier: ^6.1.1
|
specifier: ^6.1.1
|
||||||
version: 6.1.1
|
version: 6.1.1
|
||||||
@ -41,6 +44,9 @@ importers:
|
|||||||
phaser3-rex-plugins:
|
phaser3-rex-plugins:
|
||||||
specifier: ^1.80.16
|
specifier: ^1.80.16
|
||||||
version: 1.80.16(graphology-types@0.24.8)
|
version: 1.80.16(graphology-types@0.24.8)
|
||||||
|
zod:
|
||||||
|
specifier: ^4.0.5
|
||||||
|
version: 4.0.5
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@biomejs/biome':
|
'@biomejs/biome':
|
||||||
specifier: 2.0.0
|
specifier: 2.0.0
|
||||||
@ -2002,6 +2008,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
|
resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
zod@4.0.5:
|
||||||
|
resolution: {integrity: sha512-/5UuuRPStvHXu7RS+gmvRf4NXrNxpSllGwDnCBcJZtQsKrviYXm54yDGV2KYNLT5kq0lHGcl7lqWJLgSaG+tgA==}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@ampproject/remapping@2.3.0':
|
'@ampproject/remapping@2.3.0':
|
||||||
@ -3828,3 +3837,5 @@ snapshots:
|
|||||||
yargs-parser: 21.1.1
|
yargs-parser: 21.1.1
|
||||||
|
|
||||||
yoctocolors-cjs@2.1.2: {}
|
yoctocolors-cjs@2.1.2: {}
|
||||||
|
|
||||||
|
zod@4.0.5: {}
|
||||||
|
165
sample_session_data.json
Normal file
165
sample_session_data.json
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
{
|
||||||
|
"seed": "XsQk92D0JOcTKUGejq4HpzvC",
|
||||||
|
"playTime": 0,
|
||||||
|
"gameMode": 0,
|
||||||
|
"party": [
|
||||||
|
{
|
||||||
|
"id": 674110050,
|
||||||
|
"player": true,
|
||||||
|
"species": 479,
|
||||||
|
"formIndex": 0,
|
||||||
|
"abilityIndex": 0,
|
||||||
|
"passive": true,
|
||||||
|
"shiny": false,
|
||||||
|
"variant": 0,
|
||||||
|
"pokeball": 0,
|
||||||
|
"level": 5,
|
||||||
|
"exp": 125,
|
||||||
|
"levelExp": 0,
|
||||||
|
"gender": -1,
|
||||||
|
"hp": 21,
|
||||||
|
"stats": [21, 13, 13, 16, 14, 13],
|
||||||
|
"ivs": [31, 31, 25, 31, 31, 26],
|
||||||
|
"nature": 2,
|
||||||
|
"moveset": [],
|
||||||
|
"status": null,
|
||||||
|
"friendship": 50,
|
||||||
|
"metLevel": 5,
|
||||||
|
"metBiome": -1,
|
||||||
|
"metSpecies": 479,
|
||||||
|
"metWave": -1,
|
||||||
|
"luck": 2,
|
||||||
|
"pauseEvolutions": false,
|
||||||
|
"pokerus": false,
|
||||||
|
"usedTMs": [],
|
||||||
|
"teraType": 12,
|
||||||
|
"isTerastallized": false,
|
||||||
|
"stellarTypesBoosted": [],
|
||||||
|
"mysteryEncounterPokemonData": null,
|
||||||
|
"fusionMysteryEncounterPokemonData": null,
|
||||||
|
"fusionLuck": 0,
|
||||||
|
"fusionTeraType": 0,
|
||||||
|
"boss": false,
|
||||||
|
"bossSegments": 0,
|
||||||
|
"summonData": {
|
||||||
|
"statStages": [0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"moveQueue": [],
|
||||||
|
"tags": [],
|
||||||
|
"abilitySuppressed": false,
|
||||||
|
"speciesForm": null,
|
||||||
|
"fusionSpeciesForm": null,
|
||||||
|
"stats": [0, 0, 0, 0, 0, 0],
|
||||||
|
"types": [],
|
||||||
|
"addedType": null,
|
||||||
|
"illusion": null,
|
||||||
|
"illusionBroken": false,
|
||||||
|
"berriesEatenLast": [],
|
||||||
|
"moveHistory": []
|
||||||
|
},
|
||||||
|
"battleData": { "hitCount": 0, "hasEatenBerry": false, "berriesEaten": [] },
|
||||||
|
"customPokemonData": {
|
||||||
|
"spriteScale": -1,
|
||||||
|
"hitsRecCount": null,
|
||||||
|
"ability": -1,
|
||||||
|
"passive": -1,
|
||||||
|
"nature": -1,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"fusionCustomPokemonData": {
|
||||||
|
"spriteScale": -1,
|
||||||
|
"hitsRecCount": null,
|
||||||
|
"ability": -1,
|
||||||
|
"passive": -1,
|
||||||
|
"nature": -1,
|
||||||
|
"types": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemyParty": [
|
||||||
|
{
|
||||||
|
"id": 1442439343,
|
||||||
|
"player": false,
|
||||||
|
"species": 876,
|
||||||
|
"formIndex": 1,
|
||||||
|
"abilityIndex": 1,
|
||||||
|
"shiny": false,
|
||||||
|
"variant": 0,
|
||||||
|
"pokeball": 0,
|
||||||
|
"level": 2,
|
||||||
|
"exp": 7,
|
||||||
|
"levelExp": 0,
|
||||||
|
"gender": 1,
|
||||||
|
"hp": 15,
|
||||||
|
"stats": [15, 7, 7, 9, 10, 7],
|
||||||
|
"ivs": [10, 31, 19, 24, 5, 15],
|
||||||
|
"nature": 22,
|
||||||
|
"moveset": [{ "moveId": 500, "ppUsed": 0, "ppUp": 0 }, { "moveId": 589, "ppUsed": 0, "ppUp": 0 }],
|
||||||
|
"status": null,
|
||||||
|
"friendship": 140,
|
||||||
|
"metLevel": 2,
|
||||||
|
"metBiome": 0,
|
||||||
|
"metSpecies": 876,
|
||||||
|
"metWave": 1,
|
||||||
|
"luck": 0,
|
||||||
|
"pauseEvolutions": false,
|
||||||
|
"pokerus": false,
|
||||||
|
"usedTMs": [],
|
||||||
|
"teraType": 13,
|
||||||
|
"isTerastallized": false,
|
||||||
|
"stellarTypesBoosted": [],
|
||||||
|
"mysteryEncounterPokemonData": null,
|
||||||
|
"fusionMysteryEncounterPokemonData": null,
|
||||||
|
"fusionLuck": 0,
|
||||||
|
"fusionTeraType": 0,
|
||||||
|
"boss": false,
|
||||||
|
"bossSegments": 0,
|
||||||
|
"summonData": {
|
||||||
|
"statStages": [0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"moveQueue": [],
|
||||||
|
"tags": [],
|
||||||
|
"abilitySuppressed": false,
|
||||||
|
"speciesForm": null,
|
||||||
|
"fusionSpeciesForm": null,
|
||||||
|
"stats": [0, 0, 0, 0, 0, 0],
|
||||||
|
"types": [],
|
||||||
|
"addedType": null,
|
||||||
|
"illusion": null,
|
||||||
|
"illusionBroken": false,
|
||||||
|
"berriesEatenLast": [],
|
||||||
|
"moveHistory": []
|
||||||
|
},
|
||||||
|
"battleData": { "hitCount": 0, "hasEatenBerry": false, "berriesEaten": [] },
|
||||||
|
"customPokemonData": {
|
||||||
|
"spriteScale": -1,
|
||||||
|
"hitsRecCount": null,
|
||||||
|
"ability": -1,
|
||||||
|
"passive": -1,
|
||||||
|
"nature": -1,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"fusionCustomPokemonData": {
|
||||||
|
"spriteScale": -1,
|
||||||
|
"hitsRecCount": null,
|
||||||
|
"ability": -1,
|
||||||
|
"passive": -1,
|
||||||
|
"nature": -1,
|
||||||
|
"types": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"modifiers": [],
|
||||||
|
"enemyModifiers": [],
|
||||||
|
"arena": { "biome": 0, "weather": null, "terrain": null, "playerTerasUsed": 0, "tags": [] },
|
||||||
|
"pokeballCounts": { "0": 5, "1": 0, "2": 0, "3": 0, "4": 5 },
|
||||||
|
"money": 1000,
|
||||||
|
"score": 0,
|
||||||
|
"waveIndex": 1,
|
||||||
|
"battleType": 0,
|
||||||
|
"trainer": null,
|
||||||
|
"gameVersion": "1.9.6",
|
||||||
|
"timestamp": 1751940739555,
|
||||||
|
"challenges": [],
|
||||||
|
"mysteryEncounterType": -1,
|
||||||
|
"mysteryEncounterSaveData": { "encounteredEvents": [], "encounterSpawnChance": 3, "queuedEncounters": [] },
|
||||||
|
"playerFaints": 0
|
||||||
|
}
|
61
scripts/zod-test.ts
Normal file
61
scripts/zod-test.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import z from "zod";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Schema for session data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Schema of a `PokemonMove` as of version 1.10
|
||||||
|
*/
|
||||||
|
|
||||||
|
// const IVSet = z.tuple([IVSchema, IVSchema, IVSchema, IVSchema, IVSchema, IVSchema]).catch((e) => {
|
||||||
|
// e.value
|
||||||
|
// }
|
||||||
|
|
||||||
|
export const Z$NonNegativeCatchNeg1 = /*@__PURE__*/ z
|
||||||
|
.int()
|
||||||
|
.nonnegative()
|
||||||
|
.optional()
|
||||||
|
.catch(-1);
|
||||||
|
|
||||||
|
console.log(Z$NonNegativeCatchNeg1.safeParse(undefined));
|
||||||
|
|
||||||
|
// export const PokemonMoveSchema = z.object({
|
||||||
|
// moveId: z.number().int().min(0).optional().overwrite(() => 15), // Move ID, default to 0
|
||||||
|
// ppUsed: z.number().int().catch(0), // PP used, default to 0
|
||||||
|
// ppUp: z.number().int().default(0).catch(0), // PP Up count, default to 0
|
||||||
|
// maxPpOverride: z.int().min(1).optional(), // Optional max PP override, can be null
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // export const PokemonDataSchema = z.object({
|
||||||
|
// // id: z.int(),
|
||||||
|
// // player: z.boolean(),
|
||||||
|
// // species: z.int(),
|
||||||
|
// // nickname: z.string(),
|
||||||
|
// // formIndex: z.int().default(0),
|
||||||
|
// // abilityIndex: z.int().min(0).max(2).default(0).catch,
|
||||||
|
// // }).check(data => {
|
||||||
|
// // // clamp form index to be between 0 and the max form index for the species
|
||||||
|
// // const species = getPokemonSpecies(data.value.species);
|
||||||
|
// // // Clamp formindex to be between 0 and the max form index for the species
|
||||||
|
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// const mockData = {
|
||||||
|
// // ppUsed: 5,
|
||||||
|
// ppUp: 2,
|
||||||
|
// iv: [1, 15, 14, 14, 15, 16, 17]
|
||||||
|
// };
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// // Parse and validate the mock data
|
||||||
|
// const result = PokemonMoveSchema.parse(mockData);
|
||||||
|
// console.log("Validation successful:", result);
|
||||||
|
// } catch (error: unknown) {
|
||||||
|
// if (error instanceof ZodError) {
|
||||||
|
// console.error(error.message);
|
||||||
|
// console.error(z.treeifyError(error));
|
||||||
|
// } else {
|
||||||
|
// console.error("Validation failed:", error);
|
||||||
|
// }
|
||||||
|
// }
|
@ -10,4 +10,4 @@ export interface TurnMove {
|
|||||||
useMode: MoveUseMode;
|
useMode: MoveUseMode;
|
||||||
result?: MoveResult;
|
result?: MoveResult;
|
||||||
turn?: number;
|
turn?: number;
|
||||||
}
|
}
|
@ -51,6 +51,22 @@ export class CustomPokemonData {
|
|||||||
this.types = data?.types ?? [];
|
this.types = data?.types ?? [];
|
||||||
this.hitsRecCount = data?.hitsRecCount ?? null;
|
this.hitsRecCount = data?.hitsRecCount ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this CustomPokemonData has only the default properties.
|
||||||
|
* Primarily used to avoid serializing this data if it is not customized.
|
||||||
|
*/
|
||||||
|
static isDefault(data: CustomPokemonData | Partial<CustomPokemonData>): boolean {
|
||||||
|
return (
|
||||||
|
data.spriteScale === -1 &&
|
||||||
|
data.ability === -1 &&
|
||||||
|
data.passive === -1 &&
|
||||||
|
data.nature === -1 &&
|
||||||
|
Array.isArray(data.types) &&
|
||||||
|
data.types.length === 0 &&
|
||||||
|
(data.hitsRecCount === null || data.hitsRecCount === 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
27
src/system/schemas/common.ts
Normal file
27
src/system/schemas/common.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Schemas for commonly used primitive types, to avoid repeated instantiations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Reusable schema for a positive integer, equivalent to `z.int().positive()`.*/
|
||||||
|
export const Z$PositiveInt = /*@__PURE__*/ z
|
||||||
|
.int()
|
||||||
|
.positive();
|
||||||
|
|
||||||
|
/** Reusable schema for a non-negative integer, equivalent to `z.int().nonnegative()`.*/
|
||||||
|
export const Z$NonNegativeInt = /*@__PURE__*/ z
|
||||||
|
.int()
|
||||||
|
.nonnegative();
|
||||||
|
|
||||||
|
/** Reusable schema for a boolean that coerces non-boolean inputs to `false` */
|
||||||
|
export const Z$BoolCatchToFalse = /*@__PURE__*/ z
|
||||||
|
.boolean()
|
||||||
|
.catch(false);
|
||||||
|
|
||||||
|
/** Reusable schema for an optional non-negative integer that coerces invalid inputs to `undefined` */
|
||||||
|
export const Z$OptionalNonNegativeIntCatchToUndef = /*@__PURE__*/ z
|
||||||
|
.int()
|
||||||
|
.nonnegative()
|
||||||
|
.optional()
|
||||||
|
.catch(undefined);
|
8
src/system/schemas/game-version.ts
Normal file
8
src/system/schemas/game-version.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema matching a version string
|
||||||
|
*
|
||||||
|
* @remarks Equivalent to `z.string().regex(/^\d+\.\d+\.\d+$/)`
|
||||||
|
*/
|
||||||
|
export const Z$GameVersion = z.string().regex(/^\d+\.\d+\.\d+$/);
|
15
src/system/schemas/v1.10/battler-index.ts
Normal file
15
src/system/schemas/v1.10/battler-index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// biome-ignore lint/correctness/noUnusedImports: used in tsdoc comment
|
||||||
|
import { BattlerIndex } from "#enums/battler-index";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for the {@linkcode BattlerIndex} as of version 1.10
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - `-1`: Attacker
|
||||||
|
* - `0`: Player
|
||||||
|
* - `1`: Player 2
|
||||||
|
* - `2`: Enemy
|
||||||
|
* - `3`: Enemy 2
|
||||||
|
*/
|
||||||
|
export const Z$BattlerIndex = z.literal([-1, 0, 1, 2, 3]);
|
142
src/system/schemas/v1.10/battler-tag.ts
Normal file
142
src/system/schemas/v1.10/battler-tag.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import { Z$NonNegativeInt, Z$PositiveInt } from "#system/schemas/common";
|
||||||
|
import { Z$BattlerIndex } from "#system/schemas/v1.10/battler-index";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Schemas for battler tags are a bit more cumbersome,
|
||||||
|
as we need to have schemas for each subclass that has a different shape.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for the {@linkcode BattlerTagType} enum as of version 1.10
|
||||||
|
*/
|
||||||
|
const Z$BattlerTagType = z.literal([
|
||||||
|
"NONE",
|
||||||
|
"RECHARGING",
|
||||||
|
"FLINCHED",
|
||||||
|
"INTERRUPTED",
|
||||||
|
"CONFUSED",
|
||||||
|
"INFATUATED",
|
||||||
|
"SEEDED",
|
||||||
|
"NIGHTMARE",
|
||||||
|
"FRENZY",
|
||||||
|
"CHARGING",
|
||||||
|
"ENCORE",
|
||||||
|
"HELPING_HAND",
|
||||||
|
"INGRAIN",
|
||||||
|
"OCTOLOCK",
|
||||||
|
"AQUA_RING",
|
||||||
|
"DROWSY",
|
||||||
|
"TRAPPED",
|
||||||
|
"BIND",
|
||||||
|
"WRAP",
|
||||||
|
"FIRE_SPIN",
|
||||||
|
"WHIRLPOOL",
|
||||||
|
"CLAMP",
|
||||||
|
"SAND_TOMB",
|
||||||
|
"MAGMA_STORM",
|
||||||
|
"SNAP_TRAP",
|
||||||
|
"THUNDER_CAGE",
|
||||||
|
"INFESTATION",
|
||||||
|
"PROTECTED",
|
||||||
|
"SPIKY_SHIELD",
|
||||||
|
"KINGS_SHIELD",
|
||||||
|
"OBSTRUCT",
|
||||||
|
"SILK_TRAP",
|
||||||
|
"BANEFUL_BUNKER",
|
||||||
|
"BURNING_BULWARK",
|
||||||
|
"ENDURING",
|
||||||
|
"STURDY",
|
||||||
|
"PERISH_SONG",
|
||||||
|
"TRUANT",
|
||||||
|
"SLOW_START",
|
||||||
|
"PROTOSYNTHESIS",
|
||||||
|
"QUARK_DRIVE",
|
||||||
|
"FLYING",
|
||||||
|
"UNDERGROUND",
|
||||||
|
"UNDERWATER",
|
||||||
|
"HIDDEN",
|
||||||
|
"FIRE_BOOST",
|
||||||
|
"CRIT_BOOST",
|
||||||
|
"ALWAYS_CRIT",
|
||||||
|
"IGNORE_ACCURACY",
|
||||||
|
"BYPASS_SLEEP",
|
||||||
|
"IGNORE_FLYING",
|
||||||
|
"SALT_CURED",
|
||||||
|
"CURSED",
|
||||||
|
"CHARGED",
|
||||||
|
"ROOSTED",
|
||||||
|
"FLOATING",
|
||||||
|
"MINIMIZED",
|
||||||
|
"DESTINY_BOND",
|
||||||
|
"CENTER_OF_ATTENTION",
|
||||||
|
"ICE_FACE",
|
||||||
|
"DISGUISE",
|
||||||
|
"STOCKPILING",
|
||||||
|
"RECEIVE_DOUBLE_DAMAGE",
|
||||||
|
"ALWAYS_GET_HIT",
|
||||||
|
"DISABLED",
|
||||||
|
"SUBSTITUTE",
|
||||||
|
"IGNORE_GHOST",
|
||||||
|
"IGNORE_DARK",
|
||||||
|
"GULP_MISSILE_ARROKUDA",
|
||||||
|
"GULP_MISSILE_PIKACHU",
|
||||||
|
"BEAK_BLAST_CHARGING",
|
||||||
|
"SHELL_TRAP",
|
||||||
|
"DRAGON_CHEER",
|
||||||
|
"NO_RETREAT",
|
||||||
|
"GORILLA_TACTICS",
|
||||||
|
"UNBURDEN",
|
||||||
|
"THROAT_CHOPPED",
|
||||||
|
"TAR_SHOT",
|
||||||
|
"BURNED_UP",
|
||||||
|
"DOUBLE_SHOCKED",
|
||||||
|
"AUTOTOMIZED",
|
||||||
|
"MYSTERY_ENCOUNTER_POST_SUMMON",
|
||||||
|
"POWER_TRICK",
|
||||||
|
"HEAL_BLOCK",
|
||||||
|
"TORMENT",
|
||||||
|
"TAUNT",
|
||||||
|
"IMPRISON",
|
||||||
|
"SYRUP_BOMB",
|
||||||
|
"ELECTRIFIED",
|
||||||
|
"TELEKINESIS",
|
||||||
|
"COMMANDED",
|
||||||
|
"GRUDGE",
|
||||||
|
"PSYCHO_SHIFT",
|
||||||
|
"ENDURE_TOKEN",
|
||||||
|
"POWDER",
|
||||||
|
"MAGIC_COAT",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for {@linkcode BattlerTagLapseType} as of version 1.10
|
||||||
|
* @remarks
|
||||||
|
* - `0`: Faint
|
||||||
|
* - `1`: Move
|
||||||
|
* - `2`: Pre-Move
|
||||||
|
* - `3`: After Move
|
||||||
|
* - `4`: Move Effect
|
||||||
|
* - `5`: Turn End
|
||||||
|
* - `6`: Hit
|
||||||
|
* - `7`: After Hit
|
||||||
|
* - `8`: Custom
|
||||||
|
*/
|
||||||
|
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(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Z$SeedTag = z.object({
|
||||||
|
...Z$BattlerTag.shape,
|
||||||
|
seedType: z.literal("SEEDED"),
|
||||||
|
sourceIndex: Z$BattlerIndex,
|
||||||
|
})
|
19
src/system/schemas/v1.10/berry-type.ts
Normal file
19
src/system/schemas/v1.10/berry-type.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for Berry types as of version 1.10.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - `0`: Sitrus
|
||||||
|
* - `1`: Lum
|
||||||
|
* - `2`: Enigma
|
||||||
|
* - `3`: Liechi
|
||||||
|
* - `4`: Ganlon
|
||||||
|
* - `5`: Petaya
|
||||||
|
* - `6`: Apicot
|
||||||
|
* - `7`: Salac
|
||||||
|
* - `8`: Lansat
|
||||||
|
* - `9`: Starf
|
||||||
|
* - `10`: Leppa
|
||||||
|
*/
|
||||||
|
export const Z$BerryType = z.literal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
|
55
src/system/schemas/v1.10/biome-id.ts
Normal file
55
src/system/schemas/v1.10/biome-id.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for biome IDs, as of version 1.10
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - `0`: Town,
|
||||||
|
* - `1`: Plains,
|
||||||
|
* - `2`: Grass,
|
||||||
|
* - `3`: Tall Grass,
|
||||||
|
* - `4`: Metropolis,
|
||||||
|
* - `5`: Forest,
|
||||||
|
* - `6`: Sea,
|
||||||
|
* - `7`: Swamp,
|
||||||
|
* - `8`: Beach,
|
||||||
|
* - `9`: Lake,
|
||||||
|
* - `10`: Seabed,
|
||||||
|
* - `11`: Mountain,
|
||||||
|
* - `12`: Badlands,
|
||||||
|
* - `13`: Cave,
|
||||||
|
* - `14`: Desert,
|
||||||
|
* - `15`: Ice Cave,
|
||||||
|
* - `16`: Meadow,
|
||||||
|
* - `17`: Power Plant,
|
||||||
|
* - `18`: Volcano,
|
||||||
|
* - `19`: Graveyard,
|
||||||
|
* - `20`: Dojo,
|
||||||
|
* - `21`: Factory,
|
||||||
|
* - `22`: Ruins,
|
||||||
|
* - `23`: Wasteland,
|
||||||
|
* - `24`: Abyss,
|
||||||
|
* - `25`: Space,
|
||||||
|
* - `26`: Construction Site,
|
||||||
|
* - `27`: Jungle,
|
||||||
|
* - `28`: Fairy Cave,
|
||||||
|
* - `29`: Temple,
|
||||||
|
* - `30`: Slum,
|
||||||
|
* - `31`: Snowy Forest,
|
||||||
|
* - `40`: Island,
|
||||||
|
* - `41`: Laboratory,
|
||||||
|
* - `50`: End
|
||||||
|
*/
|
||||||
|
export const Z$BiomeID = z.literal([
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
40, 41, 50,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for a pokemon's met biome, as of version 1.10
|
||||||
|
* Same as {@linkcode Z$BiomeID}, additionally allowing `-1` for starters.
|
||||||
|
*/
|
||||||
|
export const Z$MetBiome = z.union([
|
||||||
|
z.literal(-1), // For starters
|
||||||
|
Z$BiomeID, // All other biomes
|
||||||
|
]);
|
17
src/system/schemas/v1.10/custom-pokemon-data.ts
Normal file
17
src/system/schemas/v1.10/custom-pokemon-data.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Z$OptionalNonNegativeIntCatchToUndef } from "#schemas/common";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for custom Pokémon data as of version 1.10.
|
||||||
|
*
|
||||||
|
* @remarks All fields are optional, but catch to `undefined`
|
||||||
|
* on malformed inputs, as the `CustomPokemonData` allows partial data and
|
||||||
|
* uses defaults for missing fields.
|
||||||
|
*/
|
||||||
|
export const Z$CustomPokemonData = z.object({
|
||||||
|
// sprite scale of -1 is allowed, but it's the default meaning there is no override for it
|
||||||
|
spriteScale: z.number().nonnegative().optional().catch(undefined),
|
||||||
|
ability: Z$OptionalNonNegativeIntCatchToUndef.catch(undefined),
|
||||||
|
passive: Z$OptionalNonNegativeIntCatchToUndef.catch(undefined),
|
||||||
|
nature: Z$OptionalNonNegativeIntCatchToUndef.catch(undefined),
|
||||||
|
});
|
8
src/system/schemas/v1.10/move-result.ts
Normal file
8
src/system/schemas/v1.10/move-result.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// biome-ignore lint/correctness/noUnusedImports: used in tsdoc comment
|
||||||
|
import type { MoveResult } from "#enums/move-result";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for the {@linkcode MoveResult} enum as of version 1.10
|
||||||
|
*/
|
||||||
|
export const Z$MoveResult = z.literal([0, 1, 2, 3, 4]);
|
17
src/system/schemas/v1.10/pokeball-type.ts
Normal file
17
src/system/schemas/v1.10/pokeball-type.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for Pokéball types that a pokemon can be caught in, as of version 1.10. Excludes Luxury Ball
|
||||||
|
* - `0`: POKEBALL,
|
||||||
|
* - `1`: GREAT_BALL,
|
||||||
|
* - `2`: ULTRA_BALL,
|
||||||
|
* - `3`: ROGUE_BALL,
|
||||||
|
* - `4`: MASTER_BALL
|
||||||
|
*/
|
||||||
|
export const Z$PokeballType = z.literal([
|
||||||
|
0, // POKEBALL
|
||||||
|
1, // GREAT_BALL
|
||||||
|
2, // ULTRA_BALL
|
||||||
|
3, // ROGUE BALL
|
||||||
|
4, // MASTER_BALL
|
||||||
|
]);
|
18
src/system/schemas/v1.10/pokemon-battle-data.ts
Normal file
18
src/system/schemas/v1.10/pokemon-battle-data.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Z$BerryType } from "#schemas/berry-type";
|
||||||
|
import { Z$NonNegativeInt } from "#schemas/common";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for Pokémon battle data as of version 1.10.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* All fields are optional and fallback to undefined if malformed, as `BattleData`'s
|
||||||
|
* constructor supports taking partial data, and using defaults for missing fields.
|
||||||
|
*/
|
||||||
|
export const Z$PokemonBattleData = z.object({
|
||||||
|
hitCount: Z$NonNegativeInt.optional().catch(undefined),
|
||||||
|
hasEatenBerry: z.boolean().optional().catch(undefined),
|
||||||
|
berriesEaten: z.array(Z$BerryType).optional().catch(undefined),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ParsedPokemonBattleData = z.output<typeof Z$PokemonBattleData>;
|
123
src/system/schemas/v1.10/pokemon-data.ts
Normal file
123
src/system/schemas/v1.10/pokemon-data.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
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$Gender } from "#system/schemas/v1.10/pokemon-gender";
|
||||||
|
import z from "zod";
|
||||||
|
import { NatureSchema } from "./pokemon-nature";
|
||||||
|
import { IVSetSchema, statSetSchema } from "./pokemon-stats";
|
||||||
|
import { Z$PokemonType } from "./pokemon-type";
|
||||||
|
import { StatusSchema } from "./status-effect";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not meant to actually be used itself.
|
||||||
|
* Instead, use either {@linkcode Z$PlayerPokemonData} or {@linkcode Z$EnemyPokemonData}.
|
||||||
|
* `looseObject` used here to allow properties specific to player or enemy Pokémon
|
||||||
|
* to be handled by their respective schemas.
|
||||||
|
*/
|
||||||
|
const Z$PokemonData = z.looseObject({
|
||||||
|
// malformed pokemon ids are _not_ supported.
|
||||||
|
id: z.uint32(),
|
||||||
|
species: z.uint32(),
|
||||||
|
nickname: z.string().optional(),
|
||||||
|
formIndex: Z$NonNegativeInt.catch(0),
|
||||||
|
// Between 0 and 2, with malformed inputs defaulting to 0
|
||||||
|
abilityIndex: z.int().min(0).max(2).catch(0),
|
||||||
|
passive: Z$BoolCatchToFalse,
|
||||||
|
shiny: Z$BoolCatchToFalse,
|
||||||
|
variant: z.literal([0, 1, 2]).catch(0),
|
||||||
|
pokeball: Z$PokeballType.catch(0),
|
||||||
|
|
||||||
|
// No fallbacks for level
|
||||||
|
level: Z$NonNegativeInt,
|
||||||
|
// TODO: Fallback to minimum experience for level if parsing error?
|
||||||
|
exp: Z$NonNegativeInt,
|
||||||
|
// Fallback to 0, patch in transformer
|
||||||
|
levelExp: Z$NonNegativeInt.catch(0),
|
||||||
|
// Fallback to -1, patch to a default gender in the transformer.
|
||||||
|
gender: Z$Gender.catch(-1),
|
||||||
|
// hp can be 0 if fainted
|
||||||
|
hp: Z$NonNegativeInt,
|
||||||
|
stats: statSetSchema,
|
||||||
|
ivs: IVSetSchema,
|
||||||
|
nature: NatureSchema,
|
||||||
|
moveset: z.array(Z$PokemonMove).catch([]),
|
||||||
|
status: z.union([z.null(), StatusSchema]).catch(null),
|
||||||
|
friendship: z.int().min(0).max(255).catch(0),
|
||||||
|
|
||||||
|
//#region "met" information
|
||||||
|
metLevel: z.int().positive().catch(1),
|
||||||
|
metBiome: z.union([z.int().nonnegative(), z.literal(-1)]).catch(-1), // -1 for starters
|
||||||
|
metSpecies: z.uint32(),
|
||||||
|
metWave: z.int().min(-1).default(0),
|
||||||
|
//#endregion "met" information
|
||||||
|
|
||||||
|
luck: Z$NonNegativeInt.catch(0),
|
||||||
|
teraType: Z$PokemonType,
|
||||||
|
isTerastallized: Z$BoolCatchToFalse,
|
||||||
|
stellarTypesBoosted: z.array(Z$PokemonType).catch([]),
|
||||||
|
|
||||||
|
//#region "fusion" information
|
||||||
|
fusionSpecies: z.uint32().optional(),
|
||||||
|
fusionFormIndex: Z$NonNegativeInt.optional(),
|
||||||
|
fusionAbilityIndex: z.int().min(0).max(2).optional().catch(0),
|
||||||
|
fusionShiny: Z$BoolCatchToFalse,
|
||||||
|
fusionLuck: Z$NonNegativeInt.catch(0),
|
||||||
|
//#endregion "fusion" information
|
||||||
|
|
||||||
|
pokerus: z.boolean().catch(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Z$PlayerPokemonData = z.object({
|
||||||
|
...Z$PokemonData.shape,
|
||||||
|
player: z.transform((): true => true),
|
||||||
|
pauseEvolutions: Z$BoolCatchToFalse,
|
||||||
|
// Assume player pokemon can never be bosses
|
||||||
|
boss: z.transform((): false => false),
|
||||||
|
bossSegments: z.transform((): 0 => 0),
|
||||||
|
// 0 is unknown, -1 is starter
|
||||||
|
metWave: z.int().min(-1).default(0),
|
||||||
|
usedTms: z.array(Z$PositiveInt).catch([]),
|
||||||
|
// Fallback for empty pokemon movesets handled by transformer
|
||||||
|
moveset: z.array(Z$PokemonMove).catch([]),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Z$EnemyPokemonData = z.object({
|
||||||
|
...Z$PokemonData.shape,
|
||||||
|
player: z.transform((): false => false),
|
||||||
|
boss: z.boolean().catch(false),
|
||||||
|
bossSegments: z.int().nonnegative().default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Replace output assertion type with the type of pokemon data that has CustomPokemonData.
|
||||||
|
export function PreCustomPokemonDataMigrator(
|
||||||
|
data: z.output<typeof Z$PokemonData>,
|
||||||
|
): asserts data is z.output<typeof Z$PokemonData> {
|
||||||
|
// Value of `-1` indicated no override, so we can ignore it.
|
||||||
|
const nature = NatureSchema.safeParse(data.natureOverride);
|
||||||
|
if (nature.success) {
|
||||||
|
const customPokemonData = data.customPokemonData;
|
||||||
|
// If natureOverride is valid, use it
|
||||||
|
if (
|
||||||
|
customPokemonData &&
|
||||||
|
typeof customPokemonData === "object" &&
|
||||||
|
((customPokemonData as { nature?: number }).nature ?? -1) === -1
|
||||||
|
) {
|
||||||
|
customPokemonData;
|
||||||
|
} else {
|
||||||
|
data.customPokemonData = {
|
||||||
|
nature: nature.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PreParsedPokemonData = z.input<typeof Z$PokemonData>;
|
||||||
|
export type ParsedPokemonData = z.output<typeof Z$PokemonData>;
|
||||||
|
|
||||||
|
export type PreParsedPlayerPokemonData = z.input<typeof Z$PlayerPokemonData>;
|
||||||
|
export type ParsedPlayerPokemon = z.output<typeof Z$PlayerPokemonData>;
|
||||||
|
|
||||||
|
export type PreParsedEnemyPokemonData = z.input<typeof Z$EnemyPokemonData>;
|
||||||
|
export type ParsedEnemyPokemon = z.output<typeof Z$EnemyPokemonData>;
|
11
src/system/schemas/v1.10/pokemon-gender.ts
Normal file
11
src/system/schemas/v1.10/pokemon-gender.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for a Pokémon's Gender, as of version 1.10
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - `-1`: Genderless,
|
||||||
|
* - `0`: Male,
|
||||||
|
* - `1`: Female
|
||||||
|
*/
|
||||||
|
export const Z$Gender = z.literal([-1, 0, 1]);
|
17
src/system/schemas/v1.10/pokemon-move.ts
Normal file
17
src/system/schemas/v1.10/pokemon-move.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for a Pokémon move, as of version 1.10.
|
||||||
|
*/
|
||||||
|
export const Z$PokemonMove = z.object({
|
||||||
|
moveId: z.number().int().min(0), // Move ID, default to 0
|
||||||
|
ppUsed: z.number().int().default(0).catch(0), // PP used, default to 0
|
||||||
|
ppUp: z.number().int().default(0).catch(0), // PP Up count, default to 0
|
||||||
|
maxPpOverride: z.int().min(1).optional(), // Optional max PP override, can be null
|
||||||
|
});
|
||||||
|
|
||||||
|
// If necessary, we can define `transforms` which implicitly create an instance of the class.
|
||||||
|
|
||||||
|
export type ParsedPokemonMove = z.output<typeof Z$PokemonMove>;
|
||||||
|
|
33
src/system/schemas/v1.10/pokemon-nature.ts
Normal file
33
src/system/schemas/v1.10/pokemon-nature.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for a Pokémon's nature, as of version 1.10
|
||||||
|
* - `0`: Hardy,
|
||||||
|
* - `1`: Lonely,
|
||||||
|
* - `2`: Brave,
|
||||||
|
* - `3`: Adamant,
|
||||||
|
* - `4`: Naughty,
|
||||||
|
* - `5`: Bold,
|
||||||
|
* - `6`: Docile,
|
||||||
|
* - `7`: Relaxed,
|
||||||
|
* - `8`: Impish,
|
||||||
|
* - `9`: Lax,
|
||||||
|
* - `10`: Timid,
|
||||||
|
* - `11`: Hasty,
|
||||||
|
* - `12`: Serious,
|
||||||
|
* - `13`: Jolly,
|
||||||
|
* - `14`: Naive,
|
||||||
|
* - `15`: Modest,
|
||||||
|
* - `16`: Mild,
|
||||||
|
* - `17`: Quiet,
|
||||||
|
* - `18`: Bashful,
|
||||||
|
* - `19`: Rash,
|
||||||
|
* - `20`: Calm,
|
||||||
|
* - `21`: Gentle,
|
||||||
|
* - `22`: Sassy,
|
||||||
|
* - `23`: Careful,
|
||||||
|
* - `24`: Quirky
|
||||||
|
*/
|
||||||
|
export const NatureSchema = z.literal([
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
]);
|
39
src/system/schemas/v1.10/pokemon-stats.ts
Normal file
39
src/system/schemas/v1.10/pokemon-stats.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Z$PositiveInt } from "#schemas/common";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for a Pokémon's Individual Values (IVs), as of version 1.10
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - Each IV is an integer between 0 and 31, inclusive.
|
||||||
|
* - Malformed values parse to 15 by default.
|
||||||
|
*/
|
||||||
|
export const IVSchema = z.int().min(0).max(31).catch(15);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for a set of 6 Pokémon IVs, as of version 1.10
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* Malformed IV sets default to [15, 15, 15, 15, 15, 15].
|
||||||
|
*/
|
||||||
|
export const IVSetSchema = z
|
||||||
|
.tuple([IVSchema, IVSchema, IVSchema, IVSchema, IVSchema, IVSchema])
|
||||||
|
.catch([15, 15, 15, 15, 15, 15]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for a Pokémon's stats, as of version 1.10
|
||||||
|
* - [0]: HP,
|
||||||
|
* - [1]: Attack,
|
||||||
|
* - [2]: Defense,
|
||||||
|
* - [3]: Special Attack,
|
||||||
|
* - [4]: Special Defense,
|
||||||
|
* - [5]: Speed
|
||||||
|
*/
|
||||||
|
export const statSetSchema = z.tuple([
|
||||||
|
Z$PositiveInt, // HP
|
||||||
|
Z$PositiveInt, // Attack
|
||||||
|
Z$PositiveInt, // Defense
|
||||||
|
Z$PositiveInt, // Special Attack
|
||||||
|
Z$PositiveInt, // Special Defense
|
||||||
|
Z$PositiveInt, // Speed
|
||||||
|
]);
|
27
src/system/schemas/v1.10/pokemon-summon-data.ts
Normal file
27
src/system/schemas/v1.10/pokemon-summon-data.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Z$TurnMove } from "#system/schemas/v1.10/turn-move";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
|
||||||
|
const Z$StatStage = z.int().min(-6).max(6).catch(0);
|
||||||
|
|
||||||
|
const Z$StatStageSet = z.tuple([
|
||||||
|
Z$StatStage,
|
||||||
|
Z$StatStage,
|
||||||
|
Z$StatStage,
|
||||||
|
Z$StatStage,
|
||||||
|
Z$StatStage,
|
||||||
|
Z$StatStage,
|
||||||
|
Z$StatStage])
|
||||||
|
/**
|
||||||
|
* Zod schema for Pokémon summon data as of version 1.10.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const Z$PokemonSummonData = z.object({
|
||||||
|
statStages: Z$StatStageSet.optional().catch(undefined),
|
||||||
|
moveQueue: z.array(Z$TurnMove).optional().catch(undefined),
|
||||||
|
|
||||||
|
//#region Overrides for transform
|
||||||
|
|
||||||
|
//#endregion Overrides for transform
|
||||||
|
|
||||||
|
});
|
26
src/system/schemas/v1.10/pokemon-type.ts
Normal file
26
src/system/schemas/v1.10/pokemon-type.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for a Pokémon's type, as of version 1.10
|
||||||
|
* - `-1`: Unknown (aka typeless),
|
||||||
|
* - `0`: Normal,
|
||||||
|
* - `1`: Fighting,
|
||||||
|
* - `2`: Flying,
|
||||||
|
* - `3`: Poison,
|
||||||
|
* - `4`: Ground,
|
||||||
|
* - `5`: Rock,
|
||||||
|
* - `6`: Bug,
|
||||||
|
* - `7`: Ghost,
|
||||||
|
* - `8`: Steel,
|
||||||
|
* - `9`: Fire,
|
||||||
|
* - `10`: Water,
|
||||||
|
* - `11`: Grass,
|
||||||
|
* - `12`: Electric,
|
||||||
|
* - `13`: Psychic,
|
||||||
|
* - `14`: Ice,
|
||||||
|
* - `15`: Dragon,
|
||||||
|
* - `16`: Dark,
|
||||||
|
* - `17`: Fairy
|
||||||
|
* - `18`: Stellar
|
||||||
|
*/
|
||||||
|
export const Z$PokemonType = z.literal([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]);
|
0
src/system/schemas/v1.10/session-save-data.ts
Normal file
0
src/system/schemas/v1.10/session-save-data.ts
Normal file
31
src/system/schemas/v1.10/status-effect.ts
Normal file
31
src/system/schemas/v1.10/status-effect.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// biome-ignore lint/correctness/noUnusedImports: used in tsdoc comment
|
||||||
|
import type { Status } from "#data/status-effect";
|
||||||
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { Z$NonNegativeInt, Z$PositiveInt } from "../common";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for the {@linkcode StatusEffect} enum
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* - `0`: NONE,
|
||||||
|
* - `1`: POISON,
|
||||||
|
* - `2`: TOXIC,
|
||||||
|
* - `3`: PARALYSIS,
|
||||||
|
* - `4`: SLEEP,
|
||||||
|
* - `5`: FREEZE,
|
||||||
|
* - `6`: BURN,
|
||||||
|
* - `7`: FAINT
|
||||||
|
*/
|
||||||
|
const Z$StatusEffect = z.int().min(StatusEffect.NONE).max(StatusEffect.FAINT).catch(StatusEffect.NONE);
|
||||||
|
|
||||||
|
// Note: This does not validate that sleepTurnsRemaining exists when effect is SLEEP.
|
||||||
|
// This is game logic that should perhaps exist in the constructor.
|
||||||
|
/**
|
||||||
|
* Zod schema for the {@linkcode Status} class
|
||||||
|
*/
|
||||||
|
export const StatusSchema = z.object({
|
||||||
|
effect: Z$StatusEffect,
|
||||||
|
toxicTurnCount: Z$NonNegativeInt.catch(0),
|
||||||
|
sleepTurnsRemaining: Z$PositiveInt.optional().catch(0),
|
||||||
|
});
|
25
src/system/schemas/v1.10/turn-move.ts
Normal file
25
src/system/schemas/v1.10/turn-move.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// biome-ignore-start lint/correctness/noUnusedImports: used in tsdoc comment
|
||||||
|
import type { MoveUseMode } from "#enums/move-use-mode";
|
||||||
|
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$MoveResult } from "#system/schemas/v1.10/move-result";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zod schema for the {@linkcode MoveUseMode} enum
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
});
|
@ -48,6 +48,7 @@
|
|||||||
"./system/version-migration/*.ts",
|
"./system/version-migration/*.ts",
|
||||||
"./system/*.ts"
|
"./system/*.ts"
|
||||||
],
|
],
|
||||||
|
"#schemas/*": ["./system/schemas/*.ts", "./system/schemas/v1.10/*.ts"],
|
||||||
"#trainers/*": ["./data/trainers/*.ts"],
|
"#trainers/*": ["./data/trainers/*.ts"],
|
||||||
"#types/*": ["./@types/helpers/*.ts", "./@types/*.ts", "./typings/phaser/*.ts"],
|
"#types/*": ["./@types/helpers/*.ts", "./@types/*.ts", "./typings/phaser/*.ts"],
|
||||||
"#ui/*": ["./ui/battle-info/*.ts", "./ui/settings/*.ts", "./ui/*.ts"],
|
"#ui/*": ["./ui/battle-info/*.ts", "./ui/settings/*.ts", "./ui/*.ts"],
|
||||||
|
Loading…
Reference in New Issue
Block a user