mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-22 07:19:28 +02:00
Integrate MoveChargePhase
in battle phase sequence
This commit is contained in:
parent
e9f82af5ea
commit
d613ffe7a8
@ -289,10 +289,9 @@ export default class Move implements Localizable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter function that returns if the move targets itself or an ally
|
* Getter function that returns if the move targets the user or its ally
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isAllyTarget(): boolean {
|
isAllyTarget(): boolean {
|
||||||
switch (this.moveTarget) {
|
switch (this.moveTarget) {
|
||||||
case MoveTarget.USER:
|
case MoveTarget.USER:
|
||||||
@ -306,6 +305,10 @@ export default class Move implements Localizable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isChargingMove(): this is ChargingMove {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the move is immune to certain types.
|
* Checks if the move is immune to certain types.
|
||||||
* Currently looks at cases of Grass types with powder moves and Dark types with moves affected by Prankster.
|
* Currently looks at cases of Grass types with powder moves and Dark types with moves affected by Prankster.
|
||||||
@ -884,7 +887,7 @@ export class SelfStatusMove extends Move {
|
|||||||
type SubMove = new (...args: any[]) => Move;
|
type SubMove = new (...args: any[]) => Move;
|
||||||
|
|
||||||
function ChargeMove<TBase extends SubMove>(Base: TBase) {
|
function ChargeMove<TBase extends SubMove>(Base: TBase) {
|
||||||
return class ChargingMove extends Base {
|
return class extends Base {
|
||||||
/** The animation to play during the move's charging phase */
|
/** The animation to play during the move's charging phase */
|
||||||
public readonly chargeAnim: ChargeAnim = ChargeAnim[`${Moves[this.id]}_CHARGING`];
|
public readonly chargeAnim: ChargeAnim = ChargeAnim[`${Moves[this.id]}_CHARGING`];
|
||||||
/** The message to show during the move's charging phase */
|
/** The message to show during the move's charging phase */
|
||||||
@ -893,6 +896,10 @@ function ChargeMove<TBase extends SubMove>(Base: TBase) {
|
|||||||
/** Move attributes that apply during the move's charging phase */
|
/** Move attributes that apply during the move's charging phase */
|
||||||
public chargeAttrs: MoveAttr[] = [];
|
public chargeAttrs: MoveAttr[] = [];
|
||||||
|
|
||||||
|
override isChargingMove(): this is ChargingMove {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the text to be displayed during this move's charging phase.
|
* Sets the text to be displayed during this move's charging phase.
|
||||||
* References to the user Pokemon should be written as "{USER}", and
|
* References to the user Pokemon should be written as "{USER}", and
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { MoveChargeAnim } from "#app/data/battle-anims";
|
import { MoveChargeAnim } from "#app/data/battle-anims";
|
||||||
import { ChargingAttackMove, ChargingSelfStatusMove, applyMoveChargeAttrs, MoveEffectAttr, InstantChargeAttr } from "#app/data/move";
|
import { applyMoveChargeAttrs, MoveEffectAttr, InstantChargeAttr } from "#app/data/move";
|
||||||
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
||||||
import { BooleanHolder } from "#app/utils";
|
import { BooleanHolder } from "#app/utils";
|
||||||
import { MovePhase } from "#app/phases/move-phase";
|
import { MovePhase } from "#app/phases/move-phase";
|
||||||
@ -31,7 +31,7 @@ export class MoveChargePhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const move = this.move.getMove();
|
const move = this.move.getMove();
|
||||||
if (!(move instanceof ChargingAttackMove || move instanceof ChargingSelfStatusMove)) {
|
if (!(move.isChargingMove())) {
|
||||||
return this.end();
|
return this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,11 +39,6 @@ export class MoveChargePhase extends PokemonPhase {
|
|||||||
move.showChargeText(user, target);
|
move.showChargeText(user, target);
|
||||||
user.getMoveQueue().push({ move: move.id, targets: [ target?.getBattlerIndex() ]});
|
user.getMoveQueue().push({ move: move.id, targets: [ target?.getBattlerIndex() ]});
|
||||||
|
|
||||||
if (move instanceof ChargingSelfStatusMove) {
|
|
||||||
user.addTag(BattlerTagType.CHARGING, 1, move.id, user.id);
|
|
||||||
return this.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
applyMoveChargeAttrs(MoveEffectAttr, user, target, move).then(() => {
|
applyMoveChargeAttrs(MoveEffectAttr, user, target, move).then(() => {
|
||||||
user.addTag(BattlerTagType.CHARGING, 1, move.id, user.id);
|
user.addTag(BattlerTagType.CHARGING, 1, move.id, user.id);
|
||||||
this.end();
|
this.end();
|
||||||
@ -51,11 +46,12 @@ export class MoveChargePhase extends PokemonPhase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Checks the move's instant charge conditions, then ends this phase. */
|
||||||
end() {
|
end() {
|
||||||
const user = this.getUserPokemon();
|
const user = this.getUserPokemon();
|
||||||
const move = this.move.getMove();
|
const move = this.move.getMove();
|
||||||
|
|
||||||
if (move instanceof ChargingAttackMove || move instanceof ChargingSelfStatusMove) {
|
if (move.isChargingMove()) {
|
||||||
const instantCharge = new BooleanHolder(false);
|
const instantCharge = new BooleanHolder(false);
|
||||||
|
|
||||||
applyMoveChargeAttrs(InstantChargeAttr, user, null, move, instantCharge);
|
applyMoveChargeAttrs(InstantChargeAttr, user, null, move, instantCharge);
|
||||||
@ -69,11 +65,11 @@ export class MoveChargePhase extends PokemonPhase {
|
|||||||
super.end();
|
super.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserPokemon(): Pokemon {
|
protected getUserPokemon(): Pokemon {
|
||||||
return (this.player ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.fieldIndex];
|
return (this.player ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.fieldIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTargetPokemon(): Pokemon | undefined {
|
protected getTargetPokemon(): Pokemon | undefined {
|
||||||
return this.scene.getField(true).find((p) => this.targetIndex === p.getBattlerIndex());
|
return this.scene.getField(true).find((p) => this.targetIndex === p.getBattlerIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr,
|
|||||||
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
||||||
import { MoveAnim } from "#app/data/battle-anims";
|
import { MoveAnim } from "#app/data/battle-anims";
|
||||||
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags";
|
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags";
|
||||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move";
|
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move";
|
||||||
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
|
||||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
@ -239,15 +239,13 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
user, target, move).then(() => {
|
user, target, move).then(() => {
|
||||||
// All other effects require the move to not have failed or have been cancelled to trigger
|
// All other effects require the move to not have failed or have been cancelled to trigger
|
||||||
if (hitResult !== HitResult.FAIL) {
|
if (hitResult !== HitResult.FAIL) {
|
||||||
/** Are the move's effects tied to the first turn of a charge move? */
|
|
||||||
const chargeEffect = !!move.getAttrs(ChargeAttr).find(ca => ca.usedChargeEffect(user, this.getTarget() ?? null, move));
|
|
||||||
/**
|
/**
|
||||||
* If the invoked move's effects are meant to trigger during the move's "charge turn,"
|
* If the invoked move's effects are meant to trigger during the move's "charge turn,"
|
||||||
* ignore all effects after this point.
|
* ignore all effects after this point.
|
||||||
* Otherwise, apply all self-targeted POST_APPLY effects.
|
* Otherwise, apply all self-targeted POST_APPLY effects.
|
||||||
*/
|
*/
|
||||||
Utils.executeIf(!chargeEffect, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_APPLY
|
applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_APPLY
|
||||||
&& attr.selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, move)).then(() => {
|
&& attr.selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, move).then(() => {
|
||||||
// All effects past this point require the move to have hit the target
|
// All effects past this point require the move to have hit the target
|
||||||
if (hitResult !== HitResult.NO_EFFECT) {
|
if (hitResult !== HitResult.NO_EFFECT) {
|
||||||
// Apply all non-self-targeted POST_APPLY effects
|
// Apply all non-self-targeted POST_APPLY effects
|
||||||
@ -265,7 +263,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the move was not protected against, apply all HIT effects
|
// If the move was not protected against, apply all HIT effects
|
||||||
Utils.executeIf(!isProtected && !chargeEffect, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.HIT
|
Utils.executeIf(!isProtected, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.HIT
|
||||||
&& (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && (!attr.firstTargetOnly || firstTarget), user, target, this.move.getMove()).then(() => {
|
&& (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && (!attr.firstTargetOnly || firstTarget), user, target, this.move.getMove()).then(() => {
|
||||||
// Apply the target's post-defend ability effects (as long as the target is active or can otherwise apply them)
|
// Apply the target's post-defend ability effects (as long as the target is active or can otherwise apply them)
|
||||||
return Utils.executeIf(!target.isFainted() || target.canApplyAbility(), () => applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult).then(() => {
|
return Utils.executeIf(!target.isFainted() || target.canApplyAbility(), () => applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult).then(() => {
|
||||||
|
@ -22,6 +22,7 @@ import { MoveEndPhase } from "#app/phases/move-end-phase";
|
|||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { MoveChargePhase } from "./move-charge-phase";
|
||||||
|
|
||||||
export class MovePhase extends BattlePhase {
|
export class MovePhase extends BattlePhase {
|
||||||
protected _pokemon: Pokemon;
|
protected _pokemon: Pokemon;
|
||||||
@ -132,6 +133,8 @@ export class MovePhase extends BattlePhase {
|
|||||||
|
|
||||||
if (this.cancelled || this.failed) {
|
if (this.cancelled || this.failed) {
|
||||||
this.handlePreMoveFailures();
|
this.handlePreMoveFailures();
|
||||||
|
} else if (this.move.getMove().isChargingMove() && !this.pokemon.getTag(BattlerTagType.CHARGING)) {
|
||||||
|
this.chargeMove();
|
||||||
} else {
|
} else {
|
||||||
this.useMove();
|
this.useMove();
|
||||||
}
|
}
|
||||||
@ -295,6 +298,11 @@ export class MovePhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Queues a {@linkcode MoveChargePhase} for this phase's invoked move. */
|
||||||
|
protected chargeMove() {
|
||||||
|
this.scene.unshiftPhase(new MoveChargePhase(this.scene, this.pokemon.getBattlerIndex(), this.targets[0], this.move));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`,
|
* Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`,
|
||||||
* then ends the phase.
|
* then ends the phase.
|
||||||
|
Loading…
Reference in New Issue
Block a user