diff --git a/src/data/ability.ts b/src/data/ability.ts index 967e0cf2e2b..21d860638e6 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -888,6 +888,58 @@ export class PreAttackAbAttr extends AbAttr { } } +export class MoveEffectChanceMultiplierAbAttr extends AbAttr { + private chanceMultiplier: number; + + constructor(chanceMultiplier?: number){ + super(true); + this.chanceMultiplier = chanceMultiplier; + } + + apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { + + if((args[0] as Utils.NumberHolder).value >=1) { + + (args[0] as Utils.NumberHolder).value *= this.chanceMultiplier; + (args[0] as Utils.NumberHolder).value = Math.min((args[0] as Utils.NumberHolder).value, 100) + + return true; + } + + return false; + } +} + + +export class IgnoreMoveEffectsAbAttr extends PreDefendAbAttr { + + applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { + + if((args[0] as Utils.NumberHolder).value >=1) { + (args[0] as Utils.NumberHolder).value = 0; + return true; + } + + return false; + } + +} + +/*export class SheerForceIgnoredAbilities extends PreAttackAbAttr { + applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean { + const ability = defender.getAbility().id + if (move.getMove().chance >= 1 && ( + ability == Abilities.COLOR_CHANGE || ability == Abilities.PICKPOCKET || + ability == Abilities.WIMP_OUT || ability == Abilities.EMERGENCY_EXIT || + ability == Abilities.BERSERK || ability == Abilities.ANGER_SHELL + )){ + (args[0] as Utils.BooleanHolder).value = true; + return true; + } + return false; + } +}*/ + export class VariableMovePowerAbAttr extends PreAttackAbAttr { applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean { //const power = args[0] as Utils.NumberHolder; @@ -2644,8 +2696,8 @@ export function initAbilities() { .attr(TypeImmunityAddBattlerTagAbAttr, Type.FIRE, BattlerTagType.FIRE_BOOST, 1, (pokemon: Pokemon) => !pokemon.status || pokemon.status.effect !== StatusEffect.FREEZE) .ignorable(), new Ability(Abilities.SHIELD_DUST, 3) - .ignorable() - .unimplemented(), + .attr(IgnoreMoveEffectsAbAttr) + .ignorable(), new Ability(Abilities.OWN_TEMPO, 3) .attr(BattlerTagImmunityAbAttr, BattlerTagType.CONFUSED) .ignorable(), @@ -2682,7 +2734,7 @@ export function initAbilities() { .attr(TypeImmunityStatChangeAbAttr, Type.ELECTRIC, BattleStat.SPATK, 1) .ignorable(), new Ability(Abilities.SERENE_GRACE, 3) - .unimplemented(), + .attr(MoveEffectChanceMultiplierAbAttr, 2), new Ability(Abilities.SWIFT_SWIM, 3) .attr(BattleStatMultiplierAbAttr, BattleStat.SPD, 2) .condition(getWeatherCondition(WeatherType.RAIN, WeatherType.HEAVY_RAIN)), @@ -2936,7 +2988,8 @@ export function initAbilities() { new Ability(Abilities.PICKPOCKET, 5) .attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT)), new Ability(Abilities.SHEER_FORCE, 5) - .unimplemented(), + .attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461/4096) + .attr(MoveEffectChanceMultiplierAbAttr, 0), new Ability(Abilities.CONTRARY, 5) .attr(StatChangeMultiplierAbAttr, -1) .ignorable(), diff --git a/src/data/move.ts b/src/data/move.ts index b09373156fb..47bc13f8e26 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -12,7 +12,7 @@ import * as Utils from "../utils"; import { WeatherType } from "./weather"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagType } from "./enums/arena-tag-type"; -import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, PreventBerryUseAbAttr, BlockItemTheftAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr } from "./ability"; +import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, PreventBerryUseAbAttr, BlockItemTheftAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr } from "./ability"; import { Abilities } from "./enums/abilities"; import { allAbilities } from './ability'; import { modifierTypes } from '../modifier/modifier-type'; @@ -458,6 +458,14 @@ export class MoveEffectAttr extends MoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { return this.canApply(user, target, move, args); } + + getMoveChance(user: Pokemon, target: Pokemon, move: Move, selfEffect?: Boolean): integer { + let moveChance = new Utils.NumberHolder(move.chance); + applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, moveChance, target, selfEffect); + applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr,target,user,null,null, moveChance); + return moveChance.value; + } + } export class PreMoveMessageAttr extends MoveAttr { @@ -1015,7 +1023,9 @@ export class StatusEffectAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const statusCheck = move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance; + + let moveChance = this.getMoveChance(user,target,move,this.selfTarget); + const statusCheck = moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance; if (statusCheck) { const pokemon = this.selfTarget ? user : target; if (pokemon.status) { @@ -1024,14 +1034,15 @@ export class StatusEffectAttr extends MoveEffectAttr { else return false; } - if (!pokemon.status || (pokemon.status.effect === this.effect && move.chance < 0)) + if (!pokemon.status || (pokemon.status.effect === this.effect && moveChance < 0)) return pokemon.trySetStatus(this.effect, true, this.cureTurn); } return false; } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { - return !(this.selfTarget ? user : target).status && (this.selfTarget ? user : target).canSetStatus(this.effect, true) ? Math.floor(move.chance * -0.1) : 0; + let moveChance = this.getMoveChance(user,target,move,this.selfTarget); + return !(this.selfTarget ? user : target).status && (this.selfTarget ? user : target).canSetStatus(this.effect, true) ? Math.floor(moveChance * -0.1) : 0; } } @@ -1519,7 +1530,9 @@ export class StatChangeAttr extends MoveEffectAttr { if (!super.apply(user, target, move, args) || (this.condition && !this.condition(user, target, move))) return false; - if (move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) { + let moveChance = this.getMoveChance(user,target,move,this.selfTarget); + + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { const levels = this.getLevels(user); user.scene.unshiftPhase(new StatChangePhase(user.scene, (this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, levels, this.showMessage)); return true; @@ -2709,17 +2722,13 @@ export class AddBattlerTagAttr extends MoveEffectAttr { if (!super.apply(user, target, move, args)) return false; - const chance = this.getTagChance(user, target, move); - if (chance < 0 || chance === 100 || user.randSeedInt(100) < chance) + let moveChance = this.getMoveChance(user,target,move,this.selfTarget); + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) return (this.selfTarget ? user : target).addTag(this.tagType, user.randSeedInt(this.turnCountMax - this.turnCountMin, this.turnCountMin), move.id, user.id); return false; } - getTagChance(user: Pokemon, target: Pokemon, move: Move): integer { - return move.chance; - } - getCondition(): MoveConditionFunc { return this.failOnOverlap ? (user, target, move) => !(this.selfTarget ? user : target).getTag(this.tagType) @@ -2769,10 +2778,10 @@ export class AddBattlerTagAttr extends MoveEffectAttr { } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { - let chance = this.getTagChance(user, target, move); - if (chance < 0) - chance = 100; - return Math.floor(this.getTagTargetBenefitScore(user, target, move) * (chance / 100)); + let moveChance = this.getMoveChance(user,target,move,this.selfTarget); + if (moveChance < 0) + moveChance = 100; + return Math.floor(this.getTagTargetBenefitScore(user, target, move) * (moveChance / 100)); } } @@ -2996,6 +3005,8 @@ export class AddArenaTagAttr extends MoveEffectAttr { export class AddArenaTrapTagAttr extends AddArenaTagAttr { getCondition(): MoveConditionFunc { return (user, target, move) => { + let moveChance = this.getMoveChance(user,target,move,this.selfTarget); + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) if (move.category !== MoveCategory.STATUS || !user.scene.arena.getTag(this.tagType)) return true; const tag = user.scene.arena.getTag(this.tagType) as ArenaTrapTag; @@ -4703,7 +4714,7 @@ export function initMoves() { .ignoresVirtual(), new SelfStatusMove(Moves.INGRAIN, Type.GRASS, -1, 20, -1, 0, 3) .attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true), - new AttackMove(Moves.SUPERPOWER, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, 100, 0, 3) + new AttackMove(Moves.SUPERPOWER, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 3) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF ], -1, true), new SelfStatusMove(Moves.MAGIC_COAT, Type.PSYCHIC, -1, 15, -1, 4, 3) .unimplemented(), @@ -4804,7 +4815,7 @@ export function initMoves() { .slicingMove() .windMove() .target(MoveTarget.ALL_NEAR_ENEMIES), - new AttackMove(Moves.OVERHEAT, Type.FIRE, MoveCategory.SPECIAL, 130, 90, 5, 100, 0, 3) + new AttackMove(Moves.OVERHEAT, Type.FIRE, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 3) .attr(StatChangeAttr, BattleStat.SPATK, -2, true) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE), new StatusMove(Moves.ODOR_SLEUTH, Type.NORMAL, -1, 40, -1, 0, 3) @@ -4906,7 +4917,7 @@ export function initMoves() { .pulseMove(), new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3) .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, 'chose\nDoom Desire as its destiny!'), - new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, 100, 0, 3) + new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3) .attr(StatChangeAttr, BattleStat.SPATK, -2, true), new SelfStatusMove(Moves.ROOST, Type.FLYING, -1, 5, -1, 0, 4) .attr(HealAttr, 0.5) @@ -4920,7 +4931,7 @@ export function initMoves() { new AttackMove(Moves.WAKE_UP_SLAP, Type.FIGHTING, MoveCategory.PHYSICAL, 70, 100, 10, -1, 0, 4) .attr(MovePowerMultiplierAttr, (user, target, move) => target.status?.effect === StatusEffect.SLEEP ? 2 : 1) .attr(HealStatusEffectAttr, false, StatusEffect.SLEEP), - new AttackMove(Moves.HAMMER_ARM, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 90, 10, 100, 0, 4) + new AttackMove(Moves.HAMMER_ARM, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 90, 10, -1, 0, 4) .attr(StatChangeAttr, BattleStat.SPD, -1, true) .punchingMove(), new AttackMove(Moves.GYRO_BALL, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4) @@ -4953,7 +4964,7 @@ export function initMoves() { .target(MoveTarget.ATTACKER), new AttackMove(Moves.U_TURN, Type.BUG, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 4) .attr(ForceSwitchOutAttr, true, false), - new AttackMove(Moves.CLOSE_COMBAT, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, 100, 0, 4) + new AttackMove(Moves.CLOSE_COMBAT, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 4) .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true), new AttackMove(Moves.PAYBACK, Type.DARK, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 4) .attr(MovePowerMultiplierAttr, (user, target, move) => target.getLastXMoves(1).find(m => m.turn === target.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.BALL ? 2 : 1), @@ -5133,7 +5144,7 @@ export function initMoves() { .attr(AddArenaTagAttr, ArenaTagType.TRICK_ROOM, 5) .ignoresProtect() .target(MoveTarget.BOTH_SIDES), - new AttackMove(Moves.DRACO_METEOR, Type.DRAGON, MoveCategory.SPECIAL, 130, 90, 5, 100, 0, 4) + new AttackMove(Moves.DRACO_METEOR, Type.DRAGON, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 4) .attr(StatChangeAttr, BattleStat.SPATK, -2, true), new AttackMove(Moves.DISCHARGE, Type.ELECTRIC, MoveCategory.SPECIAL, 80, 100, 15, 30, 0, 4) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) @@ -5141,7 +5152,7 @@ export function initMoves() { new AttackMove(Moves.LAVA_PLUME, Type.FIRE, MoveCategory.SPECIAL, 80, 100, 15, 30, 0, 4) .attr(StatusEffectAttr, StatusEffect.BURN) .target(MoveTarget.ALL_NEAR_OTHERS), - new AttackMove(Moves.LEAF_STORM, Type.GRASS, MoveCategory.SPECIAL, 130, 90, 5, 100, 0, 4) + new AttackMove(Moves.LEAF_STORM, Type.GRASS, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 4) .attr(StatChangeAttr, BattleStat.SPATK, -2, true), new AttackMove(Moves.POWER_WHIP, Type.GRASS, MoveCategory.PHYSICAL, 120, 85, 10, -1, 0, 4), new AttackMove(Moves.ROCK_WRECKER, Type.ROCK, MoveCategory.PHYSICAL, 150, 90, 5, -1, 0, 4) @@ -5459,7 +5470,7 @@ export function initMoves() { new AttackMove(Moves.ICICLE_CRASH, Type.ICE, MoveCategory.PHYSICAL, 85, 90, 10, 30, 0, 5) .attr(FlinchAttr) .makesContact(false), - new AttackMove(Moves.V_CREATE, Type.FIRE, MoveCategory.PHYSICAL, 180, 95, 5, 100, 0, 5) + new AttackMove(Moves.V_CREATE, Type.FIRE, MoveCategory.PHYSICAL, 180, 95, 5, -1, 0, 5) .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF, BattleStat.SPD ], -1, true), new AttackMove(Moves.FUSION_FLARE, Type.FIRE, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 5) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) @@ -5615,7 +5626,7 @@ export function initMoves() { new AttackMove(Moves.OBLIVION_WING, Type.FLYING, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 6) .attr(HitHealAttr, 0.75) .triageMove(), - new AttackMove(Moves.THOUSAND_ARROWS, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, 100, 0, 6) + new AttackMove(Moves.THOUSAND_ARROWS, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) .attr(NeutralDamageAgainstFlyingTypeMultiplierAttr) .attr(HitsTagAttr, BattlerTagType.FLYING, false) .makesContact(false) @@ -5635,9 +5646,9 @@ export function initMoves() { new AttackMove(Moves.PRECIPICE_BLADES, Type.GROUND, MoveCategory.PHYSICAL, 120, 85, 10, -1, 0, 6) .makesContact(false) .target(MoveTarget.ALL_NEAR_ENEMIES), - new AttackMove(Moves.DRAGON_ASCENT, Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 5, 100, 0, 6) + new AttackMove(Moves.DRAGON_ASCENT, Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 6) .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true), - new AttackMove(Moves.HYPERSPACE_FURY, Type.DARK, MoveCategory.PHYSICAL, 100, -1, 5, 100, 0, 6) + new AttackMove(Moves.HYPERSPACE_FURY, Type.DARK, MoveCategory.PHYSICAL, 100, -1, 5, -1, 0, 6) .attr(StatChangeAttr, BattleStat.DEF, -1, true) .ignoresProtect(), /* Unused */ @@ -5723,16 +5734,16 @@ export function initMoves() { .condition(new FirstMoveCondition()), new SelfStatusMove(Moves.BANEFUL_BUNKER, Type.POISON, -1, 10, -1, 4, 7) .attr(ProtectAttr, BattlerTagType.BANEFUL_BUNKER), - new AttackMove(Moves.SPIRIT_SHACKLE, Type.GHOST, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 7) + new AttackMove(Moves.SPIRIT_SHACKLE, Type.GHOST, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 7) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1) .makesContact(false), new AttackMove(Moves.DARKEST_LARIAT, Type.DARK, MoveCategory.PHYSICAL, 85, 100, 10, -1, 0, 7) .attr(IgnoreOpponentStatChangesAttr), - new AttackMove(Moves.SPARKLING_ARIA, Type.WATER, MoveCategory.SPECIAL, 90, 100, 10, -1, 0, 7) + new AttackMove(Moves.SPARKLING_ARIA, Type.WATER, MoveCategory.SPECIAL, 90, 100, 10, 100, 0, 7) .attr(HealStatusEffectAttr, false, StatusEffect.BURN) .soundBased() .target(MoveTarget.ALL_NEAR_OTHERS), - new AttackMove(Moves.ICE_HAMMER, Type.ICE, MoveCategory.PHYSICAL, 100, 90, 10, 100, 0, 7) + new AttackMove(Moves.ICE_HAMMER, Type.ICE, MoveCategory.PHYSICAL, 100, 90, 10, -1, 0, 7) .attr(StatChangeAttr, BattleStat.SPD, -1, true) .punchingMove(), new StatusMove(Moves.FLORAL_HEALING, Type.FAIRY, -1, 10, -1, 0, 7) @@ -5767,7 +5778,7 @@ export function initMoves() { new AttackMove(Moves.POLLEN_PUFF, Type.BUG, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 7) .ballBombMove() .partial(), - new AttackMove(Moves.ANCHOR_SHOT, Type.STEEL, MoveCategory.PHYSICAL, 80, 100, 20, -1, 0, 7) + new AttackMove(Moves.ANCHOR_SHOT, Type.STEEL, MoveCategory.PHYSICAL, 80, 100, 20, 100, 0, 7) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1), new StatusMove(Moves.PSYCHIC_TERRAIN, Type.PSYCHIC, -1, 10, -1, 0, 7) .attr(TerrainChangeAttr, TerrainType.PSYCHIC) @@ -5808,7 +5819,7 @@ export function initMoves() { .ballBombMove() .makesContact(false) .partial(), - new AttackMove(Moves.CLANGING_SCALES, Type.DRAGON, MoveCategory.SPECIAL, 110, 100, 5, 100, 0, 7) + new AttackMove(Moves.CLANGING_SCALES, Type.DRAGON, MoveCategory.SPECIAL, 110, 100, 5, -1, 0, 7) .attr(StatChangeAttr, BattleStat.DEF, -1, true) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES), @@ -5837,13 +5848,13 @@ export function initMoves() { .partial(), new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, 100, 0, 7) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true), - new AttackMove(Moves.GENESIS_SUPERNOVA, Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, -1, 0, 7) + new AttackMove(Moves.GENESIS_SUPERNOVA, Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, 100, 0, 7) .attr(TerrainChangeAttr, TerrainType.PSYCHIC), /* End Unused */ new AttackMove(Moves.SHELL_TRAP, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, -3, 7) .target(MoveTarget.ALL_NEAR_ENEMIES) .partial(), - new AttackMove(Moves.FLEUR_CANNON, Type.FAIRY, MoveCategory.SPECIAL, 130, 90, 5, 100, 0, 7) + new AttackMove(Moves.FLEUR_CANNON, Type.FAIRY, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 7) .attr(StatChangeAttr, BattleStat.SPATK, -2, true), new AttackMove(Moves.PSYCHIC_FANGS, Type.PSYCHIC, MoveCategory.PHYSICAL, 85, 100, 10, -1, 0, 7) .bitingMove() @@ -6106,7 +6117,7 @@ export function initMoves() { new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8) .attr(ClearTerrainAttr) .condition((user, target, move) => !!user.scene.arena.terrain), - new AttackMove(Moves.SCALE_SHOT, Type.DRAGON, MoveCategory.PHYSICAL, 25, 90, 20, 100, 0, 8) + new AttackMove(Moves.SCALE_SHOT, Type.DRAGON, MoveCategory.PHYSICAL, 25, 90, 20, -1, 0, 8) //.attr(StatChangeAttr, BattleStat.SPD, 1, true) // TODO: Have boosts only apply at end of move, not after every hit //.attr(StatChangeAttr, BattleStat.DEF, -1, true) .attr(MultiHitAttr) @@ -6224,7 +6235,7 @@ export function initMoves() { new SelfStatusMove(Moves.VICTORY_DANCE, Type.FIGHTING, -1, 10, 100, 0, 8) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPD ], 1, true) .danceMove(), - new AttackMove(Moves.HEADLONG_RUSH, Type.GROUND, MoveCategory.PHYSICAL, 120, 100, 5, 100, 0, 8) + new AttackMove(Moves.HEADLONG_RUSH, Type.GROUND, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 8) .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true) .punchingMove(), new AttackMove(Moves.BARB_BARRAGE, Type.POISON, MoveCategory.PHYSICAL, 60, 100, 10, 50, 0, 8) @@ -6397,7 +6408,7 @@ export function initMoves() { new StatusMove(Moves.SPICY_EXTRACT, Type.GRASS, -1, 15, 100, 0, 9) .attr(StatChangeAttr, BattleStat.ATK, 2) .attr(StatChangeAttr, BattleStat.DEF, -2), - new AttackMove(Moves.SPIN_OUT, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, 100, 0, 9) + new AttackMove(Moves.SPIN_OUT, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9) .attr(StatChangeAttr, BattleStat.SPD, -2, true), new AttackMove(Moves.POPULATION_BOMB, Type.NORMAL, MoveCategory.PHYSICAL, 20, 90, 10, -1, 0, 9) .attr(MultiHitAttr, MultiHitType._1_TO_10)