mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-21 14:59:26 +02:00
fulling implementing forests curse and trick or treat with edge cases
This commit is contained in:
parent
f7797603a1
commit
4251d5c919
@ -5873,16 +5873,29 @@ export class AddTypeAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
constructor(type: Type) {
|
constructor(type: Type) {
|
||||||
super(false, MoveEffectTrigger.HIT);
|
super(false, MoveEffectTrigger.HIT);
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const types = target.getTypes().slice(0, 2).filter(t => t !== Type.UNKNOWN); // TODO: Figure out some way to actually check if another version of this effect is already applied
|
let currentTypes = target.getTypes().slice(0, 2).filter(t => t !== Type.UNKNOWN) as Type[];
|
||||||
if (this.type !== Type.UNKNOWN) {
|
const baseTypes = target.getTypes(false, false, true);
|
||||||
types.push(this.type);
|
const forestsCurseApplied: boolean = currentTypes.includes(Type.GRASS) && !baseTypes.includes(Type.GRASS);
|
||||||
|
const trickOrTreatApplied: boolean = currentTypes.includes(Type.GHOST) && !baseTypes.includes(Type.GHOST);
|
||||||
|
|
||||||
|
if (move.id === Moves.TRICK_OR_TREAT && forestsCurseApplied) {
|
||||||
|
// Has extra grass type, remove that and append ghost type
|
||||||
|
currentTypes = currentTypes.filter(type => type !== Type.GRASS);
|
||||||
|
currentTypes.push(this.type);
|
||||||
|
} else if (move.id === Moves.FORESTS_CURSE && trickOrTreatApplied) {
|
||||||
|
// Has extra ghost type, remove that and append grass type
|
||||||
|
currentTypes = currentTypes.filter(type => type !== Type.GHOST);
|
||||||
|
currentTypes.push(this.type);
|
||||||
|
} else if (this.type !== Type.UNKNOWN) {
|
||||||
|
currentTypes = currentTypes;
|
||||||
|
currentTypes.push(this.type);
|
||||||
}
|
}
|
||||||
target.summonData.types = types;
|
|
||||||
|
target.summonData.types = currentTypes;
|
||||||
target.updateInfo();
|
target.updateInfo();
|
||||||
|
|
||||||
user.scene.queueMessage(i18next.t("moveTriggers:addType", { typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`), pokemonName: getPokemonNameWithAffix(target) }));
|
user.scene.queueMessage(i18next.t("moveTriggers:addType", { typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`), pokemonName: getPokemonNameWithAffix(target) }));
|
||||||
@ -8877,8 +8890,7 @@ export function initMoves() {
|
|||||||
.ignoresProtect()
|
.ignoresProtect()
|
||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
new StatusMove(Moves.TRICK_OR_TREAT, Type.GHOST, 100, 20, -1, 0, 6)
|
new StatusMove(Moves.TRICK_OR_TREAT, Type.GHOST, 100, 20, -1, 0, 6)
|
||||||
.attr(AddTypeAttr, Type.GHOST)
|
.attr(AddTypeAttr, Type.GHOST),
|
||||||
.edgeCase(), // Weird interaction with Forest's Curse, reflect type, burn up
|
|
||||||
new StatusMove(Moves.NOBLE_ROAR, Type.NORMAL, 100, 30, -1, 0, 6)
|
new StatusMove(Moves.NOBLE_ROAR, Type.NORMAL, 100, 30, -1, 0, 6)
|
||||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1)
|
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1)
|
||||||
.soundBased(),
|
.soundBased(),
|
||||||
@ -8890,8 +8902,7 @@ export function initMoves() {
|
|||||||
.target(MoveTarget.ALL_NEAR_OTHERS)
|
.target(MoveTarget.ALL_NEAR_OTHERS)
|
||||||
.triageMove(),
|
.triageMove(),
|
||||||
new StatusMove(Moves.FORESTS_CURSE, Type.GRASS, 100, 20, -1, 0, 6)
|
new StatusMove(Moves.FORESTS_CURSE, Type.GRASS, 100, 20, -1, 0, 6)
|
||||||
.attr(AddTypeAttr, Type.GRASS)
|
.attr(AddTypeAttr, Type.GRASS),
|
||||||
.edgeCase(), // Weird interaction with Trick or Treat, reflect type, burn up
|
|
||||||
new AttackMove(Moves.PETAL_BLIZZARD, Type.GRASS, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 6)
|
new AttackMove(Moves.PETAL_BLIZZARD, Type.GRASS, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 6)
|
||||||
.windMove()
|
.windMove()
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
|
87
src/test/moves/forests_curse.test.ts
Normal file
87
src/test/moves/forests_curse.test.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { Type } from "#app/data/type";
|
||||||
|
import { Moves } from "#app/enums/moves";
|
||||||
|
import { Species } from "#app/enums/species";
|
||||||
|
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
|
||||||
|
|
||||||
|
|
||||||
|
describe("Moves - Forest's Curse", () => {
|
||||||
|
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");
|
||||||
|
game.override.enemySpecies(Species.RELICANTH);
|
||||||
|
game.override.startingLevel(5);
|
||||||
|
game.override.enemyLevel(100);
|
||||||
|
game.override.enemyMoveset(Moves.FORESTS_CURSE);
|
||||||
|
game.override.moveset([ Moves.SPLASH, Moves.BURN_UP, Moves.DOUBLE_SHOCK ]);
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
"a mono type afflicted with forest's curse should be its type + grass (2 types)",
|
||||||
|
async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.RATTATA ]);
|
||||||
|
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
// Should be normal/grass
|
||||||
|
const playerPokemonTypes = playerPokemon.getTypes();
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.NORMAL)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.GRASS)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.length === 2).toBeTruthy();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"a dual type afflicted with forest's curse should be its dual type + grass (3 types)",
|
||||||
|
async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.MOLTRES ]);
|
||||||
|
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
// Should be flying/fire/grass
|
||||||
|
const playerPokemonTypes = playerPokemon.getTypes();
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.FLYING)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.FIRE)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.GRASS)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.length === 3).toBeTruthy();
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"A fire/flying type that uses burn up, then has forest's curse applied should be flying/grass",
|
||||||
|
async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.MOLTRES ]);
|
||||||
|
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||||
|
game.move.select(Moves.BURN_UP);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
// Should be flying/grass
|
||||||
|
const playerPokemonTypes = playerPokemon.getTypes();
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.FLYING)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.FIRE)).toHaveLength(0);
|
||||||
|
expect(playerPokemonTypes.filter(type => type === Type.GRASS)).toHaveLength(1);
|
||||||
|
expect(playerPokemonTypes.length === 2).toBeTruthy();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user