Spaces:
Paused
Paused
| ; | |
| 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"); | |
| } | |
| }, | |
| onModifySpePriority: -101, | |
| 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); | |
| target.regressionForme = false; | |
| } | |
| }, | |
| 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 if (sourceEffect?.effectType === "Ability") { | |
| this.add("-start", target, "confusion", "[from] ability: " + sourceEffect.name, `[of] ${source}`); | |
| } 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", | |
| onStart(target) { | |
| this.effectState.targetSlot = target.getSlot(); | |
| this.effectState.endingTurn = this.turn - 1 + 2; | |
| if (this.effectState.endingTurn >= 254) { | |
| this.hint(`In Gen 8+, Future attacks will never resolve when used on the 255th turn or later.`); | |
| } | |
| }, | |
| onResidualOrder: 3, | |
| onResidual(target) { | |
| if (this.getOverflowedTurnCount() < this.effectState.endingTurn) | |
| return; | |
| target.side.removeSlotCondition(this.getAtSlot(this.effectState.targetSlot), "futuremove"); | |
| }, | |
| 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"; | |
| } | |
| 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"); | |
| }, | |
| 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"); | |
| } | |
| }, | |
| snowscape: { | |
| name: "Snowscape", | |
| 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("snowscape")) { | |
| 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", "Snowscape", "[from] ability: " + effect.name, `[of] ${source}`); | |
| } else { | |
| this.add("-weather", "Snowscape"); | |
| } | |
| }, | |
| onFieldResidualOrder: 1, | |
| onFieldResidual() { | |
| this.add("-weather", "Snowscape", "[upkeep]"); | |
| if (this.field.isWeather("snowscape")) | |
| 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; | |
| }, | |
| // Dodging moves is handled in BattleActions#hitStepInvulnerabilityEvent | |
| // This is here for moves that manually call this event like Perish Song | |
| onInvulnerability: 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 *= 2 ** source.volatiles["rolloutstorage"].contactHitCount; | |
| if (source.volatiles["defensecurl"]) { | |
| bp *= 2; | |
| } | |
| source.removeVolatile("rolloutstorage"); | |
| return bp; | |
| } | |
| } | |
| }; | |
| //# sourceMappingURL=conditions.js.map | |