mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-19 13:59:27 +02:00
Merge branch 'beta' into mortal-spin
This commit is contained in:
commit
b5a9f46ee7
@ -15,8 +15,6 @@
|
|||||||
"test:silent": "vitest run --silent='passed-only' --no-isolate",
|
"test:silent": "vitest run --silent='passed-only' --no-isolate",
|
||||||
"test:create": "node scripts/create-test/create-test.js",
|
"test:create": "node scripts/create-test/create-test.js",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"eslint": "eslint --fix .",
|
|
||||||
"eslint-ci": "eslint .",
|
|
||||||
"biome": "biome check --write --changed --no-errors-on-unmatched --diagnostic-level=error",
|
"biome": "biome check --write --changed --no-errors-on-unmatched --diagnostic-level=error",
|
||||||
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched",
|
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched",
|
||||||
"docs": "typedoc",
|
"docs": "typedoc",
|
||||||
@ -29,6 +27,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.0.0",
|
"@biomejs/biome": "2.0.0",
|
||||||
"@ls-lint/ls-lint": "2.3.1",
|
"@ls-lint/ls-lint": "2.3.1",
|
||||||
|
"@types/crypto-js": "^4.2.0",
|
||||||
"@types/jsdom": "^21.1.7",
|
"@types/jsdom": "^21.1.7",
|
||||||
"@types/node": "^22.16.5",
|
"@types/node": "^22.16.5",
|
||||||
"@vitest/coverage-istanbul": "^3.2.4",
|
"@vitest/coverage-istanbul": "^3.2.4",
|
||||||
|
@ -48,6 +48,9 @@ importers:
|
|||||||
'@ls-lint/ls-lint':
|
'@ls-lint/ls-lint':
|
||||||
specifier: 2.3.1
|
specifier: 2.3.1
|
||||||
version: 2.3.1
|
version: 2.3.1
|
||||||
|
'@types/crypto-js':
|
||||||
|
specifier: ^4.2.0
|
||||||
|
version: 4.2.2
|
||||||
'@types/jsdom':
|
'@types/jsdom':
|
||||||
specifier: ^21.1.7
|
specifier: ^21.1.7
|
||||||
version: 21.1.7
|
version: 21.1.7
|
||||||
@ -718,6 +721,9 @@ packages:
|
|||||||
'@types/cookie@0.6.0':
|
'@types/cookie@0.6.0':
|
||||||
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
||||||
|
|
||||||
|
'@types/crypto-js@4.2.2':
|
||||||
|
resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==}
|
||||||
|
|
||||||
'@types/deep-eql@4.0.2':
|
'@types/deep-eql@4.0.2':
|
||||||
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
|
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
|
||||||
|
|
||||||
@ -2525,6 +2531,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/cookie@0.6.0': {}
|
'@types/cookie@0.6.0': {}
|
||||||
|
|
||||||
|
'@types/crypto-js@4.2.2': {}
|
||||||
|
|
||||||
'@types/deep-eql@4.0.2': {}
|
'@types/deep-eql@4.0.2': {}
|
||||||
|
|
||||||
'@types/estree@1.0.8': {}
|
'@types/estree@1.0.8': {}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit ab2716d5440c25f73986664aa3f3131821c3c392
|
Subproject commit 1ea8f865e30d1940caa0fceeabf37ae2e4689471
|
@ -17,45 +17,42 @@ export function initLoggedInUser(): void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateUserInfo(): Promise<[boolean, number]> {
|
export async function updateUserInfo(): Promise<[boolean, number]> {
|
||||||
return new Promise<[boolean, number]>(resolve => {
|
if (bypassLogin) {
|
||||||
if (bypassLogin) {
|
loggedInUser = {
|
||||||
loggedInUser = {
|
username: "Guest",
|
||||||
username: "Guest",
|
lastSessionSlot: -1,
|
||||||
lastSessionSlot: -1,
|
discordId: "",
|
||||||
discordId: "",
|
googleId: "",
|
||||||
googleId: "",
|
hasAdminRole: false,
|
||||||
hasAdminRole: false,
|
};
|
||||||
};
|
let lastSessionSlot = -1;
|
||||||
let lastSessionSlot = -1;
|
for (let s = 0; s < 5; s++) {
|
||||||
for (let s = 0; s < 5; s++) {
|
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
|
||||||
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
|
lastSessionSlot = s;
|
||||||
lastSessionSlot = s;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
loggedInUser.lastSessionSlot = lastSessionSlot;
|
|
||||||
// Migrate old data from before the username was appended
|
|
||||||
["data", "sessionData", "sessionData1", "sessionData2", "sessionData3", "sessionData4"].map(d => {
|
|
||||||
const lsItem = localStorage.getItem(d);
|
|
||||||
if (lsItem && !!loggedInUser?.username) {
|
|
||||||
const lsUserItem = localStorage.getItem(`${d}_${loggedInUser.username}`);
|
|
||||||
if (lsUserItem) {
|
|
||||||
localStorage.setItem(`${d}_${loggedInUser.username}_bak`, lsUserItem);
|
|
||||||
}
|
|
||||||
localStorage.setItem(`${d}_${loggedInUser.username}`, lsItem);
|
|
||||||
localStorage.removeItem(d);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return resolve([true, 200]);
|
|
||||||
}
|
}
|
||||||
pokerogueApi.account.getInfo().then(([accountInfo, status]) => {
|
loggedInUser.lastSessionSlot = lastSessionSlot;
|
||||||
if (!accountInfo) {
|
// Migrate old data from before the username was appended
|
||||||
resolve([false, status]);
|
["data", "sessionData", "sessionData1", "sessionData2", "sessionData3", "sessionData4"].forEach(d => {
|
||||||
return;
|
const lsItem = localStorage.getItem(d);
|
||||||
|
if (lsItem && !!loggedInUser?.username) {
|
||||||
|
const lsUserItem = localStorage.getItem(`${d}_${loggedInUser.username}`);
|
||||||
|
if (lsUserItem) {
|
||||||
|
localStorage.setItem(`${d}_${loggedInUser.username}_bak`, lsUserItem);
|
||||||
|
}
|
||||||
|
localStorage.setItem(`${d}_${loggedInUser.username}`, lsItem);
|
||||||
|
localStorage.removeItem(d);
|
||||||
}
|
}
|
||||||
loggedInUser = accountInfo;
|
|
||||||
resolve([true, 200]);
|
|
||||||
});
|
});
|
||||||
});
|
return [true, 200];
|
||||||
|
}
|
||||||
|
|
||||||
|
const [accountInfo, status] = await pokerogueApi.account.getInfo();
|
||||||
|
if (!accountInfo) {
|
||||||
|
return [false, status];
|
||||||
|
}
|
||||||
|
loggedInUser = accountInfo;
|
||||||
|
return [true, 200];
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,7 @@ import { UiInputs } from "#app/ui-inputs";
|
|||||||
import { biomeDepths, getBiomeName } from "#balance/biomes";
|
import { biomeDepths, getBiomeName } from "#balance/biomes";
|
||||||
import { pokemonPrevolutions } from "#balance/pokemon-evolutions";
|
import { pokemonPrevolutions } from "#balance/pokemon-evolutions";
|
||||||
import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#balance/starters";
|
import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#balance/starters";
|
||||||
import {
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets } from "#data/battle-anims";
|
||||||
initCommonAnims,
|
|
||||||
initMoveAnim,
|
|
||||||
loadCommonAnimAssets,
|
|
||||||
loadMoveAnimAssets,
|
|
||||||
populateAnims,
|
|
||||||
} from "#data/battle-anims";
|
|
||||||
import { allAbilities, allMoves, allSpecies, modifierTypes } from "#data/data-lists";
|
import { allAbilities, allMoves, allSpecies, modifierTypes } from "#data/data-lists";
|
||||||
import { battleSpecDialogue } from "#data/dialogue";
|
import { battleSpecDialogue } from "#data/dialogue";
|
||||||
import type { SpeciesFormChangeTrigger } from "#data/form-change-triggers";
|
import type { SpeciesFormChangeTrigger } from "#data/form-change-triggers";
|
||||||
@ -388,7 +382,6 @@ export class BattleScene extends SceneBase {
|
|||||||
const defaultMoves = [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE];
|
const defaultMoves = [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE];
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
populateAnims(),
|
|
||||||
this.initVariantData(),
|
this.initVariantData(),
|
||||||
initCommonAnims().then(() => loadCommonAnimAssets(true)),
|
initCommonAnims().then(() => loadCommonAnimAssets(true)),
|
||||||
Promise.all(defaultMoves.map(m => initMoveAnim(m))).then(() => loadMoveAnimAssets(defaultMoves, true)),
|
Promise.all(defaultMoves.map(m => initMoveAnim(m))).then(() => loadMoveAnimAssets(defaultMoves, true)),
|
||||||
|
@ -1505,9 +1505,9 @@ export function initSpecies() {
|
|||||||
new PokemonForm("Hero of Many Battles", "hero-of-many-battles", PokemonType.FIGHTING, null, 2.9, 210, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true),
|
new PokemonForm("Hero of Many Battles", "hero-of-many-battles", PokemonType.FIGHTING, null, 2.9, 210, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 660, 92, 120, 115, 80, 115, 138, 10, 0, 335, false, "", true),
|
||||||
new PokemonForm("Crowned", "crowned", PokemonType.FIGHTING, PokemonType.STEEL, 2.9, 785, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 700, 92, 120, 140, 80, 140, 128, 10, 0, 360)
|
new PokemonForm("Crowned", "crowned", PokemonType.FIGHTING, PokemonType.STEEL, 2.9, 785, AbilityId.DAUNTLESS_SHIELD, AbilityId.NONE, AbilityId.NONE, 700, 92, 120, 140, 80, 140, 128, 10, 0, 360)
|
||||||
),
|
),
|
||||||
new PokemonSpecies(SpeciesId.ETERNATUS, 8, false, true, false, "Gigantic Pokémon", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, GrowthRate.SLOW, null, false, true,
|
new PokemonSpecies(SpeciesId.ETERNATUS, 8, false, true, false, "Gigantic Pokémon", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 45, 0, 345, GrowthRate.SLOW, null, false, true,
|
||||||
new PokemonForm("Normal", "", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 255, 0, 345, false, null, true),
|
new PokemonForm("Normal", "", PokemonType.POISON, PokemonType.DRAGON, 20, 950, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 690, 140, 85, 95, 145, 95, 130, 45, 0, 345, false, null, true),
|
||||||
new PokemonForm("E-Max", "eternamax", PokemonType.POISON, PokemonType.DRAGON, 100, 999.9, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 1125, 255, 115, 250, 125, 250, 130, 255, 0, 345)
|
new PokemonForm("E-Max", "eternamax", PokemonType.POISON, PokemonType.DRAGON, 100, 999.9, AbilityId.PRESSURE, AbilityId.NONE, AbilityId.NONE, 1125, 255, 115, 250, 125, 250, 130, 45, 0, 345)
|
||||||
),
|
),
|
||||||
new PokemonSpecies(SpeciesId.KUBFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, null, 0.6, 12, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.NONE, 385, 60, 90, 60, 53, 50, 72, 3, 50, 77, GrowthRate.SLOW, 87.5, false),
|
new PokemonSpecies(SpeciesId.KUBFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, null, 0.6, 12, AbilityId.INNER_FOCUS, AbilityId.NONE, AbilityId.NONE, 385, 60, 90, 60, 53, 50, 72, 3, 50, 77, GrowthRate.SLOW, 87.5, false),
|
||||||
new PokemonSpecies(SpeciesId.URSHIFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true,
|
new PokemonSpecies(SpeciesId.URSHIFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, AbilityId.UNSEEN_FIST, AbilityId.NONE, AbilityId.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true,
|
||||||
|
@ -45736,6 +45736,285 @@ export const tmSpecies: TmSpecies = {
|
|||||||
SpeciesId.HISUI_ARCANINE,
|
SpeciesId.HISUI_ARCANINE,
|
||||||
SpeciesId.HISUI_AVALUGG,
|
SpeciesId.HISUI_AVALUGG,
|
||||||
],
|
],
|
||||||
|
[MoveId.SHOCK_WAVE]: [
|
||||||
|
SpeciesId.RATTATA,
|
||||||
|
SpeciesId.RATICATE,
|
||||||
|
SpeciesId.PIKACHU,
|
||||||
|
SpeciesId.RAICHU,
|
||||||
|
SpeciesId.NIDORAN_F,
|
||||||
|
SpeciesId.NIDORINA,
|
||||||
|
SpeciesId.NIDOQUEEN,
|
||||||
|
SpeciesId.NIDORAN_M,
|
||||||
|
SpeciesId.NIDORINO,
|
||||||
|
SpeciesId.NIDOKING,
|
||||||
|
SpeciesId.CLEFAIRY,
|
||||||
|
SpeciesId.CLEFABLE,
|
||||||
|
SpeciesId.JIGGLYPUFF,
|
||||||
|
SpeciesId.WIGGLYTUFF,
|
||||||
|
SpeciesId.MEOWTH,
|
||||||
|
SpeciesId.PERSIAN,
|
||||||
|
SpeciesId.ABRA,
|
||||||
|
SpeciesId.KADABRA,
|
||||||
|
SpeciesId.ALAKAZAM,
|
||||||
|
SpeciesId.MAGNEMITE,
|
||||||
|
SpeciesId.MAGNETON,
|
||||||
|
SpeciesId.GRIMER,
|
||||||
|
SpeciesId.MUK,
|
||||||
|
SpeciesId.VOLTORB,
|
||||||
|
SpeciesId.ELECTRODE,
|
||||||
|
SpeciesId.LICKITUNG,
|
||||||
|
SpeciesId.KOFFING,
|
||||||
|
SpeciesId.WEEZING,
|
||||||
|
SpeciesId.RHYHORN,
|
||||||
|
SpeciesId.RHYDON,
|
||||||
|
SpeciesId.CHANSEY,
|
||||||
|
SpeciesId.TANGELA,
|
||||||
|
SpeciesId.KANGASKHAN,
|
||||||
|
SpeciesId.MR_MIME,
|
||||||
|
SpeciesId.ELECTABUZZ,
|
||||||
|
SpeciesId.TAUROS,
|
||||||
|
SpeciesId.LAPRAS,
|
||||||
|
SpeciesId.JOLTEON,
|
||||||
|
SpeciesId.PORYGON,
|
||||||
|
SpeciesId.SNORLAX,
|
||||||
|
SpeciesId.ZAPDOS,
|
||||||
|
SpeciesId.DRATINI,
|
||||||
|
SpeciesId.DRAGONAIR,
|
||||||
|
SpeciesId.DRAGONITE,
|
||||||
|
SpeciesId.MEWTWO,
|
||||||
|
SpeciesId.MEW,
|
||||||
|
SpeciesId.SENTRET,
|
||||||
|
SpeciesId.FURRET,
|
||||||
|
SpeciesId.CHINCHOU,
|
||||||
|
SpeciesId.LANTURN,
|
||||||
|
SpeciesId.PICHU,
|
||||||
|
SpeciesId.CLEFFA,
|
||||||
|
SpeciesId.IGGLYBUFF,
|
||||||
|
SpeciesId.TOGEPI,
|
||||||
|
SpeciesId.TOGETIC,
|
||||||
|
SpeciesId.MAREEP,
|
||||||
|
SpeciesId.FLAAFFY,
|
||||||
|
SpeciesId.AMPHAROS,
|
||||||
|
SpeciesId.AIPOM,
|
||||||
|
SpeciesId.MISDREAVUS,
|
||||||
|
SpeciesId.GIRAFARIG,
|
||||||
|
SpeciesId.DUNSPARCE,
|
||||||
|
SpeciesId.SNUBBULL,
|
||||||
|
SpeciesId.GRANBULL,
|
||||||
|
SpeciesId.QWILFISH,
|
||||||
|
SpeciesId.PORYGON2,
|
||||||
|
SpeciesId.STANTLER,
|
||||||
|
SpeciesId.ELEKID,
|
||||||
|
SpeciesId.MILTANK,
|
||||||
|
SpeciesId.BLISSEY,
|
||||||
|
SpeciesId.RAIKOU,
|
||||||
|
SpeciesId.TYRANITAR,
|
||||||
|
SpeciesId.LUGIA,
|
||||||
|
SpeciesId.HO_OH,
|
||||||
|
SpeciesId.CELEBI,
|
||||||
|
SpeciesId.ZIGZAGOON,
|
||||||
|
SpeciesId.LINOONE,
|
||||||
|
SpeciesId.WINGULL,
|
||||||
|
SpeciesId.PELIPPER,
|
||||||
|
SpeciesId.RALTS,
|
||||||
|
SpeciesId.KIRLIA,
|
||||||
|
SpeciesId.GARDEVOIR,
|
||||||
|
SpeciesId.SLAKOTH,
|
||||||
|
SpeciesId.VIGOROTH,
|
||||||
|
SpeciesId.SLAKING,
|
||||||
|
SpeciesId.WHISMUR,
|
||||||
|
SpeciesId.LOUDRED,
|
||||||
|
SpeciesId.EXPLOUD,
|
||||||
|
SpeciesId.NOSEPASS,
|
||||||
|
SpeciesId.SKITTY,
|
||||||
|
SpeciesId.DELCATTY,
|
||||||
|
SpeciesId.SABLEYE,
|
||||||
|
SpeciesId.ARON,
|
||||||
|
SpeciesId.LAIRON,
|
||||||
|
SpeciesId.AGGRON,
|
||||||
|
SpeciesId.ELECTRIKE,
|
||||||
|
SpeciesId.MANECTRIC,
|
||||||
|
SpeciesId.PLUSLE,
|
||||||
|
SpeciesId.MINUN,
|
||||||
|
SpeciesId.VOLBEAT,
|
||||||
|
SpeciesId.ILLUMISE,
|
||||||
|
SpeciesId.GULPIN,
|
||||||
|
SpeciesId.SWALOT,
|
||||||
|
SpeciesId.SPOINK,
|
||||||
|
SpeciesId.GRUMPIG,
|
||||||
|
SpeciesId.SPINDA,
|
||||||
|
SpeciesId.ZANGOOSE,
|
||||||
|
SpeciesId.CASTFORM,
|
||||||
|
SpeciesId.KECLEON,
|
||||||
|
SpeciesId.SHUPPET,
|
||||||
|
SpeciesId.BANETTE,
|
||||||
|
SpeciesId.CHIMECHO,
|
||||||
|
SpeciesId.ABSOL,
|
||||||
|
SpeciesId.REGIROCK,
|
||||||
|
SpeciesId.REGICE,
|
||||||
|
SpeciesId.REGISTEEL,
|
||||||
|
SpeciesId.LATIAS,
|
||||||
|
SpeciesId.LATIOS,
|
||||||
|
SpeciesId.KYOGRE,
|
||||||
|
SpeciesId.GROUDON,
|
||||||
|
SpeciesId.RAYQUAZA,
|
||||||
|
SpeciesId.JIRACHI,
|
||||||
|
SpeciesId.DEOXYS,
|
||||||
|
SpeciesId.BIDOOF,
|
||||||
|
SpeciesId.BIBAREL,
|
||||||
|
SpeciesId.SHINX,
|
||||||
|
SpeciesId.LUXIO,
|
||||||
|
SpeciesId.LUXRAY,
|
||||||
|
SpeciesId.CRANIDOS,
|
||||||
|
SpeciesId.RAMPARDOS,
|
||||||
|
SpeciesId.SHIELDON,
|
||||||
|
SpeciesId.BASTIODON,
|
||||||
|
SpeciesId.PACHIRISU,
|
||||||
|
SpeciesId.AMBIPOM,
|
||||||
|
SpeciesId.DRIFLOON,
|
||||||
|
SpeciesId.DRIFBLIM,
|
||||||
|
SpeciesId.BUNEARY,
|
||||||
|
SpeciesId.LOPUNNY,
|
||||||
|
SpeciesId.MISMAGIUS,
|
||||||
|
SpeciesId.GLAMEOW,
|
||||||
|
SpeciesId.PURUGLY,
|
||||||
|
SpeciesId.CHINGLING,
|
||||||
|
SpeciesId.MIME_JR,
|
||||||
|
SpeciesId.HAPPINY,
|
||||||
|
SpeciesId.SPIRITOMB,
|
||||||
|
SpeciesId.MUNCHLAX,
|
||||||
|
SpeciesId.MAGNEZONE,
|
||||||
|
SpeciesId.LICKILICKY,
|
||||||
|
SpeciesId.RHYPERIOR,
|
||||||
|
SpeciesId.TANGROWTH,
|
||||||
|
SpeciesId.ELECTIVIRE,
|
||||||
|
SpeciesId.TOGEKISS,
|
||||||
|
SpeciesId.PORYGON_Z,
|
||||||
|
SpeciesId.GALLADE,
|
||||||
|
SpeciesId.PROBOPASS,
|
||||||
|
SpeciesId.FROSLASS,
|
||||||
|
SpeciesId.ROTOM,
|
||||||
|
SpeciesId.UXIE,
|
||||||
|
SpeciesId.MESPRIT,
|
||||||
|
SpeciesId.AZELF,
|
||||||
|
SpeciesId.DIALGA,
|
||||||
|
SpeciesId.PALKIA,
|
||||||
|
SpeciesId.REGIGIGAS,
|
||||||
|
SpeciesId.GIRATINA,
|
||||||
|
SpeciesId.DARKRAI,
|
||||||
|
SpeciesId.ARCEUS,
|
||||||
|
SpeciesId.VICTINI,
|
||||||
|
SpeciesId.PATRAT,
|
||||||
|
SpeciesId.WATCHOG,
|
||||||
|
SpeciesId.LILLIPUP,
|
||||||
|
SpeciesId.HERDIER,
|
||||||
|
SpeciesId.STOUTLAND,
|
||||||
|
SpeciesId.MUNNA,
|
||||||
|
SpeciesId.MUSHARNA,
|
||||||
|
SpeciesId.BLITZLE,
|
||||||
|
SpeciesId.ZEBSTRIKA,
|
||||||
|
SpeciesId.WOOBAT,
|
||||||
|
SpeciesId.SWOOBAT,
|
||||||
|
SpeciesId.SIGILYPH,
|
||||||
|
SpeciesId.YAMASK,
|
||||||
|
SpeciesId.COFAGRIGUS,
|
||||||
|
SpeciesId.MINCCINO,
|
||||||
|
SpeciesId.CINCCINO,
|
||||||
|
SpeciesId.GOTHITA,
|
||||||
|
SpeciesId.GOTHORITA,
|
||||||
|
SpeciesId.GOTHITELLE,
|
||||||
|
SpeciesId.SOLOSIS,
|
||||||
|
SpeciesId.DUOSION,
|
||||||
|
SpeciesId.REUNICLUS,
|
||||||
|
SpeciesId.EMOLGA,
|
||||||
|
SpeciesId.FRILLISH,
|
||||||
|
SpeciesId.JELLICENT,
|
||||||
|
SpeciesId.JOLTIK,
|
||||||
|
SpeciesId.GALVANTULA,
|
||||||
|
SpeciesId.KLINK,
|
||||||
|
SpeciesId.KLANG,
|
||||||
|
SpeciesId.KLINKLANG,
|
||||||
|
SpeciesId.EELEKTRIK,
|
||||||
|
SpeciesId.EELEKTROSS,
|
||||||
|
SpeciesId.ELGYEM,
|
||||||
|
SpeciesId.BEHEEYEM,
|
||||||
|
SpeciesId.LITWICK,
|
||||||
|
SpeciesId.LAMPENT,
|
||||||
|
SpeciesId.CHANDELURE,
|
||||||
|
SpeciesId.AXEW,
|
||||||
|
SpeciesId.FRAXURE,
|
||||||
|
SpeciesId.HAXORUS,
|
||||||
|
SpeciesId.STUNFISK,
|
||||||
|
SpeciesId.DRUDDIGON,
|
||||||
|
SpeciesId.GOLETT,
|
||||||
|
SpeciesId.GOLURK,
|
||||||
|
SpeciesId.DEINO,
|
||||||
|
SpeciesId.ZWEILOUS,
|
||||||
|
SpeciesId.HYDREIGON,
|
||||||
|
SpeciesId.THUNDURUS,
|
||||||
|
SpeciesId.ZEKROM,
|
||||||
|
SpeciesId.MELOETTA,
|
||||||
|
SpeciesId.GENESECT,
|
||||||
|
SpeciesId.BRAIXEN,
|
||||||
|
SpeciesId.DELPHOX,
|
||||||
|
SpeciesId.ESPURR,
|
||||||
|
SpeciesId.MEOWSTIC,
|
||||||
|
SpeciesId.HONEDGE,
|
||||||
|
SpeciesId.DOUBLADE,
|
||||||
|
SpeciesId.AEGISLASH,
|
||||||
|
SpeciesId.SKRELP,
|
||||||
|
SpeciesId.DRAGALGE,
|
||||||
|
SpeciesId.HELIOPTILE,
|
||||||
|
SpeciesId.HELIOLISK,
|
||||||
|
SpeciesId.DEDENNE,
|
||||||
|
SpeciesId.GOOMY,
|
||||||
|
SpeciesId.SLIGGOO,
|
||||||
|
SpeciesId.GOODRA,
|
||||||
|
SpeciesId.ZYGARDE,
|
||||||
|
SpeciesId.HOOPA,
|
||||||
|
SpeciesId.YUNGOOS,
|
||||||
|
SpeciesId.GUMSHOOS,
|
||||||
|
SpeciesId.GRUBBIN,
|
||||||
|
SpeciesId.CHARJABUG,
|
||||||
|
SpeciesId.VIKAVOLT,
|
||||||
|
SpeciesId.PASSIMIAN,
|
||||||
|
SpeciesId.TURTONATOR,
|
||||||
|
SpeciesId.TOGEDEMARU,
|
||||||
|
SpeciesId.DRAMPA,
|
||||||
|
SpeciesId.KOMMO_O,
|
||||||
|
SpeciesId.TAPU_KOKO,
|
||||||
|
SpeciesId.SOLGALEO,
|
||||||
|
SpeciesId.LUNALA,
|
||||||
|
SpeciesId.PHEROMOSA,
|
||||||
|
SpeciesId.XURKITREE,
|
||||||
|
SpeciesId.CELESTEELA,
|
||||||
|
SpeciesId.GUZZLORD,
|
||||||
|
SpeciesId.NECROZMA,
|
||||||
|
SpeciesId.MAGEARNA,
|
||||||
|
SpeciesId.NAGANADEL,
|
||||||
|
SpeciesId.ZERAORA,
|
||||||
|
SpeciesId.TOXTRICITY,
|
||||||
|
SpeciesId.MR_RIME,
|
||||||
|
SpeciesId.REGIELEKI,
|
||||||
|
SpeciesId.WYRDEER,
|
||||||
|
SpeciesId.FARIGIRAF,
|
||||||
|
SpeciesId.DUDUNSPARCE,
|
||||||
|
SpeciesId.MIRAIDON,
|
||||||
|
SpeciesId.RAGING_BOLT,
|
||||||
|
SpeciesId.ALOLA_RATTATA,
|
||||||
|
SpeciesId.ALOLA_RATICATE,
|
||||||
|
SpeciesId.ALOLA_RAICHU,
|
||||||
|
SpeciesId.ALOLA_MEOWTH,
|
||||||
|
SpeciesId.ALOLA_PERSIAN,
|
||||||
|
SpeciesId.ALOLA_GRAVELER,
|
||||||
|
SpeciesId.ALOLA_GOLEM,
|
||||||
|
SpeciesId.ALOLA_GRIMER,
|
||||||
|
SpeciesId.ALOLA_MUK,
|
||||||
|
SpeciesId.GALAR_WEEZING,
|
||||||
|
SpeciesId.GALAR_MR_MIME,
|
||||||
|
SpeciesId.HISUI_SLIGGOO,
|
||||||
|
SpeciesId.HISUI_GOODRA,
|
||||||
|
],
|
||||||
[MoveId.WATER_PULSE]: [
|
[MoveId.WATER_PULSE]: [
|
||||||
SpeciesId.SQUIRTLE,
|
SpeciesId.SQUIRTLE,
|
||||||
SpeciesId.WARTORTLE,
|
SpeciesId.WARTORTLE,
|
||||||
@ -68747,6 +69026,7 @@ export const tmPoolTiers: TmPoolTiers = {
|
|||||||
[MoveId.LEAF_BLADE]: ModifierTier.ULTRA,
|
[MoveId.LEAF_BLADE]: ModifierTier.ULTRA,
|
||||||
[MoveId.DRAGON_DANCE]: ModifierTier.GREAT,
|
[MoveId.DRAGON_DANCE]: ModifierTier.GREAT,
|
||||||
[MoveId.ROCK_BLAST]: ModifierTier.GREAT,
|
[MoveId.ROCK_BLAST]: ModifierTier.GREAT,
|
||||||
|
[MoveId.SHOCK_WAVE]: ModifierTier.GREAT,
|
||||||
[MoveId.WATER_PULSE]: ModifierTier.GREAT,
|
[MoveId.WATER_PULSE]: ModifierTier.GREAT,
|
||||||
[MoveId.ROOST]: ModifierTier.GREAT,
|
[MoveId.ROOST]: ModifierTier.GREAT,
|
||||||
[MoveId.GRAVITY]: ModifierTier.COMMON,
|
[MoveId.GRAVITY]: ModifierTier.COMMON,
|
||||||
|
@ -404,22 +404,18 @@ export const chargeAnims = new Map<ChargeAnim, AnimConfig | [AnimConfig, AnimCon
|
|||||||
export const commonAnims = new Map<CommonAnim, AnimConfig>();
|
export const commonAnims = new Map<CommonAnim, AnimConfig>();
|
||||||
export const encounterAnims = new Map<EncounterAnim, AnimConfig>();
|
export const encounterAnims = new Map<EncounterAnim, AnimConfig>();
|
||||||
|
|
||||||
export function initCommonAnims(): Promise<void> {
|
export async function initCommonAnims(): Promise<void> {
|
||||||
return new Promise(resolve => {
|
const commonAnimFetches: Promise<Map<CommonAnim, AnimConfig>>[] = [];
|
||||||
const commonAnimNames = getEnumKeys(CommonAnim);
|
for (const commonAnimName of getEnumKeys(CommonAnim)) {
|
||||||
const commonAnimIds = getEnumValues(CommonAnim);
|
const commonAnimId = CommonAnim[commonAnimName];
|
||||||
const commonAnimFetches: Promise<Map<CommonAnim, AnimConfig>>[] = [];
|
commonAnimFetches.push(
|
||||||
for (let ca = 0; ca < commonAnimIds.length; ca++) {
|
globalScene
|
||||||
const commonAnimId = commonAnimIds[ca];
|
.cachedFetch(`./battle-anims/common-${toKebabCase(commonAnimName)}.json`)
|
||||||
commonAnimFetches.push(
|
.then(response => response.json())
|
||||||
globalScene
|
.then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas))),
|
||||||
.cachedFetch(`./battle-anims/common-${toKebabCase(commonAnimNames[ca])}.json`)
|
);
|
||||||
.then(response => response.json())
|
}
|
||||||
.then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas))),
|
await Promise.allSettled(commonAnimFetches);
|
||||||
);
|
|
||||||
}
|
|
||||||
Promise.allSettled(commonAnimFetches).then(() => resolve());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initMoveAnim(move: MoveId): Promise<void> {
|
export function initMoveAnim(move: MoveId): Promise<void> {
|
||||||
@ -1396,279 +1392,3 @@ export class EncounterBattleAnim extends BattleAnim {
|
|||||||
return this.oppAnim;
|
return this.oppAnim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function populateAnims() {
|
|
||||||
const commonAnimNames = getEnumKeys(CommonAnim).map(k => k.toLowerCase());
|
|
||||||
const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/_/g, ""));
|
|
||||||
const commonAnimIds = getEnumValues(CommonAnim);
|
|
||||||
const chargeAnimNames = getEnumKeys(ChargeAnim).map(k => k.toLowerCase());
|
|
||||||
const chargeAnimMatchNames = chargeAnimNames.map(k => k.replace(/_/g, " "));
|
|
||||||
const chargeAnimIds = getEnumValues(ChargeAnim);
|
|
||||||
const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/;
|
|
||||||
const moveNameToId = {};
|
|
||||||
// Exclude MoveId.NONE;
|
|
||||||
for (const move of getEnumValues(MoveId).slice(1)) {
|
|
||||||
// KARATE_CHOP => KARATECHOP
|
|
||||||
const moveName = MoveId[move].toUpperCase().replace(/_/g, "");
|
|
||||||
moveNameToId[moveName] = move;
|
|
||||||
}
|
|
||||||
|
|
||||||
const seNames: string[] = []; //(await fs.readdir('./public/audio/se/battle_anims/')).map(se => se.toString());
|
|
||||||
|
|
||||||
const animsData: any[] = []; //battleAnimRawData.split('!ruby/array:PBAnimation').slice(1); // TODO: add a proper type
|
|
||||||
for (let a = 0; a < animsData.length; a++) {
|
|
||||||
const fields = animsData[a].split("@").slice(1);
|
|
||||||
|
|
||||||
const nameField = fields.find(f => f.startsWith("name: "));
|
|
||||||
|
|
||||||
let isOppMove: boolean | undefined;
|
|
||||||
let commonAnimId: CommonAnim | undefined;
|
|
||||||
let chargeAnimId: ChargeAnim | undefined;
|
|
||||||
if (!nameField.startsWith("name: Move:") && !(isOppMove = nameField.startsWith("name: OppMove:"))) {
|
|
||||||
const nameMatch = commonNamePattern.exec(nameField)!; // TODO: is this bang correct?
|
|
||||||
const name = nameMatch[2].toLowerCase();
|
|
||||||
if (commonAnimMatchNames.indexOf(name) > -1) {
|
|
||||||
commonAnimId = commonAnimIds[commonAnimMatchNames.indexOf(name)];
|
|
||||||
} else if (chargeAnimMatchNames.indexOf(name) > -1) {
|
|
||||||
isOppMove = nameField.startsWith("name: Opp ");
|
|
||||||
chargeAnimId = chargeAnimIds[chargeAnimMatchNames.indexOf(name)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const nameIndex = nameField.indexOf(":", 5) + 1;
|
|
||||||
const animName = nameField.slice(nameIndex, nameField.indexOf("\n", nameIndex));
|
|
||||||
if (!moveNameToId.hasOwnProperty(animName) && !commonAnimId && !chargeAnimId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const anim = commonAnimId || chargeAnimId ? new AnimConfig() : new AnimConfig();
|
|
||||||
if (anim instanceof AnimConfig) {
|
|
||||||
(anim as AnimConfig).id = moveNameToId[animName];
|
|
||||||
}
|
|
||||||
if (commonAnimId) {
|
|
||||||
commonAnims.set(commonAnimId, anim);
|
|
||||||
} else if (chargeAnimId) {
|
|
||||||
chargeAnims.set(chargeAnimId, !isOppMove ? anim : [chargeAnims.get(chargeAnimId) as AnimConfig, anim]);
|
|
||||||
} else {
|
|
||||||
moveAnims.set(
|
|
||||||
moveNameToId[animName],
|
|
||||||
!isOppMove ? (anim as AnimConfig) : [moveAnims.get(moveNameToId[animName]) as AnimConfig, anim as AnimConfig],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (let f = 0; f < fields.length; f++) {
|
|
||||||
const field = fields[f];
|
|
||||||
const fieldName = field.slice(0, field.indexOf(":"));
|
|
||||||
const fieldData = field.slice(fieldName.length + 1, field.lastIndexOf("\n")).trim();
|
|
||||||
switch (fieldName) {
|
|
||||||
case "array": {
|
|
||||||
const framesData = fieldData.split(" - - - ").slice(1);
|
|
||||||
for (let fd = 0; fd < framesData.length; fd++) {
|
|
||||||
anim.frames.push([]);
|
|
||||||
const frameData = framesData[fd];
|
|
||||||
const focusFramesData = frameData.split(" - - ");
|
|
||||||
for (let tf = 0; tf < focusFramesData.length; tf++) {
|
|
||||||
const values = focusFramesData[tf].replace(/ {6}- /g, "").split("\n");
|
|
||||||
const targetFrame = new AnimFrame(
|
|
||||||
Number.parseFloat(values[0]),
|
|
||||||
Number.parseFloat(values[1]),
|
|
||||||
Number.parseFloat(values[2]),
|
|
||||||
Number.parseFloat(values[11]),
|
|
||||||
Number.parseFloat(values[3]),
|
|
||||||
Number.parseInt(values[4]) === 1,
|
|
||||||
Number.parseInt(values[6]) === 1,
|
|
||||||
Number.parseInt(values[5]),
|
|
||||||
Number.parseInt(values[7]),
|
|
||||||
Number.parseInt(values[8]),
|
|
||||||
Number.parseInt(values[12]),
|
|
||||||
Number.parseInt(values[13]),
|
|
||||||
Number.parseInt(values[14]),
|
|
||||||
Number.parseInt(values[15]),
|
|
||||||
Number.parseInt(values[16]),
|
|
||||||
Number.parseInt(values[17]),
|
|
||||||
Number.parseInt(values[18]),
|
|
||||||
Number.parseInt(values[19]),
|
|
||||||
Number.parseInt(values[21]),
|
|
||||||
Number.parseInt(values[22]),
|
|
||||||
Number.parseInt(values[23]),
|
|
||||||
Number.parseInt(values[24]),
|
|
||||||
Number.parseInt(values[20]) === 1,
|
|
||||||
Number.parseInt(values[25]),
|
|
||||||
Number.parseInt(values[26]) as AnimFocus,
|
|
||||||
);
|
|
||||||
anim.frames[fd].push(targetFrame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "graphic": {
|
|
||||||
const graphic = fieldData !== "''" ? fieldData : "";
|
|
||||||
anim.graphic = graphic.indexOf(".") > -1 ? graphic.slice(0, fieldData.indexOf(".")) : graphic;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "timing": {
|
|
||||||
const timingEntries = fieldData.split("- !ruby/object:PBAnimTiming ").slice(1);
|
|
||||||
for (let t = 0; t < timingEntries.length; t++) {
|
|
||||||
const timingData = timingEntries[t]
|
|
||||||
.replace(/\n/g, " ")
|
|
||||||
.replace(/[ ]{2,}/g, " ")
|
|
||||||
.replace(/[a-z]+: ! '', /gi, "")
|
|
||||||
.replace(/name: (.*?),/, 'name: "$1",')
|
|
||||||
.replace(
|
|
||||||
/flashColor: !ruby\/object:Color { alpha: ([\d.]+), blue: ([\d.]+), green: ([\d.]+), red: ([\d.]+)}/,
|
|
||||||
"flashRed: $4, flashGreen: $3, flashBlue: $2, flashAlpha: $1",
|
|
||||||
);
|
|
||||||
const frameIndex = Number.parseInt(/frame: (\d+)/.exec(timingData)![1]); // TODO: is the bang correct?
|
|
||||||
let resourceName = /name: "(.*?)"/.exec(timingData)![1].replace("''", ""); // TODO: is the bang correct?
|
|
||||||
const timingType = Number.parseInt(/timingType: (\d)/.exec(timingData)![1]); // TODO: is the bang correct?
|
|
||||||
let timedEvent: AnimTimedEvent | undefined;
|
|
||||||
switch (timingType) {
|
|
||||||
case 0:
|
|
||||||
if (resourceName && resourceName.indexOf(".") === -1) {
|
|
||||||
let ext: string | undefined;
|
|
||||||
["wav", "mp3", "m4a"].every(e => {
|
|
||||||
if (seNames.indexOf(`${resourceName}.${e}`) > -1) {
|
|
||||||
ext = e;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
if (!ext) {
|
|
||||||
ext = ".wav";
|
|
||||||
}
|
|
||||||
resourceName += `.${ext}`;
|
|
||||||
}
|
|
||||||
timedEvent = new AnimTimedSoundEvent(frameIndex, resourceName);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf(".")));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf(".")));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!timedEvent) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const propPattern = /([a-z]+): (.*?)(?:,|\})/gi;
|
|
||||||
let propMatch: RegExpExecArray;
|
|
||||||
while ((propMatch = propPattern.exec(timingData)!)) {
|
|
||||||
// TODO: is this bang correct?
|
|
||||||
const prop = propMatch[1];
|
|
||||||
let value: any = propMatch[2];
|
|
||||||
switch (prop) {
|
|
||||||
case "bgX":
|
|
||||||
case "bgY":
|
|
||||||
value = Number.parseFloat(value);
|
|
||||||
break;
|
|
||||||
case "volume":
|
|
||||||
case "pitch":
|
|
||||||
case "opacity":
|
|
||||||
case "colorRed":
|
|
||||||
case "colorGreen":
|
|
||||||
case "colorBlue":
|
|
||||||
case "colorAlpha":
|
|
||||||
case "duration":
|
|
||||||
case "flashScope":
|
|
||||||
case "flashRed":
|
|
||||||
case "flashGreen":
|
|
||||||
case "flashBlue":
|
|
||||||
case "flashAlpha":
|
|
||||||
case "flashDuration":
|
|
||||||
value = Number.parseInt(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (timedEvent.hasOwnProperty(prop)) {
|
|
||||||
timedEvent[prop] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!anim.frameTimedEvents.has(frameIndex)) {
|
|
||||||
anim.frameTimedEvents.set(frameIndex, []);
|
|
||||||
}
|
|
||||||
anim.frameTimedEvents.get(frameIndex)!.push(timedEvent); // TODO: is this bang correct?
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "position":
|
|
||||||
anim.position = Number.parseInt(fieldData);
|
|
||||||
break;
|
|
||||||
case "hue":
|
|
||||||
anim.hue = Number.parseInt(fieldData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// biome-ignore lint/correctness/noUnusedVariables: used in commented code
|
|
||||||
const animReplacer = (k, v) => {
|
|
||||||
if (k === "id" && !v) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (v instanceof Map) {
|
|
||||||
return Object.fromEntries(v);
|
|
||||||
}
|
|
||||||
if (v instanceof AnimTimedEvent) {
|
|
||||||
v["eventType"] = v.getEventType();
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
|
|
||||||
const animConfigProps = ["id", "graphic", "frames", "frameTimedEvents", "position", "hue"];
|
|
||||||
const animFrameProps = [
|
|
||||||
"x",
|
|
||||||
"y",
|
|
||||||
"zoomX",
|
|
||||||
"zoomY",
|
|
||||||
"angle",
|
|
||||||
"mirror",
|
|
||||||
"visible",
|
|
||||||
"blendType",
|
|
||||||
"target",
|
|
||||||
"graphicFrame",
|
|
||||||
"opacity",
|
|
||||||
"color",
|
|
||||||
"tone",
|
|
||||||
"flash",
|
|
||||||
"locked",
|
|
||||||
"priority",
|
|
||||||
"focus",
|
|
||||||
];
|
|
||||||
const propSets = [animConfigProps, animFrameProps];
|
|
||||||
|
|
||||||
// biome-ignore lint/correctness/noUnusedVariables: used in commented code
|
|
||||||
const animComparator = (a: Element, b: Element) => {
|
|
||||||
let props: string[];
|
|
||||||
for (let p = 0; p < propSets.length; p++) {
|
|
||||||
props = propSets[p];
|
|
||||||
// @ts-expect-error TODO
|
|
||||||
const ai = props.indexOf(a.key);
|
|
||||||
if (ai === -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// @ts-expect-error TODO
|
|
||||||
const bi = props.indexOf(b.key);
|
|
||||||
|
|
||||||
return ai < bi ? -1 : ai > bi ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*for (let ma of moveAnims.keys()) {
|
|
||||||
const data = moveAnims.get(ma);
|
|
||||||
(async () => {
|
|
||||||
await fs.writeFile(`../public/battle-anims/${Moves[ma].toLowerCase().replace(/\_/g, '-')}.json`, stringify(data, { replacer: animReplacer, cmp: animComparator, space: ' ' }));
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let ca of chargeAnims.keys()) {
|
|
||||||
const data = chargeAnims.get(ca);
|
|
||||||
(async () => {
|
|
||||||
await fs.writeFile(`../public/battle-anims/${chargeAnimNames[chargeAnimIds.indexOf(ca)].replace(/\_/g, '-')}.json`, stringify(data, { replacer: animReplacer, cmp: animComparator, space: ' ' }));
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let cma of commonAnims.keys()) {
|
|
||||||
const data = commonAnims.get(cma);
|
|
||||||
(async () => {
|
|
||||||
await fs.writeFile(`../public/battle-anims/common-${commonAnimNames[commonAnimIds.indexOf(cma)].replace(/\_/g, '-')}.json`, stringify(data, { replacer: animReplacer, cmp: animComparator, space: ' ' }));
|
|
||||||
})();
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
@ -8451,7 +8451,7 @@ export function initMoves() {
|
|||||||
.punchingMove(),
|
.punchingMove(),
|
||||||
new AttackMove(MoveId.SCRATCH, PokemonType.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, 0, 1),
|
new AttackMove(MoveId.SCRATCH, PokemonType.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, 0, 1),
|
||||||
new AttackMove(MoveId.VISE_GRIP, PokemonType.NORMAL, MoveCategory.PHYSICAL, 55, 100, 30, -1, 0, 1),
|
new AttackMove(MoveId.VISE_GRIP, PokemonType.NORMAL, MoveCategory.PHYSICAL, 55, 100, 30, -1, 0, 1),
|
||||||
new AttackMove(MoveId.GUILLOTINE, PokemonType.NORMAL, MoveCategory.PHYSICAL, 200, 30, 5, -1, 0, 1)
|
new AttackMove(MoveId.GUILLOTINE, PokemonType.NORMAL, MoveCategory.PHYSICAL, 250, 30, 5, -1, 0, 1)
|
||||||
.attr(OneHitKOAttr)
|
.attr(OneHitKOAttr)
|
||||||
.attr(OneHitKOAccuracyAttr),
|
.attr(OneHitKOAccuracyAttr),
|
||||||
new ChargingAttackMove(MoveId.RAZOR_WIND, PokemonType.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 1)
|
new ChargingAttackMove(MoveId.RAZOR_WIND, PokemonType.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 1)
|
||||||
@ -8504,7 +8504,7 @@ export function initMoves() {
|
|||||||
new AttackMove(MoveId.HORN_ATTACK, PokemonType.NORMAL, MoveCategory.PHYSICAL, 65, 100, 25, -1, 0, 1),
|
new AttackMove(MoveId.HORN_ATTACK, PokemonType.NORMAL, MoveCategory.PHYSICAL, 65, 100, 25, -1, 0, 1),
|
||||||
new AttackMove(MoveId.FURY_ATTACK, PokemonType.NORMAL, MoveCategory.PHYSICAL, 15, 85, 20, -1, 0, 1)
|
new AttackMove(MoveId.FURY_ATTACK, PokemonType.NORMAL, MoveCategory.PHYSICAL, 15, 85, 20, -1, 0, 1)
|
||||||
.attr(MultiHitAttr),
|
.attr(MultiHitAttr),
|
||||||
new AttackMove(MoveId.HORN_DRILL, PokemonType.NORMAL, MoveCategory.PHYSICAL, 200, 30, 5, -1, 0, 1)
|
new AttackMove(MoveId.HORN_DRILL, PokemonType.NORMAL, MoveCategory.PHYSICAL, 250, 30, 5, -1, 0, 1)
|
||||||
.attr(OneHitKOAttr)
|
.attr(OneHitKOAttr)
|
||||||
.attr(OneHitKOAccuracyAttr),
|
.attr(OneHitKOAccuracyAttr),
|
||||||
new AttackMove(MoveId.TACKLE, PokemonType.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, 0, 1),
|
new AttackMove(MoveId.TACKLE, PokemonType.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, 0, 1),
|
||||||
@ -8685,7 +8685,7 @@ export function initMoves() {
|
|||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => globalScene.arena.getTerrainType() === TerrainType.GRASSY && target.isGrounded() ? 0.5 : 1)
|
.attr(MovePowerMultiplierAttr, (user, target, move) => globalScene.arena.getTerrainType() === TerrainType.GRASSY && target.isGrounded() ? 0.5 : 1)
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||||
new AttackMove(MoveId.FISSURE, PokemonType.GROUND, MoveCategory.PHYSICAL, 200, 30, 5, -1, 0, 1)
|
new AttackMove(MoveId.FISSURE, PokemonType.GROUND, MoveCategory.PHYSICAL, 250, 30, 5, -1, 0, 1)
|
||||||
.attr(OneHitKOAttr)
|
.attr(OneHitKOAttr)
|
||||||
.attr(OneHitKOAccuracyAttr)
|
.attr(OneHitKOAccuracyAttr)
|
||||||
.attr(HitsTagAttr, BattlerTagType.UNDERGROUND)
|
.attr(HitsTagAttr, BattlerTagType.UNDERGROUND)
|
||||||
@ -9467,7 +9467,7 @@ export function initMoves() {
|
|||||||
new AttackMove(MoveId.SAND_TOMB, PokemonType.GROUND, MoveCategory.PHYSICAL, 35, 85, 15, -1, 0, 3)
|
new AttackMove(MoveId.SAND_TOMB, PokemonType.GROUND, MoveCategory.PHYSICAL, 35, 85, 15, -1, 0, 3)
|
||||||
.attr(TrapAttr, BattlerTagType.SAND_TOMB)
|
.attr(TrapAttr, BattlerTagType.SAND_TOMB)
|
||||||
.makesContact(false),
|
.makesContact(false),
|
||||||
new AttackMove(MoveId.SHEER_COLD, PokemonType.ICE, MoveCategory.SPECIAL, 200, 30, 5, -1, 0, 3)
|
new AttackMove(MoveId.SHEER_COLD, PokemonType.ICE, MoveCategory.SPECIAL, 250, 30, 5, -1, 0, 3)
|
||||||
.attr(IceNoEffectTypeAttr)
|
.attr(IceNoEffectTypeAttr)
|
||||||
.attr(OneHitKOAttr)
|
.attr(OneHitKOAttr)
|
||||||
.attr(SheerColdAccuracyAttr),
|
.attr(SheerColdAccuracyAttr),
|
||||||
|
@ -99,6 +99,7 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE
|
|||||||
MysteryEncounterType.DARK_DEAL,
|
MysteryEncounterType.DARK_DEAL,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
|
.withDisallowedChallenges(Challenges.HARDCORE)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "dark_deal_scientist",
|
spriteKey: "dark_deal_scientist",
|
||||||
|
@ -673,6 +673,8 @@ export async function catchPokemon(
|
|||||||
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
|
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
const addStatus = new BooleanHolder(true);
|
||||||
|
applyChallenges(ChallengeType.POKEMON_ADD_TO_PARTY, pokemon, addStatus);
|
||||||
const doPokemonCatchMenu = () => {
|
const doPokemonCatchMenu = () => {
|
||||||
const end = () => {
|
const end = () => {
|
||||||
// Ensure the pokemon is in the enemy party in all situations
|
// Ensure the pokemon is in the enemy party in all situations
|
||||||
@ -708,9 +710,7 @@ export async function catchPokemon(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Promise.all([pokemon.hideInfo(), globalScene.gameData.setPokemonCaught(pokemon)]).then(() => {
|
Promise.all([pokemon.hideInfo(), globalScene.gameData.setPokemonCaught(pokemon)]).then(() => {
|
||||||
const addStatus = new BooleanHolder(true);
|
if (!(isObtain || addStatus.value)) {
|
||||||
applyChallenges(ChallengeType.POKEMON_ADD_TO_PARTY, pokemon, addStatus);
|
|
||||||
if (!addStatus.value) {
|
|
||||||
removePokemon();
|
removePokemon();
|
||||||
end();
|
end();
|
||||||
return;
|
return;
|
||||||
@ -807,10 +807,16 @@ export async function catchPokemon(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (showCatchObtainMessage) {
|
if (showCatchObtainMessage) {
|
||||||
|
let catchMessage: string;
|
||||||
|
if (isObtain) {
|
||||||
|
catchMessage = "battle:pokemonObtained";
|
||||||
|
} else if (addStatus.value) {
|
||||||
|
catchMessage = "battle:pokemonCaught";
|
||||||
|
} else {
|
||||||
|
catchMessage = "battle:pokemonCaughtButChallenge";
|
||||||
|
}
|
||||||
globalScene.ui.showText(
|
globalScene.ui.showText(
|
||||||
i18next.t(isObtain ? "battle:pokemonObtained" : "battle:pokemonCaught", {
|
i18next.t(catchMessage, { pokemonName: pokemon.getNameToRender() }),
|
||||||
pokemonName: pokemon.getNameToRender(),
|
|
||||||
}),
|
|
||||||
null,
|
null,
|
||||||
doPokemonCatchMenu,
|
doPokemonCatchMenu,
|
||||||
0,
|
0,
|
||||||
|
@ -253,8 +253,11 @@ export class AttemptCapturePhase extends PokemonPhase {
|
|||||||
|
|
||||||
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
|
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
|
||||||
|
|
||||||
|
const addStatus = new BooleanHolder(true);
|
||||||
|
applyChallenges(ChallengeType.POKEMON_ADD_TO_PARTY, pokemon, addStatus);
|
||||||
|
|
||||||
globalScene.ui.showText(
|
globalScene.ui.showText(
|
||||||
i18next.t("battle:pokemonCaught", {
|
i18next.t(addStatus.value ? "battle:pokemonCaught" : "battle:pokemonCaughtButChallenge", {
|
||||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||||
}),
|
}),
|
||||||
null,
|
null,
|
||||||
@ -290,8 +293,6 @@ export class AttemptCapturePhase extends PokemonPhase {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Promise.all([pokemon.hideInfo(), globalScene.gameData.setPokemonCaught(pokemon)]).then(() => {
|
Promise.all([pokemon.hideInfo(), globalScene.gameData.setPokemonCaught(pokemon)]).then(() => {
|
||||||
const addStatus = new BooleanHolder(true);
|
|
||||||
applyChallenges(ChallengeType.POKEMON_ADD_TO_PARTY, pokemon, addStatus);
|
|
||||||
if (!addStatus.value) {
|
if (!addStatus.value) {
|
||||||
removePokemon();
|
removePokemon();
|
||||||
end();
|
end();
|
||||||
|
@ -16,8 +16,10 @@ export class SelectBiomePhase extends BattlePhase {
|
|||||||
|
|
||||||
globalScene.resetSeed();
|
globalScene.resetSeed();
|
||||||
|
|
||||||
|
const gameMode = globalScene.gameMode;
|
||||||
const currentBiome = globalScene.arena.biomeType;
|
const currentBiome = globalScene.arena.biomeType;
|
||||||
const nextWaveIndex = globalScene.currentBattle.waveIndex + 1;
|
const currentWaveIndex = globalScene.currentBattle.waveIndex;
|
||||||
|
const nextWaveIndex = currentWaveIndex + 1;
|
||||||
|
|
||||||
const setNextBiome = (nextBiome: BiomeId) => {
|
const setNextBiome = (nextBiome: BiomeId) => {
|
||||||
if (nextWaveIndex % 10 === 1) {
|
if (nextWaveIndex % 10 === 1) {
|
||||||
@ -26,6 +28,15 @@ export class SelectBiomePhase extends BattlePhase {
|
|||||||
applyChallenges(ChallengeType.PARTY_HEAL, healStatus);
|
applyChallenges(ChallengeType.PARTY_HEAL, healStatus);
|
||||||
if (healStatus.value) {
|
if (healStatus.value) {
|
||||||
globalScene.phaseManager.unshiftNew("PartyHealPhase", false);
|
globalScene.phaseManager.unshiftNew("PartyHealPhase", false);
|
||||||
|
} else {
|
||||||
|
globalScene.phaseManager.unshiftNew(
|
||||||
|
"SelectModifierPhase",
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
gameMode.isFixedBattle(currentWaveIndex)
|
||||||
|
? gameMode.getFixedBattle(currentWaveIndex).customModifierRewardSettings
|
||||||
|
: undefined,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
globalScene.phaseManager.unshiftNew("SwitchBiomePhase", nextBiome);
|
globalScene.phaseManager.unshiftNew("SwitchBiomePhase", nextBiome);
|
||||||
@ -33,12 +44,12 @@ export class SelectBiomePhase extends BattlePhase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(globalScene.gameMode.isClassic && globalScene.gameMode.isWaveFinal(nextWaveIndex + 9)) ||
|
(gameMode.isClassic && gameMode.isWaveFinal(nextWaveIndex + 9)) ||
|
||||||
(globalScene.gameMode.isDaily && globalScene.gameMode.isWaveFinal(nextWaveIndex)) ||
|
(gameMode.isDaily && gameMode.isWaveFinal(nextWaveIndex)) ||
|
||||||
(globalScene.gameMode.hasShortBiomes && !(nextWaveIndex % 50))
|
(gameMode.hasShortBiomes && !(nextWaveIndex % 50))
|
||||||
) {
|
) {
|
||||||
setNextBiome(BiomeId.END);
|
setNextBiome(BiomeId.END);
|
||||||
} else if (globalScene.gameMode.hasRandomBiomes) {
|
} else if (gameMode.hasRandomBiomes) {
|
||||||
setNextBiome(this.generateNextBiome(nextWaveIndex));
|
setNextBiome(this.generateNextBiome(nextWaveIndex));
|
||||||
} else if (Array.isArray(biomeLinks[currentBiome])) {
|
} else if (Array.isArray(biomeLinks[currentBiome])) {
|
||||||
const biomes: BiomeId[] = (biomeLinks[currentBiome] as (BiomeId | [BiomeId, number])[])
|
const biomes: BiomeId[] = (biomeLinks[currentBiome] as (BiomeId | [BiomeId, number])[])
|
||||||
@ -73,9 +84,6 @@ export class SelectBiomePhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateNextBiome(waveIndex: number): BiomeId {
|
generateNextBiome(waveIndex: number): BiomeId {
|
||||||
if (!(waveIndex % 50)) {
|
return waveIndex % 50 === 0 ? BiomeId.END : globalScene.generateRandomBiome(waveIndex);
|
||||||
return BiomeId.END;
|
|
||||||
}
|
|
||||||
return globalScene.generateRandomBiome(waveIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,9 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { modifierTypes } from "#data/data-lists";
|
import { modifierTypes } from "#data/data-lists";
|
||||||
import { BattleType } from "#enums/battle-type";
|
import { BattleType } from "#enums/battle-type";
|
||||||
import type { BattlerIndex } from "#enums/battler-index";
|
import type { BattlerIndex } from "#enums/battler-index";
|
||||||
import { ChallengeType } from "#enums/challenge-type";
|
|
||||||
import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
||||||
import type { CustomModifierSettings } from "#modifiers/modifier-type";
|
|
||||||
import { handleMysteryEncounterVictory } from "#mystery-encounters/encounter-phase-utils";
|
import { handleMysteryEncounterVictory } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import { PokemonPhase } from "#phases/pokemon-phase";
|
import { PokemonPhase } from "#phases/pokemon-phase";
|
||||||
import { applyChallenges } from "#utils/challenge-utils";
|
|
||||||
import { BooleanHolder } from "#utils/common";
|
|
||||||
|
|
||||||
export class VictoryPhase extends PokemonPhase {
|
export class VictoryPhase extends PokemonPhase {
|
||||||
public readonly phaseName = "VictoryPhase";
|
public readonly phaseName = "VictoryPhase";
|
||||||
@ -49,15 +45,19 @@ export class VictoryPhase extends PokemonPhase {
|
|||||||
if (globalScene.currentBattle.battleType === BattleType.TRAINER) {
|
if (globalScene.currentBattle.battleType === BattleType.TRAINER) {
|
||||||
globalScene.phaseManager.pushNew("TrainerVictoryPhase");
|
globalScene.phaseManager.pushNew("TrainerVictoryPhase");
|
||||||
}
|
}
|
||||||
if (globalScene.gameMode.isEndless || !globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) {
|
|
||||||
|
const gameMode = globalScene.gameMode;
|
||||||
|
const currentWaveIndex = globalScene.currentBattle.waveIndex;
|
||||||
|
|
||||||
|
if (gameMode.isEndless || !gameMode.isWaveFinal(currentWaveIndex)) {
|
||||||
globalScene.phaseManager.pushNew("EggLapsePhase");
|
globalScene.phaseManager.pushNew("EggLapsePhase");
|
||||||
if (globalScene.gameMode.isClassic) {
|
if (gameMode.isClassic) {
|
||||||
switch (globalScene.currentBattle.waveIndex) {
|
switch (currentWaveIndex) {
|
||||||
case ClassicFixedBossWaves.RIVAL_1:
|
case ClassicFixedBossWaves.RIVAL_1:
|
||||||
case ClassicFixedBossWaves.RIVAL_2:
|
case ClassicFixedBossWaves.RIVAL_2:
|
||||||
// Get event modifiers for this wave
|
// Get event modifiers for this wave
|
||||||
timedEventManager
|
timedEventManager
|
||||||
.getFixedBattleEventRewards(globalScene.currentBattle.waveIndex)
|
.getFixedBattleEventRewards(currentWaveIndex)
|
||||||
.map(r => globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes[r]));
|
.map(r => globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes[r]));
|
||||||
break;
|
break;
|
||||||
case ClassicFixedBossWaves.EVIL_BOSS_2:
|
case ClassicFixedBossWaves.EVIL_BOSS_2:
|
||||||
@ -66,59 +66,53 @@ export class VictoryPhase extends PokemonPhase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const healStatus = new BooleanHolder(globalScene.currentBattle.waveIndex % 10 === 0);
|
if (currentWaveIndex % 10) {
|
||||||
applyChallenges(ChallengeType.PARTY_HEAL, healStatus);
|
|
||||||
if (!healStatus.value) {
|
|
||||||
globalScene.phaseManager.pushNew(
|
globalScene.phaseManager.pushNew(
|
||||||
"SelectModifierPhase",
|
"SelectModifierPhase",
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
this.getFixedBattleCustomModifiers(),
|
gameMode.isFixedBattle(currentWaveIndex)
|
||||||
|
? gameMode.getFixedBattle(currentWaveIndex).customModifierRewardSettings
|
||||||
|
: undefined,
|
||||||
);
|
);
|
||||||
} else if (globalScene.gameMode.isDaily) {
|
} else if (gameMode.isDaily) {
|
||||||
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.EXP_CHARM);
|
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.EXP_CHARM);
|
||||||
if (
|
if (currentWaveIndex > 10 && !gameMode.isWaveFinal(currentWaveIndex)) {
|
||||||
globalScene.currentBattle.waveIndex > 10 &&
|
|
||||||
!globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)
|
|
||||||
) {
|
|
||||||
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.GOLDEN_POKEBALL);
|
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.GOLDEN_POKEBALL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const superExpWave = !globalScene.gameMode.isEndless ? (globalScene.offsetGym ? 0 : 20) : 10;
|
const superExpWave = !gameMode.isEndless ? (globalScene.offsetGym ? 0 : 20) : 10;
|
||||||
if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex === 10) {
|
if (gameMode.isEndless && currentWaveIndex === 10) {
|
||||||
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.EXP_SHARE);
|
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.EXP_SHARE);
|
||||||
}
|
}
|
||||||
if (
|
if (currentWaveIndex <= 750 && (currentWaveIndex <= 500 || currentWaveIndex % 30 === superExpWave)) {
|
||||||
globalScene.currentBattle.waveIndex <= 750 &&
|
|
||||||
(globalScene.currentBattle.waveIndex <= 500 || globalScene.currentBattle.waveIndex % 30 === superExpWave)
|
|
||||||
) {
|
|
||||||
globalScene.phaseManager.pushNew(
|
globalScene.phaseManager.pushNew(
|
||||||
"ModifierRewardPhase",
|
"ModifierRewardPhase",
|
||||||
globalScene.currentBattle.waveIndex % 30 !== superExpWave || globalScene.currentBattle.waveIndex > 250
|
currentWaveIndex % 30 !== superExpWave || currentWaveIndex > 250
|
||||||
? modifierTypes.EXP_CHARM
|
? modifierTypes.EXP_CHARM
|
||||||
: modifierTypes.SUPER_EXP_CHARM,
|
: modifierTypes.SUPER_EXP_CHARM,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (globalScene.currentBattle.waveIndex <= 150 && !(globalScene.currentBattle.waveIndex % 50)) {
|
if (currentWaveIndex <= 150 && !(currentWaveIndex % 50)) {
|
||||||
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.GOLDEN_POKEBALL);
|
globalScene.phaseManager.pushNew("ModifierRewardPhase", modifierTypes.GOLDEN_POKEBALL);
|
||||||
}
|
}
|
||||||
if (globalScene.gameMode.isEndless && !(globalScene.currentBattle.waveIndex % 50)) {
|
if (gameMode.isEndless && !(currentWaveIndex % 50)) {
|
||||||
globalScene.phaseManager.pushNew(
|
globalScene.phaseManager.pushNew(
|
||||||
"ModifierRewardPhase",
|
"ModifierRewardPhase",
|
||||||
!(globalScene.currentBattle.waveIndex % 250) ? modifierTypes.VOUCHER_PREMIUM : modifierTypes.VOUCHER_PLUS,
|
!(currentWaveIndex % 250) ? modifierTypes.VOUCHER_PREMIUM : modifierTypes.VOUCHER_PLUS,
|
||||||
);
|
);
|
||||||
globalScene.phaseManager.pushNew("AddEnemyBuffModifierPhase");
|
globalScene.phaseManager.pushNew("AddEnemyBuffModifierPhase");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
if (gameMode.hasRandomBiomes || globalScene.isNewBiome()) {
|
||||||
globalScene.phaseManager.pushNew("SelectBiomePhase");
|
globalScene.phaseManager.pushNew("SelectBiomePhase");
|
||||||
}
|
}
|
||||||
|
|
||||||
globalScene.phaseManager.pushNew("NewBattlePhase");
|
globalScene.phaseManager.pushNew("NewBattlePhase");
|
||||||
} else {
|
} else {
|
||||||
globalScene.currentBattle.battleType = BattleType.CLEAR;
|
globalScene.currentBattle.battleType = BattleType.CLEAR;
|
||||||
globalScene.score += globalScene.gameMode.getClearScoreBonus();
|
globalScene.score += gameMode.getClearScoreBonus();
|
||||||
globalScene.updateScoreText();
|
globalScene.updateScoreText();
|
||||||
globalScene.phaseManager.pushNew("GameOverPhase", true);
|
globalScene.phaseManager.pushNew("GameOverPhase", true);
|
||||||
}
|
}
|
||||||
@ -126,18 +120,4 @@ export class VictoryPhase extends PokemonPhase {
|
|||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If this wave is a fixed battle with special custom modifier rewards,
|
|
||||||
* will pass those settings to the upcoming {@linkcode SelectModifierPhase}`.
|
|
||||||
*/
|
|
||||||
getFixedBattleCustomModifiers(): CustomModifierSettings | undefined {
|
|
||||||
const gameMode = globalScene.gameMode;
|
|
||||||
const waveIndex = globalScene.currentBattle.waveIndex;
|
|
||||||
if (gameMode.isFixedBattle(waveIndex)) {
|
|
||||||
return gameMode.getFixedBattle(waveIndex).customModifierRewardSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -56,15 +56,15 @@ export class PokerogueSessionSavedataApi extends ApiBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a session savedata.
|
* Update a session savedata.
|
||||||
* @param params The {@linkcode UpdateSessionSavedataRequest} to send
|
* @param params - The request to send
|
||||||
* @param rawSavedata The raw savedata (as `string`)
|
* @param rawSavedata - The raw, unencrypted savedata
|
||||||
* @returns An error message if something went wrong
|
* @returns An error message if something went wrong
|
||||||
*/
|
*/
|
||||||
public async update(params: UpdateSessionSavedataRequest, rawSavedata: string) {
|
public async update(params: UpdateSessionSavedataRequest, rawSavedata: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const urlSearchParams = this.toUrlSearchParams(params);
|
const urlSearchParams = this.toUrlSearchParams(params);
|
||||||
const response = await this.doPost(`/savedata/session/update?${urlSearchParams}`, rawSavedata);
|
|
||||||
|
|
||||||
|
const response = await this.doPost(`/savedata/session/update?${urlSearchParams}`, rawSavedata);
|
||||||
return await response.text();
|
return await response.text();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("Could not update session savedata!", err);
|
console.warn("Could not update session savedata!", err);
|
||||||
|
@ -448,6 +448,8 @@ export function getAchievementDescription(localizationKey: string): string {
|
|||||||
return i18next.t("achv:FLIP_STATS.description", { context: genderStr });
|
return i18next.t("achv:FLIP_STATS.description", { context: genderStr });
|
||||||
case "FLIP_INVERSE":
|
case "FLIP_INVERSE":
|
||||||
return i18next.t("achv:FLIP_INVERSE.description", { context: genderStr });
|
return i18next.t("achv:FLIP_INVERSE.description", { context: genderStr });
|
||||||
|
case "NUZLOCKE":
|
||||||
|
return i18next.t("achv:NUZLOCKE.description", { context: genderStr });
|
||||||
case "BREEDERS_IN_SPACE":
|
case "BREEDERS_IN_SPACE":
|
||||||
return i18next.t("achv:BREEDERS_IN_SPACE.description", {
|
return i18next.t("achv:BREEDERS_IN_SPACE.description", {
|
||||||
context: genderStr,
|
context: genderStr,
|
||||||
|
@ -128,7 +128,8 @@ export interface SessionSaveData {
|
|||||||
battleType: BattleType;
|
battleType: BattleType;
|
||||||
trainer: TrainerData;
|
trainer: TrainerData;
|
||||||
gameVersion: string;
|
gameVersion: string;
|
||||||
runNameText: string;
|
/** The player-chosen name of the run */
|
||||||
|
name: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
challenges: ChallengeData[];
|
challenges: ChallengeData[];
|
||||||
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
|
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
|
||||||
@ -986,51 +987,45 @@ export class GameData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async renameSession(slotId: number, newName: string): Promise<boolean> {
|
async renameSession(slotId: number, newName: string): Promise<boolean> {
|
||||||
return new Promise(async resolve => {
|
if (slotId < 0) {
|
||||||
if (slotId < 0) {
|
return false;
|
||||||
return resolve(false);
|
}
|
||||||
}
|
if (newName === "") {
|
||||||
const sessionData: SessionSaveData | null = await this.getSession(slotId);
|
return true;
|
||||||
|
}
|
||||||
|
const sessionData: SessionSaveData | null = await this.getSession(slotId);
|
||||||
|
|
||||||
if (!sessionData) {
|
if (!sessionData) {
|
||||||
return resolve(false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newName === "") {
|
sessionData.name = newName;
|
||||||
return resolve(true);
|
// update timestamp by 1 to ensure the session is saved
|
||||||
}
|
sessionData.timestamp += 1;
|
||||||
|
const updatedDataStr = JSON.stringify(sessionData);
|
||||||
|
const encrypted = encrypt(updatedDataStr, bypassLogin);
|
||||||
|
const secretId = this.secretId;
|
||||||
|
const trainerId = this.trainerId;
|
||||||
|
|
||||||
sessionData.runNameText = newName;
|
if (bypassLogin) {
|
||||||
const updatedDataStr = JSON.stringify(sessionData);
|
localStorage.setItem(
|
||||||
const encrypted = encrypt(updatedDataStr, bypassLogin);
|
`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`,
|
||||||
const secretId = this.secretId;
|
encrypt(updatedDataStr, bypassLogin),
|
||||||
const trainerId = this.trainerId;
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (bypassLogin) {
|
const response = await pokerogueApi.savedata.session.update(
|
||||||
localStorage.setItem(
|
{ slot: slotId, trainerId, secretId, clientSessionId },
|
||||||
`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`,
|
updatedDataStr,
|
||||||
encrypt(updatedDataStr, bypassLogin),
|
);
|
||||||
);
|
|
||||||
resolve(true);
|
if (response) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
pokerogueApi.savedata.session
|
localStorage.setItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`, encrypted);
|
||||||
.update({ slot: slotId, trainerId, secretId, clientSessionId }, encrypted)
|
const success = await updateUserInfo();
|
||||||
.then(error => {
|
return !(success !== null && !success);
|
||||||
if (error) {
|
|
||||||
console.error("Failed to update session name:", error);
|
|
||||||
resolve(false);
|
|
||||||
} else {
|
|
||||||
localStorage.setItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`, encrypted);
|
|
||||||
updateUserInfo().then(success => {
|
|
||||||
if (success !== null && !success) {
|
|
||||||
return resolve(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
resolve(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSession(slotId: number, sessionData?: SessionSaveData): Promise<boolean> {
|
loadSession(slotId: number, sessionData?: SessionSaveData): Promise<boolean> {
|
||||||
|
@ -2142,7 +2142,12 @@ class PartyCancelButton extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
this.partyCancelPb = partyCancelPb;
|
this.partyCancelPb = partyCancelPb;
|
||||||
|
|
||||||
const partyCancelText = addTextObject(-10, -7, i18next.t("partyUiHandler:cancel"), TextStyle.PARTY_CANCEL_BUTTON);
|
const partyCancelText = addTextObject(
|
||||||
|
-10,
|
||||||
|
-7,
|
||||||
|
i18next.t("partyUiHandler:cancelButton"),
|
||||||
|
TextStyle.PARTY_CANCEL_BUTTON,
|
||||||
|
);
|
||||||
this.add(partyCancelText);
|
this.add(partyCancelText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +208,26 @@ export class PokedexMonContainer extends Phaser.GameObjects.Container {
|
|||||||
);
|
);
|
||||||
this.checkIconId(defaultProps.female, defaultProps.formIndex, defaultProps.shiny, defaultProps.variant);
|
this.checkIconId(defaultProps.female, defaultProps.formIndex, defaultProps.shiny, defaultProps.variant);
|
||||||
this.add(this.icon);
|
this.add(this.icon);
|
||||||
|
|
||||||
|
[
|
||||||
|
this.hiddenAbilityIcon,
|
||||||
|
this.favoriteIcon,
|
||||||
|
this.classicWinIcon,
|
||||||
|
this.candyUpgradeIcon,
|
||||||
|
this.candyUpgradeOverlayIcon,
|
||||||
|
this.eggMove1Icon,
|
||||||
|
this.tmMove1Icon,
|
||||||
|
this.eggMove2Icon,
|
||||||
|
this.tmMove2Icon,
|
||||||
|
this.passive1Icon,
|
||||||
|
this.passive2Icon,
|
||||||
|
this.passive1OverlayIcon,
|
||||||
|
this.passive2OverlayIcon,
|
||||||
|
].forEach(icon => {
|
||||||
|
if (icon) {
|
||||||
|
this.bringToTop(icon);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIconId(female, formIndex, shiny, variant) {
|
checkIconId(female, formIndex, shiny, variant) {
|
||||||
|
@ -410,6 +410,11 @@ export class PokedexUiHandler extends MessageUiHandler {
|
|||||||
new DropDownLabel(i18next.t("filterBar:hasHiddenAbility"), undefined, DropDownState.ON),
|
new DropDownLabel(i18next.t("filterBar:hasHiddenAbility"), undefined, DropDownState.ON),
|
||||||
new DropDownLabel(i18next.t("filterBar:noHiddenAbility"), undefined, DropDownState.EXCLUDE),
|
new DropDownLabel(i18next.t("filterBar:noHiddenAbility"), undefined, DropDownState.EXCLUDE),
|
||||||
];
|
];
|
||||||
|
const seenSpeciesLabels = [
|
||||||
|
new DropDownLabel(i18next.t("filterBar:seenSpecies"), undefined, DropDownState.OFF),
|
||||||
|
new DropDownLabel(i18next.t("filterBar:isSeen"), undefined, DropDownState.ON),
|
||||||
|
new DropDownLabel(i18next.t("filterBar:isUnseen"), undefined, DropDownState.EXCLUDE),
|
||||||
|
];
|
||||||
const eggLabels = [
|
const eggLabels = [
|
||||||
new DropDownLabel(i18next.t("filterBar:egg"), undefined, DropDownState.OFF),
|
new DropDownLabel(i18next.t("filterBar:egg"), undefined, DropDownState.OFF),
|
||||||
new DropDownLabel(i18next.t("filterBar:eggPurchasable"), undefined, DropDownState.ON),
|
new DropDownLabel(i18next.t("filterBar:eggPurchasable"), undefined, DropDownState.ON),
|
||||||
@ -423,6 +428,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
|||||||
new DropDownOption("FAVORITE", favoriteLabels),
|
new DropDownOption("FAVORITE", favoriteLabels),
|
||||||
new DropDownOption("WIN", winLabels),
|
new DropDownOption("WIN", winLabels),
|
||||||
new DropDownOption("HIDDEN_ABILITY", hiddenAbilityLabels),
|
new DropDownOption("HIDDEN_ABILITY", hiddenAbilityLabels),
|
||||||
|
new DropDownOption("SEEN_SPECIES", seenSpeciesLabels),
|
||||||
new DropDownOption("EGG", eggLabels),
|
new DropDownOption("EGG", eggLabels),
|
||||||
new DropDownOption("POKERUS", pokerusLabels),
|
new DropDownOption("POKERUS", pokerusLabels),
|
||||||
];
|
];
|
||||||
@ -792,13 +798,15 @@ export class PokedexUiHandler extends MessageUiHandler {
|
|||||||
this.starterSelectMessageBoxContainer.setVisible(!!text?.length);
|
this.starterSelectMessageBoxContainer.setVisible(!!text?.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
isSeen(species: PokemonSpecies, dexEntry: DexEntry): boolean {
|
isSeen(species: PokemonSpecies, dexEntry: DexEntry, seenFilter?: boolean): boolean {
|
||||||
if (dexEntry?.seenAttr) {
|
if (dexEntry?.seenAttr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!seenFilter) {
|
||||||
const starterDexEntry = globalScene.gameData.dexData[this.getStarterSpeciesId(species.speciesId)];
|
const starterDexEntry = globalScene.gameData.dexData[this.getStarterSpeciesId(species.speciesId)];
|
||||||
return !!starterDexEntry?.caughtAttr;
|
return !!starterDexEntry?.caughtAttr;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1617,6 +1625,21 @@ export class PokedexUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Seen Filter
|
||||||
|
const dexEntry = globalScene.gameData.dexData[species.speciesId];
|
||||||
|
const isItSeen = this.isSeen(species, dexEntry, true);
|
||||||
|
const fitsSeen = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
|
if (misc.val === "SEEN_SPECIES" && misc.state === DropDownState.ON) {
|
||||||
|
return isItSeen;
|
||||||
|
}
|
||||||
|
if (misc.val === "SEEN_SPECIES" && misc.state === DropDownState.EXCLUDE) {
|
||||||
|
return !isItSeen;
|
||||||
|
}
|
||||||
|
if (misc.val === "SEEN_SPECIES" && misc.state === DropDownState.OFF) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Egg Purchasable Filter
|
// Egg Purchasable Filter
|
||||||
const isEggPurchasable = this.isSameSpeciesEggAvailable(species.speciesId);
|
const isEggPurchasable = this.isSameSpeciesEggAvailable(species.speciesId);
|
||||||
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
@ -1658,6 +1681,7 @@ export class PokedexUiHandler extends MessageUiHandler {
|
|||||||
fitsFavorite &&
|
fitsFavorite &&
|
||||||
fitsWin &&
|
fitsWin &&
|
||||||
fitsHA &&
|
fitsHA &&
|
||||||
|
fitsSeen &&
|
||||||
fitsEgg &&
|
fitsEgg &&
|
||||||
fitsPokerus
|
fitsPokerus
|
||||||
) {
|
) {
|
||||||
|
@ -208,9 +208,10 @@ export class RunInfoUiHandler extends UiHandler {
|
|||||||
headerText.setOrigin(0, 0);
|
headerText.setOrigin(0, 0);
|
||||||
headerText.setPositionRelative(headerBg, 8, 4);
|
headerText.setPositionRelative(headerBg, 8, 4);
|
||||||
this.runContainer.add(headerText);
|
this.runContainer.add(headerText);
|
||||||
const runName = addTextObject(0, 0, this.runInfo.runNameText, TextStyle.WINDOW);
|
const runName = addTextObject(0, 0, this.runInfo.name, TextStyle.WINDOW);
|
||||||
runName.setOrigin(0, 0);
|
runName.setOrigin(0, 0);
|
||||||
runName.setPositionRelative(headerBg, 60, 4);
|
const runNameX = headerText.width / 6 + headerText.x + 4;
|
||||||
|
runName.setPositionRelative(headerBg, runNameX, 4);
|
||||||
this.runContainer.add(runName);
|
this.runContainer.add(runName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
|||||||
"select_cursor_highlight_thick",
|
"select_cursor_highlight_thick",
|
||||||
undefined,
|
undefined,
|
||||||
294,
|
294,
|
||||||
this.sessionSlots[prevSlotIndex ?? 0]?.saveData?.runNameText ? 50 : 60,
|
this.sessionSlots[prevSlotIndex ?? 0]?.saveData?.name ? 50 : 60,
|
||||||
6,
|
6,
|
||||||
6,
|
6,
|
||||||
6,
|
6,
|
||||||
@ -553,10 +553,10 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async setupWithData(data: SessionSaveData) {
|
async setupWithData(data: SessionSaveData) {
|
||||||
const hasName = data?.runNameText;
|
const hasName = data?.name;
|
||||||
this.remove(this.loadingLabel, true);
|
this.remove(this.loadingLabel, true);
|
||||||
if (hasName) {
|
if (hasName) {
|
||||||
const nameLabel = addTextObject(8, 5, data.runNameText, TextStyle.WINDOW);
|
const nameLabel = addTextObject(8, 5, data.name, TextStyle.WINDOW);
|
||||||
this.add(nameLabel);
|
this.add(nameLabel);
|
||||||
} else {
|
} else {
|
||||||
const fallbackName = this.decideFallback(data);
|
const fallbackName = this.decideFallback(data);
|
||||||
|
@ -45,17 +45,17 @@ export function deepMergeSpriteData(dest: object, source: object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function encrypt(data: string, bypassLogin: boolean): string {
|
export function encrypt(data: string, bypassLogin: boolean): string {
|
||||||
return (bypassLogin
|
if (bypassLogin) {
|
||||||
? (data: string) => btoa(encodeURIComponent(data))
|
return btoa(encodeURIComponent(data));
|
||||||
: (data: string) => AES.encrypt(data, saveKey))(data) as unknown as string; // TODO: is this correct?
|
}
|
||||||
|
return AES.encrypt(data, saveKey).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decrypt(data: string, bypassLogin: boolean): string {
|
export function decrypt(data: string, bypassLogin: boolean): string {
|
||||||
return (
|
if (bypassLogin) {
|
||||||
bypassLogin
|
return decodeURIComponent(atob(data));
|
||||||
? (data: string) => decodeURIComponent(atob(data))
|
}
|
||||||
: (data: string) => AES.decrypt(data, saveKey).toString(enc.Utf8)
|
return AES.decrypt(data, saveKey).toString(enc.Utf8);
|
||||||
)(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present.
|
// the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present.
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils";
|
||||||
import { GameManager } from "#test/test-utils/game-manager";
|
import { GameManager } from "#test/test-utils/game-manager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
@ -52,4 +54,18 @@ describe("Challenges - Limited Catch", () => {
|
|||||||
|
|
||||||
expect(game.scene.getPlayerParty()).toHaveLength(1);
|
expect(game.scene.getPlayerParty()).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should allow gift Pokémon from Mystery Encounters to be added to party", async () => {
|
||||||
|
game.override
|
||||||
|
.mysteryEncounterChance(100)
|
||||||
|
.mysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN)
|
||||||
|
.startingWave(12);
|
||||||
|
game.scene.money = 20000;
|
||||||
|
|
||||||
|
await game.challengeMode.runToSummon([SpeciesId.NUZLEAF]);
|
||||||
|
|
||||||
|
await runMysteryEncounterToEnd(game, 1);
|
||||||
|
|
||||||
|
expect(game.scene.getPlayerParty()).toHaveLength(2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import { Challenges } from "#enums/challenges";
|
|||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { UiMode } from "#enums/ui-mode";
|
import { UiMode } from "#enums/ui-mode";
|
||||||
|
import { ExpBoosterModifier } from "#modifiers/modifier";
|
||||||
import { GameManager } from "#test/test-utils/game-manager";
|
import { GameManager } from "#test/test-utils/game-manager";
|
||||||
import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
|
import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
@ -75,6 +76,7 @@ describe("Challenges - Limited Support", () => {
|
|||||||
await game.doKillOpponents();
|
await game.doKillOpponents();
|
||||||
await game.toNextWave();
|
await game.toNextWave();
|
||||||
|
|
||||||
|
expect(game.scene.getModifiers(ExpBoosterModifier)).toHaveLength(1);
|
||||||
expect(playerPokemon).not.toHaveFullHp();
|
expect(playerPokemon).not.toHaveFullHp();
|
||||||
|
|
||||||
game.move.use(MoveId.SPLASH);
|
game.move.use(MoveId.SPLASH);
|
||||||
|
Loading…
Reference in New Issue
Block a user