[Refactor] Refactored duplicated code into a common Pokemon#leaveField() function (#3310)

* refactor duplicated code into leaveField function

* replace bugfix code
This commit is contained in:
Alex Van Liew 2024-08-03 12:13:42 -07:00 committed by GitHub
parent bb6ec94c02
commit a2a1f3ec24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 51 deletions

View File

@ -13,10 +13,9 @@ import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag";
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability";
import { allAbilities } from "./ability";
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier";
import { BattlerIndex } from "../battle";
import { BattlerIndex, BattleType } from "../battle";
import { Stat } from "./pokemon-stat";
import { TerrainType } from "./terrain";
import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms";
import { ModifierPoolType } from "#app/modifier/modifier-type";
import { Command } from "../ui/command-ui-handler";
import i18next from "i18next";
@ -1817,13 +1816,10 @@ export class MultiHitAttr extends MoveAttr {
}
case MultiHitType._2:
return 2;
break;
case MultiHitType._3:
return 3;
break;
case MultiHitType._10:
return 10;
break;
case MultiHitType.BEAT_UP:
const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty();
// No status means the ally pokemon can contribute to Beat Up
@ -4780,19 +4776,14 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
if (switchOutTarget.hp > 0) {
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget);
// switchOut below sets the UI to select party(this is not a separate Phase), then adds a SwitchSummonPhase with selected 'mon
(switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true));
(switchOutTarget as PlayerPokemon).switchOut(this.batonPass).then(() => resolve(true));
} else {
resolve(false);
}
return;
} else if (user.scene.currentBattle.battleType) {
// Switch out logic for the battle type
switchOutTarget.resetTurnData();
switchOutTarget.resetSummonData();
switchOutTarget.hideInfo();
switchOutTarget.setVisible(false);
switchOutTarget.scene.field.remove(switchOutTarget);
user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true);
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
// Switch out logic for trainer battles
switchOutTarget.leaveField(!this.batonPass);
if (switchOutTarget.hp > 0) {
// for opponent switching out

View File

@ -3161,6 +3161,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this.randSeedInt((max - min) + 1, min);
}
/**
* Causes a Pokemon to leave the field (such as in preparation for a switch out/escape).
* @param clearEffects Indicates if effects should be cleared (true) or passed
* to the next pokemon, such as during a baton pass (false)
*/
leaveField(clearEffects: boolean = true) {
this.resetTurnData();
if (clearEffects) {
this.resetSummonData();
this.resetBattleData();
}
this.hideInfo();
this.setVisible(false);
this.scene.field.remove(this);
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);
}
destroy(): void {
this.battleInfo?.destroy();
super.destroy();
@ -3272,25 +3289,21 @@ export class PlayerPokemon extends Pokemon {
return true;
}
switchOut(batonPass: boolean, removeFromField: boolean = false): Promise<void> {
/**
* Causes this mon to leave the field (via {@linkcode leaveField}) and then
* opens the party switcher UI to switch a new mon in
* @param batonPass Indicates if this switch was caused by a baton pass (and
* thus should maintain active mon effects)
*/
switchOut(batonPass: boolean): Promise<void> {
return new Promise(resolve => {
this.resetTurnData();
if (!batonPass) {
this.resetSummonData();
}
this.hideInfo();
this.setVisible(false);
this.leaveField(!batonPass);
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.FAINT_SWITCH, this.getFieldIndex(), (slotIndex: integer, option: PartyOption) => {
if (slotIndex >= this.scene.currentBattle.getBattlerCount() && slotIndex < 6) {
this.scene.prependToPhase(new SwitchSummonPhase(this.scene, this.getFieldIndex(), slotIndex, false, batonPass), MoveEndPhase);
}
if (removeFromField) {
this.setVisible(false);
this.scene.field.remove(this);
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);
}
this.scene.ui.setMode(Mode.MESSAGE).then(() => resolve());
this.scene.ui.setMode(Mode.MESSAGE).then(resolve);
}, PartyUiHandler.FilterNonFainted);
});
}

