pokemon-showdown/data/mods/gen3/abilities.js
Guangcong Luo 55cbc52bba Fix bugs with secondary/ability order
Fixes #6346

The `AfterDamage` event has been replaced with `DamagingHit`, which
which happens for damaging moves after secondaries.

The `AfterHit` event has also been moved after `DamagingHit`, to make
sure Knock Off still procs after Rocky Helmet.

`AfterHit` is no longer a valid event on `secondary` and `self` blocks,
because it's meaningless in those blocks, anyway. All `self.onAfterHit`
and `secondary.onAfterHit` handlers have been moved to `onHit`, which
should have the same timing in practice.
2020-02-08 08:07:39 -08:00

228 lines
7.1 KiB
JavaScript

'use strict';
/**@type {{[k: string]: ModdedAbilityData}} */
let BattleAbilities = {
"cutecharm": {
inherit: true,
desc: "There is a 1/3 chance a Pokemon making contact with this Pokemon will become infatuated if it is of the opposite gender.",
shortDesc: "1/3 chance of infatuating Pokemon of the opposite gender if they make contact.",
onDamagingHit(damage, target, source, move) {
if (move.flags['contact']) {
if (this.randomChance(1, 3)) {
source.addVolatile('attract', target);
}
}
},
},
"effectspore": {
inherit: true,
desc: "10% chance a Pokemon making contact with this Pokemon will be poisoned, paralyzed, or fall asleep.",
shortDesc: "10% chance of poison/paralysis/sleep on others making contact with this Pokemon.",
onDamagingHit(damage, target, source, move) {
if (move.flags['contact'] && !source.status) {
let r = this.random(300);
if (r < 10) {
source.setStatus('slp', target);
} else if (r < 20) {
source.setStatus('par', target);
} else if (r < 30) {
source.setStatus('psn', target);
}
}
},
},
"flamebody": {
inherit: true,
shortDesc: "1/3 chance a Pokemon making contact with this Pokemon will be burned.",
onDamagingHit(damage, target, source, move) {
if (move.flags['contact']) {
if (this.randomChance(1, 3)) {
source.trySetStatus('brn', target);
}
}
},
},
"flashfire": {
inherit: true,
desc: "This Pokemon is immune to Fire-type moves, as long as it is not frozen. The first time it is hit by a Fire-type move, damage from its Fire-type attacks will be multiplied by 1.5 as long as it remains active and has this Ability. If this Pokemon has a major status condition, is a Fire type, or has a substitute, Will-O-Wisp will not activate this Ability.",
onTryHit(target, source, move) {
if (target !== source && move.type === 'Fire') {
if (move.id === 'willowisp' && (target.hasType('Fire') || target.status || target.volatiles['substitute'])) {
return;
}
if (target.status === 'frz') {
return;
}
if (!target.addVolatile('flashfire')) {
this.add('-immune', target, '[from] ability: Flash Fire');
}
return null;
}
},
},
"intimidate": {
inherit: true,
onStart(pokemon) {
let activated = false;
for (const target of pokemon.side.foe.active) {
if (target && this.isAdjacent(target, pokemon) && !target.volatiles['substitute']) {
activated = true;
break;
}
}
if (!activated) {
this.hint("In Gen 3, Intimidate does not activate if every target has a Substitute.", false, pokemon.side);
return;
}
this.add('-ability', pokemon, 'Intimidate', 'boost');
for (const target of pokemon.side.foe.active) {
if (!target || !this.isAdjacent(target, pokemon)) continue;
if (target.volatiles['substitute']) {
this.add('-immune', target);
} else {
this.boost({atk: -1}, target, pokemon, null, true);
}
}
},
},
"lightningrod": {
desc: "If this Pokemon is not the target of a single-target Electric-type move used by an opposing Pokemon, this Pokemon redirects that move to itself. This effect considers Hidden Power a Normal-type move.",
shortDesc: "This Pokemon draws single-target Electric moves used by opponents to itself.",
onFoeRedirectTarget(target, source, source2, move) {
if (move.type !== 'Electric') return;
if (this.validTarget(this.effectData.target, source, move.target)) {
return this.effectData.target;
}
},
id: "lightningrod",
name: "Lightning Rod",
rating: 3.5,
num: 32,
},
"minus": {
inherit: true,
desc: "If an active Pokemon has the Plus Ability, this Pokemon's Special Attack is multiplied by 1.5.",
shortDesc: "If an active Pokemon has the Plus Ability, this Pokemon's Sp. Atk is 1.5x.",
onModifySpA(spa, pokemon) {
for (const active of this.getAllActive()) {
if (!active.fainted && active.hasAbility('plus')) {
return this.chainModify(1.5);
}
}
},
},
"plus": {
inherit: true,
desc: "If an active Pokemon has the Minus Ability, this Pokemon's Special Attack is multiplied by 1.5.",
shortDesc: "If an active Pokemon has the Minus Ability, this Pokemon's Sp. Atk is 1.5x.",
onModifySpA(spa, pokemon) {
for (const active of this.getAllActive()) {
if (!active.fainted && active.hasAbility('minus')) {
return this.chainModify(1.5);
}
}
},
},
"poisonpoint": {
inherit: true,
shortDesc: "1/3 chance a Pokemon making contact with this Pokemon will be poisoned.",
onDamagingHit(damage, target, source, move) {
if (move.flags['contact']) {
if (this.randomChance(1, 3)) {
source.trySetStatus('psn', target);
}
}
},
},
"pressure": {
inherit: true,
onStart(pokemon) {
this.addSplit(pokemon.side.id, ['-ability', pokemon, 'Pressure', '[silent]']);
},
},
"roughskin": {
inherit: true,
desc: "Pokemon making contact with this Pokemon lose 1/16 of their maximum HP, rounded down.",
shortDesc: "Pokemon making contact with this Pokemon lose 1/16 of their max HP.",
onDamagingHit(damage, target, source, move) {
if (move.flags['contact']) {
this.damage(source.baseMaxhp / 16, source, target);
}
},
},
"shadowtag": {
inherit: true,
desc: "Prevents opposing Pokemon from choosing to switch out.",
shortDesc: "Prevents opposing Pokemon from choosing to switch out.",
onFoeTrapPokemon(pokemon) {
pokemon.trapped = true;
},
},
"static": {
inherit: true,
shortDesc: "1/3 chance a Pokemon making contact with this Pokemon will be paralyzed.",
onDamagingHit(damage, target, source, move) {
if (move.flags['contact']) {
if (this.randomChance(1, 3)) {
source.trySetStatus('par', target);
}
}
},
},
"trace": {
inherit: true,
onUpdate(pokemon) {
if (!pokemon.isStarted) return;
let target = pokemon.side.foe.randomActive();
if (!target || target.fainted) return;
let ability = target.getAbility();
let bannedAbilities = ['forecast', 'multitype', 'trace'];
if (bannedAbilities.includes(target.ability)) {
return;
}
if (pokemon.setAbility(ability)) {
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target);
}
},
},
"truant": {
inherit: true,
onStart() {},
onSwitchIn(pokemon) {
pokemon.truantTurn = this.turn !== 0;
},
onBeforeMove(pokemon) {
if (pokemon.truantTurn) {
this.add('cant', pokemon, 'ability: Truant');
return false;
}
},
onResidualOrder: 27,
onResidual(pokemon) {
pokemon.truantTurn = !pokemon.truantTurn;
},
},
"voltabsorb": {
inherit: true,
desc: "This Pokemon is immune to damaging Electric-type moves and restores 1/4 of its maximum HP, rounded down, when hit by one.",
shortDesc: "This Pokemon heals 1/4 its max HP when hit by a damaging Electric move; immunity.",
onTryHit(target, source, move) {
if (target !== source && move.type === 'Electric' && move.id !== 'thunderwave') {
if (!this.heal(target.baseMaxhp / 4)) {
this.add('-immune', target, '[from] ability: Volt Absorb');
}
return null;
}
},
},
"wonderguard": {
inherit: true,
shortDesc: "This Pokemon is only damaged by supereffective moves and indirect damage.",
},
};
exports.BattleAbilities = BattleAbilities;