Fixed Crash Moves and Reckless (#609)

* Fixed Crash Moves and Reckless

Added a new MoveFlags flag 'RECKLESS_MOVE' to make crash and recoil moves in line with other move flag boosting attacks.

Modified how flags were defined so they are easier to maintain.

Added the appropriate flag to all mvoes listed as being affected by Reckless. Steel Beam and Mind Blown do not count according to source:
https://bulbapedia.bulbagarden.net/wiki/Reckless_(Ability)

* Update move.ts

* Update abilities.ts
This commit is contained in:
Benjamin Odom 2024-05-07 23:28:35 -05:00 committed by GitHub
parent ce3d12d58e
commit bb6bb1e6c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 66 additions and 33 deletions

View File

@ -3035,7 +3035,7 @@ export function initAbilities() {
new Ability(Abilities.FRISK, 4) new Ability(Abilities.FRISK, 4)
.attr(FriskAbAttr), .attr(FriskAbAttr),
new Ability(Abilities.RECKLESS, 4) new Ability(Abilities.RECKLESS, 4)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.getAttrs(RecoilAttr).length && move.id !== Moves.STRUGGLE, 1.2), .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.RECKLESS_MOVE), 1.2),
new Ability(Abilities.MULTITYPE, 4) new Ability(Abilities.MULTITYPE, 4)
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)

View File