View File

@ -1392,10 +1392,7 @@ export class SummonPhase extends PartyMemberPokemonPhase {
// First check if they're somehow still in play, if so remove them.
if (partyMember.isOnField()) {
partyMember.hideInfo();
partyMember.setVisible(false);
this.scene.field.remove(partyMember);
this.scene.triggerPokemonFormChange(partyMember, SpeciesFormChangeActiveTrigger, true);
partyMember.leaveField();
}
const party = this.getParty();
@ -1611,7 +1608,7 @@ export class SwitchSummonPhase extends SummonPhase {
})
);
this.scene.playSound("pb_rel");
pokemon.hideInfo();
pokemon.hideInfo(); // this is also done by pokemon.leaveField(), but needs to go earlier for animation purposes
pokemon.tint(getPokeballTintColor(pokemon.pokeball), 1, 250, "Sine.easeIn");
this.scene.tweens.add({
targets: pokemon,
@ -1619,9 +1616,9 @@ export class SwitchSummonPhase extends SummonPhase {
ease: "Sine.easeIn",
scale: 0.5,
onComplete: () => {
pokemon.setVisible(false);
this.scene.field.remove(pokemon);
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
// 250ms delay on leaveField is necessary to avoid calling hideInfo() twice
// and double-animating the stats panel slideout
this.scene.time.delayedCall(250, () => pokemon.leaveField(!this.batonPass));
this.scene.time.delayedCall(750, () => this.switchAndSummon());
}
});
@ -1629,25 +1626,25 @@ export class SwitchSummonPhase extends SummonPhase {
switchAndSummon() {
const party = this.player ? this.getParty() : this.scene.getEnemyParty();
const switchedPokemon = party[this.slotIndex];
const switchedInPokemon = party[this.slotIndex];
this.lastPokemon = this.getPokemon();
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, this.lastPokemon);
if (this.batonPass && switchedPokemon) {
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedPokemon.id));
if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
if (this.batonPass && switchedInPokemon) {
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedInPokemon.id));
if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id)) {
const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier
&& (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier;
if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false);
if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id)) {
this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedInPokemon, false);
}
}
}
if (switchedPokemon) {
if (switchedInPokemon) {
party[this.slotIndex] = this.lastPokemon;
party[this.fieldIndex] = switchedPokemon;
party[this.fieldIndex] = switchedInPokemon;
const showTextAndSummon = () => {
this.scene.ui.showText(this.player ?
i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(switchedPokemon) }) :
i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(switchedInPokemon) }) :
i18next.t("battle:trainerGo", {
trainerName: this.scene.currentBattle.trainer.getName(!(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER),
pokemonName: this.getPokemon().getNameToRender()
@ -1655,8 +1652,8 @@ export class SwitchSummonPhase extends SummonPhase {
);
// Ensure improperly persisted summon data (such as tags) is cleared upon switching
if (!this.batonPass) {
party[this.fieldIndex].resetBattleData();
party[this.fieldIndex].resetSummonData();
switchedInPokemon.resetBattleData();
switchedInPokemon.resetSummonData();
}
this.summon();
};
@ -1876,14 +1873,11 @@ export class TurnInitPhase extends FieldPhase {
this.scene.unshiftPhase(new GameOverPhase(this.scene));
} else if (allowedPokemon.length >= this.scene.currentBattle.getBattlerCount() || (this.scene.currentBattle.double && !allowedPokemon[0].isActive(true))) {
// If there is at least one pokemon in the back that is legal to switch in, force a switch.
p.switchOut(false, true);
p.switchOut(false);
} else {
// If there are no pokemon in the back but we're not game overing, just hide the pokemon.
// This should only happen in double battles.
p.hideInfo();
p.setVisible(false);
this.scene.field.remove(p);
this.scene.triggerPokemonFormChange(p, SpeciesFormChangeActiveTrigger, true);
p.leaveField();
}
if (allowedPokemon.length === 1 && this.scene.currentBattle.double) {
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));