mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-07 08:52:17 +02:00
Implemented safeguard and tests
This commit is contained in:
parent
b794662776
commit
0692ef4fe7
@ -844,7 +844,30 @@ class HappyHourTag extends ArenaTag {
|
||||
}
|
||||
}
|
||||
|
||||
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null {
|
||||
class SafegaurdTag extends ArenaTag {
|
||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
||||
super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side);
|
||||
}
|
||||
|
||||
onAdd(arena: Arena): void {
|
||||
if (this.side === ArenaTagSide.PLAYER) {
|
||||
arena.scene.queueMessage("Your team cloaked itself in a mystical veil!");
|
||||
} else {
|
||||
arena.scene.queueMessage("Enemy team cloaked itself in a mystical veil!");
|
||||
}
|
||||
}
|
||||
|
||||
onRemove(arena: Arena): void {
|
||||
if (this.side === ArenaTagSide.PLAYER) {
|
||||
arena.scene.queueMessage("Your team is not longer protected by the mystical veil!");
|
||||
} else {
|
||||
arena.scene.queueMessage("Enemy team is not longer protected by the mystical veil!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag {
|
||||
switch (tagType) {
|
||||
case ArenaTagType.MIST:
|
||||
return new MistTag(turnCount, sourceId, side);
|
||||
@ -889,6 +912,8 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
||||
return new TailwindTag(turnCount, sourceId, side);
|
||||
case ArenaTagType.HAPPY_HOUR:
|
||||
return new HappyHourTag(turnCount, sourceId, side);
|
||||
case ArenaTagType.SAFEGUARD:
|
||||
return new SafegaurdTag(turnCount, sourceId, side);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { BattleStat, getBattleStatName } from "./battle-stat";
|
||||
import { EncoreTag, GulpMissileTag, HelpingHandTag, SemiInvulnerableTag, StockpilingTag, 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";
|
||||
@ -1918,6 +1918,7 @@ export class StatusEffectAttr extends MoveEffectAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
|
||||
const statusCheck = moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance;
|
||||
const targetSide = target instanceof EnemyPokemon ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER;
|
||||
if (statusCheck) {
|
||||
const pokemon = this.selfTarget ? user : target;
|
||||
if (pokemon.status) {
|
||||
@ -1927,6 +1928,16 @@ export class StatusEffectAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (user.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, targetSide)) {
|
||||
if (move.category === MoveCategory.STATUS) {
|
||||
user.scene.pushPhase(
|
||||
new MessagePhase(user.scene,
|
||||
`${target.name} is protected by Safeguard!`,
|
||||
0, false, 0), false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ((!pokemon.status || (pokemon.status.effect === this.effect && moveChance < 0))
|
||||
&& pokemon.trySetStatus(this.effect, true, user, this.cureTurn)) {
|
||||
applyPostAttackAbAttrs(ConfusionOnStatusEffectAbAttr, user, target, move, null, this.effect);
|
||||
@ -6740,7 +6751,7 @@ export function initMoves() {
|
||||
.attr(FriendshipPowerAttr, true),
|
||||
new StatusMove(Moves.SAFEGUARD, Type.NORMAL, -1, 25, -1, 0, 2)
|
||||
.target(MoveTarget.USER_SIDE)
|
||||
.unimplemented(),
|
||||
.attr(AddArenaTagAttr, ArenaTagType.SAFEGUARD, 5, true, true),
|
||||
new StatusMove(Moves.PAIN_SPLIT, Type.NORMAL, -1, 20, -1, 0, 2)
|
||||
.attr(HpSplitAttr)
|
||||
.condition(failOnBossCondition),
|
||||
|
@ -22,5 +22,6 @@ export enum ArenaTagType {
|
||||
CRAFTY_SHIELD = "CRAFTY_SHIELD",
|
||||
TAILWIND = "TAILWIND",
|
||||
HAPPY_HOUR = "HAPPY_HOUR",
|
||||
SAFEGUARD = "SAFEGUARD",
|
||||
NO_CRIT = "NO_CRIT"
|
||||
}
|
||||
|
124
src/test/moves/safeguard.test.ts
Normal file
124
src/test/moves/safeguard.test.ts
Normal file
@ -0,0 +1,124 @@
|
||||
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 {
|
||||
CommandPhase,
|
||||
SelectTargetPhase,
|
||||
TurnEndPhase,
|
||||
} from "#app/phases";
|
||||
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import { BattlerIndex } from "#app/battle.js";
|
||||
import { Stat } from "#app/data/pokemon-stat";
|
||||
import { ArenaTagType } from "#app/enums/arena-tag-type.js";
|
||||
import { ArenaTagSide } from "#app/data/arena-tag.js";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
const SAFEGUARD = Moves.SAFEGUARD;
|
||||
|
||||
describe("Moves - Safeguard", () => {
|
||||
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.AMOONGUSS);
|
||||
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.DEOXYS);
|
||||
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100);
|
||||
vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100);
|
||||
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPORE, Moves.SPORE, Moves.SPORE, Moves.SPORE]);
|
||||
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SAFEGUARD, Moves.SAFEGUARD, Moves.SAFEGUARD, Moves.SAFEGUARD]);
|
||||
});
|
||||
it("protects from nuzzle status",
|
||||
async () => {
|
||||
|
||||
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SENTRET);
|
||||
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.NUZZLE,
|
||||
Moves.NUZZLE,
|
||||
Moves.NUZZLE,
|
||||
Moves.NUZZLE]);
|
||||
await game.startBattle([Species.DEOXYS]);
|
||||
const enemyPokemon = game.scene.getEnemyField();
|
||||
const playerPokemon = game.scene.getPlayerField();
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, SAFEGUARD));
|
||||
|
||||
expect(enemyPokemon[0].status).toBe(undefined);
|
||||
expect(playerPokemon[0].status).toBe(undefined);
|
||||
}, TIMEOUT
|
||||
);
|
||||
it("protects from spore",
|
||||
async () => {
|
||||
|
||||
await game.startBattle([Species.DEOXYS]);
|
||||
const enemyPokemon = game.scene.getEnemyField();
|
||||
const playerPokemon = game.scene.getPlayerField();
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SAFEGUARD));
|
||||
|
||||
expect(enemyPokemon[0].status).toBe(undefined);
|
||||
expect(playerPokemon[0].status).toBe(undefined);
|
||||
}, TIMEOUT
|
||||
);
|
||||
it("protects ally from status",
|
||||
async () => {
|
||||
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(false);
|
||||
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||
|
||||
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.DEOXYS);
|
||||
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.AMOONGUSS);
|
||||
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SAFEGUARD, Moves.SAFEGUARD, Moves.SAFEGUARD, Moves.SAFEGUARD]);
|
||||
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPORE, Moves.NUZZLE, Moves.SPORE, Moves.SPORE]);
|
||||
|
||||
await game.startBattle([Species.AMOONGUSS, Species.FURRET]);
|
||||
game.scene.currentBattle.enemyParty[1].stats[Stat.SPD] = 1;
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPORE));
|
||||
await game.phaseInterceptor.to(SelectTargetPhase, false);
|
||||
game.doSelectTarget(BattlerIndex.ENEMY_2);
|
||||
|
||||
await game.phaseInterceptor.to(CommandPhase);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 1, Moves.NUZZLE));
|
||||
await game.phaseInterceptor.to(SelectTargetPhase, false);
|
||||
game.doSelectTarget(BattlerIndex.ENEMY_2);
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyField();
|
||||
const playerPokemon = game.scene.getPlayerField();
|
||||
|
||||
expect(enemyPokemon[0].status).toBe(undefined);
|
||||
expect(enemyPokemon[1].status).toBe(undefined);
|
||||
expect(playerPokemon[0].status).toBe(undefined);
|
||||
expect(playerPokemon[1].status).toBe(undefined);
|
||||
}, TIMEOUT
|
||||
);
|
||||
it("applys arena tag for 5 turns",
|
||||
async () => {
|
||||
|
||||
await game.startBattle([Species.DEOXYS]);
|
||||
|
||||
for (let i=0;i<5;i++) {
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SAFEGUARD));
|
||||
await game.phaseInterceptor.to(CommandPhase);
|
||||
}
|
||||
|
||||
expect(game.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, ArenaTagSide.PLAYER)).toBeUndefined();
|
||||
}, TIMEOUT
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue
Block a user