[Bug] Fix hard press bp and pp (#2441)
* Fix hard press bp and pp * Hard Press should have a max bp of 100 * Fix typo for acc * Add test
This commit is contained in:
parent
e21b91858b
commit
694616e1e9
|
@ -2961,9 +2961,29 @@ export class HpPowerAttr extends VariablePowerAttr {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute used for moves whose base power scales with the opponent's HP
|
||||
* Used for Crush Grip, Wring Out, and Hard Press
|
||||
* maxBasePower 100 for Hard Press, 120 for others
|
||||
*/
|
||||
export class OpponentHighHpPowerAttr extends VariablePowerAttr {
|
||||
maxBasePower: number;
|
||||
|
||||
constructor(maxBasePower: number) {
|
||||
super();
|
||||
this.maxBasePower = maxBasePower;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the base power of the move to be the target's HP ratio times the maxBasePower with a min value of 1
|
||||
* @param user n/a
|
||||
* @param target the Pokemon being attacked
|
||||
* @param move n/a
|
||||
* @param args holds the base power of the move at args[0]
|
||||
* @returns true
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
(args[0] as Utils.NumberHolder).value = Math.max(Math.floor(120 * target.getHpRatio()), 1);
|
||||
(args[0] as Utils.NumberHolder).value = Math.max(Math.floor(this.maxBasePower * target.getHpRatio()), 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6685,7 +6705,7 @@ export function initMoves() {
|
|||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||
.unimplemented(),
|
||||
new AttackMove(Moves.WRING_OUT, Type.NORMAL, MoveCategory.SPECIAL, -1, 100, 5, -1, 0, 4)
|
||||
.attr(OpponentHighHpPowerAttr)
|
||||
.attr(OpponentHighHpPowerAttr, 120)
|
||||
.makesContact(),
|
||||
new SelfStatusMove(Moves.POWER_TRICK, Type.PSYCHIC, -1, 10, -1, 0, 4)
|
||||
.unimplemented(),
|
||||
|
@ -6909,7 +6929,7 @@ export function initMoves() {
|
|||
.triageMove()
|
||||
.unimplemented(),
|
||||
new AttackMove(Moves.CRUSH_GRIP, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4)
|
||||
.attr(OpponentHighHpPowerAttr),
|
||||
.attr(OpponentHighHpPowerAttr, 120),
|
||||
new AttackMove(Moves.MAGMA_STORM, Type.FIRE, MoveCategory.SPECIAL, 100, 75, 5, -1, 0, 4)
|
||||
.attr(TrapAttr, BattlerTagType.MAGMA_STORM),
|
||||
new StatusMove(Moves.DARK_VOID, Type.DARK, 50, 10, -1, 0, 4)
|
||||
|
@ -8379,8 +8399,8 @@ export function initMoves() {
|
|||
new AttackMove(Moves.TACHYON_CUTTER, Type.STEEL, MoveCategory.SPECIAL, 50, -1, 10, -1, 0, 9)
|
||||
.attr(MultiHitAttr, MultiHitType._2)
|
||||
.slicingMove(),
|
||||
new AttackMove(Moves.HARD_PRESS, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9)
|
||||
.attr(OpponentHighHpPowerAttr),
|
||||
new AttackMove(Moves.HARD_PRESS, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9)
|
||||
.attr(OpponentHighHpPowerAttr, 100),
|
||||
new StatusMove(Moves.DRAGON_CHEER, Type.DRAGON, -1, 15, -1, 0, 9)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.CRIT_BOOST, false, true)
|
||||
.target(MoveTarget.NEAR_ALLY)
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import Phaser from "phaser";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import * as overrides from "#app/overrides";
|
||||
import { Species } from "#enums/species";
|
||||
import {
|
||||
MoveEffectPhase,
|
||||
} from "#app/phases";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { NumberHolder } from "#app/utils.js";
|
||||
import Move from "#app/data/move.js";
|
||||
import Pokemon from "#app/field/pokemon.js";
|
||||
import { allMoves, OpponentHighHpPowerAttr } from "#app/data/move.js";
|
||||
|
||||
describe("Moves - Hard Press", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX);
|
||||
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE);
|
||||
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HARD_PRESS]);
|
||||
});
|
||||
|
||||
it("power varies between 1 and 100, and is greater the more HP the target has", async () => {
|
||||
await game.startBattle([Species.GRAVELER]);
|
||||
const moveToBeUsed = allMoves[Moves.HARD_PRESS];
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, moveToBeUsed));
|
||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||
|
||||
const enemy = game.scene.getEnemyPokemon();
|
||||
const movePower = getMockedMovePower(enemy, game.scene.getPlayerPokemon(), moveToBeUsed);
|
||||
const moveMaxBasePower = getMoveMaxBasePower(moveToBeUsed);
|
||||
|
||||
expect(movePower).toBe(moveMaxBasePower * enemy.getHpRatio());
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Calculates the mocked move power based on the attributes of the move and the opponent's high HP.
|
||||
*
|
||||
* @param defender - The defending Pokémon.
|
||||
* @param attacker - The attacking Pokémon.
|
||||
* @param move - The move being used.
|
||||
* @returns The calculated move power.
|
||||
*/
|
||||
const getMockedMovePower = (defender: Pokemon, attacker: Pokemon, move: Move) => {
|
||||
const powerHolder = new NumberHolder(move.power);
|
||||
|
||||
if (move.hasAttr(OpponentHighHpPowerAttr)) {
|
||||
const attr = move.getAttrs(OpponentHighHpPowerAttr);
|
||||
attr[0].apply(attacker, defender, move, [ powerHolder ]);
|
||||
}
|
||||
|
||||
return powerHolder.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the maximum base power of a move based on its attributes.
|
||||
*
|
||||
* @param move - The move which maximum base power is being retrieved.
|
||||
* @returns The maximum base power of the move.
|
||||
*/
|
||||
const getMoveMaxBasePower = (move: Move) => {
|
||||
const attr = move.getAttrs(OpponentHighHpPowerAttr);
|
||||
|
||||
return (attr[0] as OpponentHighHpPowerAttr)["maxBasePower"];
|
||||
};
|
Loading…
Reference in New Issue