mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-24 07:23:24 +02:00
PR review changes
Fix type hints test name Update Dig/Dive test name Separate TSDoc imports in `pokemon-utils.ts` Add missing `@returns` in `move-phase.ts` Fix comment typos Separate TSDoc imports in `move-phase.ts` Add return hints to `trySelectMove` Minor formatting Remove duplicate `.affectedByGravity()` on Telekinesis Fix docs for `checkRestrictions` Manually format method definition Fix comment spacing Fix variable naming
This commit is contained in:
parent
2eed38dc55
commit
9e49162012
@ -156,7 +156,7 @@ export const failAgainstFinalBossCondition = new MoveCondition((_user, target) =
|
||||
* a high-priority attack (after factoring in priority-boosting effects) and
|
||||
* hasn't moved yet this turn.
|
||||
*/
|
||||
export const UpperHandCondition = new MoveCondition((_user, target) => {
|
||||
export const upperHandCondition = new MoveCondition((_user, target) => {
|
||||
const targetCommand = globalScene.currentBattle.turnCommands[target.getBattlerIndex()];
|
||||
return (
|
||||
targetCommand?.command === Command.FIGHT &&
|
||||
@ -252,13 +252,13 @@ export class MoveRestriction {
|
||||
* @remarks
|
||||
* Used by {@link https://bulbapedia.bulbagarden.net/wiki/Blood_Moon_(move) | Blood Moon} and {@link https://bulbapedia.bulbagarden.net/wiki/Gigaton_Hammer_(move) | Gigaton Hammer}
|
||||
*/
|
||||
export const ConsecutiveUseRestriction = new MoveRestriction(
|
||||
export const consecutiveUseRestriction = new MoveRestriction(
|
||||
(user, move) => user.getLastXMoves(1)[0]?.move === move.id,
|
||||
"battle:moveDisabledConsecutive",
|
||||
);
|
||||
|
||||
/** Prevents a move from being selected if Gravity is in effect */
|
||||
export const GravityUseRestriction = new MoveRestriction(
|
||||
export const gravityUseRestriction = new MoveRestriction(
|
||||
() => globalScene.arena.hasTag(ArenaTagType.GRAVITY),
|
||||
"battle:moveDisabledGravity",
|
||||
);
|
||||
|
@ -82,7 +82,7 @@ import {
|
||||
} from "#modifiers/modifier";
|
||||
import { applyMoveAttrs } from "#moves/apply-attrs";
|
||||
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSketchMoves, invalidSleepTalkMoves } from "#moves/invalid-moves";
|
||||
import { ConsecutiveUseRestriction, counterAttackConditionBoth, counterAttackConditionPhysical, counterAttackConditionSpecial, failAgainstFinalBossCondition, FailIfInsufficientHpCondition, failIfTargetNotAttackingCondition, failTeleportCondition, FirstMoveCondition, GravityUseRestriction, lastResortCondition, MoveCondition, MoveRestriction, UpperHandCondition } from "#moves/move-condition";
|
||||
import { consecutiveUseRestriction, counterAttackConditionBoth, counterAttackConditionPhysical, counterAttackConditionSpecial, failAgainstFinalBossCondition, FailIfInsufficientHpCondition, failIfTargetNotAttackingCondition, failTeleportCondition, FirstMoveCondition, gravityUseRestriction, lastResortCondition, MoveCondition, MoveRestriction, upperHandCondition } from "#moves/move-condition";
|
||||
import { frenzyMissFunc, getCounterAttackTarget, getMoveTargets } from "#moves/move-utils";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import { MovePhase } from "#phases/move-phase";
|
||||
@ -172,8 +172,14 @@ export abstract class Move implements Localizable {
|
||||
* @see {@link https://www.smogon.com/forums/threads/sword-shield-battle-mechanics-research.3655528/page-54#post-8548957}
|
||||
*/
|
||||
private conditionsSeq3: MoveCondition[] = [];
|
||||
<<<<<<< HEAD
|
||||
/** Conditions that must be false for a move to be able to be selected.
|
||||
*
|
||||
=======
|
||||
/**
|
||||
* Conditions that must be false for a move to be able to be selected.
|
||||
*
|
||||
>>>>>>> 02f941b3a05 (PR review changes)
|
||||
* @remarks Different from {@linkcode conditions}, which is checked when the move is invoked
|
||||
*/
|
||||
private restrictions: MoveRestriction[] = [];
|
||||
@ -452,7 +458,7 @@ export abstract class Move implements Localizable {
|
||||
* @returns `this` for method chaining
|
||||
*/
|
||||
public restriction(restriction: MoveRestriction): this;
|
||||
/**
|
||||
/**
|
||||
* Adds a restriction condition to this move.
|
||||
* The move will not be selectable if at least 1 of its restrictions is met.
|
||||
* @param restriction - The function or `MoveRestriction` that evaluates to `true` if the move is restricted from
|
||||
@ -476,7 +482,12 @@ export abstract class Move implements Localizable {
|
||||
* is false
|
||||
* @returns `this` for method chaining
|
||||
*/
|
||||
public restriction<T extends UserMoveConditionFunc | MoveRestriction>(restriction: T, i18nkey?: string, alsoCondition: typeof restriction extends MoveRestriction ? false : boolean = false, conditionSeq = 4): this {
|
||||
public restriction<T extends UserMoveConditionFunc | MoveRestriction>(
|
||||
restriction: T,
|
||||
i18nkey?: string,
|
||||
alsoCondition: typeof restriction extends MoveRestriction ? false : boolean = false,
|
||||
conditionSeq = 4,
|
||||
): this {
|
||||
if (typeof restriction === "function") {
|
||||
this.restrictions.push(new MoveRestriction(restriction));
|
||||
if (alsoCondition) {
|
||||
@ -700,7 +711,7 @@ export abstract class Move implements Localizable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.GRAVITY} flag for the calling Move and adds {@linkcode GravityUseRestriction} to the
|
||||
* Sets the {@linkcode MoveFlags.GRAVITY} flag for the calling Move and adds {@linkcode gravityUseRestriction} to the
|
||||
* move's restrictions.
|
||||
*
|
||||
* @returns `this`
|
||||
@ -713,7 +724,7 @@ export abstract class Move implements Localizable {
|
||||
*/
|
||||
affectedByGravity(): this {
|
||||
this.setFlag(MoveFlags.GRAVITY, true);
|
||||
this.restrictions.push(GravityUseRestriction);
|
||||
this.restrictions.push(gravityUseRestriction);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -859,9 +870,9 @@ export abstract class Move implements Localizable {
|
||||
*
|
||||
* @param user - The Pokemon using the move
|
||||
* @returns - An array whose first element is `false` if the move is restricted, and the second element is a string
|
||||
* with the reason for the restriction, otherwise, `false` and the empty string.
|
||||
* with the reason for the restriction, otherwise, `true` and the empty string.
|
||||
*/
|
||||
public checkRestrictions(user: Pokemon): [boolean, string] {
|
||||
public checkRestrictions(user: Pokemon): [isUsable: boolean, restrictionMessage: string] {
|
||||
for (const restriction of this.restrictions) {
|
||||
if (restriction.apply(user, this)) {
|
||||
return [false, restriction.getSelectionDeniedText(user, this)];
|
||||
@ -10034,7 +10045,6 @@ export function initMoves() {
|
||||
.condition((_user, target, _move) => target.getTag(BattlerTagType.INGRAIN) == null && target.getTag(BattlerTagType.IGNORE_FLYING) == null)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3)
|
||||
.affectedByGravity()
|
||||
.reflectable(),
|
||||
new StatusMove(MoveId.MAGIC_ROOM, PokemonType.PSYCHIC, -1, 10, -1, 0, 5)
|
||||
.ignoresProtect()
|
||||
@ -10677,10 +10687,7 @@ export function initMoves() {
|
||||
.attr(HealOnAllyAttr, 0.5, true, false)
|
||||
.ballBombMove()
|
||||
// Fail if used against an ally that is affected by heal block, during the second failure check
|
||||
.condition(
|
||||
(user, target) => target.isOpponent(user) || !!target.getTag(BattlerTagType.HEAL_BLOCK),
|
||||
2
|
||||
),
|
||||
.condition((user, target) => target.isOpponent(user) || !!target.getTag(BattlerTagType.HEAL_BLOCK), 2),
|
||||
new AttackMove(MoveId.ANCHOR_SHOT, PokemonType.STEEL, MoveCategory.PHYSICAL, 80, 100, 20, 100, 0, 7)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true),
|
||||
new StatusMove(MoveId.PSYCHIC_TERRAIN, PokemonType.PSYCHIC, -1, 10, -1, 0, 7)
|
||||
@ -10693,11 +10700,8 @@ export function initMoves() {
|
||||
new AttackMove(MoveId.POWER_TRIP, PokemonType.DARK, MoveCategory.PHYSICAL, 20, 100, 10, -1, 0, 7)
|
||||
.attr(PositiveStatStagePowerAttr),
|
||||
new AttackMove(MoveId.BURN_UP, PokemonType.FIRE, MoveCategory.SPECIAL, 130, 100, 5, -1, 0, 7)
|
||||
.condition(
|
||||
// Pass `true` to `ForDefend` as it should fail if the user is terastallized to a type that is not FIRE
|
||||
user => user.isOfType(PokemonType.FIRE, true, true),
|
||||
2
|
||||
)
|
||||
// Pass `true` to `ForDefend` as it should fail if the user is terastallized to a type that is not FIRE
|
||||
.condition(user => user.isOfType(PokemonType.FIRE, true, true), 2)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false)
|
||||
.attr(RemoveTypeAttr, PokemonType.FIRE, (user) => {
|
||||
@ -10798,10 +10802,7 @@ export function initMoves() {
|
||||
.attr(AddBattlerTagHeaderAttr, BattlerTagType.SHELL_TRAP)
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||
// Fails if the user was not hit by a physical attack during the turn
|
||||
.condition(
|
||||
user => user.getTag(ShellTrapTag)?.activated === true,
|
||||
3
|
||||
),
|
||||
.condition(user => user.getTag(ShellTrapTag)?.activated === true, 3),
|
||||
new AttackMove(MoveId.FLEUR_CANNON, PokemonType.FAIRY, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 7)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true),
|
||||
new AttackMove(MoveId.PSYCHIC_FANGS, PokemonType.PSYCHIC, MoveCategory.PHYSICAL, 85, 100, 10, -1, 0, 7)
|
||||
@ -10949,11 +10950,8 @@ export function initMoves() {
|
||||
new SelfStatusMove(MoveId.NO_RETREAT, PokemonType.FIGHTING, -1, 5, -1, 0, 8)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, true /* NOT ADDED if already trapped */)
|
||||
.condition(
|
||||
// fails if the user is currently trapped specifically from no retreat
|
||||
user => user.getTag(TrappedTag)?.tagType !== BattlerTagType.NO_RETREAT,
|
||||
2
|
||||
),
|
||||
// fails if the user is currently trapped specifically from no retreat
|
||||
.condition(user => user.getTag(TrappedTag)?.tagType !== BattlerTagType.NO_RETREAT, 2),
|
||||
new StatusMove(MoveId.TAR_SHOT, PokemonType.ROCK, 100, 15, -1, 0, 8)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPD ], -1)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TAR_SHOT, false)
|
||||
@ -11515,18 +11513,15 @@ export function initMoves() {
|
||||
.slicingMove()
|
||||
.triageMove(),
|
||||
new AttackMove(MoveId.DOUBLE_SHOCK, PokemonType.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 9)
|
||||
.condition(
|
||||
// Pass `true` to `isOfType` to fail if the user is terastallized to a type other than ELECTRIC
|
||||
user => user.isOfType(PokemonType.ELECTRIC, true, true),
|
||||
2
|
||||
)
|
||||
// Pass `true` to `isOfType` to fail if the user is terastallized to a type other than ELECTRIC
|
||||
.condition(user => user.isOfType(PokemonType.ELECTRIC, true, true), 2)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.DOUBLE_SHOCKED, true, false)
|
||||
.attr(RemoveTypeAttr, PokemonType.ELECTRIC, (user) => {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", { pokemonName: getPokemonNameWithAffix(user) }));
|
||||
}),
|
||||
new AttackMove(MoveId.GIGATON_HAMMER, PokemonType.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, -1, 0, 9)
|
||||
.makesContact(false)
|
||||
.restriction(ConsecutiveUseRestriction),
|
||||
.restriction(consecutiveUseRestriction),
|
||||
new AttackMove(MoveId.COMEUPPANCE, PokemonType.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9)
|
||||
.attr(CounterDamageAttr, 1.5)
|
||||
.attr(CounterRedirectAttr)
|
||||
@ -11552,7 +11547,7 @@ export function initMoves() {
|
||||
.attr(ConfuseAttr)
|
||||
.makesContact(false),
|
||||
new AttackMove(MoveId.BLOOD_MOON, PokemonType.NORMAL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 9)
|
||||
.restriction(ConsecutiveUseRestriction),
|
||||
.restriction(consecutiveUseRestriction),
|
||||
new AttackMove(MoveId.MATCHA_GOTCHA, PokemonType.GRASS, MoveCategory.SPECIAL, 80, 90, 15, 20, 0, 9)
|
||||
.attr(HitHealAttr)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||
@ -11613,7 +11608,7 @@ export function initMoves() {
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.HEAL_BLOCK, false, false, 2),
|
||||
new AttackMove(MoveId.UPPER_HAND, PokemonType.FIGHTING, MoveCategory.PHYSICAL, 65, 100, 15, 100, 3, 9)
|
||||
.attr(FlinchAttr)
|
||||
.condition(UpperHandCondition, 3),
|
||||
.condition(upperHandCondition, 3),
|
||||
new AttackMove(MoveId.MALIGNANT_CHAIN, PokemonType.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9)
|
||||
.attr(StatusEffectAttr, StatusEffect.TOXIC)
|
||||
);
|
||||
|
@ -3138,7 +3138,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @param ignorePp - Whether to ignore PP when checking if the move is usable (defaults to false)
|
||||
* @returns A tuple containing a boolean indicating if the move can be selected, and a string with the reason if it cannot be selected
|
||||
*/
|
||||
public trySelectMove(moveIndex: number, ignorePp?: boolean): [boolean, string] {
|
||||
public trySelectMove(moveIndex: number, ignorePp?: boolean): [isUsable: boolean, failureMessage: string] {
|
||||
const move = this.getMoveset().length > moveIndex ? this.getMoveset()[moveIndex] : null;
|
||||
return move?.isUsable(this, ignorePp, true) ?? [false, ""];
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
// biome-ignore-start lint/correctness/noUnusedImports: Used in a tsdoc comment
|
||||
import type { Move, PreUseInterruptAttr } from "#types/move-types";
|
||||
// biome-ignore-end lint/correctness/noUnusedImports: Used in a tsdoc comment
|
||||
|
||||
import { applyAbAttrs } from "#abilities/apply-ab-attrs";
|
||||
import { MOVE_COLOR } from "#app/constants/colors";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
@ -28,8 +32,6 @@ import type { Pokemon } from "#field/pokemon";
|
||||
import { applyMoveAttrs } from "#moves/apply-attrs";
|
||||
import { frenzyMissFunc } from "#moves/move-utils";
|
||||
import type { PokemonMove } from "#moves/pokemon-move";
|
||||
// biome-ignore lint/correctness/noUnusedImports: Used in a tsdoc comment
|
||||
import type { Move, PreUseInterruptAttr } from "#types/move-types";
|
||||
import { applyChallenges } from "#utils/challenge-utils";
|
||||
import { BooleanHolder, NumberHolder } from "#utils/common";
|
||||
import { enumValueToKey } from "#utils/enums";
|
||||
@ -205,7 +207,7 @@ export class MovePhase extends PokemonPhase {
|
||||
*
|
||||
* @remarks
|
||||
* Other than powder, each failure condition is mutually exclusive (as they are tied to specific moves), so order does not matter.
|
||||
* Notably, this failure check only includes failure conditions intrinsic to the move itself, ther than Powder (which marks the end of this failure check)
|
||||
* Notably, this failure check only includes failure conditions intrinsic to the move itself, other than Powder (which marks the end of this failure check)
|
||||
*
|
||||
*
|
||||
* - Pollen puff used on an ally that is under effect of heal block
|
||||
@ -512,13 +514,14 @@ export class MovePhase extends PokemonPhase {
|
||||
* - Checking if the pokemon will thaw from random chance, OR from a thawing move.
|
||||
* Thawing from a freeze move is not applied until AFTER all other failure checks.
|
||||
* - Activating the freeze status effect (cancelling the move, playing the message, and displaying the animation)
|
||||
* @returns Whether the move was cancelled due to the pokemon being frozen
|
||||
*/
|
||||
protected checkFreeze(): boolean {
|
||||
if (this.pokemon.status?.effect !== StatusEffect.FREEZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For some reason, dancer will immediately its user
|
||||
// For some reason, dancer will immediately thaw its user
|
||||
if (this.useMode === MoveUseMode.INDIRECT) {
|
||||
this.pokemon.resetStatus(false);
|
||||
return false;
|
||||
@ -644,6 +647,7 @@ export class MovePhase extends PokemonPhase {
|
||||
* Lapse the tag type and check if the move is cancelled from it. Meant to be used during the first failure check
|
||||
* @param tag - The tag type whose lapse method will be called with {@linkcode BattlerTagLapseType.PRE_MOVE}
|
||||
* @param checkIgnoreStatus - Whether to check {@link isIgnoreStatus} for the current {@linkcode MoveUseMode} to skip this check
|
||||
* @returns Whether the move was cancelled due to a `BattlerTag` effect
|
||||
*/
|
||||
private checkTagCancel(tag: BattlerTagType): boolean {
|
||||
this.pokemon.lapseTag(tag, BattlerTagLapseType.PRE_MOVE);
|
||||
@ -652,7 +656,7 @@ export class MovePhase extends PokemonPhase {
|
||||
|
||||
/**
|
||||
* Handle move failures due to Gravity, cancelling the move and showing the failure text
|
||||
* @returns - Whether the move was cancelled due to Gravity
|
||||
* @returns Whether the move was cancelled due to Gravity
|
||||
*/
|
||||
private checkGravity(): boolean {
|
||||
const move = this.move.getMove();
|
||||
@ -721,7 +725,7 @@ export class MovePhase extends PokemonPhase {
|
||||
/*
|
||||
At this point, delayed moves (future sight, wish, doom desire) are issued, and if they occur, are
|
||||
Then, combined pledge moves are checked for. Interestingly, the "wasMoveEffective" flag is set to false if the delay occurs
|
||||
In either case, the phase should end here without proceeding
|
||||
In either case, the phase should end here without proceeding
|
||||
*/
|
||||
|
||||
const move = this.move.getMove();
|
||||
|
@ -1,11 +1,13 @@
|
||||
// biome-ignore-start lint/correctness/noUnusedImports: Used in a TSDoc comment
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
// biome-ignore-end lint/correctness/noUnusedImports: Used in a TSDoc comment
|
||||
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { POKERUS_STARTER_COUNT, speciesStarterCosts } from "#balance/starters";
|
||||
import { allSpecies } from "#data/data-lists";
|
||||
import type { PokemonSpecies, PokemonSpeciesForm } from "#data/pokemon-species";
|
||||
import { BattlerIndex } from "#enums/battler-index";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
// biome-ignore lint/correctness/noUnusedImports: Used in a TSDoc comment
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import { randSeedItem } from "./common";
|
||||
|
||||
/**
|
||||
|
@ -90,7 +90,7 @@ describe("Moves - Dig", () => {
|
||||
expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS);
|
||||
});
|
||||
|
||||
it("should expend PP when the attack phase is cancelled", async () => {
|
||||
it("should expend PP when the attack phase is cancelled by sleep", async () => {
|
||||
game.override.enemyAbility(AbilityId.NO_GUARD).enemyMoveset(MoveId.SPORE);
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||
|
@ -74,7 +74,7 @@ describe("Moves - Dive", () => {
|
||||
expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS);
|
||||
});
|
||||
|
||||
it("should expend PP when the attack phase is cancelled", async () => {
|
||||
it("should expend PP when the attack phase is cancelled by sleep", async () => {
|
||||
game.override.enemyAbility(AbilityId.NO_GUARD).enemyMoveset(MoveId.SPORE);
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||
|
@ -84,7 +84,7 @@ describe("UI - Type Hints", () => {
|
||||
await game.phaseInterceptor.to("CommandPhase");
|
||||
});
|
||||
|
||||
it("should show the proper hint for a move in doubles after one of the enemy pokemon flees", async () => {
|
||||
it("should show the proper hint for a move in doubles after one of the enemy pokemon faints", async () => {
|
||||
game.override
|
||||
.enemySpecies(SpeciesId.ABRA)
|
||||
.moveset([MoveId.SPLASH, MoveId.SHADOW_BALL, MoveId.SOAK])
|
||||
|
Loading…
Reference in New Issue
Block a user