mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-24 07:23:24 +02:00
Remove BYPASS_SLEEP battler tag in favor of boolean holder
This commit is contained in:
parent
4273345371
commit
77948a8ff8
@ -3788,8 +3788,6 @@ export function getBattlerTag(
|
||||
case BattlerTagType.ALWAYS_GET_HIT:
|
||||
case BattlerTagType.RECEIVE_DOUBLE_DAMAGE:
|
||||
return new SerializableBattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove);
|
||||
case BattlerTagType.BYPASS_SLEEP:
|
||||
return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove);
|
||||
case BattlerTagType.IGNORE_FLYING:
|
||||
return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove);
|
||||
case BattlerTagType.ROOSTED:
|
||||
@ -3963,7 +3961,6 @@ export type BattlerTagTypeMap = {
|
||||
[BattlerTagType.IGNORE_ACCURACY]: GenericSerializableBattlerTag<BattlerTagType.IGNORE_ACCURACY>;
|
||||
[BattlerTagType.ALWAYS_GET_HIT]: GenericSerializableBattlerTag<BattlerTagType.ALWAYS_GET_HIT>;
|
||||
[BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: GenericSerializableBattlerTag<BattlerTagType.RECEIVE_DOUBLE_DAMAGE>;
|
||||
[BattlerTagType.BYPASS_SLEEP]: BattlerTag;
|
||||
[BattlerTagType.IGNORE_FLYING]: GroundedTag;
|
||||
[BattlerTagType.ROOSTED]: RoostedTag;
|
||||
[BattlerTagType.BURNED_UP]: RemovedTypeTag;
|
||||
|
@ -3187,19 +3187,19 @@ export class HealStatusEffectAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute to add the {@linkcode BattlerTagType.BYPASS_SLEEP | BYPASS_SLEEP Battler Tag} for 1 turn to the user before move use.
|
||||
* Attribute checked during the `MovePhase`'s {@linkcode MovePhase.checkSleep | checkSleep} failure sequence to allow
|
||||
* the move to bypass the sleep condition
|
||||
* Used by {@linkcode MoveId.SNORE} and {@linkcode MoveId.SLEEP_TALK}.
|
||||
*/
|
||||
// TODO: Should this use a battler tag?
|
||||
// TODO: Give this `userSleptOrComatoseCondition` by default
|
||||
export class BypassSleepAttr extends MoveAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (user.status?.effect === StatusEffect.SLEEP) {
|
||||
user.addTag(BattlerTagType.BYPASS_SLEEP, 1, move.id, user.id);
|
||||
return true;
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: [BooleanHolder, ...any[]]): boolean {
|
||||
const bypassSleep = args[0];
|
||||
if (bypassSleep.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
bypassSleep.value = true;
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,6 @@ export enum BattlerTagType {
|
||||
CRIT_BOOST = "CRIT_BOOST",
|
||||
ALWAYS_CRIT = "ALWAYS_CRIT",
|
||||
IGNORE_ACCURACY = "IGNORE_ACCURACY",
|
||||
BYPASS_SLEEP = "BYPASS_SLEEP",
|
||||
IGNORE_FLYING = "IGNORE_FLYING",
|
||||
SALT_CURED = "SALT_CURED",
|
||||
CURSED = "CURSED",
|
||||
|
@ -182,15 +182,13 @@ export class MovePhase extends PokemonPhase {
|
||||
* - If the user is asleep but can use the move, the sleep animation and message is still shown
|
||||
* - If the user is frozen but is thawed from its move, the user's status is cured and the thaw message is shown
|
||||
*/
|
||||
private post1stFailSleepOrThaw(): void {
|
||||
private doThawCheck(): void {
|
||||
const user = this.pokemon;
|
||||
|
||||
if (isIgnoreStatus(this.useMode)) {
|
||||
return;
|
||||
}
|
||||
if (user.status?.effect === StatusEffect.SLEEP) {
|
||||
this.triggerStatus(StatusEffect.SLEEP, false);
|
||||
} else if (this.thaw) {
|
||||
if (this.thaw) {
|
||||
this.cureStatus(
|
||||
StatusEffect.FREEZE,
|
||||
i18next.t("statusEffect:freeze.healByMove", {
|
||||
@ -336,9 +334,8 @@ export class MovePhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
// If the first failure check passes (and this is not a sub-move) then thaw the user if its move will thaw it.
|
||||
// The sleep message and animation should also play if the user is asleep but using a move anyway (snore, sleep talk, etc)
|
||||
if (!isFollowUp) {
|
||||
this.post1stFailSleepOrThaw();
|
||||
this.doThawCheck();
|
||||
}
|
||||
|
||||
// Reset hit-related turn data when starting follow-up moves (e.g. Metronomed moves, Dancer repeats)
|
||||
@ -474,32 +471,36 @@ export class MovePhase extends PokemonPhase {
|
||||
* @returns Whether the move was cancelled due to sleep
|
||||
*/
|
||||
protected checkSleep(): boolean {
|
||||
if (this.pokemon.status?.effect !== StatusEffect.SLEEP) {
|
||||
const user = this.pokemon;
|
||||
if (user.status?.effect !== StatusEffect.SLEEP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For some reason, dancer will immediately wake its user from sleep when triggering
|
||||
if (this.useMode === MoveUseMode.INDIRECT) {
|
||||
this.pokemon.resetStatus(false);
|
||||
user.resetStatus(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.pokemon.status.incrementTurn();
|
||||
applyMoveAttrs("BypassSleepAttr", this.pokemon, null, this.move.getMove());
|
||||
const turnsRemaining = new NumberHolder(this.pokemon.status.sleepTurnsRemaining ?? 0);
|
||||
user.status.incrementTurn();
|
||||
const turnsRemaining = new NumberHolder(user.status.sleepTurnsRemaining ?? 0);
|
||||
applyAbAttrs("ReduceStatusEffectDurationAbAttr", {
|
||||
pokemon: this.pokemon,
|
||||
statusEffect: this.pokemon.status.effect,
|
||||
pokemon: user,
|
||||
statusEffect: user.status.effect,
|
||||
duration: turnsRemaining,
|
||||
});
|
||||
this.pokemon.status.sleepTurnsRemaining = turnsRemaining.value;
|
||||
if (this.pokemon.status.sleepTurnsRemaining <= 0) {
|
||||
|
||||
user.status.sleepTurnsRemaining = turnsRemaining.value;
|
||||
if (user.status.sleepTurnsRemaining <= 0) {
|
||||
this.cureStatus(StatusEffect.SLEEP);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.triggerStatus(StatusEffect.SLEEP);
|
||||
return true;
|
||||
const bypassSleepHolder = new BooleanHolder(false);
|
||||
applyMoveAttrs("BypassSleepAttr", this.pokemon, null, this.move.getMove(), bypassSleepHolder);
|
||||
const cancel = !bypassSleepHolder.value;
|
||||
this.triggerStatus(StatusEffect.SLEEP, cancel);
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,9 +97,16 @@ describe("Moves - Sleep Talk", () => {
|
||||
|
||||
game.move.select(MoveId.SLEEP_TALK);
|
||||
await game.toNextTurn();
|
||||
expect(game.field.getPlayerPokemon().getStatStage(Stat.ATK));
|
||||
});
|
||||
|
||||
const feebas = game.field.getPlayerPokemon();
|
||||
expect(feebas.getStatStage(Stat.SPD)).toBe(1);
|
||||
expect(feebas.getStatStage(Stat.DEF)).toBe(-1);
|
||||
it("should apply secondary effects of a move", async () => {
|
||||
game.override.moveset([MoveId.SLEEP_TALK, MoveId.DIG, MoveId.FLY, MoveId.WOOD_HAMMER]); // Dig and Fly are invalid moves, Wood Hammer should always be called
|
||||
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
|
||||
|
||||
game.move.select(MoveId.SLEEP_TALK);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.field.getPlayerPokemon().isFullHp()).toBeFalsy(); // Wood Hammer recoil effect should be applied
|
||||
});
|
||||
});
|
||||
|
@ -48,7 +48,6 @@ describe("Moves - Throat Chop", () => {
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(player.trySelectMove(MoveId.GROWL)[0]).toBe(false);
|
||||
|
||||
game.move.select(MoveId.GROWL);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user