/* 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 }, "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.", onBasePower: function(basePower, attacker, defender, move) { if (!this.willMove(defender)) { this.debug('Analytic boost'); return basePower * 1.3; } }, 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; } }, id: "arenatrap", name: "Arena Trap", rating: 5, num: 71 }, "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, it causes a permanent Rain Dance that can only be stopped by Air Lock, Cloud Nine or another weather condition.", shortDesc: "On switch-in, this Pokemon summons Rain Dance until another weather replaces it.", onStart: function(source) { this.setWeather('raindance'); this.weatherData.duration = 0; }, id: "drizzle", name: "Drizzle", rating: 5, num: 2 }, "drought": { desc: "When this Pokemon enters the battlefield, it causes a permanent Sunny Day that can only be stopped by Air Lock, Cloud Nine or another weather condition.", shortDesc: "On switch-in, this Pokemon summons Sunny Day until another weather replaces it.", onStart: function(source) { this.setWeather('sunnyday'); this.weatherData.duration = 0; }, 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') { this.heal(target.maxhp/4); return null; } }, onFoeBasePower: function(basePower, attacker, defender, move) { if (move.type === 'Fire') { return basePower * 5/4; } }, 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 }, "filter": { desc: "This Pokemon receives one-fourth reduced damage from Super Effective attacks.", shortDesc: "This Pokemon receives 3/4 damage from super effective attacks.", onSourceBasePower: function(basePower, attacker, defender, move) { if (this.getEffectiveness(move.type, defender) > 0) { this.debug('Filter neutralize'); return basePower * 3/4; } }, 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.", onBasePower: function(basePower, attacker, defender, move) { if (attacker.status === 'brn' && move.category === 'Special') { return basePower * 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') { target.addVolatile('flashfire'); return null; } }, effect: { noCopy: true, // doesn't get copied by Baton Pass onStart: function(target) { this.add('-start',target,'ability: Flash Fire'); }, onBasePower: function(basePower, attacker, defender, move) { if (move.type === 'Fire') { this.debug('Flash Fire boost'); return basePower * 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)'); } } }, onAllyModifyAtk: function(atk) { if (this.isWeather('sunnyday')) { return atk *= 1.5; } }, onAllyModifySpD: function(spd) { if (this.isWeather('sunnyday')) { return spd *= 1.5; } }, id: "flowergift", name: "Flower Gift", rating: 3, num: 122 }, "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); }, 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", onAnyBasePower: function(basePower, attacker, defender, move) { var target = this.effectData.target; if (defender !== target && defender.side === target.side) { return basePower * 3/4; } }, 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 target = pokemon.side.foe.randomActive(); if (target && target.item) { this.add('-item', target, target.getItem().name, '[from] ability: Frisk', '[of] '+pokemon); } }, id: "frisk", name: "Frisk", rating: 1.5, num: 119 }, "gluttony": { desc: "This Pokemon consumes its held berry when its health reaches 50% max HP or lower.", shortDesc: "When this Pokemon has 1/2 or less of its max HP, it uses certain Berries early.", id: "gluttony", name: "Gluttony", rating: 0, num: 82 }, "guts": { desc: "When this Pokemon is poisoned (including Toxic), burned, paralyzed or asleep (including self-induced Rest), its Attack stat receives a 50% boost; the burn status' Attack drop is also ignored.", shortDesc: "If this Pokemon is statused, its Attack is 1.5x; burn's Attack drop is ignored.", onModifyAtk: function(atk, pokemon) { if (pokemon.status) { return atk * 1.5; } }, id: "guts", name: "Guts", rating: 3, num: 62 }, "harvest": { desc: "When the user uses a held Berry, it is restored at the end of the turn.", shortDesc: "50% chance this Pokemon's Berry is restored at the end of each turn. 100% in Sun.", id: "harvest", name: "Harvest", onResidualOrder: 26, onResidualSubOrder: 1, onResidual: function(pokemon) { if (this.isWeather('sunnyday') || this.random(2) === 0) { if (!pokemon.item && this.getItem(pokemon.lastItem).isBerry) { pokemon.setItem(pokemon.lastItem); this.add("-item", pokemon, pokemon.item, '[from] ability: Harvest'); } } }, rating: 2, num: 139 }, "healer": { desc: "Has a 30% chance of curing an adjacent ally's status ailment at the end of each turn in Double and Triple Battles.", shortDesc: "30% chance of curing an adjacent ally's status at the end of each turn.", id: "healer", name: "Healer", onResidualOrder: 5, onResidualSubOrder: 1, onResidual: function(pokemon) { var allyActive = pokemon.side.active; if (allyActive.length === 1) { return; } 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)) { this.add('-transform', pokemon, target); } }, 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