Spaces:
Running
Running
; | |
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 | |