'use strict';
exports.BattleScripts = {
   init: function () {
   
let coolMoves = ['acrobatics', 'aerialace', 'aquajet', 'blazekick', 'bravebird', 'brickbreak', 'bulletseed',
         'circlethrow', 'crosschop', 'crosspoison', 'crushclaw', 'cut', 'doublehit', 'doublekick',
         'dragonclaw', 'drillpeck', 'dynamicpunch', 'extremespeed', 'falseswipe', 'fellstinger',
         'firefang', 'flamecharge', 'flareblitz', 'forcepalm', 'furyattack', 'furycutter',
         'fusionbolt', 'gyroball', 'highjumpkick', 'hornattack', 'hyperfang', 'icefang', 'irontail',
         'jumpkick', 'leafblade', 'machpunch', 'magnetbomb', 'megakick', 'megahorn', 'metalclaw',
         'meteormash', 'nightslash', 'outrage', 'peck', 'phantomforce', 'pinmissile', 'precipiceblades',
         'psychocut', 'punishment', 'quickattack', 'rapidspin', 'razorleaf', 'razorshell', 'retaliate', 'reversal',
         'rollingkick', 'sacredsword', 'shadowclaw', 'shadowforce', 'skyattack', 'skyuppercut', 'slash',
         'spark', 'spikecannon', 'steelwing', 'stormthrow', 'submission', 'thunderfang', 'thunderpunch',
         'triplekick', 'twineedle', 'vcreate', 'vinewhip', 'vitalthrow', 'volttackle', 'watershuriken',
         'wingattack', 'xscissor', 'aeroblast', 'aircutter', 'airslash', 'darkpulse', 'dragonbreath',
         'electroball', 'extrasensory', 'focusblast', 'hyperbeam', 'hypervoice', 'leaftornado',
         'nightdaze', 'oblivionwing', 'psystrike', 'searingshot', 'shockwave', 'solarbeam', 'swift',
         'technoblast', 'thunder', 'thunderbolt', 'vacuumwave', 'voltswitch', 'zapcannon',
         //everything after this is nv's fault
         'holdback', 'razorwind', 'thundershock', 'trumpcard', 'twister'];
    
    
     let toughMoves = ['armthrust', 'bite', 'bodyslam', 'boneclub', 'bonerush', 'bonemerang', 'bulldoze',
         'bulletpunch', 'chipaway', 'clamp', 'closecombat', 'crabhammer', 'crunch', 'dig', 'doubleedge',
         'dragonrush', 'dragontail', 'drainpunch', 'drillrun', 'dualchop', 'earthquake', 'firepunch',
         'flyingpress', 'focuspunch', 'gunkshot', 'hammerarm', 'headcharge', 'headsmash', 'headbutt',
         'heatcrash', 'heavyslam', 'hornleech', 'hyperspacefury', 'ironhead', 'lowkick', 'poisonjab',
         'powerwhip', 'poweruppunch', 'revenge', 'rockblast', 'rockclimb', 'rockslide', 'rockthrow',
         'rockwrecker', 'seedbomb', 'skullbash', 'slam', 'smackdown', 'smellingsalts', 'steamroller',
         'stomp', 'stoneedge', 'superpower', 'takedown', 'thief', 'wakeupslap', 'waterfall', 'wildcharge',
         'woodhammer', 'ancientpower', 'belch', 'boomburst', 'hurricane', 'incinerate', 'lavaplume',
         'magmastorm', 'muddywater', 'octazooka', 'scald', 'sludgebomb', 'sludgewave', 'snarl',
         //everything after this is nv's fault
         'bind', 'cometpunch', 'constrict', 'crushgrip', 'furyswipes', 'gigaimpact', 'karatechop',
         'magnitude', 'megapunch', 'payback', 'pound', 'rage', 'rocksmash', 'scratch', 'skydrop', 'strength',
         'tackle', 'thrash', 'vicegrip', 'wrap', 'brine', 'mudshot', 'sludge', 'smog', 'spitup', 'wringout'];
     let beautifulMoves = ['aquatail', 'avalanche', 'boltstrike', 'diamondstorm', 'explosion', 'firespin',
         'flamewheel', 'freezeshock', 'iceball', 'icepunch', 'iceshard', 'iciclecrash', 'iciclespear', 'landswrath',
         'petalblizzard', 'sacredfire', 'acidspray', 'aurasphere', 'blizzard', 'blueflare', 'bugbuzz', 'dazzlinggleam',
         'doomdesire', 'dracometeor', 'dragonpulse', 'earthpower', 'energyball', 'eruption', 'fierydance',
         'fireblast', 'flamethrower', 'flashcannon', 'freezedry', 'glaciate', 'heatwave', 'hydropump', 'icebeam',
         'icywind', 'inferno', 'leafstorm', 'moonblast', 'mysticalfire', 'naturepower', 'originpulse', 'overheat',
         'petaldance', 'powergem', 'psyshock', 'secretsword', 'seedflare', 'signalbeam', 'surf', 'triattack', 'waterpulse',
         'waterspout', 'weatherball',
         //nv's fault again
         'dive', 'dragonascent', 'selfdestruct', 'aurorabeam', 'blastburn', 'bubblebeam', 'chargebeam', 'clearsmog',
         'discharge', 'echoedvoice', 'electroweb', 'fairywind', 'firepledge', 'flameburst', 'frostbreath',
         'fusionflare', 'grasspledge', 'hydrocannon', 'iceburn', 'judgment', 'magicalleaf', 'mirrorshot',
         'ominouswind', 'powdersnow', 'psybeam', 'relicsong', 'roaroftime', 'round', 'silverwind', 'spacialrend',
         'venoshock', 'waterpledge', 'whirlpool'];
     let cleverMoves = ['attackorder', 'feint', 'feintattack', 'foulplay', 'geargrind', 'knockoff', 'lowsweep', 'naturalgift',
         'needlearm', 'poisonfang', 'poisontail', 'pursuit', 'rocktomb', 'shadowpunch', 'shadowsneak',
         'suckerpunch', 'zenheadbutt', 'dreameater', 'futuresight', 'gigadrain', 'hex', 'hiddenpower',
         'hyperspacehole', 'lusterpurge', 'mistball', 'paraboliccharge', 'psychic', 'psychoboost',
         'shadowball', 'storedpower',
         //NV SwiftRage
         'assurance', 'beatup', 'fly', 'payday', 'poisonsting', 'sandtomb', 'secretpower', 'absorb', 'acid',
         'confusion', 'gust', 'leechlife', 'megadrain', 'synchronoise'];
     let cuteMoves = ['bounce', 'bugbite', 'facade', 'fakeout', 'frustration', 'heartstamp', 'nuzzle', 'playrough', 'return',
         'rollout', 'tailslap', 'uturn', 'drainingkiss', 'grassknot', 'infestation', 'mudbomb', 'strugglebug', 'uproar',
         //you know the drill
         'astonish', 'barrage', 'covet', 'dizzypunch', 'doubleslap', 'eggbomb', 'flail', 'fling', 'lastresort', 'lick',
         'pluck', 'present', 'bubble', 'chatter', 'disarmingvoice', 'ember', 'mudslap', 'snore', 'watergun'];
     //applying coolness
     for (let i = 0; i < coolMoves.length; i++) {
       let applyTo = coolMoves[i];
       this.modData('Movedex', applyTo).contestCondition = 'cool';
     }
   
     //toughness
     for (let i = 0; i < toughMoves.length; i++) {
       let applyTo = toughMoves[i];
       this.modData('Movedex', applyTo).contestCondition = 'tough';
     }
     //beauty
     for (let i = 0; i < beautifulMoves.length; i++) {
       let applyTo = beautifulMoves[i];
       this.modData('Movedex', applyTo).contestCondition = 'beautiful';
     }
     //cleverness
     for (let i = 0; i < cleverMoves.length; i++) {
       let applyTo = cleverMoves[i];
       this.modData('Movedex', applyTo).contestCondition = 'clever';
     }
     //cuteness
     for (let i = 0; i < cuteMoves.length; i++) {
       let applyTo = cuteMoves[i];
       this.modData('Movedex', applyTo).contestCondition = 'cute';
     }
   
   },
   getDamage: function (pokemon, target, move, suppressMessages) {
     if (typeof move === 'string') move = this.getMove(move);
     if (typeof move === 'number') {
       move = {
         basePower: move,
         type: '???',
         category: 'Physical',
         flags: {},
       };
     }
     if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
       if (!target.runImmunity(move.type, !suppressMessages)) {
         return false;
       }
     }
     if (move.ohko) {
       return target.maxhp;
     }
     if (move.damageCallback) {
       return move.damageCallback.call(this, pokemon, target);
     }
     if (move.damage === 'level') {
       return pokemon.level;
     }
     if (move.damage) {
       return move.damage;
     }
     if (!move) {
       move = {};
     }
     if (!move.type) move.type = '???';
     let type = move.type;
     // '???' is typeless damage: used for Struggle and Confusion etc
     let category = this.getCategory(move);
     let defensiveCategory = move.defensiveCategory || category;
     let basePower = move.basePower;
     if (move.basePowerCallback) {
       basePower = move.basePowerCallback.call(this, pokemon, target, move);
     }
     if (!basePower) {
       if (basePower === 0) return; // returning undefined means not dealing damage
       return basePower;
     }
     basePower = this.clampIntRange(basePower, 1);
     let critMult;
     if (this.gen <= 5) {
       move.critRatio = this.clampIntRange(move.critRatio, 0, 5);
       critMult = [0, 16, 8, 4, 3, 2];
     } else {
       move.critRatio = this.clampIntRange(move.critRatio, 0, 4);
       critMult = [0, 16, 8, 2, 1];
     }
     move.crit = move.willCrit || false;
     if (move.willCrit === undefined) {
       if (move.critRatio) {
         move.crit = (this.random(critMult[move.critRatio]) === 0);
       }
     }
     if (move.crit) {
       move.crit = this.runEvent('CriticalHit', target, null, move);
     }
     // happens after crit calculation
     basePower = this.runEvent('BasePower', pokemon, target, move, basePower, true);
     if (!basePower) return 0;
     basePower = this.clampIntRange(basePower, 1);
     let level = pokemon.level;
     let attacker = pokemon;
     let defender = target;
     let attackStat;
   
     //tada!
     if (move.contestCondition) {
       if (move.contestCondition === 'cool') attackStat = 'atk';
       else if (move.contestCondition === 'tough') attackStat = 'def';
       else if (move.contestCondition === 'beautiful') attackStat = 'spa';
       else if (move.contestCondition === 'clever') attackStat = 'spd';
       else if (move.contestCondition === 'cute') attackStat = 'spe';
     }
     let defenseStat = defensiveCategory === 'Physical' ? 'def' : 'spd';
     let statTable = {atk:'Atk', def:'Def', spa:'SpA', spd:'SpD', spe:'Spe'};
     let attack;
     let defense;
     let atkBoosts = move.useTargetOffensive ? defender.boosts[attackStat] : attacker.boosts[attackStat];
     let defBoosts = move.useSourceDefensive ? attacker.boosts[defenseStat] : defender.boosts[defenseStat];
     let ignoreNegativeOffensive = !!move.ignoreNegativeOffensive;
     let ignorePositiveDefensive = !!move.ignorePositiveDefensive;
     if (move.crit) {
       ignoreNegativeOffensive = true;
       ignorePositiveDefensive = true;
     }
     let ignoreOffensive = !!(move.ignoreOffensive || (ignoreNegativeOffensive && atkBoosts < 0));
     let ignoreDefensive = !!(move.ignoreDefensive || (ignorePositiveDefensive && defBoosts > 0));
     if (ignoreOffensive) {
       this.debug('Negating (sp)atk boost/penalty.');
       atkBoosts = 0;
     }
     if (ignoreDefensive) {
       this.debug('Negating (sp)def boost/penalty.');
       defBoosts = 0;
     }
     if (move.useTargetOffensive) {
       attack = defender.calculateStat(attackStat, atkBoosts);
     } else {
       attack = attacker.calculateStat(attackStat, atkBoosts);
     }
     if (move.useSourceDefensive) {
       defense = attacker.calculateStat(defenseStat, defBoosts);
     } else {
       defense = defender.calculateStat(defenseStat, defBoosts);
     }
     // Apply Stat Modifiers
     attack = this.runEvent('Modify' + statTable[attackStat], attacker, defender, move, attack);
     defense = this.runEvent('Modify' + statTable[defenseStat], defender, attacker, move, defense);
     //int(int(int(2 * L / 5 + 2) * A * P / D) / 50);
     let baseDamage = Math.floor(Math.floor(Math.floor(2 * level / 5 + 2) * basePower * attack / defense) / 50) + 2;
     // multi-target modifier (doubles only)
     if (move.spreadHit) {
       let spreadModifier = move.spreadModifier || 0.75;
       this.debug('Spread modifier: ' + spreadModifier);
       baseDamage = this.modify(baseDamage, spreadModifier);
     }
     // weather modifier
     baseDamage = this.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
     // crit
     if (move.crit) {
       baseDamage = this.modify(baseDamage, move.critModifier || (this.gen >= 6 ? 1.5 : 2));
     }
     // this is not a modifier
     baseDamage = this.randomizer(baseDamage);
     // STAB
     if (move.hasSTAB || type !== '???' && pokemon.hasType(type)) {
       // The "???" type never gets STAB
       // Not even if you Roost in Gen 4 and somehow manage to use
       // Struggle in the same turn.
       // (On second thought, it might be easier to get a Missingno.)
       baseDamage = this.modify(baseDamage, move.stab || 1.5);
     }
     // types
     move.typeMod = target.runEffectiveness(move);
     move.typeMod = this.clampIntRange(move.typeMod, -6, 6);
     if (move.typeMod > 0) {
       if (!suppressMessages) this.add('-supereffective', target);
       for (let i = 0; i < move.typeMod; i++) {
         baseDamage *= 2;
       }
     }
     if (move.typeMod < 0) {
       if (!suppressMessages) this.add('-resisted', target);
       for (let i = 0; i > move.typeMod; i--) {
         baseDamage = Math.floor(baseDamage / 2);
       }
     }
     if (move.crit && !suppressMessages) this.add('-crit', target);
     if (pokemon.status === 'brn' && basePower && move.category === 'Physical' && !pokemon.hasAbility('guts')) {
       if (this.gen < 6 || move.id !== 'facade') {
         baseDamage = this.modify(baseDamage, 0.5);
       }
     }
     // Generation 5 sets damage to 1 before the final damage modifiers only
     if (this.gen === 5 && basePower && !Math.floor(baseDamage)) {
       baseDamage = 1;
     }
     // Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
     baseDamage = this.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
     if (this.gen !== 5 && basePower && !Math.floor(baseDamage)) {
       return 1;
     }
     return Math.floor(baseDamage);
   },
};