@ -54,22 +54,28 @@ export enum MoveTarget {
} }
export enum MoveFlags { export enum MoveFlags {
MAKES_CONTACT = 1, NONE = 0,
IGNORE_PROTECT = 2, MAKES_CONTACT = 1 << 0,
IGNORE_VIRTUAL = 4, IGNORE_PROTECT = 1 << 1,
SOUND_BASED = 8, IGNORE_VIRTUAL = 1 << 2,
HIDE_USER = 16, SOUND_BASED = 1 << 3,
HIDE_TARGET = 32, HIDE_USER = 1 << 4,
BITING_MOVE = 64, HIDE_TARGET = 1 << 5,
PULSE_MOVE = 128, BITING_MOVE = 1 << 6,
PUNCHING_MOVE = 256, PULSE_MOVE = 1 << 7,
SLICING_MOVE = 512, PUNCHING_MOVE = 1 << 8,
BALLBOMB_MOVE = 1024, SLICING_MOVE = 1 << 9,
POWDER_MOVE = 2048, /**
DANCE_MOVE = 4096, * Indicates a move should be affected by {@link Abilities.RECKLESS}
WIND_MOVE = 8192, * @see {@link Move.recklessMove()}
TRIAGE_MOVE = 16384, */
IGNORE_ABILITIES = 32768 RECKLESS_MOVE = 1 << 10,
BALLBOMB_MOVE = 1 << 11,
POWDER_MOVE = 1 << 12,
DANCE_MOVE = 1 << 13,
WIND_MOVE = 1 << 14,
TRIAGE_MOVE = 1 << 15,
IGNORE_ABILITIES = 1 << 16,
} }
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean; type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
@ -269,6 +275,17 @@ export default class Move implements Localizable {
return this; return this;
} }
/**
* Sets the {@link MoveFlags.RECKLESS_MOVE} flag for the calling Move
* @see {@link Abilities.RECKLESS}
* @param {boolean} recklessMove The value to set the flag to
* @returns {Move} The {@link Move} that called this function
*/
recklessMove(recklessMove?: boolean): this {
this.setFlag(MoveFlags.RECKLESS_MOVE, recklessMove);
return this;
}
ballBombMove(ballBombMove?: boolean): this { ballBombMove(ballBombMove?: boolean): this {
this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove); this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove);
return this; return this;
@ -4073,7 +4090,8 @@ export function initMoves() {
new AttackMove(Moves.JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 1) new AttackMove(Moves.JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 1)
.attr(MissEffectAttr, crashDamageFunc) .attr(MissEffectAttr, crashDamageFunc)
.attr(NoEffectAttr, crashDamageFunc) .attr(NoEffectAttr, crashDamageFunc)
.condition(failOnGravityCondition), .condition(failOnGravityCondition)
.recklessMove(),
new AttackMove(Moves.ROLLING_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 85, 15, 30, 0, 1) new AttackMove(Moves.ROLLING_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 85, 15, 30, 0, 1)
.attr(FlinchAttr), .attr(FlinchAttr),
new StatusMove(Moves.SAND_ATTACK, Type.GROUND, 100, 15, -1, 0, 1) new StatusMove(Moves.SAND_ATTACK, Type.GROUND, 100, 15, -1, 0, 1)
@ -4092,13 +4110,15 @@ export function initMoves() {
new AttackMove(Moves.WRAP, Type.NORMAL, MoveCategory.PHYSICAL, 15, 90, 20, 100, 0, 1) new AttackMove(Moves.WRAP, Type.NORMAL, MoveCategory.PHYSICAL, 15, 90, 20, 100, 0, 1)
.attr(TrapAttr, BattlerTagType.WRAP), .attr(TrapAttr, BattlerTagType.WRAP),
new AttackMove(Moves.TAKE_DOWN, Type.NORMAL, MoveCategory.PHYSICAL, 90, 85, 20, -1, 0, 1) new AttackMove(Moves.TAKE_DOWN, Type.NORMAL, MoveCategory.PHYSICAL, 90, 85, 20, -1, 0, 1)
.attr(RecoilAttr), .attr(RecoilAttr)
.recklessMove(),
new AttackMove(Moves.THRASH, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 1) new AttackMove(Moves.THRASH, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 1)
.attr(FrenzyAttr) .attr(FrenzyAttr)
.attr(MissEffectAttr, frenzyMissFunc) .attr(MissEffectAttr, frenzyMissFunc)
.target(MoveTarget.RANDOM_NEAR_ENEMY), .target(MoveTarget.RANDOM_NEAR_ENEMY),
new AttackMove(Moves.DOUBLE_EDGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 1) new AttackMove(Moves.DOUBLE_EDGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 1)
.attr(RecoilAttr, false, 0.33), .attr(RecoilAttr, false, 0.33)
.recklessMove(),
new StatusMove(Moves.TAIL_WHIP, Type.NORMAL, 100, 30, -1, 0, 1) new StatusMove(Moves.TAIL_WHIP, Type.NORMAL, 100, 30, -1, 0, 1)
.attr(StatChangeAttr, BattleStat.DEF, -1) .attr(StatChangeAttr, BattleStat.DEF, -1)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
@ -4170,7 +4190,8 @@ export function initMoves() {
new AttackMove(Moves.PECK, Type.FLYING, MoveCategory.PHYSICAL, 35, 100, 35, -1, 0, 1), new AttackMove(Moves.PECK, Type.FLYING, MoveCategory.PHYSICAL, 35, 100, 35, -1, 0, 1),
new AttackMove(Moves.DRILL_PECK, Type.FLYING, MoveCategory.PHYSICAL, 80, 100, 20, -1, 0, 1), new AttackMove(Moves.DRILL_PECK, Type.FLYING, MoveCategory.PHYSICAL, 80, 100, 20, -1, 0, 1),
new AttackMove(Moves.SUBMISSION, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 80, 20, -1, 0, 1) new AttackMove(Moves.SUBMISSION, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 80, 20, -1, 0, 1)
.attr(RecoilAttr), .attr(RecoilAttr)
.recklessMove(),
new AttackMove(Moves.LOW_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 1) new AttackMove(Moves.LOW_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 1)
.attr(WeightPowerAttr) .attr(WeightPowerAttr)
.condition(failOnMaxCondition), .condition(failOnMaxCondition),
@ -4358,7 +4379,8 @@ export function initMoves() {
new AttackMove(Moves.HIGH_JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 130, 90, 10, -1, 0, 1) new AttackMove(Moves.HIGH_JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 130, 90, 10, -1, 0, 1)
.attr(MissEffectAttr, crashDamageFunc) .attr(MissEffectAttr, crashDamageFunc)
.attr(NoEffectAttr, crashDamageFunc) .attr(NoEffectAttr, crashDamageFunc)
.condition(failOnGravityCondition), .condition(failOnGravityCondition)
.recklessMove(),
new StatusMove(Moves.GLARE, Type.NORMAL, 100, 30, -1, 0, 1) new StatusMove(Moves.GLARE, Type.NORMAL, 100, 30, -1, 0, 1)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS), .attr(StatusEffectAttr, StatusEffect.PARALYSIS),
new AttackMove(Moves.DREAM_EATER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 15, -1, 0, 1) new AttackMove(Moves.DREAM_EATER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 15, -1, 0, 1)
@ -4943,7 +4965,8 @@ export function initMoves() {
.attr(StealHeldItemChanceAttr, 0.3), .attr(StealHeldItemChanceAttr, 0.3),
new AttackMove(Moves.VOLT_TACKLE, Type.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 3) new AttackMove(Moves.VOLT_TACKLE, Type.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 3)
.attr(RecoilAttr, false, 0.33) .attr(RecoilAttr, false, 0.33)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS), .attr(StatusEffectAttr, StatusEffect.PARALYSIS)
.recklessMove(),
new AttackMove(Moves.MAGICAL_LEAF, Type.GRASS, MoveCategory.SPECIAL, 60, -1, 20, -1, 0, 3), new AttackMove(Moves.MAGICAL_LEAF, Type.GRASS, MoveCategory.SPECIAL, 60, -1, 20, -1, 0, 3),
new StatusMove(Moves.WATER_SPORT, Type.WATER, -1, 15, -1, 0, 3) new StatusMove(Moves.WATER_SPORT, Type.WATER, -1, 15, -1, 0, 3)
.attr(AddArenaTagAttr, ArenaTagType.WATER_SPORT, 5) .attr(AddArenaTagAttr, ArenaTagType.WATER_SPORT, 5)
@ -5086,7 +5109,8 @@ export function initMoves() {
.attr(RecoilAttr, false, 0.33) .attr(RecoilAttr, false, 0.33)
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
.attr(StatusEffectAttr, StatusEffect.BURN) .attr(StatusEffectAttr, StatusEffect.BURN)
.condition(failOnGravityCondition), .condition(failOnGravityCondition)
.recklessMove(),
new AttackMove(Moves.FORCE_PALM, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, 30, 0, 4) new AttackMove(Moves.FORCE_PALM, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, 30, 0, 4)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS), .attr(StatusEffectAttr, StatusEffect.PARALYSIS),
new AttackMove(Moves.AURA_SPHERE, Type.FIGHTING, MoveCategory.SPECIAL, 80, -1, 20, -1, 0, 4) new AttackMove(Moves.AURA_SPHERE, Type.FIGHTING, MoveCategory.SPECIAL, 80, -1, 20, -1, 0, 4)
@ -5131,7 +5155,8 @@ export function initMoves() {
.attr(StatChangeAttr, BattleStat.SPDEF, -1) .attr(StatChangeAttr, BattleStat.SPDEF, -1)
.ballBombMove(), .ballBombMove(),
new AttackMove(Moves.BRAVE_BIRD, Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4) new AttackMove(Moves.BRAVE_BIRD, Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
.attr(RecoilAttr, false, 0.33), .attr(RecoilAttr, false, 0.33)
.recklessMove(),
new AttackMove(Moves.EARTH_POWER, Type.GROUND, MoveCategory.SPECIAL, 90, 100, 10, 10, 0, 4) new AttackMove(Moves.EARTH_POWER, Type.GROUND, MoveCategory.SPECIAL, 90, 100, 10, 10, 0, 4)
.attr(StatChangeAttr, BattleStat.SPDEF, -1), .attr(StatChangeAttr, BattleStat.SPDEF, -1),
new StatusMove(Moves.SWITCHEROO, Type.DARK, 100, 10, -1, 0, 4) new StatusMove(Moves.SWITCHEROO, Type.DARK, 100, 10, -1, 0, 4)
@ -5237,7 +5262,8 @@ export function initMoves() {
new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4) new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4)
.attr(StatChangeAttr, BattleStat.SPATK, 1, true), .attr(StatChangeAttr, BattleStat.SPATK, 1, true),
new AttackMove(Moves.WOOD_HAMMER, Type.GRASS, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4) new AttackMove(Moves.WOOD_HAMMER, Type.GRASS, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
.attr(RecoilAttr, false, 0.33), .attr(RecoilAttr, false, 0.33)
.recklessMove(),
new AttackMove(Moves.AQUA_JET, Type.WATER, MoveCategory.PHYSICAL, 40, 100, 20, -1, 1, 4), new AttackMove(Moves.AQUA_JET, Type.WATER, MoveCategory.PHYSICAL, 40, 100, 20, -1, 1, 4),
new AttackMove(Moves.ATTACK_ORDER, Type.BUG, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 4) new AttackMove(Moves.ATTACK_ORDER, Type.BUG, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 4)
.attr(HighCritAttr) .attr(HighCritAttr)
@ -5248,7 +5274,8 @@ export function initMoves() {
.attr(HealAttr, 0.5) .attr(HealAttr, 0.5)
.triageMove(), .triageMove(),
new AttackMove(Moves.HEAD_SMASH, Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, 0, 4) new AttackMove(Moves.HEAD_SMASH, Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, 0, 4)
.attr(RecoilAttr, false, 0.5), .attr(RecoilAttr, false, 0.5)
.recklessMove(),
new AttackMove(Moves.DOUBLE_HIT, Type.NORMAL, MoveCategory.PHYSICAL, 35, 90, 10, -1, 0, 4) new AttackMove(Moves.DOUBLE_HIT, Type.NORMAL, MoveCategory.PHYSICAL, 35, 90, 10, -1, 0, 4)
.attr(MultiHitAttr, MultiHitType._2), .attr(MultiHitAttr, MultiHitType._2),
new AttackMove(Moves.ROAR_OF_TIME, Type.DRAGON, MoveCategory.SPECIAL, 150, 90, 5, -1, 0, 4) new AttackMove(Moves.ROAR_OF_TIME, Type.DRAGON, MoveCategory.SPECIAL, 150, 90, 5, -1, 0, 4)
@ -5436,7 +5463,8 @@ export function initMoves() {
.attr(StatChangeAttr, BattleStat.SPD, -1) .attr(StatChangeAttr, BattleStat.SPD, -1)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new AttackMove(Moves.WILD_CHARGE, Type.ELECTRIC, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 5) new AttackMove(Moves.WILD_CHARGE, Type.ELECTRIC, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 5)
.attr(RecoilAttr), .attr(RecoilAttr)
.recklessMove(),
new AttackMove(Moves.DRILL_RUN, Type.GROUND, MoveCategory.PHYSICAL, 80, 95, 10, -1, 0, 5) new AttackMove(Moves.DRILL_RUN, Type.GROUND, MoveCategory.PHYSICAL, 80, 95, 10, -1, 0, 5)
.attr(HighCritAttr), .attr(HighCritAttr),
new AttackMove(Moves.DUAL_CHOP, Type.DRAGON, MoveCategory.PHYSICAL, 40, 90, 15, -1, 0, 5) new AttackMove(Moves.DUAL_CHOP, Type.DRAGON, MoveCategory.PHYSICAL, 40, 90, 15, -1, 0, 5)
@ -5473,7 +5501,8 @@ export function initMoves() {
.attr(HitsTagAttr, BattlerTagType.FLYING, false) .attr(HitsTagAttr, BattlerTagType.FLYING, false)
.windMove(), .windMove(),
new AttackMove(Moves.HEAD_CHARGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 5) new AttackMove(Moves.HEAD_CHARGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 5)
.attr(RecoilAttr), .attr(RecoilAttr)
.recklessMove(),
new AttackMove(Moves.GEAR_GRIND, Type.STEEL, MoveCategory.PHYSICAL, 50, 85, 15, -1, 0, 5) new AttackMove(Moves.GEAR_GRIND, Type.STEEL, MoveCategory.PHYSICAL, 50, 85, 15, -1, 0, 5)
.attr(MultiHitAttr, MultiHitType._2), .attr(MultiHitAttr, MultiHitType._2),
new AttackMove(Moves.SEARING_SHOT, Type.FIRE, MoveCategory.SPECIAL, 100, 100, 5, 30, 0, 5) new AttackMove(Moves.SEARING_SHOT, Type.FIRE, MoveCategory.SPECIAL, 100, 100, 5, 30, 0, 5)
@ -5687,7 +5716,8 @@ export function initMoves() {
.makesContact(false) .makesContact(false)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new AttackMove(Moves.LIGHT_OF_RUIN, Type.FAIRY, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 6) new AttackMove(Moves.LIGHT_OF_RUIN, Type.FAIRY, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 6)
.attr(RecoilAttr, false, 0.5), .attr(RecoilAttr, false, 0.5)
.recklessMove(),
new AttackMove(Moves.ORIGIN_PULSE, Type.WATER, MoveCategory.SPECIAL, 110, 85, 10, -1, 0, 6) new AttackMove(Moves.ORIGIN_PULSE, Type.WATER, MoveCategory.SPECIAL, 110, 85, 10, -1, 0, 6)
.pulseMove() .pulseMove()
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
@ -6268,7 +6298,8 @@ export function initMoves() {
.attr(MissEffectAttr, frenzyMissFunc) .attr(MissEffectAttr, frenzyMissFunc)
.target(MoveTarget.RANDOM_NEAR_ENEMY), .target(MoveTarget.RANDOM_NEAR_ENEMY),
new AttackMove(Moves.WAVE_CRASH, Type.WATER, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8) new AttackMove(Moves.WAVE_CRASH, Type.WATER, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8)
.attr(RecoilAttr, false, 0.33), .attr(RecoilAttr, false, 0.33)
.recklessMove(),
new AttackMove(Moves.CHLOROBLAST, Type.GRASS, MoveCategory.SPECIAL, 150, 95, 5, -1, 0, 8) new AttackMove(Moves.CHLOROBLAST, Type.GRASS, MoveCategory.SPECIAL, 150, 95, 5, -1, 0, 8)
.attr(RecoilAttr, true, 0.5), .attr(RecoilAttr, true, 0.5),
new AttackMove(Moves.MOUNTAIN_GALE, Type.ICE, MoveCategory.PHYSICAL, 100, 85, 10, 30, 0, 8) new AttackMove(Moves.MOUNTAIN_GALE, Type.ICE, MoveCategory.PHYSICAL, 100, 85, 10, 30, 0, 8)
@ -6432,7 +6463,8 @@ export function initMoves() {
new AttackMove(Moves.AXE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 90, 10, 30, 0, 9) new AttackMove(Moves.AXE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 90, 10, 30, 0, 9)
.attr(MissEffectAttr, crashDamageFunc) .attr(MissEffectAttr, crashDamageFunc)
.attr(NoEffectAttr, crashDamageFunc) .attr(NoEffectAttr, crashDamageFunc)
.attr(ConfuseAttr), .attr(ConfuseAttr)
.recklessMove(),
new AttackMove(Moves.LAST_RESPECTS, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9) new AttackMove(Moves.LAST_RESPECTS, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9)
.attr(MovePowerMultiplierAttr, (user, target, move) => { .attr(MovePowerMultiplierAttr, (user, target, move) => {
return user.scene.getParty().reduce((acc, pokemonInParty) => acc + (pokemonInParty.status?.effect == StatusEffect.FAINT ? 1 : 0), return user.scene.getParty().reduce((acc, pokemonInParty) => acc + (pokemonInParty.status?.effect == StatusEffect.FAINT ? 1 : 0),
@ -6636,7 +6668,8 @@ export function initMoves() {
.attr(MovePowerMultiplierAttr, (user, target, move) => user.getLastXMoves(2)[1]?.result == MoveResult.MISS || user.getLastXMoves(2)[1]?.result == MoveResult.FAIL ? 2 : 1), .attr(MovePowerMultiplierAttr, (user, target, move) => user.getLastXMoves(2)[1]?.result == MoveResult.MISS || user.getLastXMoves(2)[1]?.result == MoveResult.FAIL ? 2 : 1),
new AttackMove(Moves.SUPERCELL_SLAM, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 95, 15, -1, 0, 9) new AttackMove(Moves.SUPERCELL_SLAM, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 95, 15, -1, 0, 9)
.attr(MissEffectAttr, crashDamageFunc) .attr(MissEffectAttr, crashDamageFunc)
.attr(NoEffectAttr, crashDamageFunc), .attr(NoEffectAttr, crashDamageFunc)
.recklessMove(),
new AttackMove(Moves.PSYCHIC_NOISE, Type.PSYCHIC, MoveCategory.SPECIAL, 75, 100, 10, -1, 0, 9) new AttackMove(Moves.PSYCHIC_NOISE, Type.PSYCHIC, MoveCategory.SPECIAL, 75, 100, 10, -1, 0, 9)
.soundBased() .soundBased()
.partial(), .partial(),