Fixed interaction with instruct and dead mon redirection
This commit is contained in:
parent
e0600a9476
commit
21c7546ae5
|
@ -6108,7 +6108,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Don't allow wild mons to flee with U-turn et al
|
||||
// Don't allow wild mons to flee with U-turn et al.
|
||||
if (this.selfSwitch && !user.isPlayer() && move.category !== MoveCategory.STATUS) {
|
||||
return false;
|
||||
}
|
||||
|
@ -7068,7 +7068,20 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||
// (mainly for alternating double/single battle shenanigans)
|
||||
// Rampaging moves (e.g. Outrage) are not included due to being incompatible with Instruct
|
||||
// TODO: Fix this once dragon darts gets smart targeting
|
||||
const moveTargets = movesetMove.getMove().isMultiTarget() ? getMoveTargets(target, lastMove.move).targets : lastMove.targets!;
|
||||
let moveTargets = movesetMove.getMove().isMultiTarget() ? getMoveTargets(target, lastMove.move).targets : lastMove.targets;
|
||||
|
||||
/** In the event the instructed move's only target is a fainted opponent, redirect it to an alive ally if possible
|
||||
Normally, all yet-unexecuted move phases would swap over when the enemy in question faints
|
||||
(see `redirectPokemonMoves` in `battle-scene.ts`),
|
||||
but since instruct adds a new move phase pre-emptively, we need to handle this interaction manually.
|
||||
*/
|
||||
const firstTarget = globalScene.getField()[moveTargets[0]];
|
||||
if (globalScene.currentBattle.double && moveTargets.length === 1 && firstTarget.isFainted() && firstTarget !== target.getAlly()) {
|
||||
const ally = firstTarget.getAlly();
|
||||
if (ally.isActive()) { // ally exists, is not dead and can sponge the blast
|
||||
moveTargets = [ ally.getBattlerIndex() ];
|
||||
}
|
||||
}
|
||||
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:instructingMove", {
|
||||
userPokemonName: getPokemonNameWithAffix(user),
|
||||
|
|
|
@ -43,7 +43,9 @@ describe("Moves - Instruct", () => {
|
|||
});
|
||||
|
||||
it("should repeat target's last used move", async () => {
|
||||
game.override.moveset(Moves.INSTRUCT);
|
||||
game.override
|
||||
.moveset(Moves.INSTRUCT)
|
||||
.enemyLevel(1000); // ensures shuckle no die
|
||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
@ -170,6 +172,33 @@ describe("Moves - Instruct", () => {
|
|||
expect(enemyPokemon.getMoveHistory().length).toBe(1);
|
||||
});
|
||||
|
||||
it("should redirect attacking moves if enemy faints", async () => {
|
||||
game.override
|
||||
.battleType("double")
|
||||
.enemyMoveset(Moves.SPLASH)
|
||||
.enemySpecies(Species.MAGIKARP)
|
||||
.enemyLevel(1);
|
||||
await game.classicMode.startBattle([ Species.HISUI_ELECTRODE, Species.KOMMO_O ]);
|
||||
|
||||
const [ electrode, kommo_o ] = game.scene.getPlayerField()!;
|
||||
game.move.changeMoveset(electrode, Moves.CHLOROBLAST);
|
||||
game.move.changeMoveset(kommo_o, Moves.INSTRUCT);
|
||||
|
||||
game.move.select(Moves.CHLOROBLAST, BattlerIndex.PLAYER);
|
||||
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER);
|
||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
// Chloroblast always deals 50% max HP% recoil UNLESS you whiff
|
||||
// due to lack of targets or similar,
|
||||
// so all we have to do is check whether electrode fainted or not.
|
||||
// Naturally, both karps should also be dead as well.
|
||||
expect(electrode.isFainted()).toBe(true);
|
||||
const [ karp1, karp2 ] = game.scene.getEnemyField()!;
|
||||
expect(karp1.isFainted()).toBe(true);
|
||||
expect(karp2.isFainted()).toBe(true);
|
||||
}),
|
||||
|
||||
it("should not repeat move when switching out", async () => {
|
||||
game.override
|
||||
.enemyMoveset(Moves.INSTRUCT)
|
||||
|
|
|
@ -459,9 +459,9 @@ export default class GameManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Intercepts `TurnStartPhase` and mocks the getSpeedOrder's return value {@linkcode TurnStartPhase.getSpeedOrder}
|
||||
* Used to modify the turn order.
|
||||
* Note: This *DOES NOT* account for priority.
|
||||
* Intercepts `TurnStartPhase` and mocks {@linkcode TurnStartPhase.getSpeedOrder}'s return value.
|
||||
* Used to manually modify Pokemon turn order.
|
||||
* Note: This *DOES NOT* account for priority, only speed.
|
||||
* @param {BattlerIndex[]} order The turn order to set
|
||||
* @example
|
||||
* ```ts
|
||||
|
@ -475,7 +475,7 @@ export default class GameManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes all held items from enemy pokemon
|
||||
* Removes all held items from enemy pokemon.
|
||||
*/
|
||||
removeEnemyHeldItems(): void {
|
||||
this.scene.clearEnemyHeldItemModifiers();
|
||||
|
|
Loading…
Reference in New Issue