"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 = {
  bide: {
    inherit: true,
    priority: 0,
    accuracy: true,
    condition: {
      durationCallback(target, source, effect) {
        return this.random(3, 5);
      },
      onStart(pokemon) {
        this.effectState.totalDamage = 0;
        this.effectState.lastDamage = 0;
        this.add("-start", pokemon, "Bide");
      },
      onHit(target, source, move) {
        if (source && source !== target && move.category !== "Physical" && move.category !== "Special") {
          const damage = this.effectState.totalDamage;
          this.effectState.totalDamage += damage;
          this.effectState.lastDamage = damage;
          this.effectState.sourceSlot = source.getSlot();
        }
      },
      onDamage(damage, target, source, move) {
        if (!source || source.isAlly(target))
          return;
        if (!move || move.effectType !== "Move")
          return;
        if (!damage && this.effectState.lastDamage > 0) {
          damage = this.effectState.totalDamage;
        }
        this.effectState.totalDamage += damage;
        this.effectState.lastDamage = damage;
        this.effectState.sourceSlot = source.getSlot();
      },
      onAfterSetStatus(status, pokemon) {
        if (pokemon.volatiles["flinch"]) {
          this.effectState.duration++;
        } else if (pokemon.volatiles["partiallytrapped"]) {
          this.effectState.duration++;
        } else {
          switch (status.id) {
            case "slp":
            case "frz":
              this.effectState.duration++;
              break;
          }
        }
      },
      onBeforeMove(pokemon, t, move) {
        if (this.effectState.duration === 1) {
          this.add("-end", pokemon, "Bide");
          if (!this.effectState.totalDamage) {
            this.debug("Bide failed because no damage was taken");
            this.add("-fail", pokemon);
            return false;
          }
          const target = this.getAtSlot(this.effectState.sourceSlot);
          if (target.isSemiInvulnerable()) {
            this.add("-message", "The foe " + target.name + " can't be hit while flying!");
            pokemon.removeVolatile("bide");
            return false;
          }
          this.actions.moveHit(target, pokemon, move, { damage: this.effectState.totalDamage * 2 });
          pokemon.removeVolatile("bide");
          return false;
        }
        this.add("-activate", pokemon, "Bide");
        return false;
      },
      onDisableMove(pokemon) {
        if (!pokemon.hasMove("bide")) {
          return;
        }
        for (const moveSlot of pokemon.moveSlots) {
          if (moveSlot.id !== "bide") {
            pokemon.disableMove(moveSlot.id);
          }
        }
      }
    },
    type: "???"
    // Will look as Normal but it's STAB-less
  },
  bind: {
    inherit: true
    // FIXME: onBeforeMove() {},
  },
  clamp: {
    inherit: true
    // FIXME: onBeforeMove() {},
  },
  counter: {
    inherit: true,
    ignoreImmunity: true,
    willCrit: false,
    basePower: 1,
    damageCallback(pokemon, target) {
      const lastMoveThisTurn = target.side.lastMove && target.side.lastMove.id === target.side.lastSelectedMove && !this.queue.willMove(target) && this.dex.moves.get(target.side.lastMove.id);
      if (!lastMoveThisTurn) {
        this.debug("Stadium 1 Counter: last move was not this turn");
        this.add("-fail", pokemon);
        return false;
      }
      const lastMoveThisTurnIsCounterable = lastMoveThisTurn && lastMoveThisTurn.basePower > 0 && ["Normal", "Fighting"].includes(lastMoveThisTurn.type) && lastMoveThisTurn.id !== "counter";
      if (!lastMoveThisTurnIsCounterable) {
        this.debug(`Stadium 1 Counter: last move ${lastMoveThisTurn.name} was not Counterable`);
        this.add("-fail", pokemon);
        return false;
      }
      if (this.lastDamage <= 0) {
        this.debug("Stadium 1 Counter: no previous damage exists");
        this.add("-fail", pokemon);
        return false;
      }
      return 2 * this.lastDamage;
    }
  },
  firespin: {
    inherit: true
    // FIXME: onBeforeMove() {},
  },
  haze: {
    inherit: true,
    onHit(target, source) {
      this.add("-activate", target, "move: Haze");
      this.add("-clearallboost", "[silent]");
      for (const pokemon of this.getAllActive()) {
        pokemon.clearBoosts();
        pokemon.cureStatus(true);
        for (const id of Object.keys(pokemon.volatiles)) {
          pokemon.removeVolatile(id);
          this.add("-end", pokemon, id, "[silent]");
        }
        pokemon.recalculateStats();
      }
    }
  },
  hyperbeam: {
    inherit: true,
    onMoveFail(target, source, move) {
      source.addVolatile("mustrecharge");
    }
  },
  psywave: {
    inherit: true,
    basePower: 1,
    damageCallback(pokemon) {
      return this.random(1, this.trunc(1.5 * pokemon.level));
    }
  },
  rage: {
    inherit: true,
    self: {
      volatileStatus: "rage"
    },
    condition: {
      // Rage lock
      onStart(target, source, effect) {
        this.effectState.move = "rage";
      },
      onLockMove: "rage",
      onHit(target, source, move) {
        if (target.boosts.atk < 6 && (move.category !== "Status" || move.id === "disable")) {
          this.boost({ atk: 1 });
        }
      }
    }
  },
  recover: {
    inherit: true,
    heal: null,
    onHit(target) {
      if (target.hp === target.maxhp) {
        return false;
      }
      this.heal(Math.floor(target.maxhp / 2), target, target);
    }
  },
  rest: {
    inherit: true,
    onHit(target, source, move) {
      if (target.hp >= target.maxhp)
        return false;
      if (!target.setStatus("slp", source, move))
        return false;
      target.statusState.time = 2;
      target.statusState.startTime = 2;
      target.recalculateStats();
      this.heal(target.maxhp);
    }
  },
  softboiled: {
    inherit: true,
    heal: null,
    onHit(target) {
      if (target.hp === target.maxhp) {
        return false;
      }
      this.heal(Math.floor(target.maxhp / 2), target, target);
    }
  },
  substitute: {
    inherit: true,
    onTryHit(target) {
      if (target.volatiles["substitute"]) {
        this.add("-fail", target, "move: Substitute");
        return null;
      }
      if (target.hp <= target.maxhp / 4) {
        this.add("-fail", target, "move: Substitute", "[weak]");
        return null;
      }
    },
    condition: {
      onStart(target) {
        this.add("-start", target, "Substitute");
        this.effectState.hp = Math.floor(target.maxhp / 4);
        delete target.volatiles["partiallytrapped"];
      },
      onTryHitPriority: -1,
      onTryHit(target, source, move) {
        if (target === source) {
          this.debug("sub bypass: self hit");
          return;
        }
        if (move.drain) {
          this.add("-miss", source);
          return null;
        }
        if (move.category === "Status") {
          const SubBlocked = ["leechseed", "lockon", "mindreader", "nightmare"];
          if (move.status || move.boosts || move.volatileStatus === "confusion" || SubBlocked.includes(move.id)) {
            this.add("-activate", target, "Substitute", "[block] " + move.name);
            return null;
          }
          return;
        }
        if (move.volatileStatus && target === source)
          return;
        let damage = this.actions.getDamage(source, target, move);
        if (damage && damage > target.volatiles["substitute"].hp) {
          damage = target.volatiles["substitute"].hp;
        }
        if (!damage && damage !== 0)
          return null;
        damage = this.runEvent("SubDamage", target, source, move, damage);
        if (!damage && damage !== 0)
          return damage;
        target.volatiles["substitute"].hp -= damage;
        this.lastDamage = damage;
        if (target.volatiles["substitute"].hp <= 0) {
          this.debug("Substitute broke");
          target.removeVolatile("substitute");
          target.subFainted = true;
        } else {
          this.add("-activate", target, "Substitute", "[damage]");
        }
        if (target.volatiles["substitute"]) {
          if (move.recoil) {
            this.damage(this.clampIntRange(Math.floor(damage * move.recoil[0] / move.recoil[1]), 1), source, target, "recoil");
          }
        }
        this.runEvent("AfterSubDamage", target, source, move, damage);
        const lastAttackedBy = target.getLastAttackedBy();
        if (!lastAttackedBy) {
          target.attackedBy.push({ source, move: move.id, damage, slot: source.getSlot(), thisTurn: true });
        } else {
          lastAttackedBy.move = move.id;
          lastAttackedBy.damage = damage;
        }
        return 0;
      },
      onEnd(target) {
        this.add("-end", target, "Substitute");
      }
    },
    secondary: null,
    target: "self",
    type: "Normal"
  },
  struggle: {
    inherit: true,
    ignoreImmunity: { "Normal": true }
  },
  wrap: {
    inherit: true
    // FIXME: onBeforeMove() {},
  }
};
//# sourceMappingURL=moves.js.map