mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-06 08:22:16 +02:00
[Move] Implement Rage
This commit is contained in:
parent
c846f552bb
commit
9e018f4fe4
@ -205,6 +205,24 @@ export class ShellTrapTag extends BattlerTag {
|
||||
}
|
||||
}
|
||||
|
||||
export class RageTag extends BattlerTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.RAGE,[BattlerTagLapseType.MOVE_EFFECT],1,Moves.RAGE);
|
||||
}
|
||||
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
if (lapseType === BattlerTagLapseType.MOVE_EFFECT) {
|
||||
return (pokemon.scene.getCurrentPhase() as MovePhase).move.getMove().id === Moves.RAGE;
|
||||
} else if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene,pokemon.getBattlerIndex(),true,[BattleStat.ATK],1,false));
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:rageOnHit", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)}));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class TrappedTag extends BattlerTag {
|
||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
|
||||
super(tagType, lapseType, turnCount, sourceMove, sourceId);
|
||||
@ -1962,6 +1980,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
||||
case BattlerTagType.GULP_MISSILE_ARROKUDA:
|
||||
case BattlerTagType.GULP_MISSILE_PIKACHU:
|
||||
return new GulpMissileTag(tagType, sourceMove);
|
||||
case BattlerTagType.RAGE:
|
||||
return new RageTag();
|
||||
case BattlerTagType.NONE:
|
||||
default:
|
||||
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||
|
@ -6450,7 +6450,7 @@ export function initMoves() {
|
||||
.attr(StatChangeAttr, BattleStat.SPD, 2, true),
|
||||
new AttackMove(Moves.QUICK_ATTACK, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 30, -1, 1, 1),
|
||||
new AttackMove(Moves.RAGE, Type.NORMAL, MoveCategory.PHYSICAL, 20, 100, 20, -1, 0, 1)
|
||||
.partial(),
|
||||
.attr(AddBattlerTagAttr,BattlerTagType.RAGE,true,false,0,0,false,true),
|
||||
new SelfStatusMove(Moves.TELEPORT, Type.PSYCHIC, -1, 20, -1, -6, 1)
|
||||
.attr(ForceSwitchOutAttr, true)
|
||||
.hidesUser(),
|
||||
|
@ -69,5 +69,6 @@ export enum BattlerTagType {
|
||||
GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA",
|
||||
GULP_MISSILE_PIKACHU = "GULP_MISSILE_PIKACHU",
|
||||
BEAK_BLAST_CHARGING = "BEAK_BLAST_CHARGING",
|
||||
SHELL_TRAP = "SHELL_TRAP"
|
||||
SHELL_TRAP = "SHELL_TRAP",
|
||||
RAGE = "RAGE"
|
||||
}
|
||||
|
@ -70,4 +70,5 @@ export const battlerTags: SimpleTranslationEntries = {
|
||||
"cursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!",
|
||||
"cursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!",
|
||||
"stockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!",
|
||||
"rageOnHit": "{{pokemonNameWithAffix}}'s rage is building"
|
||||
} as const;
|
||||
|
@ -262,6 +262,9 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
if (move.category === MoveCategory.PHYSICAL && user.isPlayer() !== target.isPlayer()) {
|
||||
target.lapseTag(BattlerTagType.SHELL_TRAP);
|
||||
}
|
||||
if (hitResult < HitResult.NO_EFFECT && move.category !== MoveCategory.STATUS) {
|
||||
target.lapseTag(BattlerTagType.RAGE);
|
||||
}
|
||||
if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) {
|
||||
user.scene.applyShuffledModifiers(this.scene, EnemyAttackStatusEffectChanceModifier, false, target);
|
||||
}
|
||||
|
110
src/test/moves/rage.test.ts
Normal file
110
src/test/moves/rage.test.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { Species } from "#enums/species";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import {BattleStat} from "#app/data/battle-stat";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Moves - Rage", () => {
|
||||
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")
|
||||
.ability(Abilities.UNNERVE)
|
||||
.moveset([Moves.RAGE,Moves.SPLASH,Moves.SPORE])
|
||||
.enemyAbility(Abilities.INSOMNIA)
|
||||
.startingLevel(100)
|
||||
.enemyLevel(100);
|
||||
});
|
||||
|
||||
it(
|
||||
"should raise attack if hit after use",
|
||||
async () => {
|
||||
game.override
|
||||
.enemySpecies(Species.SHUCKLE)
|
||||
.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]);
|
||||
await game.startBattle([Species.NINJASK]);
|
||||
|
||||
const leadPokemon = game.scene.getPlayerPokemon()!;
|
||||
|
||||
// Ninjask uses rage, then gets hit, gets atk boost
|
||||
game.doAttack(0);
|
||||
await game.toNextTurn();
|
||||
expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(1);
|
||||
|
||||
}, TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
"should raise ATK if hit before using non-rage option",
|
||||
async () => {
|
||||
game.override
|
||||
.enemySpecies(Species.NINJASK)
|
||||
.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]);
|
||||
await game.startBattle([Species.SHUCKLE]);
|
||||
|
||||
const leadPokemon = game.scene.getPlayerPokemon()!;
|
||||
|
||||
// Ninjask moves first, THEN shuckle uses rage, no ATK boost
|
||||
game.doAttack(0);
|
||||
await game.toNextTurn();
|
||||
expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(0);
|
||||
|
||||
// Shuckle Raged last turn, so when Ninjask hits it, ATK boost despite not using rage this turn
|
||||
game.doAttack(1);
|
||||
await game.toNextTurn();
|
||||
expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(1);
|
||||
}, TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
"should not raise ATK if hit by status move",
|
||||
async () => {
|
||||
game.override
|
||||
.enemySpecies(Species.NINJASK)
|
||||
.enemyMoveset([Moves.RAGE, Moves.RAGE, Moves.RAGE, Moves.RAGE]);
|
||||
await game.startBattle([Species.NINJASK]);
|
||||
|
||||
const leadPokemon = game.scene.getPlayerPokemon()!;
|
||||
|
||||
// Ninjask Rages, then slept. No boost.
|
||||
game.doAttack(2);
|
||||
await game.toNextTurn();
|
||||
expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(0);
|
||||
}, TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
"should not raise ATK if rage has no effect",
|
||||
async () => {
|
||||
game.override
|
||||
.enemySpecies(Species.GASTLY)
|
||||
.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE])
|
||||
.moveset([Moves.RAGE]);
|
||||
await game.startBattle([Species.NINJASK]);
|
||||
|
||||
const leadPokemon = game.scene.getPlayerPokemon()!;
|
||||
|
||||
// Ninjask uses rage, but it has no effect, no ATK boost
|
||||
game.doAttack(0);
|
||||
await game.toNextTurn();
|
||||
expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(0);
|
||||
}, TIMEOUT
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue
Block a user