fix follow me with pursuit
This commit is contained in:
parent
b057c144ac
commit
f0eac00179
|
@ -4203,8 +4203,21 @@ export class TypelessAttr extends MoveAttr { }
|
|||
/**
|
||||
* Attribute used for moves which ignore redirection effects, and always target their original target, i.e. Snipe Shot
|
||||
* Bypasses Storm Drain, Follow Me, Ally Switch, and the like.
|
||||
*
|
||||
* Optionally accepts a function to run which can be used to conditionally bypass redirection effects.
|
||||
*/
|
||||
export class BypassRedirectAttr extends MoveAttr { }
|
||||
export class BypassRedirectAttr extends MoveAttr {
|
||||
private bypassConditionFn?: (user: Pokemon | null, target: Pokemon | null, move: Move) => boolean;
|
||||
|
||||
constructor(bypassConditionFn?: (user: Pokemon | null, target: Pokemon | null, move: Move) => boolean) {
|
||||
super();
|
||||
this.bypassConditionFn = bypassConditionFn;
|
||||
}
|
||||
|
||||
apply(user: Pokemon | null, target: Pokemon | null, move: Move) {
|
||||
return this.bypassConditionFn?.(user, target, move) ?? true;
|
||||
}
|
||||
}
|
||||
|
||||
export class DisableMoveAttr extends MoveEffectAttr {
|
||||
constructor() {
|
||||
|
@ -6876,6 +6889,7 @@ export function initMoves() {
|
|||
.condition((user, target, move) => new EncoreTag(user.id).canAdd(target)),
|
||||
new AttackMove(Moves.PURSUIT, Type.DARK, MoveCategory.PHYSICAL, 40, 100, 20, -1, 0, 2)
|
||||
.attr(PursuitAccuracyAttr)
|
||||
.attr(BypassRedirectAttr, (user, target) => Boolean(user && target && isPursuingFunc(user, target)))
|
||||
.attr(AddBattlerTagHeaderAttr, BattlerTagType.ANTICIPATING_ACTION)
|
||||
.attr(RemoveBattlerTagAttr, [BattlerTagType.ANTICIPATING_ACTION], true, MoveEffectTrigger.POST_APPLY)
|
||||
.attr(MovePowerMultiplierAttr, (user, target) => isPursuingFunc(user, target) ? 2 : 1),
|
||||
|
|
|
@ -2777,9 +2777,11 @@ export class MovePhase extends BattlePhase {
|
|||
}
|
||||
});
|
||||
//Check if this move is immune to being redirected, and restore its target to the intended target if it is.
|
||||
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) || this.move.getMove().hasAttr(BypassRedirectAttr))) {
|
||||
const abilityRedirectImmune = this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr);
|
||||
const moveRedirectImmune = this.move.getMove().getAttrs(BypassRedirectAttr).some(attr => attr.apply(this.pokemon, this.scene.getField(false)[oldTarget], this.move.getMove()));
|
||||
if (abilityRedirectImmune || moveRedirectImmune) {
|
||||
//If an ability prevented this move from being redirected, display its ability pop up.
|
||||
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) && !this.move.getMove().hasAttr(BypassRedirectAttr)) && oldTarget !== moveTarget.value) {
|
||||
if (abilityRedirectImmune && !moveRedirectImmune && oldTarget !== moveTarget.value) {
|
||||
this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr)));
|
||||
}
|
||||
moveTarget.value = oldTarget;
|
||||
|
|
|
@ -495,7 +495,6 @@ describe("Moves - Pursuit", () => {
|
|||
game.override.battleType("double");
|
||||
});
|
||||
|
||||
// fails: pursuit does not ignore follow me
|
||||
it("should bypass follow me when hitting a switching target", async () => {
|
||||
// arrange
|
||||
await startBattle();
|
||||
|
@ -509,13 +508,32 @@ describe("Moves - Pursuit", () => {
|
|||
await runCombatTurn(game.scene.getEnemyField()[1]);
|
||||
|
||||
// assert
|
||||
expectPursuitPowerUnchanged();
|
||||
expectPursuitPowerDoubled();
|
||||
expectWasHit(findPartyMember(game.scene.getParty(), Species.RAICHU))
|
||||
.and(expectNotOnField);
|
||||
expectWasNotHit(findPartyMember(game.scene.getParty(), playerLead));
|
||||
});
|
||||
|
||||
// fails: fainting a pursuiter still runs the enemy SwitchSummonPhase
|
||||
it("should not bypass follow me when hitting a non-switching target", async () => {
|
||||
// arrange
|
||||
await startBattle();
|
||||
forceMovesLast(game.scene.getEnemyPokemon());
|
||||
|
||||
// act
|
||||
game.override.moveset([Moves.FOLLOW_ME, Moves.SPLASH]);
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.FOLLOW_ME));
|
||||
game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH));
|
||||
enemyUses(Moves.PURSUIT);
|
||||
game.move.forceAiTargets(game.scene.getEnemyPokemon(), BattlerIndex.PLAYER_2);
|
||||
await runCombatTurn(game.scene.getEnemyField()[1]);
|
||||
|
||||
// assert
|
||||
expectPursuitPowerUnchanged();
|
||||
expectWasHit(findPartyMember(game.scene.getParty(), playerLead));
|
||||
expectWasNotHit(findPartyMember(game.scene.getParty(), Species.RAICHU));
|
||||
});
|
||||
|
||||
// fails: fainting an escapee still runs the enemy SwitchSummonPhase
|
||||
it("should fail if both pokemon use pursuit on a target that is switching out and it faints after the first one", async () => {
|
||||
// arrange
|
||||
await startBattle();
|
||||
|
|
Loading…
Reference in New Issue