"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var moves_exports = {};
__export(moves_exports, {
  Moves: () => Moves
});
module.exports = __toCommonJS(moves_exports);
const Moves = {
  aeroblast: {
    inherit: true,
    critRatio: 3
  },
  beatup: {
    inherit: true,
    onModifyMove(move, pokemon) {
      move.type = "???";
      move.category = "Special";
      move.allies = pokemon.side.pokemon.filter((ally) => !ally.fainted && !ally.status);
      move.multihit = move.allies.length;
    }
  },
  bellydrum: {
    inherit: true,
    onHit(target) {
      if (target.boosts.atk >= 6) {
        return false;
      }
      if (target.hp <= target.maxhp / 2) {
        this.boost({ atk: 2 }, null, null, this.dex.conditions.get("bellydrum2"));
        return false;
      }
      this.directDamage(target.maxhp / 2);
      const originalStage = target.boosts.atk;
      let currentStage = originalStage;
      let boosts = 0;
      let loopStage = 0;
      while (currentStage < 6) {
        loopStage = currentStage;
        currentStage++;
        if (currentStage < 6)
          currentStage++;
        target.boosts.atk = loopStage;
        if (target.getStat("atk", false, true) < 999) {
          target.boosts.atk = currentStage;
          continue;
        }
        target.boosts.atk = currentStage - 1;
        break;
      }
      boosts = target.boosts.atk - originalStage;
      target.boosts.atk = originalStage;
      this.boost({ atk: boosts });
    }
  },
  bide: {
    inherit: true,
    condition: {
      duration: 3,
      durationCallback(target, source, effect) {
        return this.random(3, 5);
      },
      onLockMove: "bide",
      onStart(pokemon) {
        this.effectState.totalDamage = 0;
        this.add("-start", pokemon, "move: Bide");
      },
      onDamagePriority: -101,
      onDamage(damage, target, source, move) {
        if (!move || move.effectType !== "Move" || !source)
          return;
        this.effectState.totalDamage += damage;
        this.effectState.lastDamageSource = source;
      },
      onBeforeMove(pokemon, target, move) {
        if (this.effectState.duration === 1) {
          this.add("-end", pokemon, "move: Bide");
          if (!this.effectState.totalDamage) {
            this.add("-fail", pokemon);
            return false;
          }
          target = this.effectState.lastDamageSource;
          if (!target) {
            this.add("-fail", pokemon);
            return false;
          }
          if (!target.isActive) {
            const possibleTarget = this.getRandomTarget(pokemon, this.dex.moves.get("pound"));
            if (!possibleTarget) {
              this.add("-miss", pokemon);
              return false;
            }
            target = possibleTarget;
          }
          const moveData = {
            id: "bide",
            name: "Bide",
            accuracy: 100,
            damage: this.effectState.totalDamage * 2,
            category: "Physical",
            priority: 0,
            flags: { contact: 1, protect: 1 },
            effectType: "Move",
            type: "Normal"
          };
          this.actions.tryMoveHit(target, pokemon, moveData);
          pokemon.removeVolatile("bide");
          return false;
        }
        this.add("-activate", pokemon, "move: Bide");
      },
      onMoveAborted(pokemon) {
        pokemon.removeVolatile("bide");
      },
      onEnd(pokemon) {
        this.add("-end", pokemon, "move: Bide", "[silent]");
      }
    }
  },
  counter: {
    inherit: true,
    damageCallback(pokemon, target) {
      const lastAttackedBy = pokemon.getLastAttackedBy();
      if (!lastAttackedBy?.move || !lastAttackedBy.thisTurn)
        return false;
      if (this.getCategory(lastAttackedBy.move) === "Physical" && target.lastMove?.id !== "sleeptalk") {
        return 2 * lastAttackedBy.damage;
      }
      return false;
    },
    beforeTurnCallback() {
    },
    onTry() {
    },
    condition: {},
    priority: -1
  },
  crabhammer: {
    inherit: true,
    critRatio: 3
  },
  crosschop: {
    inherit: true,
    critRatio: 3
  },
  curse: {
    inherit: true,
    condition: {
      onStart(pokemon, source) {
        this.add("-start", pokemon, "Curse", "[of] " + source);
      },
      onAfterMoveSelf(pokemon) {
        this.damage(pokemon.baseMaxhp / 4);
      }
    }
  },
  detect: {
    inherit: true,
    priority: 2
  },
  dig: {
    inherit: true,
    onPrepareHit(target, source) {
      return source.status !== "slp";
    },
    condition: {
      duration: 2,
      onImmunity(type, pokemon) {
        if (type === "sandstorm")
          return false;
      },
      onInvulnerability(target, source, move) {
        if (move.id === "earthquake" || move.id === "magnitude" || move.id === "fissure") {
          return;
        }
        if (["attract", "curse", "foresight", "meanlook", "mimic", "nightmare", "spiderweb", "transform"].includes(move.id)) {
          return false;
        }
        if (source.volatiles["lockon"] && target === source.volatiles["lockon"].source)
          return;
        return false;
      },
      onSourceBasePower(basePower, target, source, move) {
        if (move.id === "earthquake" || move.id === "magnitude") {
          return this.chainModify(2);
        }
      }
    }
  },
  doubleedge: {
    inherit: true,
    recoil: [25, 100]
  },
  encore: {
    inherit: true,
    condition: {
      durationCallback() {
        return this.random(3, 7);
      },
      onStart(target) {
        const lockedMove = target.lastMoveEncore?.id || "";
        const moveIndex = lockedMove ? target.moves.indexOf(lockedMove) : -1;
        if (moveIndex < 0 || target.lastMoveEncore?.flags["failencore"] || target.moveSlots[moveIndex].pp <= 0) {
          return false;
        }
        this.effectState.move = lockedMove;
        this.add("-start", target, "Encore");
      },
      onOverrideAction(pokemon) {
        return this.effectState.move;
      },
      onResidualOrder: 13,
      onResidual(target) {
        const lockedMoveIndex = target.moves.indexOf(this.effectState.move);
        if (lockedMoveIndex >= 0 && target.moveSlots[lockedMoveIndex].pp <= 0) {
          target.removeVolatile("encore");
        }
      },
      onEnd(target) {
        this.add("-end", target, "Encore");
      },
      onDisableMove(pokemon) {
        if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
          return;
        }
        for (const moveSlot of pokemon.moveSlots) {
          if (moveSlot.id !== this.effectState.move) {
            pokemon.disableMove(moveSlot.id);
          }
        }
      }
    }
  },
  endure: {
    inherit: true,
    priority: 2
  },
  explosion: {
    inherit: true,
    noSketch: true
  },
  flail: {
    inherit: true,
    noDamageVariance: true,
    willCrit: false
  },
  fly: {
    inherit: true,
    onPrepareHit(target, source) {
      return source.status !== "slp";
    },
    condition: {
      duration: 2,
      onInvulnerability(target, source, move) {
        if (move.id === "gust" || move.id === "twister" || move.id === "thunder" || move.id === "whirlwind") {
          return;
        }
        if (move.id === "earthquake" || move.id === "magnitude" || move.id === "fissure") {
          return false;
        }
        if (["attract", "curse", "foresight", "meanlook", "mimic", "nightmare", "spiderweb", "transform"].includes(move.id)) {
          return false;
        }
        if (source.volatiles["lockon"] && target === source.volatiles["lockon"].source)
          return;
        return false;
      },
      onSourceBasePower(basePower, target, source, move) {
        if (move.id === "gust" || move.id === "twister") {
          return this.chainModify(2);
        }
      }
    }
  },
  focusenergy: {
    inherit: true,
    condition: {
      onStart(pokemon) {
        this.add("-start", pokemon, "move: Focus Energy");
      },
      onModifyCritRatio(critRatio) {
        return critRatio + 1;
      }
    }
  },
  foresight: {
    inherit: true,
    onTryHit(target) {
      if (target.volatiles["foresight"])
        return false;
    },
    condition: {
      onStart(pokemon) {
        this.add("-start", pokemon, "Foresight");
      },
      onNegateImmunity(pokemon, type) {
        if (pokemon.hasType("Ghost") && ["Normal", "Fighting"].includes(type))
          return false;
      },
      onModifyBoost(boosts) {
        if (boosts.evasion && boosts.evasion > 0) {
          boosts.evasion = 0;
        }
      }
    }
  },
  frustration: {
    inherit: true,
    basePowerCallback(pokemon) {
      return Math.floor((255 - pokemon.happiness) * 10 / 25) || null;
    }
  },
  healbell: {
    inherit: true,
    onHit(target, source) {
      this.add("-cureteam", source, "[from] move: Heal Bell");
      for (const pokemon of target.side.pokemon) {
        pokemon.clearStatus();
      }
    }
  },
  highjumpkick: {
    inherit: true,
    onMoveFail(target, source, move) {
      if (target.runImmunity("Fighting")) {
        const damage = this.actions.getDamage(source, target, move, true);
        if (typeof damage !== "number")
          throw new Error("Couldn't get High Jump Kick recoil");
        this.damage(this.clampIntRange(damage / 8, 1), source, source, move);
      }
    }
  },
  jumpkick: {
    inherit: true,
    onMoveFail(target, source, move) {
      if (target.runImmunity("Fighting")) {
        const damage = this.actions.getDamage(source, target, move, true);
        if (typeof damage !== "number")
          throw new Error("Couldn't get Jump Kick recoil");
        this.damage(this.clampIntRange(damage / 8, 1), source, source, move);
      }
    }
  },
  karatechop: {
    inherit: true,
    critRatio: 3
  },
  leechseed: {
    inherit: true,
    onHit() {
    },
    condition: {
      onStart(target) {
        this.add("-start", target, "move: Leech Seed");
      },
      onAfterMoveSelfPriority: 2,
      onAfterMoveSelf(pokemon) {
        if (!pokemon.hp)
          return;
        const leecher = this.getAtSlot(pokemon.volatiles["leechseed"].sourceSlot);
        if (!leecher || leecher.fainted || leecher.hp <= 0) {
          return;
        }
        const toLeech = this.clampIntRange(pokemon.maxhp / 8, 1);
        const damage = this.damage(toLeech, pokemon, leecher);
        if (damage) {
          this.heal(damage, leecher, pokemon);
        }
      }
    }
  },
  lightscreen: {
    inherit: true,
    condition: {
      duration: 5,
      // Sp. Def boost applied directly in stat calculation
      onSideStart(side) {
        this.add("-sidestart", side, "move: Light Screen");
      },
      onSideResidualOrder: 9,
      onSideEnd(side) {
        this.add("-sideend", side, "move: Light Screen");
      }
    }
  },
  lockon: {
    inherit: true,
    onTryHit(target) {
      if (target.volatiles["foresight"] || target.volatiles["lockon"])
        return false;
    },
    condition: {
      duration: 2,
      onSourceAccuracy(accuracy, target, source, move) {
        if (move && source === this.effectState.target && target === this.effectState.source)
          return true;
      }
    }
  },
  lowkick: {
    inherit: true,
    accuracy: 90,
    basePower: 50,
    basePowerCallback() {
      return 50;
    },
    secondary: {
      chance: 30,
      volatileStatus: "flinch"
    }
  },
  meanlook: {
    inherit: true,
    flags: { reflectable: 1, mirror: 1, metronome: 1 }
  },
  metronome: {
    inherit: true,
    flags: { failencore: 1 },
    noSketch: true
  },
  mimic: {
    inherit: true,
    accuracy: 100,
    noSketch: true,
    flags: { protect: 1, bypasssub: 1, allyanim: 1, failencore: 1, noassist: 1 }
  },
  mindreader: {
    inherit: true,
    onTryHit(target) {
      if (target.volatiles["foresight"] || target.volatiles["lockon"])
        return false;
    }
  },
  mirrorcoat: {
    inherit: true,
    damageCallback(pokemon, target) {
      const lastAttackedBy = pokemon.getLastAttackedBy();
      if (!lastAttackedBy?.move || !lastAttackedBy.thisTurn)
        return false;
      if (this.getCategory(lastAttackedBy.move) === "Special" && target.lastMove?.id !== "sleeptalk") {
        return 2 * lastAttackedBy.damage;
      }
      return false;
    },
    beforeTurnCallback() {
    },
    onTry() {
    },
    condition: {},
    priority: -1
  },
  mirrormove: {
    inherit: true,
    flags: { metronome: 1, failencore: 1 },
    onHit(pokemon) {
      const noMirror = ["metronome", "mimic", "mirrormove", "sketch", "sleeptalk", "transform"];
      const target = pokemon.side.foe.active[0];
      const lastMove = target?.lastMove && target?.lastMove.id;
      if (!lastMove || !pokemon.activeTurns && !target.moveThisTurn) {
        return false;
      }
      if (noMirror.includes(lastMove) || pokemon.moves.includes(lastMove)) {
        return false;
      }
      this.actions.useMove(lastMove, pokemon);
    },
    noSketch: true
  },
  mist: {
    num: 54,
    accuracy: true,
    basePower: 0,
    category: "Status",
    name: "Mist",
    pp: 30,
    priority: 0,
    flags: { metronome: 1 },
    volatileStatus: "mist",
    condition: {
      onStart(pokemon) {
        this.add("-start", pokemon, "Mist");
      },
      onTryBoost(boost, target, source, effect) {
        if (source && target !== source) {
          let showMsg = false;
          let i;
          for (i in boost) {
            if (boost[i] < 0) {
              delete boost[i];
              showMsg = true;
            }
          }
          if (showMsg && !effect.secondaries) {
            this.add("-activate", target, "move: Mist");
          }
        }
      }
    },
    secondary: null,
    target: "self",
    type: "Ice"
  },
  moonlight: {
    inherit: true,
    onHit(pokemon) {
      if (this.field.isWeather(["sunnyday", "desolateland"])) {
        this.heal(pokemon.maxhp);
      } else if (this.field.isWeather(["raindance", "primordialsea", "sandstorm", "hail"])) {
        this.heal(pokemon.baseMaxhp / 4);
      } else {
        this.heal(pokemon.baseMaxhp / 2);
      }
    }
  },
  morningsun: {
    inherit: true,
    onHit(pokemon) {
      if (this.field.isWeather(["sunnyday", "desolateland"])) {
        this.heal(pokemon.maxhp);
      } else if (this.field.isWeather(["raindance", "primordialsea", "sandstorm", "hail"])) {
        this.heal(pokemon.baseMaxhp / 4);
      } else {
        this.heal(pokemon.baseMaxhp / 2);
      }
    }
  },
  nightmare: {
    inherit: true,
    condition: {
      noCopy: true,
      onStart(pokemon) {
        if (pokemon.status !== "slp") {
          return false;
        }
        this.add("-start", pokemon, "Nightmare");
      },
      onAfterMoveSelfPriority: 1,
      onAfterMoveSelf(pokemon) {
        if (pokemon.status === "slp")
          this.damage(pokemon.baseMaxhp / 4);
      }
    }
  },
  outrage: {
    inherit: true,
    onMoveFail(target, source, move) {
      source.addVolatile("lockedmove");
    },
    onAfterMove(pokemon) {
      if (pokemon.volatiles["lockedmove"] && pokemon.volatiles["lockedmove"].duration === 1) {
        pokemon.removeVolatile("lockedmove");
      }
    }
  },
  painsplit: {
    inherit: true,
    accuracy: 100
  },
  perishsong: {
    inherit: true,
    condition: {
      duration: 4,
      onEnd(target) {
        this.add("-start", target, "perish0");
        target.faint();
      },
      onResidualOrder: 4,
      onResidual(pokemon) {
        const duration = pokemon.volatiles["perishsong"].duration;
        this.add("-start", pokemon, "perish" + duration);
      }
    }
  },
  petaldance: {
    inherit: true,
    onMoveFail(target, source, move) {
      source.addVolatile("lockedmove");
    },
    onAfterMove(pokemon) {
      if (pokemon.volatiles["lockedmove"] && pokemon.volatiles["lockedmove"].duration === 1) {
        pokemon.removeVolatile("lockedmove");
      }
    }
  },
  poisongas: {
    inherit: true,
    ignoreImmunity: false
  },
  poisonpowder: {
    inherit: true,
    ignoreImmunity: false
  },
  protect: {
    inherit: true,
    priority: 2
  },
  psywave: {
    inherit: true,
    damageCallback(pokemon) {
      return this.random(1, pokemon.level + Math.floor(pokemon.level / 2));
    }
  },
  pursuit: {
    inherit: true,
    onModifyMove() {
    },
    condition: {
      duration: 1,
      onBeforeSwitchOut(pokemon) {
        this.debug("Pursuit start");
        let alreadyAdded = false;
        for (const source of this.effectState.sources) {
          if (source.speed < pokemon.speed || source.speed === pokemon.speed && this.random(2) === 0) {
            pokemon.removeVolatile("destinybond");
          }
          if (!this.queue.cancelMove(source) || !source.hp)
            continue;
          if (!alreadyAdded) {
            this.add("-activate", pokemon, "move: Pursuit");
            alreadyAdded = true;
          }
          if (source.canMegaEvo || source.canUltraBurst) {
            for (const [actionIndex, action] of this.queue.entries()) {
              if (action.pokemon === source && action.choice === "megaEvo") {
                this.actions.runMegaEvo(source);
                this.queue.list.splice(actionIndex, 1);
                break;
              }
            }
          }
          this.actions.runMove("pursuit", source, source.getLocOf(pokemon));
        }
      }
    }
  },
  razorleaf: {
    inherit: true,
    critRatio: 3
  },
  razorwind: {
    inherit: true,
    accuracy: 75,
    critRatio: 3,
    onPrepareHit(target, source) {
      return source.status !== "slp";
    }
  },
  reflect: {
    inherit: true,
    condition: {
      duration: 5,
      // Defense boost applied directly in stat calculation
      onSideStart(side) {
        this.add("-sidestart", side, "Reflect");
      },
      onSideResidualOrder: 9,
      onSideEnd(side) {
        this.add("-sideend", side, "Reflect");
      }
    }
  },
  rest: {
    inherit: true,
    onTry(pokemon) {
      if (pokemon.hp < pokemon.maxhp)
        return;
      this.add("-fail", pokemon);
      return null;
    },
    onHit(target, source, move) {
      if (target.status !== "slp") {
        if (!target.setStatus("slp", source, move))
          return;
      } else {
        this.add("-status", target, "slp", "[from] move: Rest");
      }
      target.statusState.time = 3;
      target.statusState.startTime = 3;
      target.statusState.source = target;
      this.heal(target.maxhp);
    },
    secondary: null
  },
  return: {
    inherit: true,
    basePowerCallback(pokemon) {
      return Math.floor(pokemon.happiness * 10 / 25) || null;
    }
  },
  reversal: {
    inherit: true,
    noDamageVariance: true,
    willCrit: false
  },
  roar: {
    inherit: true,
    onTryHit() {
      for (const action of this.queue) {
        if (action.choice === "move" || action.choice === "switch")
          return false;
      }
    },
    priority: -1
  },
  safeguard: {
    inherit: true,
    condition: {
      duration: 5,
      durationCallback(target, source, effect) {
        if (source?.hasAbility("persistent")) {
          this.add("-activate", source, "ability: Persistent", effect);
          return 7;
        }
        return 5;
      },
      onSetStatus(status, target, source, effect) {
        if (!effect || !source)
          return;
        if (effect.id === "yawn")
          return;
        if (effect.effectType === "Move" && effect.infiltrates && !target.isAlly(source))
          return;
        if (target !== source) {
          this.debug("interrupting setStatus");
          if (effect.id === "synchronize" || effect.effectType === "Move" && !effect.secondaries) {
            this.add("-activate", target, "move: Safeguard");
          }
          return null;
        }
      },
      onTryAddVolatile(status, target, source, effect) {
        if (!effect || !source)
          return;
        if (effect.effectType === "Move" && effect.infiltrates && !target.isAlly(source))
          return;
        if ((status.id === "confusion" || status.id === "yawn") && target !== source) {
          if (effect.effectType === "Move" && !effect.secondaries)
            this.add("-activate", target, "move: Safeguard");
          return null;
        }
      },
      onSideStart(side) {
        this.add("-sidestart", side, "Safeguard");
      },
      onSideResidualOrder: 8,
      onSideEnd(side) {
        this.add("-sideend", side, "Safeguard");
      }
    }
  },
  selfdestruct: {
    inherit: true,
    noSketch: true
  },
  sketch: {
    inherit: true,
    flags: { bypasssub: 1, failencore: 1, noassist: 1 },
    onHit() {
      this.add("-nothing");
    }
  },
  skullbash: {
    inherit: true,
    onPrepareHit(target, source) {
      return source.status !== "slp";
    }
  },
  skyattack: {
    inherit: true,
    critRatio: 1,
    onPrepareHit(target, source) {
      return source.status !== "slp";
    },
    secondary: null
  },
  slash: {
    inherit: true,
    critRatio: 3
  },
  sleeptalk: {
    inherit: true,
    flags: { failencore: 1, nosleeptalk: 1 },
    onHit(pokemon) {
      const moves = [];
      for (const moveSlot of pokemon.moveSlots) {
        const moveid = moveSlot.id;
        const move = this.dex.moves.get(moveid);
        if (moveid && !move.flags["nosleeptalk"] && !move.flags["charge"]) {
          moves.push(moveid);
        }
      }
      let randomMove = "";
      if (moves.length)
        randomMove = this.sample(moves);
      if (!randomMove)
        return false;
      this.actions.useMove(randomMove, pokemon);
    },
    noSketch: true
  },
  solarbeam: {
    inherit: true,
    onPrepareHit(target, source) {
      return source.status !== "slp";
    },
    // Rain weakening done directly in the damage formula
    onBasePower() {
    }
  },
  spiderweb: {
    inherit: true,
    flags: { reflectable: 1, mirror: 1, metronome: 1 }
  },
  spikes: {
    inherit: true,
    condition: {
      // this is a side condition
      onSideStart(side) {
        if (!this.effectState.layers || this.effectState.layers === 0) {
          this.add("-sidestart", side, "Spikes");
          this.effectState.layers = 1;
        } else {
          return false;
        }
      },
      onSwitchIn(pokemon) {
        if (!pokemon.runImmunity("Ground"))
          return;
        const damageAmounts = [0, 3];
        this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
      }
    }
  },
  substitute: {
    inherit: true,
    condition: {
      onStart(target) {
        this.add("-start", target, "Substitute");
        this.effectState.hp = Math.floor(target.maxhp / 4);
        delete target.volatiles["partiallytrapped"];
      },
      onTryPrimaryHitPriority: -1,
      onTryPrimaryHit(target, source, move) {
        if (move.stallingMove) {
          this.add("-fail", source);
          return null;
        }
        if (target === source) {
          this.debug("sub bypass: self hit");
          return;
        }
        if (move.id === "twineedle") {
          move.secondaries = move.secondaries.filter((p) => !p.kingsrock);
        }
        if (move.drain) {
          this.add("-miss", source);
          this.hint("In Gen 2, draining moves always miss against Substitute.");
          return null;
        }
        if (move.category === "Status") {
          const SubBlocked = ["leechseed", "lockon", "mindreader", "nightmare", "painsplit", "sketch"];
          if (move.id === "swagger") {
            delete move.volatileStatus;
          }
          if (move.status || move.boosts && move.id !== "swagger" || move.volatileStatus === "confusion" || SubBlocked.includes(move.id)) {
            this.add("-activate", target, "Substitute", "[block] " + move.name);
            return null;
          }
          return;
        }
        let damage = this.actions.getDamage(source, target, move);
        if (!damage) {
          return null;
        }
        damage = this.runEvent("SubDamage", target, source, move, damage);
        if (!damage) {
          return damage;
        }
        if (damage > target.volatiles["substitute"].hp) {
          damage = target.volatiles["substitute"].hp;
        }
        target.volatiles["substitute"].hp -= damage;
        source.lastDamage = damage;
        if (target.volatiles["substitute"].hp <= 0) {
          target.removeVolatile("substitute");
        } else {
          this.add("-activate", target, "Substitute", "[damage]");
        }
        if (move.recoil) {
          this.damage(1, source, target, "recoil");
        }
        this.runEvent("AfterSubDamage", target, source, move, damage);
        return this.HIT_SUBSTITUTE;
      },
      onEnd(target) {
        this.add("-end", target, "Substitute");
      }
    }
  },
  swagger: {
    inherit: true,
    onTryHit(target, pokemon) {
      if (target.boosts.atk >= 6 || target.getStat("atk", false, true) === 999) {
        this.add("-miss", pokemon);
        return null;
      }
    }
  },
  synthesis: {
    inherit: true,
    onHit(pokemon) {
      if (this.field.isWeather(["sunnyday", "desolateland"])) {
        this.heal(pokemon.maxhp);
      } else if (this.field.isWeather(["raindance", "primordialsea", "sandstorm", "hail"])) {
        this.heal(pokemon.baseMaxhp / 4);
      } else {
        this.heal(pokemon.baseMaxhp / 2);
      }
    }
  },
  thief: {
    inherit: true,
    onAfterHit() {
    },
    secondary: {
      chance: 100,
      onHit(target, source) {
        if (source.item || source.volatiles["gem"]) {
          return;
        }
        const yourItem = target.takeItem(source);
        if (!yourItem) {
          return;
        }
        if (!source.setItem(yourItem)) {
          target.item = yourItem.id;
          return;
        }
        this.add("-item", source, yourItem, "[from] move: Thief", "[of] " + target);
      }
    }
  },
  thrash: {
    inherit: true,
    onMoveFail(target, source, move) {
      source.addVolatile("lockedmove");
    },
    onAfterMove(pokemon) {
      if (pokemon.volatiles["lockedmove"] && pokemon.volatiles["lockedmove"].duration === 1) {
        pokemon.removeVolatile("lockedmove");
      }
    }
  },
  toxic: {
    inherit: true,
    ignoreImmunity: false
  },
  transform: {
    inherit: true,
    noSketch: true
  },
  triattack: {
    inherit: true,
    onHit(target, source, move) {
      move.statusRoll = ["par", "frz", "brn"][this.random(3)];
    },
    secondary: {
      chance: 20,
      onHit(target, source, move) {
        if (move.statusRoll) {
          target.trySetStatus(move.statusRoll, source);
        }
      }
    }
  },
  triplekick: {
    inherit: true,
    multiaccuracy: false,
    multihit: [1, 3]
  },
  whirlwind: {
    inherit: true,
    onTryHit() {
      for (const action of this.queue) {
        if (action.choice === "move" || action.choice === "switch")
          return false;
      }
    },
    priority: -1
  }
};
//# sourceMappingURL=moves.js.map
