[Bug] Fix #762: All Pokemon become invisible when capturing then switching with your only pokemon that was not fainted (#4025)

* fix #762 by using slotIndex to add to party

for now the new pokemon was ALWAYS just pushed to the party array. Now it's put into the slot that was also previously selected as the mon to release

* add docs for `Pokemon.addToParty()`

* add simple tests for addToParty

* update `isBetween` docs. Remove `.js` imports
This commit is contained in:
flx-sta 2024-09-08 22:10:47 -07:00 committed by GitHub
parent 06f98f6737
commit 39b6a72517
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 66 additions and 6 deletions

1
src/constants.ts Normal file
View File

@ -0,0 +1 @@
export const PLAYER_PARTY_MAX_SIZE = 6;

View File

@ -58,6 +58,7 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase"; import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase"; import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
import { Challenges } from "#enums/challenges"; import { Challenges } from "#enums/challenges";
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
export enum FieldPosition { export enum FieldPosition {
CENTER, CENTER,
@ -4465,17 +4466,29 @@ export class EnemyPokemon extends Pokemon {
return BattlerIndex.ENEMY + this.getFieldIndex(); return BattlerIndex.ENEMY + this.getFieldIndex();
} }
addToParty(pokeballType: PokeballType) { /**
* Add a new pokemon to the player's party (at `slotIndex` if set).
* @param pokeballType the type of pokeball the pokemon was caught with
* @param slotIndex an optional index to place the pokemon in the party
* @returns the pokemon that was added or null if the pokemon could not be added
*/
addToParty(pokeballType: PokeballType, slotIndex: number = -1) {
const party = this.scene.getParty(); const party = this.scene.getParty();
let ret: PlayerPokemon | null = null; let ret: PlayerPokemon | null = null;
if (party.length < 6) { if (party.length < PLAYER_PARTY_MAX_SIZE) {
this.pokeball = pokeballType; this.pokeball = pokeballType;
this.metLevel = this.level; this.metLevel = this.level;
this.metBiome = this.scene.arena.biomeType; this.metBiome = this.scene.arena.biomeType;
this.metSpecies = this.species.speciesId; this.metSpecies = this.species.speciesId;
const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this.variant, this.ivs, this.nature, this); const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this.variant, this.ivs, this.nature, this);
if (Utils.isBetween(slotIndex, 0, PLAYER_PARTY_MAX_SIZE - 1)) {
party.splice(slotIndex, 0, newPokemon);
} else {
party.push(newPokemon); party.push(newPokemon);
}
ret = newPokemon; ret = newPokemon;
this.scene.triggerPokemonFormChange(newPokemon, SpeciesFormChangeActiveTrigger, true); this.scene.triggerPokemonFormChange(newPokemon, SpeciesFormChangeActiveTrigger, true);
} }

View File

@ -221,8 +221,8 @@ export class AttemptCapturePhase extends PokemonPhase {
this.scene.clearEnemyHeldItemModifiers(); this.scene.clearEnemyHeldItemModifiers();
this.scene.field.remove(pokemon, true); this.scene.field.remove(pokemon, true);
}; };
const addToParty = () => { const addToParty = (slotIndex?: number) => {
const newPokemon = pokemon.addToParty(this.pokeballType); const newPokemon = pokemon.addToParty(this.pokeballType, slotIndex);
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false); const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
if (this.scene.getParty().filter(p => p.isShiny()).length === 6) { if (this.scene.getParty().filter(p => p.isShiny()).length === 6) {
this.scene.validateAchv(achvs.SHINY_PARTY); this.scene.validateAchv(achvs.SHINY_PARTY);
@ -253,7 +253,7 @@ export class AttemptCapturePhase extends PokemonPhase {
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, this.fieldIndex, (slotIndex: integer, _option: PartyOption) => { this.scene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, this.fieldIndex, (slotIndex: integer, _option: PartyOption) => {
this.scene.ui.setMode(Mode.MESSAGE).then(() => { this.scene.ui.setMode(Mode.MESSAGE).then(() => {
if (slotIndex < 6) { if (slotIndex < 6) {
addToParty(); addToParty(slotIndex);
} else { } else {
promptRelease(); promptRelease();
} }

View File

@ -1,6 +1,8 @@
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import GameManager from "../utils/gameManager"; import GameManager from "../utils/gameManager";
import { PokeballType } from "#app/enums/pokeball";
import BattleScene from "#app/battle-scene";
describe("Spec - Pokemon", () => { describe("Spec - Pokemon", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -28,4 +30,37 @@ describe("Spec - Pokemon", () => {
expect(pkm.trySetStatus(undefined)).toBe(true); expect(pkm.trySetStatus(undefined)).toBe(true);
}); });
describe("Add To Party", () => {
let scene: BattleScene;
beforeEach(async () => {
game.override.enemySpecies(Species.ZUBAT);
await game.classicMode.runToSummon([Species.ABRA, Species.ABRA, Species.ABRA, Species.ABRA, Species.ABRA]); // 5 Abra, only 1 slot left
scene = game.scene;
});
it("should append a new pokemon by default", async () => {
const zubat = scene.getEnemyPokemon()!;
zubat.addToParty(PokeballType.LUXURY_BALL);
const party = scene.getParty();
expect(party).toHaveLength(6);
party.forEach((pkm, index) =>{
expect(pkm.species.speciesId).toBe(index === 5 ? Species.ZUBAT : Species.ABRA);
});
});
it("should put a new pokemon into the passed slotIndex", async () => {
const slotIndex = 1;
const zubat = scene.getEnemyPokemon()!;
zubat.addToParty(PokeballType.LUXURY_BALL, slotIndex);
const party = scene.getParty();
expect(party).toHaveLength(6);
party.forEach((pkm, index) =>{
expect(pkm.species.speciesId).toBe(index === slotIndex ? Species.ZUBAT : Species.ABRA);
});
});
});
}); });

View File

@ -609,3 +609,14 @@ export function toDmgValue(value: number, minValue: number = 1) {
export function getLocalizedSpriteKey(baseKey: string) { export function getLocalizedSpriteKey(baseKey: string) {
return `${baseKey}${verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`; return `${baseKey}${verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`;
} }
/**
* Check if a number is **inclusive** between two numbers
* @param num the number to check
* @param min the minimum value (included)
* @param max the maximum value (included)
* @returns true if number is **inclusive** between min and max
*/
export function isBetween(num: number, min: number, max: number): boolean {
return num >= min && num <= max;
}