mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-21 14:59:26 +02:00
Fix indentation in move-effect-phase.ts
Rename `getTarget` to `getFirstTarget` for clarity Convert namespace import to named imports Add `public`/etc to methods
This commit is contained in:
parent
4d05fb7021
commit
62962e8305
@ -1,20 +1,20 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, applyPostDefendAbAttrs, PostDefendAbAttr, applyPostAttackAbAttrs, PostAttackAbAttr, MaxMultiHitAbAttr, AlwaysHitAbAttr, TypeImmunityAbAttr } from "#app/data/ability";
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import { AddSecondStrikeAbAttr, AlwaysHitAbAttr, IgnoreMoveEffectsAbAttr, MaxMultiHitAbAttr, PostAttackAbAttr, PostDefendAbAttr, TypeImmunityAbAttr, applyPostAttackAbAttrs, applyPostDefendAbAttrs, applyPreAttackAbAttrs } from "#app/data/ability";
|
||||||
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 { AttackMove, ChargeAttr, FixedDamageAttr, HitsTagAttr, MissEffectAttr, MoveAttr, MoveCategory, MoveEffectAttr, MoveEffectTrigger, MoveFlags, MoveTarget, MultiHitAttr, NoEffectAttr, OverrideMoveEffectAttr, ToxicAccuracyAttr, VariableTargetAttr, applyFilteredMoveAttrs, applyMoveAttrs } 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 { Moves } from "#app/enums/moves";
|
|
||||||
import Pokemon, { PokemonMove, MoveResult, HitResult } from "#app/field/pokemon";
|
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
|
||||||
import { PokemonMultiHitModifier, FlinchChanceModifier, EnemyAttackStatusEffectChanceModifier, ContactHeldItemTransferChanceModifier, HitHealModifier } from "#app/modifier/modifier";
|
|
||||||
import i18next from "i18next";
|
|
||||||
import * as Utils from "#app/utils";
|
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
|
||||||
import { Type } from "#app/data/type";
|
import { Type } from "#app/data/type";
|
||||||
|
import Pokemon, { HitResult, MoveResult, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, FlinchChanceModifier, HitHealModifier, PokemonMultiHitModifier } from "#app/modifier/modifier";
|
||||||
|
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
||||||
|
import { BooleanHolder, NumberHolder, executeIf } from "#app/utils";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class MoveEffectPhase extends PokemonPhase {
|
export class MoveEffectPhase extends PokemonPhase {
|
||||||
public move: PokemonMove;
|
public move: PokemonMove;
|
||||||
@ -35,7 +35,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
this.targets = targets;
|
this.targets = targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
public start() {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
/** The Pokemon using this phase's invoked move */
|
/** The Pokemon using this phase's invoked move */
|
||||||
@ -52,12 +52,12 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* Does an effect from this move override other effects on this turn?
|
* Does an effect from this move override other effects on this turn?
|
||||||
* e.g. Charging moves (Fly, etc.) on their first turn of use.
|
* e.g. Charging moves (Fly, etc.) on their first turn of use.
|
||||||
*/
|
*/
|
||||||
const overridden = new Utils.BooleanHolder(false);
|
const overridden = new BooleanHolder(false);
|
||||||
/** The {@linkcode Move} object from {@linkcode allMoves} invoked by this phase */
|
/** The {@linkcode Move} object from {@linkcode allMoves} invoked by this phase */
|
||||||
const move = this.move.getMove();
|
const move = this.move.getMove();
|
||||||
|
|
||||||
// Assume single target for override
|
// Assume single target for override
|
||||||
applyMoveAttrs(OverrideMoveEffectAttr, user, this.getTarget() ?? null, move, overridden, this.move.virtual).then(() => {
|
applyMoveAttrs(OverrideMoveEffectAttr, user, this.getFirstTarget() ?? null, move, overridden, this.move.virtual).then(() => {
|
||||||
// If other effects were overriden, stop this phase before they can be applied
|
// If other effects were overriden, stop this phase before they can be applied
|
||||||
if (overridden.value) {
|
if (overridden.value) {
|
||||||
return this.end();
|
return this.end();
|
||||||
@ -71,14 +71,14 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* effects of the move itself, Parental Bond, and Multi-Lens to do so.
|
* effects of the move itself, Parental Bond, and Multi-Lens to do so.
|
||||||
*/
|
*/
|
||||||
if (user.turnData.hitsLeft === -1) {
|
if (user.turnData.hitsLeft === -1) {
|
||||||
const hitCount = new Utils.IntegerHolder(1);
|
const hitCount = new NumberHolder(1);
|
||||||
// Assume single target for multi hit
|
// Assume single target for multi hit
|
||||||
applyMoveAttrs(MultiHitAttr, user, this.getTarget() ?? null, move, hitCount);
|
applyMoveAttrs(MultiHitAttr, user, this.getFirstTarget() ?? null, move, hitCount);
|
||||||
// If Parental Bond is applicable, double the hit count
|
// If Parental Bond is applicable, double the hit count
|
||||||
applyPreAttackAbAttrs(AddSecondStrikeAbAttr, user, null, move, false, targets.length, hitCount, new Utils.IntegerHolder(0));
|
applyPreAttackAbAttrs(AddSecondStrikeAbAttr, user, null, move, false, targets.length, hitCount, new NumberHolder(0));
|
||||||
// If Multi-Lens is applicable, multiply the hit count by 1 + the number of Multi-Lenses held by the user
|
// If Multi-Lens is applicable, multiply the hit count by 1 + the number of Multi-Lenses held by the user
|
||||||
if (move instanceof AttackMove && !move.hasAttr(FixedDamageAttr)) {
|
if (move instanceof AttackMove && !move.hasAttr(FixedDamageAttr)) {
|
||||||
this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new Utils.IntegerHolder(0));
|
this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new NumberHolder(0));
|
||||||
}
|
}
|
||||||
// Set the user's relevant turnData fields to reflect the final hit count
|
// Set the user's relevant turnData fields to reflect the final hit count
|
||||||
user.turnData.hitCount = hitCount.value;
|
user.turnData.hitCount = hitCount.value;
|
||||||
@ -107,11 +107,10 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* (and not random target) and failed the hit check against its target (MISS), log the move
|
* (and not random target) and failed the hit check against its target (MISS), log the move
|
||||||
* as FAILed or MISSed (depending on the conditions above) and end this phase.
|
* as FAILed or MISSed (depending on the conditions above) and end this phase.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag) && !isImmune)) {
|
if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag) && !isImmune)) {
|
||||||
this.stopMultiHit();
|
this.stopMultiHit();
|
||||||
if (hasActiveTargets) {
|
if (hasActiveTargets) {
|
||||||
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget() ? getPokemonNameWithAffix(this.getTarget()!) : "" }));
|
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getFirstTarget() ? getPokemonNameWithAffix(this.getFirstTarget()!) : "" }));
|
||||||
moveHistoryEntry.result = MoveResult.MISS;
|
moveHistoryEntry.result = MoveResult.MISS;
|
||||||
applyMoveAttrs(MissEffectAttr, user, null, move);
|
applyMoveAttrs(MissEffectAttr, user, null, move);
|
||||||
} else {
|
} else {
|
||||||
@ -127,7 +126,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
|
|
||||||
const playOnEmptyField = this.scene.currentBattle?.mysteryEncounter?.hasBattleAnimationsWithoutTargets ?? false;
|
const playOnEmptyField = this.scene.currentBattle?.mysteryEncounter?.hasBattleAnimationsWithoutTargets ?? false;
|
||||||
// Move animation only needs one target
|
// Move animation only needs one target
|
||||||
new MoveAnim(move.id as Moves, user, this.getTarget()!.getBattlerIndex()!, playOnEmptyField).play(this.scene, move.hitsSubstitute(user, this.getTarget()!), () => {
|
new MoveAnim(move.id as Moves, user, this.getFirstTarget()!.getBattlerIndex()!, playOnEmptyField).play(this.scene, move.hitsSubstitute(user, this.getFirstTarget()!), () => {
|
||||||
/** Has the move successfully hit a target (for damage) yet? */
|
/** Has the move successfully hit a target (for damage) yet? */
|
||||||
let hasHit: boolean = false;
|
let hasHit: boolean = false;
|
||||||
for (const target of targets) {
|
for (const target of targets) {
|
||||||
@ -135,9 +134,9 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
/** The {@linkcode ArenaTagSide} to which the target belongs */
|
/** The {@linkcode ArenaTagSide} to which the target belongs */
|
||||||
const targetSide = target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
const targetSide = target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
/** Has the invoked move been cancelled by conditional protection (e.g Quick Guard)? */
|
/** Has the invoked move been cancelled by conditional protection (e.g Quick Guard)? */
|
||||||
const hasConditionalProtectApplied = new Utils.BooleanHolder(false);
|
const hasConditionalProtectApplied = new BooleanHolder(false);
|
||||||
/** Does the applied conditional protection bypass Protect-ignoring effects? */
|
/** Does the applied conditional protection bypass Protect-ignoring effects? */
|
||||||
const bypassIgnoreProtect = new Utils.BooleanHolder(false);
|
const bypassIgnoreProtect = new BooleanHolder(false);
|
||||||
/** If the move is not targeting a Pokemon on the user's side, try to apply conditional protection effects */
|
/** If the move is not targeting a Pokemon on the user's side, try to apply conditional protection effects */
|
||||||
if (!this.move.getMove().isAllyTarget()) {
|
if (!this.move.getMove().isAllyTarget()) {
|
||||||
this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect);
|
this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect);
|
||||||
@ -217,7 +216,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Does this phase represent the invoked move's last strike? */
|
/** Does this phase represent the invoked move's last strike? */
|
||||||
const lastHit = (user.turnData.hitsLeft === 1 || !this.getTarget()?.isActive());
|
const lastHit = (user.turnData.hitsLeft === 1 || !this.getFirstTarget()?.isActive());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the user can change forms by using the invoked move,
|
* If the user can change forms by using the invoked move,
|
||||||
@ -235,18 +234,18 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
*/
|
*/
|
||||||
applyAttrs.push(new Promise(resolve => {
|
applyAttrs.push(new Promise(resolve => {
|
||||||
// Apply all effects with PRE_MOVE triggers (if the target isn't immune to the move)
|
// Apply all effects with PRE_MOVE triggers (if the target isn't immune to the move)
|
||||||
applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.PRE_APPLY && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && hitResult !== HitResult.NO_EFFECT,
|
applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.PRE_APPLY
|
||||||
user, target, move).then(() => {
|
&& (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && hitResult !== HitResult.NO_EFFECT, 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? */
|
/** 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));
|
const chargeEffect = !!move.getAttrs(ChargeAttr).find(ca => ca.usedChargeEffect(user, this.getFirstTarget() ?? 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
|
executeIf(!chargeEffect, () => 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) {
|
||||||
@ -258,17 +257,17 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* apply the chance to flinch the target gained from King's Rock
|
* apply the chance to flinch the target gained from King's Rock
|
||||||
*/
|
*/
|
||||||
if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && !move.hitsSubstitute(user, target)) {
|
if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && !move.hitsSubstitute(user, target)) {
|
||||||
const flinched = new Utils.BooleanHolder(false);
|
const flinched = new BooleanHolder(false);
|
||||||
user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched);
|
user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched);
|
||||||
if (flinched.value) {
|
if (flinched.value) {
|
||||||
target.addTag(BattlerTagType.FLINCHED, undefined, this.move.moveId, user.id);
|
target.addTag(BattlerTagType.FLINCHED, undefined, this.move.moveId, user.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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
|
executeIf(!isProtected && !chargeEffect, () => 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 executeIf(!target.isFainted() || target.canApplyAbility(), () => applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult).then(() => {
|
||||||
// Only apply the following effects if the move was not deflected by a substitute
|
// Only apply the following effects if the move was not deflected by a substitute
|
||||||
if (move.hitsSubstitute(user, target)) {
|
if (move.hitsSubstitute(user, target)) {
|
||||||
return resolve();
|
return resolve();
|
||||||
@ -309,7 +308,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// Apply the move's POST_TARGET effects on the move's last hit, after all targeted effects have resolved
|
// Apply the move's POST_TARGET effects on the move's last hit, after all targeted effects have resolved
|
||||||
const postTarget = (user.turnData.hitsLeft === 1 || !this.getTarget()?.isActive()) ?
|
const postTarget = (user.turnData.hitsLeft === 1 || !this.getFirstTarget()?.isActive()) ?
|
||||||
applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_TARGET, user, null, move) :
|
applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_TARGET, user, null, move) :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
@ -340,7 +339,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
end() {
|
public end() {
|
||||||
const user = this.getUserPokemon();
|
const user = this.getUserPokemon();
|
||||||
/**
|
/**
|
||||||
* If this phase isn't for the invoked move's last strike,
|
* If this phase isn't for the invoked move's last strike,
|
||||||
@ -350,7 +349,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* to the user.
|
* to the user.
|
||||||
*/
|
*/
|
||||||
if (user) {
|
if (user) {
|
||||||
if (user.turnData.hitsLeft && --user.turnData.hitsLeft >= 1 && this.getTarget()?.isActive()) {
|
if (user.turnData.hitsLeft && --user.turnData.hitsLeft >= 1 && this.getFirstTarget()?.isActive()) {
|
||||||
this.scene.unshiftPhase(this.getNewHitPhase());
|
this.scene.unshiftPhase(this.getNewHitPhase());
|
||||||
} else {
|
} else {
|
||||||
// Queue message for number of hits made by multi-move
|
// Queue message for number of hits made by multi-move
|
||||||
@ -374,7 +373,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* @param target {@linkcode Pokemon} the Pokemon targeted by the invoked move
|
* @param target {@linkcode Pokemon} the Pokemon targeted by the invoked move
|
||||||
* @returns `true` if the move does not miss the target; `false` otherwise
|
* @returns `true` if the move does not miss the target; `false` otherwise
|
||||||
*/
|
*/
|
||||||
hitCheck(target: Pokemon): boolean {
|
public hitCheck(target: Pokemon): boolean {
|
||||||
// Moves targeting the user and entry hazards can't miss
|
// Moves targeting the user and entry hazards can't miss
|
||||||
if ([ MoveTarget.USER, MoveTarget.ENEMY_SIDE ].includes(this.move.getMove().moveTarget)) {
|
if ([ MoveTarget.USER, MoveTarget.ENEMY_SIDE ].includes(this.move.getMove().moveTarget)) {
|
||||||
return true;
|
return true;
|
||||||
@ -425,28 +424,28 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the {@linkcode Pokemon} using this phase's invoked move */
|
/** Returns the {@linkcode Pokemon} using this phase's invoked move */
|
||||||
getUserPokemon(): Pokemon | undefined {
|
public getUserPokemon(): Pokemon | null {
|
||||||
if (this.battlerIndex > BattlerIndex.ENEMY_2) {
|
if (this.battlerIndex > BattlerIndex.ENEMY_2) {
|
||||||
return this.scene.getPokemonById(this.battlerIndex) ?? undefined;
|
return this.scene.getPokemonById(this.battlerIndex);
|
||||||
}
|
}
|
||||||
return (this.player ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.fieldIndex];
|
return (this.player ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.fieldIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an array of all {@linkcode Pokemon} targeted by this phase's invoked move */
|
/** Returns an array of all {@linkcode Pokemon} targeted by this phase's invoked move */
|
||||||
getTargets(): Pokemon[] {
|
public getTargets(): Pokemon[] {
|
||||||
return this.scene.getField(true).filter(p => this.targets.indexOf(p.getBattlerIndex()) > -1);
|
return this.scene.getField(true).filter(p => this.targets.indexOf(p.getBattlerIndex()) > -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the first target of this phase's invoked move */
|
/** Returns the first target of this phase's invoked move */
|
||||||
getTarget(): Pokemon | undefined {
|
public getFirstTarget(): Pokemon | undefined {
|
||||||
return this.getTargets()[0];
|
return this.getTargets()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given {@linkcode Pokemon} from this phase's target list
|
* Removes the given {@linkcode Pokemon} from this phase's target list
|
||||||
* @param target {@linkcode Pokemon} the Pokemon to be removed
|
* @param target - The {@linkcode Pokemon} to be removed
|
||||||
*/
|
*/
|
||||||
removeTarget(target: Pokemon): void {
|
protected removeTarget(target: Pokemon): void {
|
||||||
const targetIndex = this.targets.findIndex(ind => ind === target.getBattlerIndex());
|
const targetIndex = this.targets.findIndex(ind => ind === target.getBattlerIndex());
|
||||||
if (targetIndex !== -1) {
|
if (targetIndex !== -1) {
|
||||||
this.targets.splice(this.targets.findIndex(ind => ind === target.getBattlerIndex()), 1);
|
this.targets.splice(this.targets.findIndex(ind => ind === target.getBattlerIndex()), 1);
|
||||||
@ -455,11 +454,10 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents subsequent strikes of this phase's invoked move from occurring
|
* Prevents subsequent strikes of this phase's invoked move from occurring
|
||||||
* @param target {@linkcode Pokemon} if defined, only stop subsequent
|
* @param target - If defined, only stop subsequent strikes against this {@linkcode Pokemon}
|
||||||
* strikes against this Pokemon
|
|
||||||
*/
|
*/
|
||||||
stopMultiHit(target?: Pokemon): void {
|
public stopMultiHit(target?: Pokemon): void {
|
||||||
/** If given a specific target, remove the target from subsequent strikes */
|
// If given a specific target, remove the target from subsequent strikes
|
||||||
if (target) {
|
if (target) {
|
||||||
this.removeTarget(target);
|
this.removeTarget(target);
|
||||||
}
|
}
|
||||||
@ -468,13 +466,16 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* targets, completely cancel all subsequent strikes.
|
* targets, completely cancel all subsequent strikes.
|
||||||
*/
|
*/
|
||||||
if (!target || this.targets.length === 0) {
|
if (!target || this.targets.length === 0) {
|
||||||
this.getUserPokemon()!.turnData.hitCount = 1; // TODO: is the bang correct here?
|
const userPokemon = this.getUserPokemon();
|
||||||
this.getUserPokemon()!.turnData.hitsLeft = 1; // TODO: is the bang correct here?
|
if (userPokemon) {
|
||||||
|
userPokemon.turnData.hitCount = 1;
|
||||||
|
userPokemon.turnData.hitsLeft = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a new MoveEffectPhase with the same properties as this phase */
|
/** Returns a new `MoveEffectPhase` with the same properties as this phase */
|
||||||
getNewHitPhase() {
|
protected getNewHitPhase() {
|
||||||
return new MoveEffectPhase(this.scene, this.battlerIndex, this.targets, this.move);
|
return new MoveEffectPhase(this.scene, this.battlerIndex, this.targets, this.move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ describe("Abilities - Serene Grace", () => {
|
|||||||
|
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
console.log(move.chance + " Their ability is " + phase.getUserPokemon()!.getAbility().name);
|
console.log(move.chance + " Their ability is " + phase.getUserPokemon()!.getAbility().name);
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getTarget(), false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getFirstTarget(), false);
|
||||||
expect(chance.value).toBe(30);
|
expect(chance.value).toBe(30);
|
||||||
|
|
||||||
}, 20000);
|
}, 20000);
|
||||||
@ -83,7 +83,7 @@ describe("Abilities - Serene Grace", () => {
|
|||||||
expect(move.id).toBe(Moves.AIR_SLASH);
|
expect(move.id).toBe(Moves.AIR_SLASH);
|
||||||
|
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getTarget(), false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getFirstTarget(), false);
|
||||||
expect(chance.value).toBe(60);
|
expect(chance.value).toBe(60);
|
||||||
|
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
@ -59,8 +59,8 @@ describe("Abilities - Sheer Force", () => {
|
|||||||
const power = new Utils.IntegerHolder(move.power);
|
const power = new Utils.IntegerHolder(move.power);
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
|
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getTarget(), false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getFirstTarget(), false);
|
||||||
applyPreAttackAbAttrs(MovePowerBoostAbAttr, phase.getUserPokemon()!, phase.getTarget()!, move, false, power);
|
applyPreAttackAbAttrs(MovePowerBoostAbAttr, phase.getUserPokemon()!, phase.getFirstTarget()!, move, false, power);
|
||||||
|
|
||||||
expect(chance.value).toBe(0);
|
expect(chance.value).toBe(0);
|
||||||
expect(power.value).toBe(move.power * 5461 / 4096);
|
expect(power.value).toBe(move.power * 5461 / 4096);
|
||||||
@ -92,8 +92,8 @@ describe("Abilities - Sheer Force", () => {
|
|||||||
const power = new Utils.IntegerHolder(move.power);
|
const power = new Utils.IntegerHolder(move.power);
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
|
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getTarget(), false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getFirstTarget(), false);
|
||||||
applyPreAttackAbAttrs(MovePowerBoostAbAttr, phase.getUserPokemon()!, phase.getTarget()!, move, false, power);
|
applyPreAttackAbAttrs(MovePowerBoostAbAttr, phase.getUserPokemon()!, phase.getFirstTarget()!, move, false, power);
|
||||||
|
|
||||||
expect(chance.value).toBe(-1);
|
expect(chance.value).toBe(-1);
|
||||||
expect(power.value).toBe(move.power);
|
expect(power.value).toBe(move.power);
|
||||||
@ -125,8 +125,8 @@ describe("Abilities - Sheer Force", () => {
|
|||||||
const power = new Utils.IntegerHolder(move.power);
|
const power = new Utils.IntegerHolder(move.power);
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
|
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getTarget(), false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getFirstTarget(), false);
|
||||||
applyPreAttackAbAttrs(MovePowerBoostAbAttr, phase.getUserPokemon()!, phase.getTarget()!, move, false, power);
|
applyPreAttackAbAttrs(MovePowerBoostAbAttr, phase.getUserPokemon()!, phase.getFirstTarget()!, move, false, power);
|
||||||
|
|
||||||
expect(chance.value).toBe(-1);
|
expect(chance.value).toBe(-1);
|
||||||
expect(power.value).toBe(move.power);
|
expect(power.value).toBe(move.power);
|
||||||
@ -160,7 +160,7 @@ describe("Abilities - Sheer Force", () => {
|
|||||||
const power = new Utils.IntegerHolder(move.power);
|
const power = new Utils.IntegerHolder(move.power);
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
const user = phase.getUserPokemon()!;
|
const user = phase.getUserPokemon()!;
|
||||||
const target = phase.getTarget()!;
|
const target = phase.getFirstTarget()!;
|
||||||
const opponentType = target.getTypes()[0];
|
const opponentType = target.getTypes()[0];
|
||||||
|
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, false, chance, move, target, false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, false, chance, move, target, false);
|
||||||
|
@ -57,8 +57,8 @@ describe("Abilities - Shield Dust", () => {
|
|||||||
expect(move.id).toBe(Moves.AIR_SLASH);
|
expect(move.id).toBe(Moves.AIR_SLASH);
|
||||||
|
|
||||||
const chance = new Utils.IntegerHolder(move.chance);
|
const chance = new Utils.IntegerHolder(move.chance);
|
||||||
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getTarget(), false);
|
applyAbAttrs(MoveEffectChanceMultiplierAbAttr, phase.getUserPokemon()!, null, false, chance, move, phase.getFirstTarget(), false);
|
||||||
applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr, phase.getTarget()!, phase.getUserPokemon()!, null, null, false, chance);
|
applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr, phase.getFirstTarget()!, phase.getUserPokemon()!, null, null, false, chance);
|
||||||
expect(chance.value).toBe(0);
|
expect(chance.value).toBe(0);
|
||||||
|
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
@ -81,7 +81,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
||||||
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
||||||
// Force level cap to be 100
|
// Force level cap to be 100
|
||||||
vi.spyOn(phase.getTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
vi.spyOn(phase.getFirstTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
||||||
await game.phaseInterceptor.to(DamagePhase, false);
|
await game.phaseInterceptor.to(DamagePhase, false);
|
||||||
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(120);
|
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(120);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
@ -98,7 +98,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
||||||
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
||||||
// Force level cap to be 100
|
// Force level cap to be 100
|
||||||
vi.spyOn(phase.getTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
vi.spyOn(phase.getFirstTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
||||||
await game.phaseInterceptor.to(DamagePhase, false);
|
await game.phaseInterceptor.to(DamagePhase, false);
|
||||||
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(140);
|
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(140);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
@ -115,7 +115,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
||||||
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
||||||
// Force level cap to be 100
|
// Force level cap to be 100
|
||||||
vi.spyOn(phase.getTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
vi.spyOn(phase.getFirstTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
||||||
await game.phaseInterceptor.to(DamagePhase, false);
|
await game.phaseInterceptor.to(DamagePhase, false);
|
||||||
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(160);
|
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(160);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
@ -132,7 +132,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
||||||
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
||||||
// Force level cap to be 100
|
// Force level cap to be 100
|
||||||
vi.spyOn(phase.getTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
vi.spyOn(phase.getFirstTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
||||||
await game.phaseInterceptor.to(DamagePhase, false);
|
await game.phaseInterceptor.to(DamagePhase, false);
|
||||||
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(180);
|
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(180);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
@ -149,7 +149,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
const phase = game.scene.getCurrentPhase() as MoveEffectPhase;
|
||||||
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
expect(phase.move.moveId).toBe(dynamaxCannon.id);
|
||||||
// Force level cap to be 100
|
// Force level cap to be 100
|
||||||
vi.spyOn(phase.getTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
vi.spyOn(phase.getFirstTarget()!.scene, "getMaxExpLevel").mockReturnValue(100);
|
||||||
await game.phaseInterceptor.to(DamagePhase, false);
|
await game.phaseInterceptor.to(DamagePhase, false);
|
||||||
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(200);
|
expect(dynamaxCannon.calculateBattlePower).toHaveLastReturnedWith(200);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
Loading…
Reference in New Issue
Block a user