Implement Quick Guard and other conditional team protection moves (#1275)
* Implement conditional protection arena tag Affected moves: - Quick Guard - Wide Guard - Mat Block - Crafty Shield - Feint (updated) * Add support for moves that ignore Protect to conditional protection moves * Comments for protect arena tags * ESLint --------- Co-authored-by: Benjamin Odom <bennybroseph@gmail.com>
This commit is contained in:
parent
5c327e347a
commit
4ffff8e1ee
|
@ -1,7 +1,7 @@
|
||||||
import { Arena } from "../field/arena";
|
import { Arena } from "../field/arena";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { MoveCategory, allMoves } from "./move";
|
import { MoveCategory, allMoves, MoveTarget } from "./move";
|
||||||
import { getPokemonMessage } from "../messages";
|
import { getPokemonMessage } from "../messages";
|
||||||
import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
|
import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
|
||||||
import { MoveEffectPhase, PokemonHealPhase, StatChangePhase} from "../phases";
|
import { MoveEffectPhase, PokemonHealPhase, StatChangePhase} from "../phases";
|
||||||
|
@ -11,6 +11,7 @@ import { Moves } from "./enums/moves";
|
||||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||||
import { BlockNonDirectDamageAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
|
import { BlockNonDirectDamageAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
|
||||||
import { BattleStat } from "./battle-stat";
|
import { BattleStat } from "./battle-stat";
|
||||||
|
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
|
||||||
|
|
||||||
export enum ArenaTagSide {
|
export enum ArenaTagSide {
|
||||||
BOTH,
|
BOTH,
|
||||||
|
@ -146,6 +147,128 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProtectConditionFunc = (...args: any[]) => boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class to implement conditional team protection
|
||||||
|
* applies protection based on the attributes of incoming moves
|
||||||
|
* @param protectConditionFunc: The function determining if an incoming move is negated
|
||||||
|
*/
|
||||||
|
abstract class ConditionalProtectTag extends ArenaTag {
|
||||||
|
protected protectConditionFunc: ProtectConditionFunc;
|
||||||
|
|
||||||
|
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, condition: ProtectConditionFunc) {
|
||||||
|
super(tagType, 1, sourceMove, sourceId, side);
|
||||||
|
|
||||||
|
this.protectConditionFunc = condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd(arena: Arena): void {
|
||||||
|
arena.scene.queueMessage(`${super.getMoveName()} protected${this.side === ArenaTagSide.PLAYER ? " your" : this.side === ArenaTagSide.ENEMY ? " the\nopposing" : ""} team!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes default message for effect removal
|
||||||
|
onRemove(arena: Arena): void { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply(): Checks incoming moves against the condition function
|
||||||
|
* and protects the target if conditions are met
|
||||||
|
* @param arena The arena containing this tag
|
||||||
|
* @param args[0] (Utils.BooleanHolder) Signals if the move is cancelled
|
||||||
|
* @param args[1] (Pokemon) The intended target of the move
|
||||||
|
* @param args[2...] (any[]) The parameters to the condition function
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
apply(arena: Arena, args: any[]): boolean {
|
||||||
|
if ((args[0] as Utils.BooleanHolder).value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = args[1] as Pokemon;
|
||||||
|
if ((this.side === ArenaTagSide.PLAYER) === target.isPlayer()
|
||||||
|
&& this.protectConditionFunc(...args.slice(2))) {
|
||||||
|
(args[0] as Utils.BooleanHolder).value = true;
|
||||||
|
new CommonBattleAnim(CommonAnim.PROTECT, target).play(arena.scene);
|
||||||
|
arena.scene.queueMessage(`${super.getMoveName()} protected ${getPokemonMessage(target, "!")}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Quick_Guard_(move) Quick Guard}
|
||||||
|
* Condition: The incoming move has increased priority.
|
||||||
|
*/
|
||||||
|
class QuickGuardTag extends ConditionalProtectTag {
|
||||||
|
constructor(sourceId: integer, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side,
|
||||||
|
(priority: integer) : boolean => {
|
||||||
|
return priority > 0;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Wide_Guard_(move) Wide Guard}
|
||||||
|
* Condition: The incoming move can target multiple Pokemon. The move's source
|
||||||
|
* can be an ally or enemy.
|
||||||
|
*/
|
||||||
|
class WideGuardTag extends ConditionalProtectTag {
|
||||||
|
constructor(sourceId: integer, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side,
|
||||||
|
(moveTarget: MoveTarget) : boolean => {
|
||||||
|
switch (moveTarget) {
|
||||||
|
case MoveTarget.ALL_ENEMIES:
|
||||||
|
case MoveTarget.ALL_NEAR_ENEMIES:
|
||||||
|
case MoveTarget.ALL_OTHERS:
|
||||||
|
case MoveTarget.ALL_NEAR_OTHERS:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Mat_Block_(move) Mat Block}
|
||||||
|
* Condition: The incoming move is a Physical or Special attack move.
|
||||||
|
*/
|
||||||
|
class MatBlockTag extends ConditionalProtectTag {
|
||||||
|
constructor(sourceId: integer, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side,
|
||||||
|
(moveCategory: MoveCategory) : boolean => {
|
||||||
|
return moveCategory !== MoveCategory.STATUS;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd(arena: Arena) {
|
||||||
|
const source = arena.scene.getPokemonById(this.sourceId);
|
||||||
|
arena.scene.queueMessage(getPokemonMessage(source, " intends to flip up a mat\nand block incoming attacks!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Crafty_Shield_(move) Crafty Shield}
|
||||||
|
* Condition: The incoming move is a Status move, is not a hazard, and does
|
||||||
|
* not target all Pokemon or sides of the field.
|
||||||
|
*/
|
||||||
|
class CraftyShieldTag extends ConditionalProtectTag {
|
||||||
|
constructor(sourceId: integer, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side,
|
||||||
|
(moveCategory: MoveCategory, moveTarget: MoveTarget) : boolean => {
|
||||||
|
return moveCategory === MoveCategory.STATUS
|
||||||
|
&& moveTarget !== MoveTarget.ENEMY_SIDE
|
||||||
|
&& moveTarget !== MoveTarget.BOTH_SIDES
|
||||||
|
&& moveTarget !== MoveTarget.ALL;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class WishTag extends ArenaTag {
|
class WishTag extends ArenaTag {
|
||||||
private battlerIndex: BattlerIndex;
|
private battlerIndex: BattlerIndex;
|
||||||
private triggerMessage: string;
|
private triggerMessage: string;
|
||||||
|
@ -513,6 +636,14 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
||||||
switch (tagType) {
|
switch (tagType) {
|
||||||
case ArenaTagType.MIST:
|
case ArenaTagType.MIST:
|
||||||
return new MistTag(turnCount, sourceId, side);
|
return new MistTag(turnCount, sourceId, side);
|
||||||
|
case ArenaTagType.QUICK_GUARD:
|
||||||
|
return new QuickGuardTag(sourceId, side);
|
||||||
|
case ArenaTagType.WIDE_GUARD:
|
||||||
|
return new WideGuardTag(sourceId, side);
|
||||||
|
case ArenaTagType.MAT_BLOCK:
|
||||||
|
return new MatBlockTag(sourceId, side);
|
||||||
|
case ArenaTagType.CRAFTY_SHIELD:
|
||||||
|
return new CraftyShieldTag(sourceId, side);
|
||||||
case ArenaTagType.MUD_SPORT:
|
case ArenaTagType.MUD_SPORT:
|
||||||
return new MudSportTag(turnCount, sourceId);
|
return new MudSportTag(turnCount, sourceId);
|
||||||
case ArenaTagType.WATER_SPORT:
|
case ArenaTagType.WATER_SPORT:
|
||||||
|
|
|
@ -16,5 +16,9 @@ export enum ArenaTagType {
|
||||||
REFLECT = "REFLECT",
|
REFLECT = "REFLECT",
|
||||||
LIGHT_SCREEN = "LIGHT_SCREEN",
|
LIGHT_SCREEN = "LIGHT_SCREEN",
|
||||||
AURORA_VEIL = "AURORA_VEIL",
|
AURORA_VEIL = "AURORA_VEIL",
|
||||||
|
QUICK_GUARD = "QUICK_GUARD",
|
||||||
|
WIDE_GUARD = "WIDE_GUARD",
|
||||||
|
MAT_BLOCK = "MAT_BLOCK",
|
||||||
|
CRAFTY_SHIELD = "CRAFTY_SHIELD",
|
||||||
TAILWIND = "TAILWIND"
|
TAILWIND = "TAILWIND"
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,6 +204,19 @@ export default class Move implements Localizable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAllyTarget(): boolean {
|
||||||
|
switch (this.moveTarget) {
|
||||||
|
case MoveTarget.USER:
|
||||||
|
case MoveTarget.NEAR_ALLY:
|
||||||
|
case MoveTarget.ALLY:
|
||||||
|
case MoveTarget.USER_OR_NEAR_ALLY:
|
||||||
|
case MoveTarget.USER_AND_ALLIES:
|
||||||
|
case MoveTarget.USER_SIDE:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
isTypeImmune(type: Type): boolean {
|
isTypeImmune(type: Type): boolean {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type.GRASS:
|
case Type.GRASS:
|
||||||
|
@ -3720,6 +3733,37 @@ export class AddArenaTagAttr extends MoveEffectAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic class for removing arena tags
|
||||||
|
* @param tagTypes: The types of tags that can be removed
|
||||||
|
* @param selfSideTarget: Is the user removing tags from its own side?
|
||||||
|
*/
|
||||||
|
export class RemoveArenaTagsAttr extends MoveEffectAttr {
|
||||||
|
public tagTypes: ArenaTagType[];
|
||||||
|
public selfSideTarget: boolean;
|
||||||
|
|
||||||
|
constructor(tagTypes: ArenaTagType[], selfSideTarget: boolean) {
|
||||||
|
super(true, MoveEffectTrigger.POST_APPLY);
|
||||||
|
|
||||||
|
this.tagTypes = tagTypes;
|
||||||
|
this.selfSideTarget = selfSideTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if (!super.apply(user, target, move, args)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
|
|
||||||
|
for (const tagType of this.tagTypes) {
|
||||||
|
user.scene.arena.removeTagOnSide(tagType, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class AddArenaTrapTagAttr extends AddArenaTagAttr {
|
export class AddArenaTrapTagAttr extends AddArenaTagAttr {
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
return (user, target, move) => {
|
return (user, target, move) => {
|
||||||
|
@ -5909,6 +5953,7 @@ export function initMoves() {
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new AttackMove(Moves.FEINT, Type.NORMAL, MoveCategory.PHYSICAL, 30, 100, 10, -1, 2, 4)
|
new AttackMove(Moves.FEINT, Type.NORMAL, MoveCategory.PHYSICAL, 30, 100, 10, -1, 2, 4)
|
||||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.PROTECTED ])
|
.attr(RemoveBattlerTagAttr, [ BattlerTagType.PROTECTED ])
|
||||||
|
.attr(RemoveArenaTagsAttr, [ ArenaTagType.QUICK_GUARD, ArenaTagType.WIDE_GUARD, ArenaTagType.MAT_BLOCK, ArenaTagType.CRAFTY_SHIELD ], false)
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.ignoresProtect(),
|
.ignoresProtect(),
|
||||||
new AttackMove(Moves.PLUCK, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4)
|
new AttackMove(Moves.PLUCK, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4)
|
||||||
|
@ -6198,7 +6243,7 @@ export function initMoves() {
|
||||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.ACC ], 1, true),
|
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.ACC ], 1, true),
|
||||||
new StatusMove(Moves.WIDE_GUARD, Type.ROCK, -1, 10, -1, 3, 5)
|
new StatusMove(Moves.WIDE_GUARD, Type.ROCK, -1, 10, -1, 3, 5)
|
||||||
.target(MoveTarget.USER_SIDE)
|
.target(MoveTarget.USER_SIDE)
|
||||||
.unimplemented(),
|
.attr(AddArenaTagAttr, ArenaTagType.WIDE_GUARD, 1, true, true),
|
||||||
new StatusMove(Moves.GUARD_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
new StatusMove(Moves.GUARD_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new StatusMove(Moves.POWER_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
new StatusMove(Moves.POWER_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
||||||
|
@ -6286,7 +6331,7 @@ export function initMoves() {
|
||||||
.attr(StatChangeCountPowerAttr),
|
.attr(StatChangeCountPowerAttr),
|
||||||
new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5)
|
new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5)
|
||||||
.target(MoveTarget.USER_SIDE)
|
.target(MoveTarget.USER_SIDE)
|
||||||
.unimplemented(),
|
.attr(AddArenaTagAttr, ArenaTagType.QUICK_GUARD, 1, true, true),
|
||||||
new SelfStatusMove(Moves.ALLY_SWITCH, Type.PSYCHIC, -1, 15, -1, 2, 5)
|
new SelfStatusMove(Moves.ALLY_SWITCH, Type.PSYCHIC, -1, 15, -1, 2, 5)
|
||||||
.ignoresProtect()
|
.ignoresProtect()
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
|
@ -6452,7 +6497,9 @@ export function initMoves() {
|
||||||
.attr(HitsTagAttr, BattlerTagType.MINIMIZED, true)
|
.attr(HitsTagAttr, BattlerTagType.MINIMIZED, true)
|
||||||
.condition(failOnGravityCondition),
|
.condition(failOnGravityCondition),
|
||||||
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
|
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
|
||||||
.unimplemented(),
|
.target(MoveTarget.USER_SIDE)
|
||||||
|
.attr(AddArenaTagAttr, ArenaTagType.MAT_BLOCK, 1, true, true)
|
||||||
|
.condition(new FirstMoveCondition()),
|
||||||
new AttackMove(Moves.BELCH, Type.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6)
|
new AttackMove(Moves.BELCH, Type.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6)
|
||||||
.condition((user, target, move) => user.battleData.berriesEaten.length > 0),
|
.condition((user, target, move) => user.battleData.berriesEaten.length > 0),
|
||||||
new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, 100, 0, 6)
|
new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, 100, 0, 6)
|
||||||
|
@ -6505,7 +6552,7 @@ export function initMoves() {
|
||||||
.triageMove(),
|
.triageMove(),
|
||||||
new StatusMove(Moves.CRAFTY_SHIELD, Type.FAIRY, -1, 10, -1, 3, 6)
|
new StatusMove(Moves.CRAFTY_SHIELD, Type.FAIRY, -1, 10, -1, 3, 6)
|
||||||
.target(MoveTarget.USER_SIDE)
|
.target(MoveTarget.USER_SIDE)
|
||||||
.unimplemented(),
|
.attr(AddArenaTagAttr, ArenaTagType.CRAFTY_SHIELD, 1, true, true),
|
||||||
new StatusMove(Moves.FLOWER_SHIELD, Type.FAIRY, -1, 10, 100, 0, 6)
|
new StatusMove(Moves.FLOWER_SHIELD, Type.FAIRY, -1, 10, 100, 0, 6)
|
||||||
.target(MoveTarget.ALL)
|
.target(MoveTarget.ALL)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
||||||
import { variantData } from "#app/data/variant";
|
import { variantData } from "#app/data/variant";
|
||||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
|
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
|
||||||
import { Moves } from "../data/enums/moves";
|
import { Moves } from "../data/enums/moves";
|
||||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit } from "../data/move";
|
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, MoveFlags } from "../data/move";
|
||||||
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
|
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type";
|
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type";
|
||||||
|
@ -1613,6 +1613,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
typeMultiplier.value = 0;
|
typeMultiplier.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply arena tags for conditional protection
|
||||||
|
if (!move.hasFlag(MoveFlags.IGNORE_PROTECT) && !move.isAllyTarget()) {
|
||||||
|
const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
|
this.scene.arena.applyTagsForSide(ArenaTagType.QUICK_GUARD, defendingSide, cancelled, this, move.priority);
|
||||||
|
this.scene.arena.applyTagsForSide(ArenaTagType.WIDE_GUARD, defendingSide, cancelled, this, move.moveTarget);
|
||||||
|
this.scene.arena.applyTagsForSide(ArenaTagType.MAT_BLOCK, defendingSide, cancelled, this, move.category);
|
||||||
|
this.scene.arena.applyTagsForSide(ArenaTagType.CRAFTY_SHIELD, defendingSide, cancelled, this, move.category, move.moveTarget);
|
||||||
|
}
|
||||||
|
|
||||||
switch (moveCategory) {
|
switch (moveCategory) {
|
||||||
case MoveCategory.PHYSICAL:
|
case MoveCategory.PHYSICAL:
|
||||||
case MoveCategory.SPECIAL:
|
case MoveCategory.SPECIAL:
|
||||||
|
|
Loading…
Reference in New Issue