mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-01-23 17:31:10 +00:00
[Bug] Prevent battle skip with Wimp Out (#4931)
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com> Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Co-authored-by: Moka <54149968+MokaStitcher@users.noreply.github.com>
This commit is contained in:
parent
d1294caeb6
commit
5af2bcd5ec
@ -3720,16 +3720,16 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
|
||||
|
||||
/**
|
||||
* Deals damage to all sleeping opponents equal to 1/8 of their max hp (min 1)
|
||||
* @param {Pokemon} pokemon Pokemon that has this ability
|
||||
* @param {boolean} passive N/A
|
||||
* @param {boolean} simulated true if applying in a simulated call.
|
||||
* @param {any[]} args N/A
|
||||
* @returns {boolean} true if any opponents are sleeping
|
||||
* @param pokemon Pokemon that has this ability
|
||||
* @param passive N/A
|
||||
* @param simulated `true` if applying in a simulated call.
|
||||
* @param args N/A
|
||||
* @returns `true` if any opponents are sleeping
|
||||
*/
|
||||
applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
||||
let hadEffect: boolean = false;
|
||||
for (const opp of pokemon.getOpponents()) {
|
||||
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
||||
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !opp.switchOutStatus) {
|
||||
if (!simulated) {
|
||||
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
|
||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
|
||||
|
@ -1144,7 +1144,7 @@ class FireGrassPledgeTag extends ArenaTag {
|
||||
? arena.scene.getPlayerField()
|
||||
: arena.scene.getEnemyField();
|
||||
|
||||
field.filter(pokemon => !pokemon.isOfType(Type.FIRE)).forEach(pokemon => {
|
||||
field.filter(pokemon => !pokemon.isOfType(Type.FIRE) && !pokemon.switchOutStatus).forEach(pokemon => {
|
||||
// "{pokemonNameWithAffix} was hurt by the sea of fire!"
|
||||
pokemon.scene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
// TODO: Replace this with a proper animation
|
||||
|
@ -1867,7 +1867,7 @@ export class FlameBurstAttr extends MoveEffectAttr {
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, targetAlly, cancelled);
|
||||
}
|
||||
|
||||
if (cancelled.value || !targetAlly) {
|
||||
if (cancelled.value || !targetAlly || targetAlly.switchOutStatus) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3007,6 +3007,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
damageAndUpdate(damage: integer, result?: DamageResult, critical: boolean = false, ignoreSegments: boolean = false, preventEndure: boolean = false, ignoreFaintPhase: boolean = false, source?: Pokemon): integer {
|
||||
const damagePhase = new DamageAnimPhase(this.scene, this.getBattlerIndex(), damage, result as DamageResult, critical);
|
||||
this.scene.unshiftPhase(damagePhase);
|
||||
if (this.switchOutStatus && source) {
|
||||
damage = 0;
|
||||
}
|
||||
damage = this.damage(damage, ignoreSegments, preventEndure, ignoreFaintPhase);
|
||||
// Damage amount may have changed, but needed to be queued before calling damage function
|
||||
damagePhase.updateAmount(damage);
|
||||
|
@ -228,9 +228,11 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
* If the move missed a target, stop all future hits against that target
|
||||
* and move on to the next target (if there is one).
|
||||
*/
|
||||
if (isCommanding || (!isImmune && !isProtected && !targetHitChecks[target.getBattlerIndex()])) {
|
||||
if (target.switchOutStatus || isCommanding || (!isImmune && !isProtected && !targetHitChecks[target.getBattlerIndex()])) {
|
||||
this.stopMultiHit(target);
|
||||
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
|
||||
if (!target.switchOutStatus) {
|
||||
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
|
||||
}
|
||||
if (moveHistoryEntry.result === MoveResult.PENDING) {
|
||||
moveHistoryEntry.result = MoveResult.MISS;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
||||
|
||||
start() {
|
||||
const pokemon = this.getPokemon();
|
||||
if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn()) {
|
||||
if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn() && !pokemon.switchOutStatus) {
|
||||
pokemon.status.incrementTurn();
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
||||
|
@ -23,22 +23,24 @@ export class TurnEndPhase extends FieldPhase {
|
||||
this.scene.eventTarget.dispatchEvent(new TurnEndEvent(this.scene.currentBattle.turn));
|
||||
|
||||
const handlePokemon = (pokemon: Pokemon) => {
|
||||
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
|
||||
if (!pokemon.switchOutStatus) {
|
||||
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
|
||||
|
||||
this.scene.applyModifiers(TurnHealModifier, pokemon.isPlayer(), pokemon);
|
||||
this.scene.applyModifiers(TurnHealModifier, pokemon.isPlayer(), pokemon);
|
||||
|
||||
if (this.scene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) {
|
||||
this.scene.unshiftPhase(new PokemonHealPhase(this.scene, pokemon.getBattlerIndex(),
|
||||
Math.max(pokemon.getMaxHp() >> 4, 1), i18next.t("battle:turnEndHpRestore", { pokemonName: getPokemonNameWithAffix(pokemon) }), true));
|
||||
if (this.scene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) {
|
||||
this.scene.unshiftPhase(new PokemonHealPhase(this.scene, pokemon.getBattlerIndex(),
|
||||
Math.max(pokemon.getMaxHp() >> 4, 1), i18next.t("battle:turnEndHpRestore", { pokemonName: getPokemonNameWithAffix(pokemon) }), true));
|
||||
}
|
||||
|
||||
if (!pokemon.isPlayer()) {
|
||||
this.scene.applyModifiers(EnemyTurnHealModifier, false, pokemon);
|
||||
this.scene.applyModifier(EnemyStatusEffectHealChanceModifier, false, pokemon);
|
||||
}
|
||||
|
||||
applyPostTurnAbAttrs(PostTurnAbAttr, pokemon);
|
||||
}
|
||||
|
||||
if (!pokemon.isPlayer()) {
|
||||
this.scene.applyModifiers(EnemyTurnHealModifier, false, pokemon);
|
||||
this.scene.applyModifier(EnemyStatusEffectHealChanceModifier, false, pokemon);
|
||||
}
|
||||
|
||||
applyPostTurnAbAttrs(PostTurnAbAttr, pokemon);
|
||||
|
||||
this.scene.applyModifiers(TurnStatusEffectModifier, pokemon.isPlayer(), pokemon);
|
||||
|
||||
this.scene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon);
|
||||
|
@ -51,7 +51,7 @@ export class WeatherEffectPhase extends CommonAnimPhase {
|
||||
};
|
||||
|
||||
this.executeForAll((pokemon: Pokemon) => {
|
||||
const immune = !pokemon || !!pokemon.getTypes(true, true).filter(t => this.weather?.isTypeDamageImmune(t)).length;
|
||||
const immune = !pokemon || !!pokemon.getTypes(true, true).filter(t => this.weather?.isTypeDamageImmune(t)).length || pokemon.switchOutStatus;
|
||||
if (!immune) {
|
||||
inflictDamage(pokemon);
|
||||
}
|
||||
@ -59,8 +59,12 @@ export class WeatherEffectPhase extends CommonAnimPhase {
|
||||
}
|
||||
}
|
||||
|
||||
this.scene.ui.showText(getWeatherLapseMessage(this.weather.weatherType)!, null, () => { // TODO: is this bang correct?
|
||||
this.executeForAll((pokemon: Pokemon) => applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather));
|
||||
this.scene.ui.showText(getWeatherLapseMessage(this.weather.weatherType) ?? "", null, () => {
|
||||
this.executeForAll((pokemon: Pokemon) => {
|
||||
if (!pokemon.switchOutStatus) {
|
||||
applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather);
|
||||
}
|
||||
});
|
||||
|
||||
super.start();
|
||||
});
|
||||
|
@ -632,4 +632,34 @@ describe("Abilities - Wimp Out", () => {
|
||||
const hasFled = enemyPokemon.switchOutStatus;
|
||||
expect(isVisible && !hasFled).toBe(true);
|
||||
});
|
||||
it("wimp out will not skip battles when triggered in a double battle", async () => {
|
||||
const wave = 2;
|
||||
game.override
|
||||
.enemyMoveset(Moves.SPLASH)
|
||||
.enemySpecies(Species.WIMPOD)
|
||||
.enemyAbility(Abilities.WIMP_OUT)
|
||||
.moveset([ Moves.MATCHA_GOTCHA, Moves.FALSE_SWIPE ])
|
||||
.startingLevel(50)
|
||||
.enemyLevel(1)
|
||||
.battleType("double")
|
||||
.startingWave(wave);
|
||||
await game.classicMode.startBattle([
|
||||
Species.RAICHU,
|
||||
Species.PIKACHU
|
||||
]);
|
||||
const [ wimpod0, wimpod1 ] = game.scene.getEnemyField();
|
||||
|
||||
game.move.select(Moves.FALSE_SWIPE, 0, BattlerIndex.ENEMY);
|
||||
game.move.select(Moves.MATCHA_GOTCHA, 1);
|
||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
expect(wimpod0.hp).toBeGreaterThan(0);
|
||||
expect(wimpod0.switchOutStatus).toBe(true);
|
||||
expect(wimpod0.isFainted()).toBe(false);
|
||||
expect(wimpod1.isFainted()).toBe(true);
|
||||
|
||||
await game.toNextWave();
|
||||
expect(game.scene.currentBattle.waveIndex).toBe(wave + 1);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user