"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 conditions_exports = {};
__export(conditions_exports, {
    Conditions: () => Conditions,
});
module.exports = __toCommonJS(conditions_exports);
const Conditions = {
    brn: {
        name: "brn",
        effectType: "Status",
        onStart(target, source, sourceEffect) {
            if (sourceEffect && sourceEffect.id === "flameorb") {
                this.add("-status", target, "brn", "[from] item: Flame Orb");
            } else if (sourceEffect && sourceEffect.effectType === "Ability") {
                this.add(
                    "-status",
                    target,
                    "brn",
                    "[from] ability: " + sourceEffect.name,
                    "[of] " + source
                );
            } else {
                this.add("-status", target, "brn");
            }
        },
        // Damage reduction is handled directly in the sim/battle.js damage function
        onResidualOrder: 10,
        onResidual(pokemon) {
            this.damage(pokemon.baseMaxhp / 16);
        },
    },
    par: {
        name: "par",
        effectType: "Status",
        onStart(target, source, sourceEffect) {
            if (sourceEffect && sourceEffect.effectType === "Ability") {
                this.add(
                    "-status",
                    target,
                    "par",
                    "[from] ability: " + sourceEffect.name,
                    "[of] " + source
                );
            } else {
                this.add("-status", target, "par");
            }
        },
        onModifySpe(spe, pokemon) {
            spe = this.finalModify(spe);
            if (!pokemon.hasAbility("quickfeet")) {
                spe = Math.floor((spe * 50) / 100);
            }
            return spe;
        },
        onBeforeMovePriority: 1,
        onBeforeMove(pokemon) {
            if (this.randomChance(1, 4)) {
                this.add("cant", pokemon, "par");
                return false;
            }
        },
    },
    slp: {
        name: "slp",
        effectType: "Status",
        onStart(target, source, sourceEffect) {
            if (sourceEffect && sourceEffect.effectType === "Ability") {
                this.add(
                    "-status",
                    target,
                    "slp",
                    "[from] ability: " + sourceEffect.name,
                    "[of] " + source
                );
            } else if (sourceEffect && sourceEffect.effectType === "Move") {
                this.add(
                    "-status",
                    target,
                    "slp",
                    "[from] move: " + sourceEffect.name
                );
            } else {
                this.add("-status", target, "slp");
            }
            this.effectState.startTime = this.random(2, 5);
            this.effectState.time = this.effectState.startTime;
            if (target.removeVolatile("nightmare")) {
                this.add("-end", target, "Nightmare", "[silent]");
            }
        },
        onBeforeMovePriority: 10,
        onBeforeMove(pokemon, target, move) {
            if (pokemon.hasAbility("earlybird")) {
                pokemon.statusState.time--;
            }
            pokemon.statusState.time--;
            if (pokemon.statusState.time <= 0) {
                pokemon.cureStatus();
                return;
            }
            this.add("cant", pokemon, "slp");
            if (move.sleepUsable) {
                return;
            }
            return false;
        },
    },
    frz: {
        name: "frz",
        effectType: "Status",
        onStart(target, source, sourceEffect) {
            if (sourceEffect && sourceEffect.effectType === "Ability") {
                this.add(
                    "-status",
                    target,
                    "frz",
                    "[from] ability: " + sourceEffect.name,
                    "[of] " + source
                );
            } else {
                this.add("-status", target, "frz");
            }
            if (
                target.species.name === "Shaymin-Sky" &&
                target.baseSpecies.baseSpecies === "Shaymin"
            ) {
                target.formeChange("Shaymin", this.effect, true);
            }
        },
        onBeforeMovePriority: 10,
        onBeforeMove(pokemon, target, move) {
            if (move.flags["defrost"]) return;
            if (this.randomChance(1, 5)) {
                pokemon.cureStatus();
                return;
            }
            this.add("cant", pokemon, "frz");
            return false;
        },
        onModifyMove(move, pokemon) {
            if (move.flags["defrost"]) {
                this.add("-curestatus", pokemon, "frz", "[from] move: " + move);
                pokemon.clearStatus();
            }
        },
        onAfterMoveSecondary(target, source, move) {
            if (move.thawsTarget) {
                target.cureStatus();
            }
        },
        onDamagingHit(damage, target, source, move) {
            if (move.type === "Fire" && move.category !== "Status") {
                target.cureStatus();
            }
        },
    },
    psn: {
        name: "psn",
        effectType: "Status",
        onStart(target, source, sourceEffect) {
            if (sourceEffect && sourceEffect.effectType === "Ability") {
                this.add(
                    "-status",
                    target,
                    "psn",
                    "[from] ability: " + sourceEffect.name,
                    "[of] " + source
                );
            } else {
                this.add("-status", target, "psn");
            }
        },
        onResidualOrder: 9,
        onResidual(pokemon) {
            this.damage(pokemon.baseMaxhp / 8);
        },
    },
    tox: {
        name: "tox",
        effectType: "Status",
        onStart(target, source, sourceEffect) {
            this.effectState.stage = 0;
            if (sourceEffect && sourceEffect.id === "toxicorb") {
                this.add("-status", target, "tox", "[from] item: Toxic Orb");
            } else if (sourceEffect && sourceEffect.effectType === "Ability") {
                this.add(
                    "-status",
                    target,
                    "tox",
                    "[from] ability: " + sourceEffect.name,
                    "[of] " + source
                );
            } else {
                this.add("-status", target, "tox");
            }
        },
        onSwitchIn() {
            this.effectState.stage = 0;
        },
        onResidualOrder: 9,
        onResidual(pokemon) {
            if (this.effectState.stage < 15) {
                this.effectState.stage++;
            }
            this.damage(
                this.clampIntRange(pokemon.baseMaxhp / 16, 1) *
                    this.effectState.stage
            );
        },
    },
    confusion: {
        name: "confusion",
        // this is a volatile status
        onStart(target, source, sourceEffect) {
            if (sourceEffect?.id === "lockedmove") {
                this.add("-start", target, "confusion", "[fatigue]");
            } else {
                this.add("-start", target, "confusion");
            }
            const min = sourceEffect?.id === "axekick" ? 3 : 2;
            this.effectState.time = this.random(min, 6);
        },
        onEnd(target) {
            this.add("-end", target, "confusion");
        },
        onBeforeMovePriority: 3,
        onBeforeMove(pokemon) {
            pokemon.volatiles["confusion"].time--;
            if (!pokemon.volatiles["confusion"].time) {
                pokemon.removeVolatile("confusion");
                return;
            }
            this.add("-activate", pokemon, "confusion");
            if (!this.randomChance(33, 100)) {
                return;
            }
            this.activeTarget = pokemon;
            const damage = this.actions.getConfusionDamage(pokemon, 40);
            if (typeof damage !== "number")
                throw new Error("Confusion damage not dealt");
            const activeMove = {
                id: this.toID("confused"),
                effectType: "Move",
                type: "???",
            };
            this.damage(damage, pokemon, pokemon, activeMove);
            return false;
        },
    },
    flinch: {
        name: "flinch",
        duration: 1,
        onBeforeMovePriority: 8,
        onBeforeMove(pokemon) {
            this.add("cant", pokemon, "flinch");
            this.runEvent("Flinch", pokemon);
            return false;
        },
    },
    trapped: {
        name: "trapped",
        noCopy: true,
        onTrapPokemon(pokemon) {
            pokemon.tryTrap();
        },
        onStart(target) {
            this.add("-activate", target, "trapped");
        },
    },
    trapper: {
        name: "trapper",
        noCopy: true,
    },
    partiallytrapped: {
        name: "partiallytrapped",
        duration: 5,
        durationCallback(target, source) {
            if (source?.hasItem("gripclaw")) return 8;
            return this.random(5, 7);
        },
        onStart(pokemon, source) {
            this.add(
                "-activate",
                pokemon,
                "move: " + this.effectState.sourceEffect,
                "[of] " + source
            );
            this.effectState.boundDivisor = source.hasItem("bindingband")
                ? 6
                : 8;
        },
        onResidualOrder: 13,
        onResidual(pokemon) {
            const source = this.effectState.source;
            const gmaxEffect = ["gmaxcentiferno", "gmaxsandblast"].includes(
                this.effectState.sourceEffect.id
            );
            if (
                source &&
                (!source.isActive || source.hp <= 0 || !source.activeTurns) &&
                !gmaxEffect
            ) {
                delete pokemon.volatiles["partiallytrapped"];
                this.add(
                    "-end",
                    pokemon,
                    this.effectState.sourceEffect,
                    "[partiallytrapped]",
                    "[silent]"
                );
                return;
            }
            this.damage(pokemon.baseMaxhp / this.effectState.boundDivisor);
        },
        onEnd(pokemon) {
            this.add(
                "-end",
                pokemon,
                this.effectState.sourceEffect,
                "[partiallytrapped]"
            );
        },
        onTrapPokemon(pokemon) {
            const gmaxEffect = ["gmaxcentiferno", "gmaxsandblast"].includes(
                this.effectState.sourceEffect.id
            );
            if (this.effectState.source?.isActive || gmaxEffect)
                pokemon.tryTrap();
        },
    },
    lockedmove: {
        // Outrage, Thrash, Petal Dance...
        name: "lockedmove",
        duration: 2,
        onResidual(target) {
            if (target.status === "slp") {
                delete target.volatiles["lockedmove"];
            }
            this.effectState.trueDuration--;
        },
        onStart(target, source, effect) {
            this.effectState.trueDuration = this.random(2, 4);
            this.effectState.move = effect.id;
        },
        onRestart() {
            if (this.effectState.trueDuration >= 2) {
                this.effectState.duration = 2;
            }
        },
        onEnd(target) {
            if (this.effectState.trueDuration > 1) return;
            target.addVolatile("confusion");
        },
        onLockMove(pokemon) {
            if (pokemon.volatiles["dynamax"]) return;
            return this.effectState.move;
        },
    },
    twoturnmove: {
        // Skull Bash, SolarBeam, Sky Drop...
        name: "twoturnmove",
        duration: 2,
        onStart(attacker, defender, effect) {
            this.effectState.move = effect.id;
            attacker.addVolatile(effect.id);
            let moveTargetLoc = attacker.lastMoveTargetLoc;
            if (
                effect.sourceEffect &&
                this.dex.moves.get(effect.id).target !== "self"
            ) {
                if (defender.fainted) {
                    defender = this.sample(attacker.foes(true));
                }
                moveTargetLoc = attacker.getLocOf(defender);
            }
            attacker.volatiles[effect.id].targetLoc = moveTargetLoc;
            this.attrLastMove("[still]");
            this.runEvent("PrepareHit", attacker, defender, effect);
        },
        onEnd(target) {
            target.removeVolatile(this.effectState.move);
        },
        onLockMove() {
            return this.effectState.move;
        },
        onMoveAborted(pokemon) {
            pokemon.removeVolatile("twoturnmove");
        },
    },
    choicelock: {
        name: "choicelock",
        noCopy: true,
        onStart(pokemon) {
            if (!this.activeMove) throw new Error("Battle.activeMove is null");
            if (
                !this.activeMove.id ||
                this.activeMove.hasBounced ||
                this.activeMove.sourceEffect === "snatch"
            )
                return false;
            this.effectState.move = this.activeMove.id;
        },
        onBeforeMove(pokemon, target, move) {
            if (!pokemon.getItem().isChoice) {
                pokemon.removeVolatile("choicelock");
                return;
            }
            if (
                !pokemon.ignoringItem() &&
                !pokemon.volatiles["dynamax"] &&
                move.id !== this.effectState.move &&
                move.id !== "struggle"
            ) {
                this.addMove("move", pokemon, move.name);
                this.attrLastMove("[still]");
                this.debug("Disabled by Choice item lock");
                this.add("-fail", pokemon);
                return false;
            }
        },
        onDisableMove(pokemon) {
            if (
                !pokemon.getItem().isChoice ||
                !pokemon.hasMove(this.effectState.move)
            ) {
                pokemon.removeVolatile("choicelock");
                return;
            }
            if (pokemon.ignoringItem() || pokemon.volatiles["dynamax"]) {
                return;
            }
            for (const moveSlot of pokemon.moveSlots) {
                if (moveSlot.id !== this.effectState.move) {
                    pokemon.disableMove(
                        moveSlot.id,
                        false,
                        this.effectState.sourceEffect
                    );
                }
            }
        },
    },
    mustrecharge: {
        name: "mustrecharge",
        duration: 2,
        onBeforeMovePriority: 11,
        onBeforeMove(pokemon) {
            this.add("cant", pokemon, "recharge");
            pokemon.removeVolatile("mustrecharge");
            pokemon.removeVolatile("truant");
            return null;
        },
        onStart(pokemon) {
            this.add("-mustrecharge", pokemon);
        },
        onLockMove: "recharge",
    },
    futuremove: {
        // this is a slot condition
        name: "futuremove",
        duration: 3,
        onResidualOrder: 3,
        onEnd(target) {
            const data = this.effectState;
            const move = this.dex.moves.get(data.move);
            if (target.fainted || target === data.source) {
                this.hint(
                    `${move.name} did not hit because the target is ${
                        target.fainted ? "fainted" : "the user"
                    }.`
                );
                return;
            }
            this.add("-end", target, "move: " + move.name);
            target.removeVolatile("Protect");
            target.removeVolatile("Endure");
            if (data.source.hasAbility("infiltrator") && this.gen >= 6) {
                data.moveData.infiltrates = true;
            }
            if (data.source.hasAbility("normalize") && this.gen >= 6) {
                data.moveData.type = "Normal";
            }
            if (data.source.hasAbility("adaptability") && this.gen >= 6) {
                data.moveData.stab = 2;
            }
            const hitMove = new this.dex.Move(data.moveData);
            this.actions.trySpreadMoveHit([target], data.source, hitMove, true);
            if (
                data.source.isActive &&
                data.source.hasItem("lifeorb") &&
                this.gen >= 5
            ) {
                this.singleEvent(
                    "AfterMoveSecondarySelf",
                    data.source.getItem(),
                    data.source.itemState,
                    data.source,
                    target,
                    data.source.getItem()
                );
            }
            this.activeMove = null;
            this.checkWin();
        },
    },
    healreplacement: {
        // this is a slot condition
        name: "healreplacement",
        onStart(target, source, sourceEffect) {
            this.effectState.sourceEffect = sourceEffect;
            this.add("-activate", source, "healreplacement");
        },
        onSwitchInPriority: 1,
        onSwitchIn(target) {
            if (!target.fainted) {
                target.heal(target.maxhp);
                this.add(
                    "-heal",
                    target,
                    target.getHealth,
                    "[from] move: " + this.effectState.sourceEffect,
                    "[zeffect]"
                );
                target.side.removeSlotCondition(target, "healreplacement");
            }
        },
    },
    stall: {
        // Protect, Detect, Endure counter
        name: "stall",
        duration: 2,
        counterMax: 729,
        onStart() {
            this.effectState.counter = 3;
        },
        onStallMove(pokemon) {
            const counter = this.effectState.counter || 1;
            this.debug("Success chance: " + Math.round(100 / counter) + "%");
            const success = this.randomChance(1, counter);
            if (!success) delete pokemon.volatiles["stall"];
            return success;
        },
        onRestart() {
            if (this.effectState.counter < this.effect.counterMax) {
                this.effectState.counter *= 3;
            }
            this.effectState.duration = 2;
        },
    },
    gem: {
        name: "gem",
        duration: 1,
        affectsFainted: true,
        onBasePowerPriority: 14,
        onBasePower(basePower, user, target, move) {
            this.debug("Gem Boost");
            return this.chainModify([5325, 4096]);
        },
    },
    // weather is implemented here since it's so important to the game
    raindance: {
        name: "RainDance",
        effectType: "Weather",
        duration: 5,
        durationCallback(source, effect) {
            if (source?.hasItem("damprock")) {
                return 8;
            }
            return 5;
        },
        onWeatherModifyDamage(damage, attacker, defender, move) {
            if (defender.hasItem("utilityumbrella")) return;
            if (move.type === "Water") {
                this.debug("rain water boost");
                return this.chainModify(1.5);
            }
            if (move.type === "Fire") {
                this.debug("rain fire suppress");
                return this.chainModify(0.5);
            }
        },
        onFieldStart(field, source, effect) {
            if (effect?.effectType === "Ability") {
                if (this.gen <= 5) this.effectState.duration = 0;
                this.add(
                    "-weather",
                    "RainDance",
                    "[from] ability: " + effect.name,
                    "[of] " + source
                );
            } else {
                this.add("-weather", "RainDance");
            }
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "RainDance", "[upkeep]");
            this.eachEvent("Weather");
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    primordialsea: {
        name: "PrimordialSea",
        effectType: "Weather",
        duration: 0,
        onTryMovePriority: 1,
        onTryMove(attacker, defender, move) {
            if (move.type === "Fire" && move.category !== "Status") {
                this.debug("Primordial Sea fire suppress");
                this.add("-fail", attacker, move, "[from] Primordial Sea");
                this.attrLastMove("[still]");
                return null;
            }
        },
        onWeatherModifyDamage(damage, attacker, defender, move) {
            if (defender.hasItem("utilityumbrella")) return;
            if (move.type === "Water") {
                this.debug("Rain water boost");
                return this.chainModify(1.5);
            }
        },
        onFieldStart(field, source, effect) {
            this.add(
                "-weather",
                "PrimordialSea",
                "[from] ability: " + effect.name,
                "[of] " + source
            );
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "PrimordialSea", "[upkeep]");
            this.eachEvent("Weather");
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    sunnyday: {
        name: "SunnyDay",
        effectType: "Weather",
        duration: 5,
        durationCallback(source, effect) {
            if (source?.hasItem("heatrock")) {
                return 8;
            }
            return 5;
        },
        onWeatherModifyDamage(damage, attacker, defender, move) {
            if (
                move.id === "hydrosteam" &&
                !attacker.hasItem("utilityumbrella")
            ) {
                this.debug("Sunny Day Hydro Steam boost");
                return this.chainModify(1.5);
            }
            if (defender.hasItem("utilityumbrella")) return;
            if (move.type === "Fire") {
                this.debug("Sunny Day fire boost");
                return this.chainModify(1.5);
            }
            if (move.type === "Water") {
                this.debug("Sunny Day water suppress");
                return this.chainModify(0.5);
            }
        },
        onFieldStart(battle, source, effect) {
            if (effect?.effectType === "Ability") {
                if (this.gen <= 5) this.effectState.duration = 0;
                this.add(
                    "-weather",
                    "SunnyDay",
                    "[from] ability: " + effect.name,
                    "[of] " + source
                );
            } else {
                this.add("-weather", "SunnyDay");
            }
        },
        onImmunity(type, pokemon) {
            if (pokemon.hasItem("utilityumbrella")) return;
            if (type === "frz") return false;
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "SunnyDay", "[upkeep]");
            this.eachEvent("Weather");
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    desolateland: {
        name: "DesolateLand",
        effectType: "Weather",
        duration: 0,
        onTryMovePriority: 1,
        onTryMove(attacker, defender, move) {
            if (move.type === "Water" && move.category !== "Status") {
                this.debug("Desolate Land water suppress");
                this.add("-fail", attacker, move, "[from] Desolate Land");
                this.attrLastMove("[still]");
                return null;
            }
        },
        onWeatherModifyDamage(damage, attacker, defender, move) {
            if (defender.hasItem("utilityumbrella")) return;
            if (move.type === "Fire") {
                this.debug("Sunny Day fire boost");
                return this.chainModify(1.5);
            }
        },
        onFieldStart(field, source, effect) {
            this.add(
                "-weather",
                "DesolateLand",
                "[from] ability: " + effect.name,
                "[of] " + source
            );
        },
        onImmunity(type, pokemon) {
            if (pokemon.hasItem("utilityumbrella")) return;
            if (type === "frz") return false;
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "DesolateLand", "[upkeep]");
            this.eachEvent("Weather");
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    sandstorm: {
        name: "Sandstorm",
        effectType: "Weather",
        duration: 5,
        durationCallback(source, effect) {
            if (source?.hasItem("smoothrock")) {
                return 8;
            }
            return 5;
        },
        // This should be applied directly to the stat before any of the other modifiers are chained
        // So we give it increased priority.
        onModifySpDPriority: 10,
        onModifySpD(spd, pokemon) {
            if (pokemon.hasType("Rock") && this.field.isWeather("sandstorm")) {
                return this.modify(spd, 1.5);
            }
        },
        onFieldStart(field, source, effect) {
            if (effect?.effectType === "Ability") {
                if (this.gen <= 5) this.effectState.duration = 0;
                this.add(
                    "-weather",
                    "Sandstorm",
                    "[from] ability: " + effect.name,
                    "[of] " + source
                );
            } else {
                this.add("-weather", "Sandstorm");
            }
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "Sandstorm", "[upkeep]");
            if (this.field.isWeather("sandstorm")) this.eachEvent("Weather");
        },
        onWeather(target) {
            this.damage(target.baseMaxhp / 16);
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    hail: {
        name: "Hail",
        effectType: "Weather",
        duration: 5,
        durationCallback(source, effect) {
            if (source?.hasItem("icyrock")) {
                return 8;
            }
            return 5;
        },
        onFieldStart(field, source, effect) {
            if (effect?.effectType === "Ability") {
                if (this.gen <= 5) this.effectState.duration = 0;
                this.add(
                    "-weather",
                    "Hail",
                    "[from] ability: " + effect.name,
                    "[of] " + source
                );
            } else {
                this.add("-weather", "Hail");
            }
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "Hail", "[upkeep]");
            if (this.field.isWeather("hail")) this.eachEvent("Weather");
        },
        onWeather(target) {
            this.damage(target.baseMaxhp / 16);
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    snow: {
        name: "Snow",
        effectType: "Weather",
        duration: 5,
        durationCallback(source, effect) {
            if (source?.hasItem("icyrock")) {
                return 8;
            }
            return 5;
        },
        onModifyDefPriority: 10,
        onModifyDef(def, pokemon) {
            if (pokemon.hasType("Ice") && this.field.isWeather("snow")) {
                return this.modify(def, 1.5);
            }
        },
        onFieldStart(field, source, effect) {
            if (effect?.effectType === "Ability") {
                if (this.gen <= 5) this.effectState.duration = 0;
                this.add(
                    "-weather",
                    "Snow",
                    "[from] ability: " + effect.name,
                    "[of] " + source
                );
            } else {
                this.add("-weather", "Snow");
            }
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "Snow", "[upkeep]");
            if (this.field.isWeather("snow")) this.eachEvent("Weather");
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    deltastream: {
        name: "DeltaStream",
        effectType: "Weather",
        duration: 0,
        onEffectivenessPriority: -1,
        onEffectiveness(typeMod, target, type, move) {
            if (
                move &&
                move.effectType === "Move" &&
                move.category !== "Status" &&
                type === "Flying" &&
                typeMod > 0
            ) {
                this.add("-fieldactivate", "Delta Stream");
                return 0;
            }
        },
        onFieldStart(field, source, effect) {
            this.add(
                "-weather",
                "DeltaStream",
                "[from] ability: " + effect.name,
                "[of] " + source
            );
        },
        onFieldResidualOrder: 1,
        onFieldResidual() {
            this.add("-weather", "DeltaStream", "[upkeep]");
            this.eachEvent("Weather");
        },
        onFieldEnd() {
            this.add("-weather", "none");
        },
    },
    dynamax: {
        name: "Dynamax",
        noCopy: true,
        onStart(pokemon) {
            this.effectState.turns = 0;
            pokemon.removeVolatile("minimize");
            pokemon.removeVolatile("substitute");
            if (pokemon.volatiles["torment"]) {
                delete pokemon.volatiles["torment"];
                this.add("-end", pokemon, "Torment", "[silent]");
            }
            if (
                ["cramorantgulping", "cramorantgorging"].includes(
                    pokemon.species.id
                ) &&
                !pokemon.transformed
            ) {
                pokemon.formeChange("cramorant");
            }
            this.add(
                "-start",
                pokemon,
                "Dynamax",
                pokemon.gigantamax ? "Gmax" : ""
            );
            if (pokemon.baseSpecies.name === "Shedinja") return;
            const ratio = 1.5 + pokemon.dynamaxLevel * 0.05;
            pokemon.maxhp = Math.floor(pokemon.maxhp * ratio);
            pokemon.hp = Math.floor(pokemon.hp * ratio);
            this.add("-heal", pokemon, pokemon.getHealth, "[silent]");
        },
        onTryAddVolatile(status, pokemon) {
            if (status.id === "flinch") return null;
        },
        onBeforeSwitchOutPriority: -1,
        onBeforeSwitchOut(pokemon) {
            pokemon.removeVolatile("dynamax");
        },
        onSourceModifyDamage(damage, source, target, move) {
            if (
                move.id === "behemothbash" ||
                move.id === "behemothblade" ||
                move.id === "dynamaxcannon"
            ) {
                return this.chainModify(2);
            }
        },
        onDragOutPriority: 2,
        onDragOut(pokemon) {
            this.add("-block", pokemon, "Dynamax");
            return null;
        },
        onResidualPriority: -100,
        onResidual() {
            this.effectState.turns++;
        },
        onEnd(pokemon) {
            this.add("-end", pokemon, "Dynamax");
            if (pokemon.baseSpecies.name === "Shedinja") return;
            pokemon.hp = pokemon.getUndynamaxedHP();
            pokemon.maxhp = pokemon.baseMaxhp;
            this.add("-heal", pokemon, pokemon.getHealth, "[silent]");
        },
    },
    // Commander needs two conditions so they are implemented here
    // Dondozo
    commanded: {
        name: "Commanded",
        noCopy: true,
        onStart(pokemon) {
            this.boost({ atk: 2, spa: 2, spe: 2, def: 2, spd: 2 }, pokemon);
        },
        onDragOutPriority: 2,
        onDragOut() {
            return false;
        },
        // Prevents Shed Shell allowing a swap
        onTrapPokemonPriority: -11,
        onTrapPokemon(pokemon) {
            pokemon.trapped = true;
        },
    },
    // Tatsugiri
    commanding: {
        name: "Commanding",
        noCopy: true,
        onDragOutPriority: 2,
        onDragOut() {
            return false;
        },
        // Prevents Shed Shell allowing a swap
        onTrapPokemonPriority: -11,
        onTrapPokemon(pokemon) {
            pokemon.trapped = true;
        },
        // Override No Guard
        onInvulnerabilityPriority: 2,
        onInvulnerability(target, source, move) {
            return false;
        },
        onBeforeTurn(pokemon) {
            this.queue.cancelAction(pokemon);
        },
    },
    // Arceus and Silvally's actual typing is implemented here.
    // Their true typing for all their formes is Normal, and it's only
    // Multitype and RKS System, respectively, that changes their type,
    // but their formes are specified to be their corresponding type
    // in the Pokedex, so that needs to be overridden.
    // This is mainly relevant for Hackmons Cup and Balanced Hackmons.
    arceus: {
        name: "Arceus",
        onTypePriority: 1,
        onType(types, pokemon) {
            if (
                pokemon.transformed ||
                (pokemon.ability !== "multitype" && this.gen >= 8)
            )
                return types;
            let type = "Normal";
            if (pokemon.ability === "multitype") {
                type = pokemon.getItem().onPlate;
                if (!type) {
                    type = "Normal";
                }
            }
            return [type];
        },
    },
    silvally: {
        name: "Silvally",
        onTypePriority: 1,
        onType(types, pokemon) {
            if (
                pokemon.transformed ||
                (pokemon.ability !== "rkssystem" && this.gen >= 8)
            )
                return types;
            let type = "Normal";
            if (pokemon.ability === "rkssystem") {
                type = pokemon.getItem().onMemory;
                if (!type) {
                    type = "Normal";
                }
            }
            return [type];
        },
    },
    rolloutstorage: {
        name: "rolloutstorage",
        duration: 2,
        onBasePower(relayVar, source, target, move) {
            let bp = Math.max(1, move.basePower);
            bp *= Math.pow(
                2,
                source.volatiles["rolloutstorage"].contactHitCount
            );
            if (source.volatiles["defensecurl"]) {
                bp *= 2;
            }
            source.removeVolatile("rolloutstorage");
            return bp;
        },
    },
};
//# sourceMappingURL=conditions.js.map
