mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-10-23 13:35:53 +02:00
* add .github/workflows/mystery-event.yml * update mystery-event.yml * mystery encounters: resolve review comments: Lost at Sea: -fix typo in handlePokemonGuidingYouPhase function Mysterious Chest: - remove obsolete commented code mystery-encounter.ts - remove unused `onDone` field from MysteryEncounterBuilder * fix typo in CanLearnMoveRequirementOptions * remove redundance from Pokemon.isAllowedInBattle() * chore: jsdoc formatting * fix lost-at-sea tests * add fallback for biomeMysteryEncounters if empty * lost-at-sea-encounter: fix and extend tests * move "battle:fainted" into `koPlayerPokemon` * add retries to quick-draw tests * fix lost-at-sea-encounter tests * clean up battle animation logic * Update and rename mystery-event.yml to mystery-events.yml * Update mystery-events.yml * Fix typo * Update mystery-events.yml Fix debug runs * clean up unit tests and utils * attach github issues to all encounter jsdocs * start dialogue refactor * update sleeping snorlax encounter * migrate encounters dialogue to new format * cleanup and add jsdocs * finish fiery fallout encounter * fix unit test breaks * add skeleton tests to fiery fallout * commit latest test changes * finish unit tests for fiery fallout * bug fix for empty modifier shop * stash working changes * stash changes * Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/data/battle-anims.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * nit updates and cleanup * Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * add jsdocs and more cleanup * add more jsdoc * add the strong stuff encounter * add the strong stuff encounter and more unit tests * cleanup container length checks in ME ui * add retries to tests * add retries to tests * fix trainer wave disable override * add shuckle juice modifier * add dialogue bug fixes * add dialogue bug fixes * add pokemon salesman encounter and affects pokedex UI display * add unit tests for pokemon salesman * temp stash * add offer you can't refuse * add unit tests for offer you can't refuse encounter * remove unnecessary prompt handlers * add tests for disabled encounter options * add delibird-y encounter * add delibird-y encounter * add absolute avarice encounter * finish absolute avarice encounter * add unit tests and enhancements for item overrides in tests * fix unit test * cleanup absolute avarice PR * small bug fixes with latest sync from main * update visuals loading for safari and stat trainer visuals * update visuals loading for safari and stat trainer visuals * update a trainer's test encounter and add unit tests * add Trash to Treasure encounter * clean up trash to treasure encounter * clean up trash to treasure encounter * add berries abound encounter * start clowning around encounter * first implementation pass at clowning around * add unit tests for clowning around * add unit tests for clowning around * clean up ME unit tests * clean up unit tests * update unit tests * add part timer and dancing lessons encounters * add unit tests for Dancing Lessons and Part-Timer * reordered biome list and adjusted redirection for project and labels * Add Weird Dream encounter and slight reworks to Berries Abound/Fight or Flight * adjusting yml to match new labels * fix yml whoopsie * Expanded 'Weird Dream' banlist and fixed a bug with the BST bump range * adds Winstrate Challenge mystery encounter * small cleanup for winstrates * add unit tests for Winstrate Challenge * fix pokemon not returning after winstrate battle * commit latest beta merge updates * fix ME null checks and unit tests with beta update * fix ME null checks and unit tests with beta update * MEs to pokerogue beta branch * test dialogue changes * test patch fix * test patch fix * test patch fix * adds teleporting hijinks encounter * add unit tests for Teleporting Hijinks * small change to teleporting hijinks dialogue * migrate ME translations to json * add retries to berries-abound.Option1: should reward the player with X berries based on wave * add missing ME dialogue back in * revert template changes * add ME unique trainer dialogue to both dialogue jsons * fix hanging comma in json * fix broken imports * resolve lint issues * fix flaky test * balance tweaks to a few MEs, updates to bug superfan * add unit tests for Bug-Type Superfan and clean up dialogue * Adds Fun and Games mystery encounter * add unit tests for Fun and Games encounter * update jsdoc * small ME balance changes * small ME balance changes * Adds Uncommon Breed ME and misc. ME bug fixes * Update getFinalSessionData() to collect Mystery Encounter data * adds GTS encounter * various ME bug fixes and balance changes * latest ME bug fixes * clean up GTS Encounter and add unit tests * small cleanup to MEs branch * add BGM music names for ME music * bug fixes and balance changes for MEs * ME data schema updates * balance changes and bug fixes to MEs * balance changes and bug fixes to MEs * update tests for MEs * add jsdoc to party exp function * dialogue updates and test fixes for MEs * dialogue updates and test fixes for MEs * PR suggestions and fixees * stash PR feedback and bugfixes * fix all tests for MEs and cleanup * PR feedback * update flaky ME test * update tests, bug fix MEs, and sprite assets * remove unintentional console log * re-enable stubbed function for Phaser text styling * handle undefined introVisuals properly * PR feedback from NightKev * disable Uncommon Breed tests * locales updates and bug fixes for safari zone * more PR feedback and update field trip with Rarer Candy * fix unit test * Change how reroll button gets disabled in Modifier Shop Phase * update continue button text logic * Update src/ui/modifier-select-ui-handler.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * fix money formatting and some nits * more nits * more nits * update ME tsdocs with links * update ME tsdocs with links --------- Co-authored-by: Felix Staud <felix.staud@headwire.com> Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> Co-authored-by: ImperialSympathizer <imperialsympathizer@gmail.com> Co-authored-by: InnocentGameDev <asdargmng@gmail.com> Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
259 lines
9.8 KiB
TypeScript
259 lines
9.8 KiB
TypeScript
import BattleScene from "#app/battle-scene";
|
|
import { BattleType } from "#app/battle";
|
|
import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball";
|
|
import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
|
import { TrainerSlot } from "#app/data/trainer-config";
|
|
import { PlayerGender } from "#app/enums/player-gender";
|
|
import { addPokeballOpenParticles } from "#app/field/anims";
|
|
import Pokemon, { FieldPosition } from "#app/field/pokemon";
|
|
import { getPokemonNameWithAffix } from "#app/messages";
|
|
import i18next from "i18next";
|
|
import { PartyMemberPokemonPhase } from "./party-member-pokemon-phase";
|
|
import { PostSummonPhase } from "./post-summon-phase";
|
|
import { GameOverPhase } from "./game-over-phase";
|
|
import { ShinySparklePhase } from "./shiny-sparkle-phase";
|
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
|
|
|
export class SummonPhase extends PartyMemberPokemonPhase {
|
|
private loaded: boolean;
|
|
|
|
constructor(scene: BattleScene, fieldIndex: integer, player: boolean = true, loaded: boolean = false) {
|
|
super(scene, fieldIndex, player);
|
|
|
|
this.loaded = loaded;
|
|
}
|
|
|
|
start() {
|
|
super.start();
|
|
|
|
this.preSummon();
|
|
}
|
|
|
|
/**
|
|
* Sends out a Pokemon before the battle begins and shows the appropriate messages
|
|
*/
|
|
preSummon(): void {
|
|
const partyMember = this.getPokemon();
|
|
// If the Pokemon about to be sent out is fainted, illegal under a challenge, or no longer in the party for some reason, switch to the first non-fainted legal Pokemon
|
|
if (!partyMember.isAllowedInBattle() || (this.player && !this.getParty().some(p => p.id === partyMember.id))) {
|
|
console.warn("The Pokemon about to be sent out is fainted or illegal under a challenge. Attempting to resolve...");
|
|
|
|
// First check if they're somehow still in play, if so remove them.
|
|
if (partyMember.isOnField()) {
|
|
partyMember.leaveField();
|
|
}
|
|
|
|
const party = this.getParty();
|
|
|
|
// Find the first non-fainted Pokemon index above the current one
|
|
const legalIndex = party.findIndex((p, i) => i > this.partyMemberIndex && p.isAllowedInBattle());
|
|
if (legalIndex === -1) {
|
|
console.error("Party Details:\n", party);
|
|
console.error("All available Pokemon were fainted or illegal!");
|
|
this.scene.clearPhaseQueue();
|
|
this.scene.unshiftPhase(new GameOverPhase(this.scene));
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
// Swaps the fainted Pokemon and the first non-fainted legal Pokemon in the party
|
|
[party[this.partyMemberIndex], party[legalIndex]] = [party[legalIndex], party[this.partyMemberIndex]];
|
|
console.warn("Swapped %s %O with %s %O", getPokemonNameWithAffix(partyMember), partyMember, getPokemonNameWithAffix(party[0]), party[0]);
|
|
}
|
|
|
|
if (this.player) {
|
|
this.scene.ui.showText(i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(this.getPokemon()) }));
|
|
if (this.player) {
|
|
this.scene.pbTray.hide();
|
|
}
|
|
this.scene.trainer.setTexture(`trainer_${this.scene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
|
|
this.scene.time.delayedCall(562, () => {
|
|
this.scene.trainer.setFrame("2");
|
|
this.scene.time.delayedCall(64, () => {
|
|
this.scene.trainer.setFrame("3");
|
|
});
|
|
});
|
|
this.scene.tweens.add({
|
|
targets: this.scene.trainer,
|
|
x: -36,
|
|
duration: 1000,
|
|
onComplete: () => this.scene.trainer.setVisible(false)
|
|
});
|
|
this.scene.time.delayedCall(750, () => this.summon());
|
|
} else if (this.scene.currentBattle.battleType === BattleType.TRAINER || this.scene.currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
|
const trainerName = this.scene.currentBattle.trainer?.getName(!(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER);
|
|
const pokemonName = this.getPokemon().getNameToRender();
|
|
const message = i18next.t("battle:trainerSendOut", { trainerName, pokemonName });
|
|
|
|
this.scene.pbTrayEnemy.hide();
|
|
this.scene.ui.showText(message, null, () => this.summon());
|
|
} else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) {
|
|
this.scene.pbTrayEnemy.hide();
|
|
this.summonWild();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enemy trainer or player trainer will do animations to throw Pokeball and summon a Pokemon to the field.
|
|
*/
|
|
summon(): void {
|
|
const pokemon = this.getPokemon();
|
|
|
|
const pokeball = this.scene.addFieldSprite(this.player ? 36 : 248, this.player ? 80 : 44, "pb", getPokeballAtlasKey(pokemon.pokeball));
|
|
pokeball.setVisible(false);
|
|
pokeball.setOrigin(0.5, 0.625);
|
|
this.scene.field.add(pokeball);
|
|
|
|
if (this.fieldIndex === 1) {
|
|
pokemon.setFieldPosition(FieldPosition.RIGHT, 0);
|
|
} else {
|
|
const availablePartyMembers = this.getParty().filter(p => p.isAllowedInBattle()).length;
|
|
pokemon.setFieldPosition(!this.scene.currentBattle.double || availablePartyMembers === 1 ? FieldPosition.CENTER : FieldPosition.LEFT);
|
|
}
|
|
|
|
const fpOffset = pokemon.getFieldPositionOffset();
|
|
|
|
pokeball.setVisible(true);
|
|
|
|
this.scene.tweens.add({
|
|
targets: pokeball,
|
|
duration: 650,
|
|
x: (this.player ? 100 : 236) + fpOffset[0]
|
|
});
|
|
|
|
this.scene.tweens.add({
|
|
targets: pokeball,
|
|
duration: 150,
|
|
ease: "Cubic.easeOut",
|
|
y: (this.player ? 70 : 34) + fpOffset[1],
|
|
onComplete: () => {
|
|
this.scene.tweens.add({
|
|
targets: pokeball,
|
|
duration: 500,
|
|
ease: "Cubic.easeIn",
|
|
angle: 1440,
|
|
y: (this.player ? 132 : 86) + fpOffset[1],
|
|
onComplete: () => {
|
|
this.scene.playSound("se/pb_rel");
|
|
pokeball.destroy();
|
|
this.scene.add.existing(pokemon);
|
|
this.scene.field.add(pokemon);
|
|
if (!this.player) {
|
|
const playerPokemon = this.scene.getPlayerPokemon() as Pokemon;
|
|
if (playerPokemon?.visible) {
|
|
this.scene.field.moveBelow(pokemon, playerPokemon);
|
|
}
|
|
this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id);
|
|
}
|
|
addPokeballOpenParticles(this.scene, pokemon.x, pokemon.y - 16, pokemon.pokeball);
|
|
this.scene.updateModifiers(this.player);
|
|
this.scene.updateFieldScale();
|
|
pokemon.showInfo();
|
|
pokemon.playAnim();
|
|
pokemon.setVisible(true);
|
|
pokemon.getSprite().setVisible(true);
|
|
pokemon.setScale(0.5);
|
|
pokemon.tint(getPokeballTintColor(pokemon.pokeball));
|
|
pokemon.untint(250, "Sine.easeIn");
|
|
this.scene.updateFieldScale();
|
|
this.scene.tweens.add({
|
|
targets: pokemon,
|
|
duration: 250,
|
|
ease: "Sine.easeIn",
|
|
scale: pokemon.getSpriteScale(),
|
|
onComplete: () => {
|
|
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
|
|
pokemon.getSprite().clearTint();
|
|
pokemon.resetSummonData();
|
|
this.scene.time.delayedCall(1000, () => this.end());
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handles tweening and battle setup for a wild Pokemon that appears outside of the normal screen transition.
|
|
* Wild Pokemon will ease and fade in onto the field, then perform standard summon behavior.
|
|
* Currently only used by Mystery Encounters, as all other battle types pre-summon wild pokemon before screen transitions.
|
|
*/
|
|
summonWild(): void {
|
|
const pokemon = this.getPokemon();
|
|
|
|
if (this.fieldIndex === 1) {
|
|
pokemon.setFieldPosition(FieldPosition.RIGHT, 0);
|
|
} else {
|
|
const availablePartyMembers = this.getParty().filter(p => !p.isFainted()).length;
|
|
pokemon.setFieldPosition(!this.scene.currentBattle.double || availablePartyMembers === 1 ? FieldPosition.CENTER : FieldPosition.LEFT);
|
|
}
|
|
|
|
this.scene.add.existing(pokemon);
|
|
this.scene.field.add(pokemon);
|
|
if (!this.player) {
|
|
const playerPokemon = this.scene.getPlayerPokemon() as Pokemon;
|
|
if (playerPokemon?.visible) {
|
|
this.scene.field.moveBelow(pokemon, playerPokemon);
|
|
}
|
|
this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id);
|
|
}
|
|
this.scene.updateModifiers(this.player);
|
|
this.scene.updateFieldScale();
|
|
pokemon.showInfo();
|
|
pokemon.playAnim();
|
|
pokemon.setVisible(true);
|
|
pokemon.getSprite().setVisible(true);
|
|
pokemon.setScale(0.75);
|
|
pokemon.tint(getPokeballTintColor(pokemon.pokeball));
|
|
pokemon.untint(250, "Sine.easeIn");
|
|
this.scene.updateFieldScale();
|
|
pokemon.x += 16;
|
|
pokemon.y -= 20;
|
|
pokemon.alpha = 0;
|
|
|
|
// Ease pokemon in
|
|
this.scene.tweens.add({
|
|
targets: pokemon,
|
|
x: "-=16",
|
|
y: "+=16",
|
|
alpha: 1,
|
|
duration: 1000,
|
|
ease: "Sine.easeIn",
|
|
scale: pokemon.getSpriteScale(),
|
|
onComplete: () => {
|
|
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
|
|
pokemon.getSprite().clearTint();
|
|
pokemon.resetSummonData();
|
|
this.scene.updateFieldScale();
|
|
this.scene.time.delayedCall(1000, () => this.end());
|
|
}
|
|
});
|
|
}
|
|
|
|
onEnd(): void {
|
|
const pokemon = this.getPokemon();
|
|
|
|
if (pokemon.isShiny()) {
|
|
this.scene.unshiftPhase(new ShinySparklePhase(this.scene, pokemon.getBattlerIndex()));
|
|
}
|
|
|
|
pokemon.resetTurnData();
|
|
|
|
if (!this.loaded || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.scene.currentBattle.battleType) || (this.scene.currentBattle.waveIndex % 10) === 1) {
|
|
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
|
|
this.queuePostSummon();
|
|
}
|
|
}
|
|
|
|
queuePostSummon(): void {
|
|
this.scene.pushPhase(new PostSummonPhase(this.scene, this.getPokemon().getBattlerIndex()));
|
|
}
|
|
|
|
end() {
|
|
this.onEnd();
|
|
|
|
super.end();
|
|
}
|
|
}
|