[Bug] Primal weather no longer persists if last mon dies to indirect damage (#3492)
* Fixed Delta Stream remaining active when last mon dies to indirect damage * Rebasing changes * Linting fix * Combined if statements * Changed params to optional * Added unit test * Apply suggestions from code review * Fix test and remove `.js` from import --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
This commit is contained in:
parent
11d912bad8
commit
8df7422e8f
|
@ -3923,7 +3923,7 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostFaintAbAttr extends AbAttr {
|
export class PostFaintAbAttr extends AbAttr {
|
||||||
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3974,7 +3974,7 @@ export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr {
|
||||||
* @param args N/A
|
* @param args N/A
|
||||||
* @returns {boolean} Returns true if the weather clears, otherwise false.
|
* @returns {boolean} Returns true if the weather clears, otherwise false.
|
||||||
*/
|
*/
|
||||||
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean {
|
||||||
const weatherType = pokemon.scene.arena.weather?.weatherType;
|
const weatherType = pokemon.scene.arena.weather?.weatherType;
|
||||||
let turnOffWeather = false;
|
let turnOffWeather = false;
|
||||||
|
|
||||||
|
@ -4022,8 +4022,8 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
|
||||||
this.damageRatio = damageRatio;
|
this.damageRatio = damageRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
|
if (move !== undefined && attacker !== undefined && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { //If the mon didn't die to indirect damage
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
pokemon.scene.getField(true).map(p => applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled, simulated));
|
pokemon.scene.getField(true).map(p => applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled, simulated));
|
||||||
if (cancelled.value || attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
if (cancelled.value || attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
||||||
|
@ -4052,8 +4052,8 @@ export class PostFaintHPDamageAbAttr extends PostFaintAbAttr {
|
||||||
super ();
|
super ();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean {
|
||||||
if (!simulated) {
|
if (move !== undefined && attacker !== undefined && !simulated) { //If the mon didn't die to indirect damage
|
||||||
const damage = pokemon.turnData.attacksReceived[0].damage;
|
const damage = pokemon.turnData.attacksReceived[0].damage;
|
||||||
attacker.damageAndUpdate((damage), HitResult.OTHER);
|
attacker.damageAndUpdate((damage), HitResult.OTHER);
|
||||||
attacker.turnData.damageTaken += damage;
|
attacker.turnData.damageTaken += damage;
|
||||||
|
@ -4711,7 +4711,7 @@ export function applyPostBattleAbAttrs(attrType: Constructor<PostBattleAbAttr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyPostFaintAbAttrs(attrType: Constructor<PostFaintAbAttr>,
|
export function applyPostFaintAbAttrs(attrType: Constructor<PostFaintAbAttr>,
|
||||||
pokemon: Pokemon, attacker: Pokemon, move: Move, hitResult: HitResult, simulated: boolean = false, ...args: any[]): Promise<void> {
|
pokemon: Pokemon, attacker?: Pokemon, move?: Move, hitResult?: HitResult, simulated: boolean = false, ...args: any[]): Promise<void> {
|
||||||
return applyAbAttrsInternal<PostFaintAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, simulated, attacker, move, hitResult, args), args, false, simulated);
|
return applyAbAttrsInternal<PostFaintAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, simulated, attacker, move, hitResult, args), args, false, simulated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,8 @@ export class FaintPhase extends PokemonPhase {
|
||||||
if (pokemon.turnData?.attacksReceived?.length) {
|
if (pokemon.turnData?.attacksReceived?.length) {
|
||||||
const lastAttack = pokemon.turnData.attacksReceived[0];
|
const lastAttack = pokemon.turnData.attacksReceived[0];
|
||||||
applyPostFaintAbAttrs(PostFaintAbAttr, pokemon, this.scene.getPokemonById(lastAttack.sourceId)!, new PokemonMove(lastAttack.move).getMove(), lastAttack.result); // TODO: is this bang correct?
|
applyPostFaintAbAttrs(PostFaintAbAttr, pokemon, this.scene.getPokemonById(lastAttack.sourceId)!, new PokemonMove(lastAttack.move).getMove(), lastAttack.result); // TODO: is this bang correct?
|
||||||
|
} else { //If killed by indirect damage, apply post-faint abilities without providing a last move
|
||||||
|
applyPostFaintAbAttrs(PostFaintAbAttr, pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
const alivePlayField = this.scene.getField(true);
|
const alivePlayField = this.scene.getField(true);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { allMoves } from "#app/data/move";
|
import { allMoves } from "#app/data/move";
|
||||||
|
import { StatusEffect } from "#app/enums/status-effect";
|
||||||
import { TurnStartPhase } from "#app/phases/turn-start-phase";
|
import { TurnStartPhase } from "#app/phases/turn-start-phase";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
|
@ -33,7 +34,7 @@ describe("Weather - Strong Winds", () => {
|
||||||
it("electric type move is not very effective on Rayquaza", async () => {
|
it("electric type move is not very effective on Rayquaza", async () => {
|
||||||
game.override.enemySpecies(Species.RAYQUAZA);
|
game.override.enemySpecies(Species.RAYQUAZA);
|
||||||
|
|
||||||
await game.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
const pikachu = game.scene.getPlayerPokemon()!;
|
const pikachu = game.scene.getPlayerPokemon()!;
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ describe("Weather - Strong Winds", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("electric type move is neutral for flying type pokemon", async () => {
|
it("electric type move is neutral for flying type pokemon", async () => {
|
||||||
await game.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
const pikachu = game.scene.getPlayerPokemon()!;
|
const pikachu = game.scene.getPlayerPokemon()!;
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ describe("Weather - Strong Winds", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ice type move is neutral for flying type pokemon", async () => {
|
it("ice type move is neutral for flying type pokemon", async () => {
|
||||||
await game.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
const pikachu = game.scene.getPlayerPokemon()!;
|
const pikachu = game.scene.getPlayerPokemon()!;
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ describe("Weather - Strong Winds", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("rock type move is neutral for flying type pokemon", async () => {
|
it("rock type move is neutral for flying type pokemon", async () => {
|
||||||
await game.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
const pikachu = game.scene.getPlayerPokemon()!;
|
const pikachu = game.scene.getPlayerPokemon()!;
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
@ -75,4 +76,18 @@ describe("Weather - Strong Winds", () => {
|
||||||
await game.phaseInterceptor.to(TurnStartPhase);
|
await game.phaseInterceptor.to(TurnStartPhase);
|
||||||
expect(enemy.getAttackTypeEffectiveness(allMoves[Moves.ROCK_SLIDE].type, pikachu)).toBe(1);
|
expect(enemy.getAttackTypeEffectiveness(allMoves[Moves.ROCK_SLIDE].type, pikachu)).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("weather goes away when last trainer pokemon dies to indirect damage", async () => {
|
||||||
|
game.override.enemyStatusEffect(StatusEffect.POISON);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||||
|
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
enemy.hp = 1;
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
|
||||||
|
expect(game.scene.arena.weather?.weatherType).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue