mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 15:32:18 +02:00
Implement Lash Out
This commit is contained in:
parent
47c95658ae
commit
0b5741ea1b
@ -3,7 +3,7 @@ import { BattleStat, getBattleStatName } from "./battle-stat";
|
||||
import { EncoreTag, GulpMissileTag, HelpingHandTag, SemiInvulnerableTag, ShellTrapTag, StockpilingTag, TrappedTag, TypeBoostTag } from "./battler-tags";
|
||||
import { getPokemonNameWithAffix } from "../messages";
|
||||
import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon";
|
||||
import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects} from "./status-effect";
|
||||
import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects } from "./status-effect";
|
||||
import { getTypeResistances, Type } from "./type";
|
||||
import { Constructor } from "#app/utils";
|
||||
import * as Utils from "../utils";
|
||||
@ -5891,7 +5891,6 @@ export class DestinyBondAttr extends MoveEffectAttr {
|
||||
|
||||
/**
|
||||
* Attribute to apply a battler tag to the target if they have had their stats boosted this turn.
|
||||
*
|
||||
* @extends AddBattlerTagAttr
|
||||
*/
|
||||
export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr {
|
||||
@ -5907,7 +5906,7 @@ export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr {
|
||||
* @returns true
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (target.turnData.battleStatsChange.find(v => v > 0)) {
|
||||
if (target.turnData.battleStatsIncrease) {
|
||||
super.apply(user, target, move, args);
|
||||
}
|
||||
return true;
|
||||
@ -5916,7 +5915,6 @@ export class AddBattlerTagIfBoostedAttr extends AddBattlerTagAttr {
|
||||
|
||||
/**
|
||||
* Attribute to apply a status effect to the target if they have had their stats boosted this turn.
|
||||
*
|
||||
* @extends MoveEffectAttr
|
||||
*/
|
||||
export class StatusIfBoostedAttr extends MoveEffectAttr {
|
||||
@ -5935,7 +5933,7 @@ export class StatusIfBoostedAttr extends MoveEffectAttr {
|
||||
* @returns true
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (target.turnData.battleStatsChange.find(v => v > 0)) {
|
||||
if (target.turnData.battleStatsIncrease) {
|
||||
target.trySetStatus(this.effect, true, user);
|
||||
}
|
||||
return true;
|
||||
@ -8573,7 +8571,7 @@ export function initMoves() {
|
||||
.attr(StatusIfBoostedAttr, StatusEffect.BURN)
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
new AttackMove(Moves.LASH_OUT, Type.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8)
|
||||
.partial(),
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.turnData.battleStatsDecrease ? 2 : 1),
|
||||
new AttackMove(Moves.POLTERGEIST, Type.GHOST, MoveCategory.PHYSICAL, 110, 90, 5, -1, 0, 8)
|
||||
.attr(AttackedByItemAttr)
|
||||
.makesContact(false),
|
||||
|
@ -4278,7 +4278,8 @@ export class PokemonTurnData {
|
||||
public damageTaken: number = 0;
|
||||
public attacksReceived: AttackMoveResult[] = [];
|
||||
public order: number;
|
||||
public battleStatsChange: number[] = [0, 0, 0, 0, 0, 0, 0];
|
||||
public battleStatsIncrease: boolean = false;
|
||||
public battleStatsDecrease: boolean = false;
|
||||
}
|
||||
|
||||
export enum AiType {
|
||||
|
@ -72,7 +72,7 @@ export class StatChangePhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
const battleStats = this.getPokemon().summonData.battleStats;
|
||||
const relLevels = filteredStats.map(stat => (levels.value >= 1 ? Math.min(battleStats![stat] + levels.value, 6) : Math.max(battleStats![stat] + levels.value, -6)) - battleStats![stat]);
|
||||
const relLevels = filteredStats.map(stat => (levels.value >= 1 ? Math.min(battleStats[stat] + levels.value, 6) : Math.max(battleStats[stat] + levels.value, -6)) - battleStats[stat]);
|
||||
|
||||
this.onChange && this.onChange(this.getPokemon(), filteredStats, relLevels);
|
||||
|
||||
@ -85,12 +85,18 @@ export class StatChangePhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
for (const stat of filteredStats) {
|
||||
if (levels.value > 0 && pokemon.summonData.battleStats[stat] + levels.value <= 6) {
|
||||
if (levels.value > 0 && pokemon.summonData.battleStats[stat] < 6) {
|
||||
if (!pokemon.turnData) {
|
||||
// Temporary fix for missing turn data struct on turn 1
|
||||
pokemon.resetTurnData();
|
||||
}
|
||||
pokemon.turnData.battleStatsChange[stat] += levels.value;
|
||||
pokemon.turnData.battleStatsIncrease = true;
|
||||
} else if (levels.value < 0 && pokemon.summonData.battleStats[stat] > -6) {
|
||||
if (!pokemon.turnData) {
|
||||
// Temporary fix for missing turn data struct on turn 1
|
||||
pokemon.resetTurnData();
|
||||
}
|
||||
pokemon.turnData.battleStatsDecrease = true;
|
||||
}
|
||||
|
||||
pokemon.summonData.battleStats[stat] = Math.max(Math.min(pokemon.summonData.battleStats[stat] + levels.value, 6), -6);
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { StatusEffect } from "#app/enums/status-effect";
|
||||
import { BerryPhase } from "#app/phases/berry-phase";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { getMovePosition } from "#test/utils/gameManagerUtils";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
@ -37,7 +38,7 @@ describe("Moves - Burning Jealousy", () => {
|
||||
.enemyLevel(10)
|
||||
.starterSpecies(Species.FEEBAS)
|
||||
.ability(Abilities.BALL_FETCH)
|
||||
.moveset([Moves.BURNING_JEALOUSY]);
|
||||
.moveset([Moves.BURNING_JEALOUSY, Moves.GROWL]);
|
||||
|
||||
});
|
||||
|
||||
@ -48,8 +49,56 @@ describe("Moves - Burning Jealousy", () => {
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.BURNING_JEALOUSY));
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to(BerryPhase);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
expect(enemy.status?.effect).toBe(StatusEffect.BURN);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should still burn the opponent if their stats were both raised and lowered in the same turn", async () => {
|
||||
game.override
|
||||
.starterSpecies(0)
|
||||
.battleType("double");
|
||||
await game.startBattle([Species.FEEBAS, Species.ABRA]);
|
||||
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.BURNING_JEALOUSY));
|
||||
game.doAttack(getMovePosition(game.scene, 1, Moves.GROWL));
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
expect(enemy.status?.effect).toBe(StatusEffect.BURN);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should ignore stats raised by imposter", async () => {
|
||||
game.override
|
||||
.enemySpecies(Species.DITTO)
|
||||
.enemyAbility(Abilities.IMPOSTER)
|
||||
.enemyMoveset(SPLASH_ONLY);
|
||||
await game.startBattle();
|
||||
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.BURNING_JEALOUSY));
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
expect(enemy.status?.effect).toBeUndefined();
|
||||
}, TIMEOUT);
|
||||
|
||||
it.skip("should ignore weakness policy", async () => { // TODO: Make this test if WP is implemented
|
||||
await game.startBattle();
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should be boosted by Sheer Force even if opponent didn't raise stats", async () => {
|
||||
game.override
|
||||
.ability(Abilities.SHEER_FORCE)
|
||||
.enemyMoveset(SPLASH_ONLY);
|
||||
vi.spyOn(allMoves[Moves.BURNING_JEALOUSY], "calculateBattlePower");
|
||||
await game.startBattle();
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.BURNING_JEALOUSY));
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
expect(allMoves[Moves.BURNING_JEALOUSY].calculateBattlePower).toHaveReturnedWith(allMoves[Moves.BURNING_JEALOUSY].power * 5461 / 4096);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
53
src/test/moves/lash_out.test.ts
Normal file
53
src/test/moves/lash_out.test.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { getMovePosition } from "#test/utils/gameManagerUtils";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Moves - Burning Jealousy", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.battleType("single")
|
||||
.disableCrits()
|
||||
.enemySpecies(Species.MAGIKARP)
|
||||
.enemyAbility(Abilities.FUR_COAT)
|
||||
.enemyMoveset(Array(4).fill(Moves.GROWL))
|
||||
.startingLevel(10)
|
||||
.enemyLevel(10)
|
||||
.starterSpecies(Species.FEEBAS)
|
||||
.ability(Abilities.BALL_FETCH)
|
||||
.moveset([Moves.LASH_OUT]);
|
||||
|
||||
});
|
||||
|
||||
it("should deal double damage if the user's stats were lowered this turn", async () => {
|
||||
vi.spyOn(allMoves[Moves.LASH_OUT], "calculateBattlePower");
|
||||
await game.startBattle();
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.LASH_OUT));
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
expect(allMoves[Moves.LASH_OUT].calculateBattlePower).toHaveReturnedWith(150);
|
||||
}, TIMEOUT);
|
||||
});
|
Loading…
Reference in New Issue
Block a user