diff --git a/src/data/ability.ts b/src/data/ability.ts index 0aa4c948f75..c657582f596 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -1678,7 +1678,7 @@ export class SynchronizeStatusAbAttr extends PostSetStatusAbAttr { ]); if (sourcePokemon && syncStatuses.has(effect)) { - return sourcePokemon.trySetStatus(effect, true); + return sourcePokemon.trySetStatus(effect, true, pokemon); } return false; @@ -4307,7 +4307,7 @@ export function initAbilities() { new Ability(Abilities.SYNCHRONIZE, 3) .attr(SyncEncounterNatureAbAttr) .attr(SynchronizeStatusAbAttr) - .partial(), // interaction with psycho shift needs work + .partial(), // interaction with psycho shift needs work, keeping to old Gen interaction for now new Ability(Abilities.CLEAR_BODY, 3) .attr(ProtectStatAbAttr) .ignorable(), diff --git a/src/data/move.ts b/src/data/move.ts index 5ab4b1e8a64..a1c167f0c7e 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1761,13 +1761,14 @@ export class PsychoShiftEffectAttr extends MoveEffectAttr { return false; } if (!target.status || (target.status.effect === statusToApply && move.chance < 0)) { - const statusAfflictResult = target.trySetStatus(statusToApply, true, user); - if (statusAfflictResult) { + const canSetStatus = target.canSetStatus(statusToApply, true, false, user); + if (canSetStatus) { user.scene.queueMessage(getPokemonMessage(user, getStatusEffectHealText(user.status.effect))); user.resetStatus(); user.updateInfo(); + target.trySetStatus(statusToApply, true, user); } - return statusAfflictResult; + return canSetStatus; } return false; diff --git a/src/test/abilities/synchronize.test.ts b/src/test/abilities/synchronize.test.ts index 302312f1f6a..f34a6b0103a 100644 --- a/src/test/abilities/synchronize.test.ts +++ b/src/test/abilities/synchronize.test.ts @@ -209,4 +209,29 @@ describe("Abilities - Synchronize", () => { expect(game.scene.getEnemyParty()[0].status?.effect).toBe(undefined); expect(game.phaseInterceptor.log).not.toContain("ShowAbilityPhase"); }, 20000); + + it("should activate with Psycho Shift after the move clears the status", async () => { + // Arrange + const moveToUse = Moves.PSYCHO_SHIFT; + + // Starter mocks + vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.HOOTHOOT); + vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); + vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.KEEN_EYE); + vi.spyOn(overrides, "STATUS_OVERRIDE", "get").mockReturnValue(StatusEffect.PARALYSIS); + + // Act + await game.startBattle(); + game.doAttack(getMovePosition(game.scene, 0, moveToUse)); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + vi.spyOn(game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValue(true); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Assert + expect(game.scene.getParty()[0].status?.effect).toBe(StatusEffect.PARALYSIS); // keeping old gen < V impl for now since it's buggy otherwise + expect(game.scene.getEnemyParty()[0].status?.effect).toBe(StatusEffect.PARALYSIS); + expect(game.phaseInterceptor.log).toContain("ShowAbilityPhase"); + }, 20000); });