mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-01-24 01:41:08 +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)
|
* 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 pokemon Pokemon that has this ability
|
||||||
* @param {boolean} passive N/A
|
* @param passive N/A
|
||||||
* @param {boolean} simulated true if applying in a simulated call.
|
* @param simulated `true` if applying in a simulated call.
|
||||||
* @param {any[]} args N/A
|
* @param args N/A
|
||||||
* @returns {boolean} true if any opponents are sleeping
|
* @returns `true` if any opponents are sleeping
|
||||||
*/
|
*/
|
||||||
applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
||||||
let hadEffect: boolean = false;
|
let hadEffect: boolean = false;
|
||||||
for (const opp of pokemon.getOpponents()) {
|
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) {
|
if (!simulated) {
|
||||||
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
|
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
|
||||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
|
||||||
|
@ -1144,7 +1144,7 @@ class FireGrassPledgeTag extends ArenaTag {
|
|||||||
? arena.scene.getPlayerField()
|
? arena.scene.getPlayerField()
|
||||||
: arena.scene.getEnemyField();
|
: 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!"
|
// "{pokemonNameWithAffix} was hurt by the sea of fire!"
|
||||||
pokemon.scene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
pokemon.scene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||||
// TODO: Replace this with a proper animation
|
// TODO: Replace this with a proper animation
|
||||||
|
@ -1867,7 +1867,7 @@ export class FlameBurstAttr extends MoveEffectAttr {
|
|||||||
applyAbAttrs(BlockNonDirectDamageAbAttr, targetAlly, cancelled);
|
applyAbAttrs(BlockNonDirectDamageAbAttr, targetAlly, cancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cancelled.value || !targetAlly) {
|
if (cancelled.value || !targetAlly || targetAlly.switchOutStatus) {
|
||||||
return false;
|
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 {
|
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);
|
const damagePhase = new DamageAnimPhase(this.scene, this.getBattlerIndex(), damage, result as DamageResult, critical);
|
||||||
this.scene.unshiftPhase(damagePhase);
|
this.scene.unshiftPhase(damagePhase);
|
||||||
|
if (this.switchOutStatus && source) {
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
damage = this.damage(damage, ignoreSegments, preventEndure, ignoreFaintPhase);
|
damage = this.damage(damage, ignoreSegments, preventEndure, ignoreFaintPhase);
|
||||||
// Damage amount may have changed, but needed to be queued before calling damage function
|
// Damage amount may have changed, but needed to be queued before calling damage function
|
||||||
damagePhase.updateAmount(damage);
|
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
|
* If the move missed a target, stop all future hits against that target
|
||||||
* and move on to the next target (if there is one).
|
* 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.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) {
|
if (moveHistoryEntry.result === MoveResult.PENDING) {
|
||||||
moveHistoryEntry.result = MoveResult.MISS;
|
moveHistoryEntry.result = MoveResult.MISS;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
|||||||
|
|
||||||
start() {
|
start() {
|
||||||
const pokemon = this.getPokemon();
|
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();
|
pokemon.status.incrementTurn();
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
||||||
|
@ -23,22 +23,24 @@ export class TurnEndPhase extends FieldPhase {
|
|||||||
this.scene.eventTarget.dispatchEvent(new TurnEndEvent(this.scene.currentBattle.turn));
|
this.scene.eventTarget.dispatchEvent(new TurnEndEvent(this.scene.currentBattle.turn));
|
||||||
|
|
||||||
const handlePokemon = (pokemon: Pokemon) => {
|
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()) {
|
if (this.scene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) {
|
||||||
this.scene.unshiftPhase(new PokemonHealPhase(this.scene, pokemon.getBattlerIndex(),
|
this.scene.unshiftPhase(new PokemonHealPhase(this.scene, pokemon.getBattlerIndex(),
|
||||||
Math.max(pokemon.getMaxHp() >> 4, 1), i18next.t("battle:turnEndHpRestore", { pokemonName: getPokemonNameWithAffix(pokemon) }), true));
|
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(TurnStatusEffectModifier, pokemon.isPlayer(), pokemon);
|
||||||
|
|
||||||
this.scene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon);
|
this.scene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon);
|
||||||
|
@ -51,7 +51,7 @@ export class WeatherEffectPhase extends CommonAnimPhase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.executeForAll((pokemon: Pokemon) => {
|
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) {
|
if (!immune) {
|
||||||
inflictDamage(pokemon);
|
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.scene.ui.showText(getWeatherLapseMessage(this.weather.weatherType) ?? "", null, () => {
|
||||||
this.executeForAll((pokemon: Pokemon) => applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather));
|
this.executeForAll((pokemon: Pokemon) => {
|
||||||
|
if (!pokemon.switchOutStatus) {
|
||||||
|
applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
super.start();
|
super.start();
|
||||||
});
|
});
|
||||||
|
@ -632,4 +632,34 @@ describe("Abilities - Wimp Out", () => {
|
|||||||
const hasFled = enemyPokemon.switchOutStatus;
|
const hasFled = enemyPokemon.switchOutStatus;
|
||||||
expect(isVisible && !hasFled).toBe(true);
|
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