/* Ratings and how they work: -2: Extremely detrimental The sort of ability that relegates Pokemon with Uber-level BSTs into NU. ex. Slow Start, Truant -1: Detrimental An ability that does more harm than good. ex. Defeatist, Klutz 0: Useless An ability with no net effect on a Pokemon during a battle. ex. Pickup, Illuminate 1: Ineffective An ability that has a minimal effect. Should never be chosen over any other ability. ex. Pressure, Damp 2: Situationally useful An ability that can be useful in certain situations. ex. Blaze, Insomnia 3: Useful An ability that is generally useful. ex. Volt Absorb, Iron Fist 4: Very useful One of the most popular abilities. The difference between 3 and 4 can be ambiguous. ex. Technician, Intimidate 5: Essential The sort of ability that defines metagames. ex. Drizzle, Magnet Pull */ exports.BattleAbilities = { "adaptability": { desc: "This Pokemon's attacks that receive STAB (Same Type Attack Bonus) are increased from 50% to 100%.", shortDesc: "This Pokemon's same-type attack bonus (STAB) is increased from 1.5x to 2x.", onModifyMove: function(move) { move.stab = 2; }, id: "adaptability", name: "Adaptability", rating: 3.5, num: 91 }, "aftermath": { desc: "If a contact move knocks out this Pokemon, the opponent receives damage equal to one-fourth of its max HP.", shortDesc: "If this Pokemon is KOed with a contact move, that move's user loses 1/4 its max HP.", id: "aftermath", name: "Aftermath", onFaint: function(target, source, effect) { if (effect && effect.effectType === 'Move' && effect.isContact && source) { this.damage(source.maxhp/4, source, target); } }, rating: 3, num: 106 }, "aerilate": { desc: "Turns all of this Pokemon's Normal-typed attacks into Flying-typed. Does 1.3x damage. Does not affect Hidden Power.", shortDesc: "This Pokemon's Normal moves become Flying. Does 1.3x damage.", onModifyMove: function(move, pokemon) { if (move.type === 'Normal' && move.id !== 'hiddenpower') { move.type = 'Flying'; pokemon.addVolatile('aerilate'); } }, effect: { duration: 1, onBasePowerPriority: 8, onBasePower: function(basePower, pokemon, target, move) { return this.chainModify([0x14CD, 0x1000]); } }, id: "aerilate", name: "Aerilate", rating: 3, num: -6, gen: 6 }, "airlock": { desc: "While this Pokemon is active, all weather conditions and their effects are disabled.", shortDesc: "While this Pokemon is active, all weather conditions and their effects are disabled.", onStart: function(pokemon) { this.add('-message', 'The effects of weather disappeared. (placeholder)'); }, onAnyModifyPokemon: function(pokemon) { pokemon.ignore['WeatherTarget'] = true; }, onAnyTryWeather: false, id: "airlock", name: "Air Lock", rating: 3, num: 76 }, "analytic": { desc: "If the user moves last, the power of that move is increased by 30%.", shortDesc: "This Pokemon's attacks do 1.3x damage if it is the last to move in a turn.", onBasePowerPriority: 8, onBasePower: function(basePower, attacker, defender, move) { if (!this.willMove(defender)) { this.debug('Analytic boost'); return this.chainModify([0x14CD, 0x1000]); // The Analytic modifier is slightly higher than the normal 1.3 (0x14CC) } }, id: "analytic", name: "Analytic", rating: 1, num: 148 }, "angerpoint": { desc: "If this Pokemon, or its Substitute, is struck by a Critical Hit, its Attack is boosted to six stages.", shortDesc: "If this Pokemon (not a Substitute) is hit by a critical hit, its Attack is boosted by 12.", onCriticalHit: function(target) { if (!target.volatiles['substitute']) { target.setBoost({atk: 6}); this.add('-setboost',target,'atk',12,'[from] ability: Anger Point'); } }, id: "angerpoint", name: "Anger Point", rating: 2, num: 83 }, "anticipation": { desc: "A warning is displayed if an opposing Pokemon has the moves Fissure, Guillotine, Horn Drill, Sheer Cold, or any attacking move from a type that is considered super effective against this Pokemon (including Counter, Mirror Coat, and Metal Burst). Hidden Power, Judgment, Natural Gift and Weather Ball are considered Normal-type moves.", shortDesc: "On switch-in, this Pokemon shudders if any foe has a super effective or OHKO move.", onStart: function(pokemon) { var targets = pokemon.side.foe.active; for (var i=0; i 0 || move.ohko)) { this.add('-message', pokemon.name+' shuddered! (placeholder)'); return; } } } }, id: "anticipation", name: "Anticipation", rating: 1, num: 107 }, "arenatrap": { desc: "When this Pokemon enters the field, its opponents cannot switch or flee the battle unless they are part Flying-type, have the Levitate ability, are holding Shed Shell, or they use the moves Baton Pass or U-Turn. Flying-type and Levitate Pokemon cannot escape if they are holding Iron Ball or Gravity is in effect. Levitate Pokemon also cannot escape if their ability is disabled through other means, such as Skill Swap or Gastro Acid.", shortDesc: "Prevents foes from switching out normally unless they have immunity to Ground.", onFoeModifyPokemon: function(pokemon) { if (pokemon.runImmunity('Ground', false)) { pokemon.trapped = true; } }, onFoeMaybeTrapPokemon: function(pokemon) { if (pokemon.runImmunity('Ground', false)) { pokemon.maybeTrapped = true; } }, id: "arenatrap", name: "Arena Trap", rating: 5, num: 71 }, "aurabreak": { desc: "Reverses the effect of Dark Aura and Fairy Aura.", shortDesc: "Reverses the effect of Aura abilities.", onStart: function(pokemon) { this.add('-message', 'The effects of aura abilities are reversed. (placeholder)'); }, id: "aurabreak", name: "Aura Break", rating: 3, num: -6, gen: 6 }, "baddreams": { desc: "If asleep, each of this Pokemon's opponents receives damage equal to one-eighth of its max HP.", shortDesc: "Causes sleeping adjacent foes to lose 1/8 of their max HP at the end of each turn.", onResidualOrder: 26, onResidualSubOrder: 1, onResidual: function(pokemon) { for (var i=0; i= totalspd) { this.boost({spa:1}); } else if (totalspd) { this.boost({atk:1}); } }, id: "download", name: "Download", rating: 4, num: 88 }, "drizzle": { desc: "When this Pokemon enters the battlefield, the weather becomes Rain Dance (for 5 turns normally, or 8 turns while holding Damp Rock).", shortDesc: "On switch-in, the weather becomes Rain Dance.", onStart: function(source) { this.setWeather('raindance'); }, id: "drizzle", name: "Drizzle", rating: 5, num: 2 }, "drought": { desc: "When this Pokemon enters the battlefield, the weather becomes Sunny Day (for 5 turns normally, or 8 turns while holding Heat Rock).", shortDesc: "On switch-in, the weather becomes Sunny Day.", onStart: function(source) { this.setWeather('sunnyday'); }, id: "drought", name: "Drought", rating: 5, num: 70 }, "dryskin": { desc: "This Pokemon absorbs Water attacks and gains a weakness to Fire attacks. If Sunny Day is in effect, this Pokemon takes damage. If Rain Dance is in effect, this Pokemon recovers health.", shortDesc: "This Pokemon is healed 1/4 by Water, 1/8 by Rain; is hurt 1.25x by Fire, 1/8 by Sun.", onTryHit: function(target, source, move) { if (target !== source && move.type === 'Water') { if (!this.heal(target.maxhp/4)) { this.add('-immune', target, '[msg]'); } return null; } }, onBasePowerPriority: 7, onFoeBasePower: function(basePower, attacker, defender, move) { if (move.type === 'Fire') { return this.chainModify(1.25); } }, onWeather: function(target, source, effect) { if (effect.id === 'raindance') { this.heal(target.maxhp/8); } else if (effect.id === 'sunnyday') { this.damage(target.maxhp/8); } }, id: "dryskin", name: "Dry Skin", rating: 3.5, num: 87 }, "earlybird": { desc: "This Pokemon will remain asleep for half as long as it normally would; this includes both opponent-induced sleep and user-induced sleep via Rest.", shortDesc: "This Pokemon's sleep status lasts half as long as usual, self-induced or not.", id: "earlybird", name: "Early Bird", isHalfSleep: true, rating: 2.5, num: 48 }, "effectspore": { desc: "If an opponent directly attacks this Pokemon, there is a 30% chance that the opponent will become either poisoned, paralyzed or put to sleep. There is an equal chance to inflict each status.", shortDesc: "30% chance of poisoning, paralyzing, or causing sleep on Pokemon making contact.", onAfterDamage: function(damage, target, source, move) { if (move && move.isContact && !source.status) { var r = this.random(100); if (r < 11) source.setStatus('slp'); else if (r < 21) source.setStatus('par'); else if (r < 30) source.setStatus('psn'); } }, id: "effectspore", name: "Effect Spore", rating: 2, num: 27 }, "fairyaura": { desc: "Increases the power of all Fairy-type moves in battle to 1.3x.", shortDesc: "Increases the power of all Fairy-type moves in battle to 1.3x.", onBasePowerPriority: 8, onBasePower: function(basePower, attacker, defender, move) { var reverseAura = false; for (var p in attacker.side.active) { if (attacker.side.active[p] && attacker.side.active[p].ability === 'aurabreak') { reverseAura = true; this.debug('Reversing Fairy Aura due to Aura Break'); } } for (var p in defender.side.active) { if (defender.side.active[p] && defender.side.active[p].ability === 'aurabreak') { reverseAura = true; this.debug('Reversing Fairy Aura due to Aura Break'); } } if (move.type === 'Fairy') { return this.chainModify(reverseAura? 0.75 : 1.3); } }, id: "fairyaura", name: "Fairy Aura", rating: 3, num: -6, gen: 6 }, "filter": { desc: "This Pokemon receives one-fourth reduced damage from Super Effective attacks.", shortDesc: "This Pokemon receives 3/4 damage from super effective attacks.", onSourceModifyDamage: function(damage, source, target, move) { if (this.getEffectiveness(move.type, target) > 0) { this.debug('Filter neutralize'); return this.chainModify(0.75); } }, id: "filter", name: "Filter", rating: 3, num: 111 }, "flamebody": { desc: "If an opponent directly attacks this Pokemon, there is a 30% chance that the opponent will become burned.", shortDesc: "30% chance of burning a Pokemon making contact with this Pokemon.", onAfterDamage: function(damage, target, source, move) { if (move && move.isContact) { if (this.random(10) < 3) { source.trySetStatus('brn', target, move); } } }, id: "flamebody", name: "Flame Body", rating: 2, num: 49 }, "flareboost": { desc: "When the user with this ability is burned, its Special Attack is raised by 50%.", shortDesc: "When this Pokemon is burned, its special attacks do 1.5x damage.", onBasePowerPriority: 8, onBasePower: function(basePower, attacker, defender, move) { if (attacker.status === 'brn' && move.category === 'Special') { return this.chainModify(1.5); } }, id: "flareboost", name: "Flare Boost", rating: 3, num: 138 }, "flashfire": { desc: "This Pokemon is immune to all Fire-type attacks; additionally, its own Fire-type attacks receive a 50% boost if a Fire-type move hits this Pokemon. Multiple boosts do not occur if this Pokemon is hit with multiple Fire-type attacks.", shortDesc: "This Pokemon's Fire attacks do 1.5x damage if hit by one Fire move; Fire immunity.", onTryHit: function(target, source, move) { if (target !== source && move.type === 'Fire') { move.accuracy = true; if (!target.addVolatile('flashfire')) { this.add('-immune', target, '[msg]'); } return null; } }, effect: { noCopy: true, // doesn't get copied by Baton Pass onStart: function(target) { this.add('-start',target,'ability: Flash Fire'); }, onModifyAtkPriority: 5, onModifyAtk: function(atk, attacker, defender, move) { if (move.type === 'Fire') { this.debug('Flash Fire boost'); return this.chainModify(1.5); } }, onModifySpAPriority: 5, onModifySpA: function(atk, attacker, defender, move) { if (move.type === 'Fire') { this.debug('Flash Fire boost'); return this.chainModify(1.5); } } }, id: "flashfire", name: "Flash Fire", rating: 3, num: 18 }, "flowergift": { desc: "If this Pokemon is active while Sunny Day is in effect, its Attack and Special Defense stats (as well as its partner's stats in double battles) receive a 50% boost.", shortDesc: "If user is Cherrim and Sunny Day is active, it and allies' Attack and Sp. Def are 1.5x.", onStart: function(pokemon) { delete this.effectData.forme; }, onUpdate: function(pokemon) { if (!pokemon.isActive || pokemon.speciesid !== 'cherrim') return; if (this.isWeather('sunnyday')) { if (this.effectData.forme !== 'Sunshine') { this.effectData.forme = 'Sunshine'; this.add('-formechange', pokemon, 'Cherrim-Sunshine'); this.add('-message', pokemon.name+' transformed! (placeholder)'); } } else { if (this.effectData.forme) { delete this.effectData.forme; this.add('-formechange', pokemon, 'Cherrim'); this.add('-message', pokemon.name+' transformed! (placeholder)'); } } }, onModifyAtkPriority: 3, onAllyModifyAtk: function(atk) { if (this.effectData.target.template.speciesid !== 'cherrim') return; if (this.isWeather('sunnyday')) { return this.chainModify(1.5); } }, onModifySpDPriority: 4, onAllyModifySpD: function(spd) { if (this.effectData.target.template.speciesid !== 'cherrim') return; if (this.isWeather('sunnyday')) { return this.chainModify(1.5); } }, id: "flowergift", name: "Flower Gift", rating: 3, num: 122 }, "flowerveil": { desc: "Prevents lowering of ally Grass-type Pokemon's stats.", shortDesc: "Prevents lowering of ally Grass-type Pokemon's stats.", onStart: function(pokemon) { this.add('-ability', pokemon, 'Flower Veil'); pokemon.side.addSideCondition('flowerveil'); }, onSwitchOut: function(pokemon) { pokemon.side.removeSideCondition('flowerveil'); }, effect: { onBoost: function(boost, target, source, effect) { if (source && target === source) return; if (!target.hasType('Grass')) return; var showMsg = false; for (var i in boost) { if (boost[i] < 0) { delete boost[i]; showMsg = true; } } if (showMsg && !effect.secondaries) this.add("-fail", target, "unboost", "[from] ability: Flower Veil", "[of] "+target); } }, id: "flowerveil", name: "Flower Veil", rating: 0, num: -6, gen: 6 }, "forecast": { desc: "This Pokemon's type changes according to the current weather conditions: it becomes Fire-type during Sunny Day, Water-type during Rain Dance, Ice-type during Hail and remains its regular type otherwise.", shortDesc: "Castform's type changes to the current weather condition's type, except Sandstorm.", onUpdate: function(pokemon) { if (pokemon.baseTemplate.species !== 'Castform' || pokemon.transformed) return; var forme = null; switch (this.effectiveWeather()) { case 'sunnyday': if (pokemon.template.speciesid !== 'castformsunny') forme = 'Castform-Sunny'; break; case 'raindance': if (pokemon.template.speciesid !== 'castformrainy') forme = 'Castform-Rainy'; break; case 'hail': if (pokemon.template.speciesid !== 'castformsnowy') forme = 'Castform-Snowy'; break; default: if (pokemon.template.speciesid !== 'castform') forme = 'Castform'; break; } if (pokemon.isActive && forme) { pokemon.formeChange(forme); this.add('-formechange', pokemon, forme); this.add('-message', pokemon.name+' transformed! (placeholder)'); } }, id: "forecast", name: "Forecast", rating: 4, num: 59 }, "forewarn": { desc: "The move with the highest Base Power in the opponent's moveset is revealed.", shortDesc: "On switch-in, this Pokemon is alerted to the foes' move with the highest Base Power.", onStart: function(pokemon) { var targets = pokemon.side.foe.active; var warnMoves = []; var warnBp = 1; for (var i=0; i warnBp) { warnMoves = [[move, targets[i]]]; warnBp = bp; } else if (bp == warnBp) { warnMoves.push([move, targets[i]]); } } } if (!warnMoves.length) return; var warnMove = warnMoves[this.random(warnMoves.length)]; this.add('-activate', pokemon, 'ability: Forewarn', warnMove[0], warnMove[1]); }, id: "forewarn", name: "Forewarn", rating: 1, num: 108 }, "friendguard": { desc: "Reduces the damage received from an ally in a double or triple battle.", shortDesc: "This Pokemon's allies receive 3/4 damage from other Pokemon's attacks.", id: "friendguard", name: "Friend Guard", onAnyModifyDamage: function(damage, source, target, move) { if (target !== this.effectData.target && target.side === this.effectData.target.side) { this.debug('Friend Guard weaken') return this.chainModify(0.75); } }, rating: 0, num: 132 }, "frisk": { desc: "When this Pokemon enters the field, it identifies the opponent's held item; in double battles, the held item of an unrevealed, randomly selected opponent is identified.", shortDesc: "On switch-in, this Pokemon identifies a random foe's held item.", onStart: function(pokemon) { var foeactive = pokemon.side.foe.active; for (var i=0; ipokemon.position; i--) { if (!pokemon.side.pokemon[i]) continue; if (!pokemon.side.pokemon[i].fainted) break; } if (!pokemon.side.pokemon[i]) return; if (pokemon === pokemon.side.pokemon[i]) return; pokemon.illusion = pokemon.side.pokemon[i]; }, // illusion clearing is hardcoded in the damage function id: "illusion", name: "Illusion", rating: 4.5, num: 149 }, "immunity": { desc: "This Pokemon cannot become poisoned nor Toxic poisoned.", shortDesc: "This Pokemon cannot be poisoned. Gaining this Ability while poisoned cures it.", onUpdate: function(pokemon) { if (pokemon.status === 'psn' || pokemon.status === 'tox') { pokemon.cureStatus(); } }, onImmunity: function(type) { if (type === 'psn') return false; }, id: "immunity", name: "Immunity", rating: 1, num: 17 }, "imposter": { desc: "As soon as the user comes into battle, it Transforms into its opponent, copying the opponent's stats exactly, with the exception of HP. Imposter copies all stat changes on the target originating from moves and abilities such as Swords Dance and Intimidate, but not from items such as Choice Specs. Imposter will not Transform the user if the opponent is an Illusion or if the opponent is behind a Substitute.", shortDesc: "On switch-in, this Pokemon copies the foe it's facing; stats, moves, types, Ability.", onStart: function(pokemon) { var target = pokemon.side.foe.active[pokemon.side.foe.active.length-1-pokemon.position]; if (target) { pokemon.transformInto(target, pokemon); } }, id: "imposter", name: "Imposter", rating: 5, num: 150 }, "infiltrator": { desc: "Ignores Reflect, Light Screen and Safeguard under effect on the target.", shortDesc: "This Pokemon's moves ignore the foe's Reflect, Light Screen, Safeguard, and Mist.", // Implemented in the corresponding effects. id: "infiltrator", name: "Infiltrator", rating: 1, num: 151 }, "innerfocus": { desc: "This Pokemon cannot be made to flinch.", shortDesc: "This Pokemon cannot be made to flinch.", onFlinch: false, id: "innerfocus", name: "Inner Focus", rating: 1, num: 39 }, "insomnia": { desc: "This Pokemon cannot be put to sleep; this includes both opponent-induced sleep as well as user-induced sleep via Rest.", shortDesc: "This Pokemon cannot fall asleep. Gaining this Ability while asleep cures it.", onUpdate: function(pokemon) { if (pokemon.status === 'slp') { pokemon.cureStatus(); } }, onImmunity: function(type, pokemon) { if (type === 'slp') return false; }, id: "insomnia", name: "Insomnia", rating: 2, num: 15 }, "intimidate": { desc: "When this Pokemon enters the field, the Attack stat of each of its opponents lowers by one stage.", shortDesc: "On switch-in, this Pokemon lowers adjacent foes' Attack by 1.", onStart: function(pokemon) { var foeactive = pokemon.side.foe.active; for (var i=0; i