[Move] Fully Implement Plasma Fists (#4446)
* Implement Plasma Fists * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json * Update arena-tag.json --------- Co-authored-by: Lugiad <adrien.grivel@hotmail.fr>
This commit is contained in:
parent
d8ee8ad821
commit
1bae87fa56
|
@ -511,6 +511,39 @@ class WaterSportTag extends WeakenMoveTypeTag {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Arena Tag class for the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}.
|
||||
* Converts Normal-type moves to Electric type for the rest of the turn.
|
||||
*/
|
||||
export class PlasmaFistsTag extends ArenaTag {
|
||||
constructor() {
|
||||
super(ArenaTagType.PLASMA_FISTS, 1, Moves.PLASMA_FISTS);
|
||||
}
|
||||
|
||||
/** Queues Plasma Fists' on-add message */
|
||||
onAdd(arena: Arena): void {
|
||||
arena.scene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
|
||||
}
|
||||
|
||||
onRemove(arena: Arena): void { } // Removes default on-remove message
|
||||
|
||||
/**
|
||||
* Converts Normal-type moves to Electric type
|
||||
* @param arena n/a
|
||||
* @param args
|
||||
* - `[0]` {@linkcode Utils.NumberHolder} A container with a move's {@linkcode Type}
|
||||
* @returns `true` if the given move type changed; `false` otherwise.
|
||||
*/
|
||||
apply(arena: Arena, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (moveType instanceof Utils.NumberHolder && moveType.value === Type.NORMAL) {
|
||||
moveType.value = Type.ELECTRIC;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class to implement arena traps.
|
||||
*/
|
||||
|
@ -1010,6 +1043,8 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
|||
return new MudSportTag(turnCount, sourceId);
|
||||
case ArenaTagType.WATER_SPORT:
|
||||
return new WaterSportTag(turnCount, sourceId);
|
||||
case ArenaTagType.PLASMA_FISTS:
|
||||
return new PlasmaFistsTag();
|
||||
case ArenaTagType.SPIKES:
|
||||
return new SpikesTag(sourceId, side);
|
||||
case ArenaTagType.TOXIC_SPIKES:
|
||||
|
|
|
@ -8906,8 +8906,8 @@ export function initMoves() {
|
|||
.attr(HalfSacrificialAttr)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||
new AttackMove(Moves.PLASMA_FISTS, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 15, -1, 0, 7)
|
||||
.punchingMove()
|
||||
.partial(),
|
||||
.attr(AddArenaTagAttr, ArenaTagType.PLASMA_FISTS, 1)
|
||||
.punchingMove(),
|
||||
new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
|
||||
.attr(PhotonGeyserCategoryAttr)
|
||||
.ignoresAbilities()
|
||||
|
|
|
@ -25,4 +25,5 @@ export enum ArenaTagType {
|
|||
SAFEGUARD = "SAFEGUARD",
|
||||
NO_CRIT = "NO_CRIT",
|
||||
IMPRISON = "IMPRISON",
|
||||
PLASMA_FISTS = "PLASMA_FISTS",
|
||||
}
|
||||
|
|
|
@ -1518,6 +1518,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
|
||||
|
||||
this.scene.arena.applyTags(ArenaTagType.PLASMA_FISTS, moveTypeHolder);
|
||||
|
||||
return moveTypeHolder.value as Type;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "Lehmsuhler hört auf zu wirken!",
|
||||
"waterSportOnAdd": "Die Stärke aller Feuer-Attacken wurde reduziert!",
|
||||
"waterSportOnRemove": "Nassmacher hört auf zu wirken!",
|
||||
"plasmaFistsOnAdd": "Ein elektrisch geladener Niederschlag regnet auf das Kampffeld herab!",
|
||||
"spikesOnAdd": "Die {{opponentDesc}} sind von Stacheln umgeben!",
|
||||
"spikesActivateTrap": "Die {{pokemonNameWithAffix}} wurde durch Stachler verletzt!!",
|
||||
"toxicSpikesOnAdd": "Die {{opponentDesc}} sind überall von giftigen Stacheln umgeben",
|
||||
|
@ -54,4 +55,4 @@
|
|||
"safeguardOnRemove": "Der mystische Schleier, der das ganze Feld umgab, hat sich gelüftet!",
|
||||
"safeguardOnRemovePlayer": "Der mystische Schleier, der dein Team umgab, hat sich gelüftet!",
|
||||
"safeguardOnRemoveEnemy": "Der mystische Schleier, der das gegnerische Team umgab, hat sich gelüftet!"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "The effects of Mud Sport\nhave faded.",
|
||||
"waterSportOnAdd": "Fire's power was weakened!",
|
||||
"waterSportOnRemove": "The effects of Water Sport\nhave faded.",
|
||||
"plasmaFistsOnAdd": "A deluge of ions showers the battlefield!",
|
||||
"spikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}} is hurt\nby the spikes!",
|
||||
"toxicSpikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "Chapoteo Lodo ha dejado de surtir efecto.",
|
||||
"waterSportOnAdd": "¡Se han debilitado los ataques\nde tipo Fuego!",
|
||||
"waterSportOnRemove": "Hidrochorro ha dejado de surtir efecto.",
|
||||
"plasmaFistsOnAdd": "¡Una lluvia de electrones cae sobre\nel terreno de combate!",
|
||||
"spikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!",
|
||||
"spikesActivateTrap": "¡Las púas han herido a {{pokemonNameWithAffix}}!",
|
||||
"toxicSpikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!",
|
||||
|
@ -54,4 +55,4 @@
|
|||
"safeguardOnRemove": "¡Velo Sagrado dejó de hacer efecto!",
|
||||
"safeguardOnRemovePlayer": "El efecto de Velo Sagrado en tu equipo se ha disipado.",
|
||||
"safeguardOnRemoveEnemy": "El efecto de Velo Sagrado en el equipo enemigo se ha disipado."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "L’effet de Lance-Boue se dissipe !",
|
||||
"waterSportOnAdd": "La puissance des capacités\nde type Feu diminue !",
|
||||
"waterSportOnRemove": "L’effet de Tourniquet se dissipe !",
|
||||
"plasmaFistsOnAdd": "Un déluge de plasma s’abat sur le terrain !",
|
||||
"spikesOnAdd": "Des {{moveName}} s’éparpillent autour de {{opponentDesc}} !",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}} est blessé\npar les picots !",
|
||||
"toxicSpikesOnAdd": "Des {{moveName}} s’éparpillent autour de {{opponentDesc}} !",
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{
|
||||
"plasmaFistsOnAdd": "Una pioggia di elettroni si rovescia sui Pokémon!",
|
||||
"safeguardOnAdd": "Un velo mistico ricopre il campo!",
|
||||
"safeguardOnAddPlayer": "Un velo mistico ricopre la tua squadra!",
|
||||
"safeguardOnAddEnemy": "Un velo mistico ricopre la squadra avversaria!",
|
||||
"safeguardOnRemove": "Il campo non è più protetto da Salvaguardia!",
|
||||
"safeguardOnRemovePlayer": "La tua squadra non è più protetta da Salvaguardia!",
|
||||
"safeguardOnRemoveEnemy": "La squadra avversaria non è più protetta da Salvaguardia!"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "どろあそびの 効果が なくなった!",
|
||||
"waterSportOnAdd": "炎の威力が 弱まった!",
|
||||
"waterSportOnRemove": "みずあそびの 効果が なくなった!",
|
||||
"plasmaFistsOnAdd": "電子のシャワーが 降りそそいだ!",
|
||||
"spikesOnAdd": "{{opponentDesc}}の 足下に\n{{moveName}}が 散らばった!",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}}は\nまきびしの ダメージを 受けた!",
|
||||
"toxicSpikesOnAdd": "{{opponentDesc}}の 足下に\n{{moveName}}が 散らばった!",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "흙놀이의 효과가\n없어졌다!",
|
||||
"waterSportOnAdd": "불꽃의 위력이 약해졌다!",
|
||||
"waterSportOnRemove": "물놀이의 효과가\n없어졌다!",
|
||||
"plasmaFistsOnAdd": "전기 입자가 쏟아졌다!",
|
||||
"spikesOnAdd": "{{opponentDesc}}의 발밑에\n압정이 뿌려졌다!",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}}[[는]]\n압정뿌리기의 데미지를 입었다!",
|
||||
"toxicSpikesOnAdd": "{{opponentDesc}}의 발밑에\n독압정이 뿌려졌다!",
|
||||
|
@ -54,4 +55,4 @@
|
|||
"safeguardOnRemove": "필드를 감싸던 신비의 베일이 없어졌다!",
|
||||
"safeguardOnRemovePlayer": "우리 편을 감싸던 신비의 베일이 없어졌다!",
|
||||
"safeguardOnRemoveEnemy": "상대 편을 감싸던 신비의 베일이 없어졌다!"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "Os efeitos de Mud Sport\nsumiram.",
|
||||
"waterSportOnAdd": "O poder de movimentos de fogo foi enfraquecido!",
|
||||
"waterSportOnRemove": "Os efeitos de Water Sport\nsumiram.",
|
||||
"plasmaFistsOnAdd": "Um dilúvio de íons chove sobre o campo de batalha!",
|
||||
"spikesOnAdd": "{{moveName}} foram espalhados\nno chão ao redor de {{opponentDesc}}!",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}} foi ferido\npelos espinhos!",
|
||||
"toxicSpikesOnAdd": "{{moveName}} foram espalhados\nno chão ao redor de {{opponentDesc}}!",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "玩泥巴的效果消失了!",
|
||||
"waterSportOnAdd": "火焰的威力减弱了!",
|
||||
"waterSportOnRemove": "玩水的效果消失了!",
|
||||
"plasmaFistsOnAdd": "等离子雨倾盆而下!",
|
||||
"spikesOnAdd": "{{opponentDesc}}脚下\n散落着{{moveName}}!",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}}\n受到了撒菱的伤害!",
|
||||
"toxicSpikesOnAdd": "{{opponentDesc}}脚下\n散落着{{moveName}}!",
|
||||
|
@ -54,4 +55,4 @@
|
|||
"safeguardOnRemove": "包围整个场地的\n神秘之幕消失了!",
|
||||
"safeguardOnRemovePlayer": "包围我方的\n神秘之幕消失了!",
|
||||
"safeguardOnRemoveEnemy": "包围对手的\n神秘之幕消失了!"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"mudSportOnRemove": "玩泥巴的效果消失了!",
|
||||
"waterSportOnAdd": "火焰的威力減弱了!",
|
||||
"waterSportOnRemove": "玩水的效果消失了!",
|
||||
"plasmaFistsOnAdd": "等離子雨傾盆而下!",
|
||||
"spikesOnAdd": "{{opponentDesc}}腳下\n散落著{{moveName}}!",
|
||||
"spikesActivateTrap": "{{pokemonNameWithAffix}}\n受到了撒菱的傷害!",
|
||||
"toxicSpikesOnAdd": "{{opponentDesc}}腳下\n散落著{{moveName}}!",
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
import { BattlerIndex } from "#app/battle";
|
||||
import { Type } from "#app/data/type";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest";
|
||||
|
||||
describe("Moves - Plasma Fists", () => {
|
||||
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
|
||||
.moveset([Moves.PLASMA_FISTS, Moves.TACKLE])
|
||||
.battleType("double")
|
||||
.startingLevel(100)
|
||||
.enemySpecies(Species.DUSCLOPS)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.TACKLE)
|
||||
.enemyLevel(100);
|
||||
});
|
||||
|
||||
it("should convert all subsequent Normal-type attacks to Electric-type", async () => {
|
||||
await game.classicMode.startBattle([Species.DUSCLOPS, Species.BLASTOISE]);
|
||||
|
||||
const field = game.scene.getField(true);
|
||||
field.forEach(p => vi.spyOn(p, "getMoveType"));
|
||||
|
||||
game.move.select(Moves.PLASMA_FISTS, 0, BattlerIndex.ENEMY);
|
||||
game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY_2);
|
||||
|
||||
await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
|
||||
await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2);
|
||||
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
|
||||
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
field.forEach(p => {
|
||||
expect(p.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
|
||||
expect(p.hp).toBeLessThan(p.getMaxHp());
|
||||
});
|
||||
});
|
||||
|
||||
it("should not affect Normal-type attacks boosted by Pixilate", async () => {
|
||||
game.override
|
||||
.battleType("single")
|
||||
.enemyAbility(Abilities.PIXILATE);
|
||||
|
||||
await game.classicMode.startBattle([Species.ONIX]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "getMoveType");
|
||||
|
||||
game.move.select(Moves.PLASMA_FISTS);
|
||||
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.FAIRY);
|
||||
expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp());
|
||||
});
|
||||
|
||||
it("should affect moves that become Normal type due to Normalize", async () => {
|
||||
game.override
|
||||
.battleType("single")
|
||||
.enemyAbility(Abilities.NORMALIZE)
|
||||
.enemyMoveset(Moves.WATER_GUN);
|
||||
|
||||
await game.classicMode.startBattle([Species.DUSCLOPS]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "getMoveType");
|
||||
|
||||
game.move.select(Moves.PLASMA_FISTS);
|
||||
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
|
||||
expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp());
|
||||
});
|
||||
});
|
|
@ -303,7 +303,7 @@ export default class GameManager {
|
|||
|
||||
vi.spyOn(enemy, "getNextMove").mockReturnValueOnce({
|
||||
move: moveId,
|
||||
targets: (target && !legalTargets.multiple && legalTargets.targets.includes(target))
|
||||
targets: (target !== undefined && !legalTargets.multiple && legalTargets.targets.includes(target))
|
||||
? [target]
|
||||
: enemy.getNextTargets(moveId)
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue